浏览代码

[infiniband] Pass address vector in receive completions

Receive completion handlers now get passed an address vector
containing the information extracted from the packet headers
(including the GRH, if present), and only the payload remains in the
I/O buffer.

This breaks the symmetry between transmit and receive completions, so
remove the ib_completer_t type and use an ib_completion_queue_operations
structure instead.

Rename the "destination QPN" and "destination LID" fields in struct
ib_address_vector to reflect its new dual usage.

Since the ib_completion structure now contains only an IB status code,
("syndrome") replace it with a generic gPXE integer status code.
tags/v0.9.6
Michael Brown 16 年前
父节点
当前提交
830e19eb54
共有 5 个文件被更改,包括 172 次插入176 次删除
  1. 27
    23
      src/drivers/infiniband/arbel.c
  2. 25
    21
      src/drivers/infiniband/hermon.c
  3. 49
    60
      src/drivers/net/ipoib.c
  4. 53
    52
      src/include/gpxe/infiniband.h
  5. 18
    20
      src/net/infiniband.c

+ 27
- 23
src/drivers/infiniband/arbel.c 查看文件

1006
 		     ud_address_vector.pd, ARBEL_GLOBAL_PD,
1006
 		     ud_address_vector.pd, ARBEL_GLOBAL_PD,
1007
 		     ud_address_vector.port_number, ibdev->port );
1007
 		     ud_address_vector.port_number, ibdev->port );
1008
 	MLX_FILL_2 ( &wqe->ud, 1,
1008
 	MLX_FILL_2 ( &wqe->ud, 1,
1009
-		     ud_address_vector.rlid, av->dlid,
1009
+		     ud_address_vector.rlid, av->lid,
1010
 		     ud_address_vector.g, av->gid_present );
1010
 		     ud_address_vector.g, av->gid_present );
1011
 	MLX_FILL_2 ( &wqe->ud, 2,
1011
 	MLX_FILL_2 ( &wqe->ud, 2,
1012
 		     ud_address_vector.max_stat_rate,
1012
 		     ud_address_vector.max_stat_rate,
1015
 	MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1015
 	MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1016
 	gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
1016
 	gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
1017
 	memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
1017
 	memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
1018
-	MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp );
1018
+	MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->qpn );
1019
 	MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1019
 	MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1020
 	MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1020
 	MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1021
 	MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
1021
 	MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
1112
 			    struct ib_completion_queue *cq,
1112
 			    struct ib_completion_queue *cq,
1113
 			    union arbelprm_completion_entry *cqe ) {
1113
 			    union arbelprm_completion_entry *cqe ) {
1114
 	struct arbel *arbel = ib_get_drvdata ( ibdev );
1114
 	struct arbel *arbel = ib_get_drvdata ( ibdev );
1115
-	struct ib_completion completion;
1116
 	struct ib_work_queue *wq;
1115
 	struct ib_work_queue *wq;
1117
 	struct ib_queue_pair *qp;
1116
 	struct ib_queue_pair *qp;
1118
 	struct arbel_queue_pair *arbel_qp;
1117
 	struct arbel_queue_pair *arbel_qp;
1120
 	struct arbel_recv_work_queue *arbel_recv_wq;
1119
 	struct arbel_recv_work_queue *arbel_recv_wq;
1121
 	struct arbelprm_recv_wqe *recv_wqe;
1120
 	struct arbelprm_recv_wqe *recv_wqe;
1122
 	struct io_buffer *iobuf;
1121
 	struct io_buffer *iobuf;
1122
+	struct ib_address_vector av;
1123
+	struct ib_global_route_header *grh;
1123
 	unsigned int opcode;
1124
 	unsigned int opcode;
1124
 	unsigned long qpn;
1125
 	unsigned long qpn;
1125
 	int is_send;
1126
 	int is_send;
1126
 	unsigned long wqe_adr;
1127
 	unsigned long wqe_adr;
1127
 	unsigned int wqe_idx;
1128
 	unsigned int wqe_idx;
1129
+	size_t len;
1128
 	int rc = 0;
1130
 	int rc = 0;
1129
 
1131
 
1130
 	/* Parse completion */
1132
 	/* Parse completion */
1131
-	memset ( &completion, 0, sizeof ( completion ) );
1132
 	qpn = MLX_GET ( &cqe->normal, my_qpn );
1133
 	qpn = MLX_GET ( &cqe->normal, my_qpn );
1133
 	is_send = MLX_GET ( &cqe->normal, s );
1134
 	is_send = MLX_GET ( &cqe->normal, s );
1134
 	wqe_adr = ( MLX_GET ( &cqe->normal, wqe_adr ) << 6 );
1135
 	wqe_adr = ( MLX_GET ( &cqe->normal, wqe_adr ) << 6 );
1136
 	if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
1137
 	if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
1137
 		/* "s" field is not valid for error opcodes */
1138
 		/* "s" field is not valid for error opcodes */
1138
 		is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR );
1139
 		is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR );
1139
-		completion.syndrome = MLX_GET ( &cqe->error, syndrome );
1140
-		DBGC ( arbel, "Arbel %p CPN %lx syndrome %x vendor %lx\n",
1141
-		       arbel, cq->cqn, completion.syndrome,
1140
+		DBGC ( arbel, "Arbel %p CPN %lx syndrome %lx vendor %lx\n",
1141
+		       arbel, cq->cqn, MLX_GET ( &cqe->error, syndrome ),
1142
 		       MLX_GET ( &cqe->error, vendor_code ) );
1142
 		       MLX_GET ( &cqe->error, vendor_code ) );
1143
 		rc = -EIO;
1143
 		rc = -EIO;
1144
 		/* Don't return immediately; propagate error to completer */
1144
 		/* Don't return immediately; propagate error to completer */
1176
 	}
1176
 	}
1177
 	wq->iobufs[wqe_idx] = NULL;
1177
 	wq->iobufs[wqe_idx] = NULL;
1178
 
1178
 
1179
-	/* Fill in length for received packets */
1180
-	if ( ! is_send ) {
1181
-		completion.len = MLX_GET ( &cqe->normal, byte_cnt );
1179
+	if ( is_send ) {
1180
+		/* Hand off to completion handler */
1181
+		ib_complete_send ( ibdev, qp, iobuf, rc );
1182
+	} else {
1183
+		/* Set received length */
1184
+		len = MLX_GET ( &cqe->normal, byte_cnt );
1182
 		recv_wqe = &arbel_recv_wq->wqe[wqe_idx].recv;
1185
 		recv_wqe = &arbel_recv_wq->wqe[wqe_idx].recv;
1183
 		assert ( MLX_GET ( &recv_wqe->data[0], local_address_l ) ==
1186
 		assert ( MLX_GET ( &recv_wqe->data[0], local_address_l ) ==
1184
 			 virt_to_bus ( iobuf->data ) );
1187
 			 virt_to_bus ( iobuf->data ) );
1187
 		MLX_FILL_1 ( &recv_wqe->data[0], 0, byte_count, 0 );
1190
 		MLX_FILL_1 ( &recv_wqe->data[0], 0, byte_count, 0 );
1188
 		MLX_FILL_1 ( &recv_wqe->data[0], 1,
1191
 		MLX_FILL_1 ( &recv_wqe->data[0], 1,
1189
 			     l_key, ARBEL_INVALID_LKEY );
1192
 			     l_key, ARBEL_INVALID_LKEY );
1190
-		if ( completion.len > iob_tailroom ( iobuf ) ) {
1191
-			DBGC ( arbel, "Arbel %p CQN %lx QPN %lx IDX %x "
1192
-			       "overlength received packet length %zd\n",
1193
-			       arbel, cq->cqn, qpn, wqe_idx, completion.len );
1194
-			return -EIO;
1195
-		}
1196
-	}
1197
-
1198
-	/* Pass off to caller's completion handler */
1199
-	if ( is_send ) {
1200
-		ib_complete_send ( ibdev, qp, &completion, iobuf );
1201
-	} else {
1202
-		ib_complete_recv ( ibdev, qp, &completion, iobuf );
1193
+		assert ( len <= iob_tailroom ( iobuf ) );
1194
+		iob_put ( iobuf, len );
1195
+		assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
1196
+		grh = iobuf->data;
1197
+		iob_pull ( iobuf, sizeof ( *grh ) );
1198
+		/* Construct address vector */
1199
+		memset ( &av, 0, sizeof ( av ) );
1200
+		av.qpn = MLX_GET ( &cqe->normal, rqpn );
1201
+		av.lid = MLX_GET ( &cqe->normal, rlid );
1202
+		av.sl = MLX_GET ( &cqe->normal, sl );
1203
+		av.gid_present = MLX_GET ( &cqe->normal, g );
1204
+		memcpy ( &av.gid, &grh->sgid, sizeof ( av.gid ) );
1205
+		/* Hand off to completion handler */
1206
+		ib_complete_recv ( ibdev, qp, &av, iobuf, rc );
1203
 	}
1207
 	}
1204
 
1208
 
1205
 	return rc;
1209
 	return rc;

+ 25
- 21
src/drivers/infiniband/hermon.c 查看文件

1015
 		     ud_address_vector.pd, HERMON_GLOBAL_PD,
1015
 		     ud_address_vector.pd, HERMON_GLOBAL_PD,
1016
 		     ud_address_vector.port_number, ibdev->port );
1016
 		     ud_address_vector.port_number, ibdev->port );
1017
 	MLX_FILL_2 ( &wqe->ud, 1,
1017
 	MLX_FILL_2 ( &wqe->ud, 1,
1018
-		     ud_address_vector.rlid, av->dlid,
1018
+		     ud_address_vector.rlid, av->lid,
1019
 		     ud_address_vector.g, av->gid_present );
1019
 		     ud_address_vector.g, av->gid_present );
1020
 	MLX_FILL_1 ( &wqe->ud, 2,
1020
 	MLX_FILL_1 ( &wqe->ud, 2,
1021
 		     ud_address_vector.max_stat_rate,
1021
 		     ud_address_vector.max_stat_rate,
1024
 	MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1024
 	MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1025
 	gid = ( av->gid_present ? &av->gid : &hermon_no_gid );
1025
 	gid = ( av->gid_present ? &av->gid : &hermon_no_gid );
1026
 	memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
1026
 	memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
1027
-	MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp );
1027
+	MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->qpn );
1028
 	MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1028
 	MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1029
 	MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1029
 	MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1030
 	MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->reserved_lkey );
1030
 	MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->reserved_lkey );
1107
 			     struct ib_completion_queue *cq,
1107
 			     struct ib_completion_queue *cq,
1108
 			     union hermonprm_completion_entry *cqe ) {
1108
 			     union hermonprm_completion_entry *cqe ) {
1109
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
1109
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
1110
-	struct ib_completion completion;
1111
 	struct ib_work_queue *wq;
1110
 	struct ib_work_queue *wq;
1112
 	struct ib_queue_pair *qp;
1111
 	struct ib_queue_pair *qp;
1113
 	struct hermon_queue_pair *hermon_qp;
1112
 	struct hermon_queue_pair *hermon_qp;
1114
 	struct io_buffer *iobuf;
1113
 	struct io_buffer *iobuf;
1114
+	struct ib_address_vector av;
1115
+	struct ib_global_route_header *grh;
1115
 	unsigned int opcode;
1116
 	unsigned int opcode;
1116
 	unsigned long qpn;
1117
 	unsigned long qpn;
1117
 	int is_send;
1118
 	int is_send;
1118
 	unsigned int wqe_idx;
1119
 	unsigned int wqe_idx;
1120
+	size_t len;
1119
 	int rc = 0;
1121
 	int rc = 0;
1120
 
1122
 
1121
 	/* Parse completion */
1123
 	/* Parse completion */
1122
-	memset ( &completion, 0, sizeof ( completion ) );
1123
 	qpn = MLX_GET ( &cqe->normal, qpn );
1124
 	qpn = MLX_GET ( &cqe->normal, qpn );
1124
 	is_send = MLX_GET ( &cqe->normal, s_r );
1125
 	is_send = MLX_GET ( &cqe->normal, s_r );
1125
 	opcode = MLX_GET ( &cqe->normal, opcode );
1126
 	opcode = MLX_GET ( &cqe->normal, opcode );
1126
 	if ( opcode >= HERMON_OPCODE_RECV_ERROR ) {
1127
 	if ( opcode >= HERMON_OPCODE_RECV_ERROR ) {
1127
 		/* "s" field is not valid for error opcodes */
1128
 		/* "s" field is not valid for error opcodes */
1128
 		is_send = ( opcode == HERMON_OPCODE_SEND_ERROR );
1129
 		is_send = ( opcode == HERMON_OPCODE_SEND_ERROR );
1129
-		completion.syndrome = MLX_GET ( &cqe->error, syndrome );
1130
-		DBGC ( hermon, "Hermon %p CQN %lx syndrome %x vendor %lx\n",
1131
-		       hermon, cq->cqn, completion.syndrome,
1130
+		DBGC ( hermon, "Hermon %p CQN %lx syndrome %lx vendor %lx\n",
1131
+		       hermon, cq->cqn, MLX_GET ( &cqe->error, syndrome ),
1132
 		       MLX_GET ( &cqe->error, vendor_error_syndrome ) );
1132
 		       MLX_GET ( &cqe->error, vendor_error_syndrome ) );
1133
 		rc = -EIO;
1133
 		rc = -EIO;
1134
 		/* Don't return immediately; propagate error to completer */
1134
 		/* Don't return immediately; propagate error to completer */
1155
 	}
1155
 	}
1156
 	wq->iobufs[wqe_idx] = NULL;
1156
 	wq->iobufs[wqe_idx] = NULL;
1157
 
1157
 
1158
-	/* Fill in length for received packets */
1159
-	if ( ! is_send ) {
1160
-		completion.len = MLX_GET ( &cqe->normal, byte_cnt );
1161
-		if ( completion.len > iob_tailroom ( iobuf ) ) {
1162
-			DBGC ( hermon, "Hermon %p CQN %lx QPN %lx IDX %x "
1163
-			       "overlength received packet length %zd\n",
1164
-			       hermon, cq->cqn, qpn, wqe_idx, completion.len );
1165
-			return -EIO;
1166
-		}
1167
-	}
1168
-
1169
-	/* Pass off to caller's completion handler */
1170
 	if ( is_send ) {
1158
 	if ( is_send ) {
1171
-		ib_complete_send ( ibdev, qp, &completion, iobuf );
1159
+		/* Hand off to completion handler */
1160
+		ib_complete_send ( ibdev, qp, iobuf, rc );
1172
 	} else {
1161
 	} else {
1173
-		ib_complete_recv ( ibdev, qp, &completion, iobuf );
1162
+		/* Set received length */
1163
+		len = MLX_GET ( &cqe->normal, byte_cnt );
1164
+		assert ( len <= iob_tailroom ( iobuf ) );
1165
+		iob_put ( iobuf, len );
1166
+		assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
1167
+		grh = iobuf->data;
1168
+		iob_pull ( iobuf, sizeof ( *grh ) );
1169
+		/* Construct address vector */
1170
+		memset ( &av, 0, sizeof ( av ) );
1171
+		av.qpn = MLX_GET ( &cqe->normal, srq_rqpn );
1172
+		av.lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
1173
+		av.sl = MLX_GET ( &cqe->normal, sl );
1174
+		av.gid_present = MLX_GET ( &cqe->normal, g );
1175
+		memcpy ( &av.gid, &grh->sgid, sizeof ( av.gid ) );
1176
+		/* Hand off to completion handler */
1177
+		ib_complete_recv ( ibdev, qp, &av, iobuf, rc );
1174
 	}
1178
 	}
1175
 
1179
 
1176
 	return rc;
1180
 	return rc;

+ 49
- 60
src/drivers/net/ipoib.c 查看文件

277
  * @v ipoib		IPoIB device
277
  * @v ipoib		IPoIB device
278
  * @v qset		Queue set
278
  * @v qset		Queue set
279
  * @v num_cqes		Number of completion queue entries
279
  * @v num_cqes		Number of completion queue entries
280
+ * @v cq_op		Completion queue operations
280
  * @v num_send_wqes	Number of send work queue entries
281
  * @v num_send_wqes	Number of send work queue entries
281
- * @v complete_send	Send completion handler
282
  * @v num_recv_wqes	Number of receive work queue entries
282
  * @v num_recv_wqes	Number of receive work queue entries
283
- * @v complete_recv	Receive completion handler
284
  * @v qkey		Queue key
283
  * @v qkey		Queue key
285
  * @ret rc		Return status code
284
  * @ret rc		Return status code
286
  */
285
  */
287
 static int ipoib_create_qset ( struct ipoib_device *ipoib,
286
 static int ipoib_create_qset ( struct ipoib_device *ipoib,
288
 			       struct ipoib_queue_set *qset,
287
 			       struct ipoib_queue_set *qset,
289
 			       unsigned int num_cqes,
288
 			       unsigned int num_cqes,
289
+			       struct ib_completion_queue_operations *cq_op,
290
 			       unsigned int num_send_wqes,
290
 			       unsigned int num_send_wqes,
291
-			       ib_completer_t complete_send,
292
 			       unsigned int num_recv_wqes,
291
 			       unsigned int num_recv_wqes,
293
-			       ib_completer_t complete_recv,
294
 			       unsigned long qkey ) {
292
 			       unsigned long qkey ) {
295
 	struct ib_device *ibdev = ipoib->ibdev;
293
 	struct ib_device *ibdev = ipoib->ibdev;
296
 	int rc;
294
 	int rc;
303
 	qset->recv_max_fill = num_recv_wqes;
301
 	qset->recv_max_fill = num_recv_wqes;
304
 
302
 
305
 	/* Allocate completion queue */
303
 	/* Allocate completion queue */
306
-	qset->cq = ib_create_cq ( ibdev, num_cqes, complete_send,
307
-				  complete_recv );
304
+	qset->cq = ib_create_cq ( ibdev, num_cqes, cq_op );
308
 	if ( ! qset->cq ) {
305
 	if ( ! qset->cq ) {
309
 		DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
306
 		DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
310
 		       ipoib );
307
 		       ipoib );
391
 
388
 
392
 	/* Construct address vector */
389
 	/* Construct address vector */
393
 	memset ( &av, 0, sizeof ( av ) );
390
 	memset ( &av, 0, sizeof ( av ) );
394
-	av.dlid = ibdev->sm_lid;
395
-	av.dest_qp = IB_SA_QPN;
391
+	av.lid = ibdev->sm_lid;
392
+	av.qpn = IB_SA_QPN;
396
 	av.qkey = IB_GLOBAL_QKEY;
393
 	av.qkey = IB_GLOBAL_QKEY;
397
 
394
 
398
 	/* Post send request */
395
 	/* Post send request */
451
 
448
 
452
 	/* Construct address vector */
449
 	/* Construct address vector */
453
 	memset ( &av, 0, sizeof ( av ) );
450
 	memset ( &av, 0, sizeof ( av ) );
454
-	av.dlid = ibdev->sm_lid;
455
-	av.dest_qp = IB_SA_QPN;
451
+	av.lid = ibdev->sm_lid;
452
+	av.qpn = IB_SA_QPN;
456
 	av.qkey = IB_GLOBAL_QKEY;
453
 	av.qkey = IB_GLOBAL_QKEY;
457
 
454
 
458
 	/* Post send request */
455
 	/* Post send request */
503
 	av.gid_present = 1;
500
 	av.gid_present = 1;
504
 	if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
501
 	if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
505
 		/* Broadcast address */
502
 		/* Broadcast address */
506
-		av.dest_qp = IB_BROADCAST_QPN;
507
-		av.dlid = ipoib->broadcast_lid;
503
+		av.qpn = IB_BROADCAST_QPN;
504
+		av.lid = ipoib->broadcast_lid;
508
 		gid = &ipoib->broadcast_gid;
505
 		gid = &ipoib->broadcast_gid;
509
 	} else {
506
 	} else {
510
 		/* Unicast - look in path cache */
507
 		/* Unicast - look in path cache */
516
 			netdev_tx_complete ( netdev, iobuf );
513
 			netdev_tx_complete ( netdev, iobuf );
517
 			return rc;
514
 			return rc;
518
 		}
515
 		}
519
-		av.dest_qp = ntohl ( ipoib_pshdr->peer.qpn );
520
-		av.dlid = path->dlid;
516
+		av.qpn = ntohl ( ipoib_pshdr->peer.qpn );
517
+		av.lid = path->dlid;
521
 		av.rate = path->rate;
518
 		av.rate = path->rate;
522
 		av.sl = path->sl;
519
 		av.sl = path->sl;
523
 		gid = &ipoib_pshdr->peer.gid;
520
 		gid = &ipoib_pshdr->peer.gid;
532
  *
529
  *
533
  * @v ibdev		Infiniband device
530
  * @v ibdev		Infiniband device
534
  * @v qp		Queue pair
531
  * @v qp		Queue pair
535
- * @v completion	Completion
536
  * @v iobuf		I/O buffer
532
  * @v iobuf		I/O buffer
533
+ * @v rc		Completion status code
537
  */
534
  */
538
 static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
535
 static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
539
 				       struct ib_queue_pair *qp,
536
 				       struct ib_queue_pair *qp,
540
-				       struct ib_completion *completion,
541
-				       struct io_buffer *iobuf ) {
537
+				       struct io_buffer *iobuf, int rc ) {
542
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
538
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
543
 
539
 
544
-	netdev_tx_complete_err ( netdev, iobuf,
545
-				 ( completion->syndrome ? -EIO : 0 ) );
540
+	netdev_tx_complete_err ( netdev, iobuf, rc );
546
 }
541
 }
547
 
542
 
548
 /**
543
 /**
550
  *
545
  *
551
  * @v ibdev		Infiniband device
546
  * @v ibdev		Infiniband device
552
  * @v qp		Queue pair
547
  * @v qp		Queue pair
553
- * @v completion	Completion
548
+ * @v av		Address vector, or NULL
554
  * @v iobuf		I/O buffer
549
  * @v iobuf		I/O buffer
550
+ * @v rc		Completion status code
555
  */
551
  */
556
 static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
552
 static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
557
 				       struct ib_queue_pair *qp,
553
 				       struct ib_queue_pair *qp,
558
-				       struct ib_completion *completion,
559
-				       struct io_buffer *iobuf ) {
554
+				       struct ib_address_vector *av __unused,
555
+				       struct io_buffer *iobuf, int rc ) {
560
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
556
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
561
 	struct ipoib_device *ipoib = netdev->priv;
557
 	struct ipoib_device *ipoib = netdev->priv;
562
 	struct ipoib_pseudo_hdr *ipoib_pshdr;
558
 	struct ipoib_pseudo_hdr *ipoib_pshdr;
563
 
559
 
564
-	if ( completion->syndrome ) {
565
-		netdev_rx_err ( netdev, iobuf, -EIO );
560
+	if ( rc != 0 ) {
561
+		netdev_rx_err ( netdev, iobuf, rc );
566
 		return;
562
 		return;
567
 	}
563
 	}
568
 
564
 
569
-	iob_put ( iobuf, completion->len );
570
-	if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
571
-		DBGC ( ipoib, "IPoIB %p received data packet too short to "
572
-		       "contain GRH\n", ipoib );
573
-		DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
574
-		netdev_rx_err ( netdev, iobuf, -EIO );
575
-		return;
576
-	}
577
-	iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
578
-
579
 	if ( iob_len ( iobuf ) < sizeof ( struct ipoib_real_hdr ) ) {
565
 	if ( iob_len ( iobuf ) < sizeof ( struct ipoib_real_hdr ) ) {
580
 		DBGC ( ipoib, "IPoIB %p received data packet too short to "
566
 		DBGC ( ipoib, "IPoIB %p received data packet too short to "
581
 		       "contain IPoIB header\n", ipoib );
567
 		       "contain IPoIB header\n", ipoib );
590
 	netdev_rx ( netdev, iobuf );
576
 	netdev_rx ( netdev, iobuf );
591
 }
577
 }
592
 
578
 
579
+/** IPoIB data completion operations */
580
+static struct ib_completion_queue_operations ipoib_data_cq_op = {
581
+	.complete_send = ipoib_data_complete_send,
582
+	.complete_recv = ipoib_data_complete_recv,
583
+};
584
+
593
 /**
585
 /**
594
  * Handle IPoIB metadata send completion
586
  * Handle IPoIB metadata send completion
595
  *
587
  *
596
  * @v ibdev		Infiniband device
588
  * @v ibdev		Infiniband device
597
  * @v qp		Queue pair
589
  * @v qp		Queue pair
598
- * @v completion	Completion
599
  * @v iobuf		I/O buffer
590
  * @v iobuf		I/O buffer
591
+ * @v rc		Completion status code
600
  */
592
  */
601
 static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
593
 static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
602
 				       struct ib_queue_pair *qp,
594
 				       struct ib_queue_pair *qp,
603
-				       struct ib_completion *completion,
604
-				       struct io_buffer *iobuf ) {
595
+				       struct io_buffer *iobuf, int rc ) {
605
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
596
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
606
 	struct ipoib_device *ipoib = netdev->priv;
597
 	struct ipoib_device *ipoib = netdev->priv;
607
 
598
 
608
-	if ( completion->syndrome ) {
609
-		DBGC ( ipoib, "IPoIB %p metadata TX completion error %x\n",
610
-		       ipoib, completion->syndrome );
599
+	if ( rc != 0 ) {
600
+		DBGC ( ipoib, "IPoIB %p metadata TX completion error: %s\n",
601
+		       ipoib, strerror ( rc ) );
611
 	}
602
 	}
612
 	free_iob ( iobuf );
603
 	free_iob ( iobuf );
613
 }
604
 }
673
  *
664
  *
674
  * @v ibdev		Infiniband device
665
  * @v ibdev		Infiniband device
675
  * @v qp		Queue pair
666
  * @v qp		Queue pair
676
- * @v completion	Completion
667
+ * @v av		Address vector, or NULL
677
  * @v iobuf		I/O buffer
668
  * @v iobuf		I/O buffer
669
+ * @v rc		Completion status code
678
  */
670
  */
679
-static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
680
-				       struct ib_queue_pair *qp,
681
-				       struct ib_completion *completion,
682
-				       struct io_buffer *iobuf ) {
671
+static void
672
+ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
673
+			   struct ib_queue_pair *qp,
674
+			   struct ib_address_vector *av __unused,
675
+			   struct io_buffer *iobuf, int rc ) {
683
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
676
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
684
 	struct ipoib_device *ipoib = netdev->priv;
677
 	struct ipoib_device *ipoib = netdev->priv;
685
 	union ib_mad *mad;
678
 	union ib_mad *mad;
686
 
679
 
687
-	if ( completion->syndrome ) {
688
-		DBGC ( ipoib, "IPoIB %p metadata RX completion error %x\n",
689
-		       ipoib, completion->syndrome );
680
+	if ( rc != 0 ) {
681
+		DBGC ( ipoib, "IPoIB %p metadata RX completion error: %s\n",
682
+		       ipoib, strerror ( rc ) );
690
 		goto done;
683
 		goto done;
691
 	}
684
 	}
692
 
685
 
693
-	iob_put ( iobuf, completion->len );
694
-	if ( iob_len ( iobuf ) < sizeof ( struct ib_global_route_header ) ) {
695
-		DBGC ( ipoib, "IPoIB %p received metadata packet too short "
696
-		       "to contain GRH\n", ipoib );
697
-		DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
698
-		goto done;
699
-	}
700
-	iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
701
 	if ( iob_len ( iobuf ) < sizeof ( *mad ) ) {
686
 	if ( iob_len ( iobuf ) < sizeof ( *mad ) ) {
702
 		DBGC ( ipoib, "IPoIB %p received metadata packet too short "
687
 		DBGC ( ipoib, "IPoIB %p received metadata packet too short "
703
 		       "to contain reply\n", ipoib );
688
 		       "to contain reply\n", ipoib );
730
 	free_iob ( iobuf );
715
 	free_iob ( iobuf );
731
 }
716
 }
732
 
717
 
718
+/** IPoIB metadata completion operations */
719
+static struct ib_completion_queue_operations ipoib_meta_cq_op = {
720
+	.complete_send = ipoib_meta_complete_send,
721
+	.complete_recv = ipoib_meta_complete_recv,
722
+};
723
+
733
 /**
724
 /**
734
  * Refill IPoIB receive ring
725
  * Refill IPoIB receive ring
735
  *
726
  *
846
 	/* Allocate metadata queue set */
837
 	/* Allocate metadata queue set */
847
 	if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
838
 	if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
848
 					IPOIB_META_NUM_CQES,
839
 					IPOIB_META_NUM_CQES,
840
+					&ipoib_meta_cq_op,
849
 					IPOIB_META_NUM_SEND_WQES,
841
 					IPOIB_META_NUM_SEND_WQES,
850
-					ipoib_meta_complete_send,
851
 					IPOIB_META_NUM_RECV_WQES,
842
 					IPOIB_META_NUM_RECV_WQES,
852
-					ipoib_meta_complete_recv,
853
 					IB_GLOBAL_QKEY ) ) != 0 ) {
843
 					IB_GLOBAL_QKEY ) ) != 0 ) {
854
 		DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
844
 		DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
855
 		       ipoib, strerror ( rc ) );
845
 		       ipoib, strerror ( rc ) );
859
 	/* Allocate data queue set */
849
 	/* Allocate data queue set */
860
 	if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
850
 	if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
861
 					IPOIB_DATA_NUM_CQES,
851
 					IPOIB_DATA_NUM_CQES,
852
+					&ipoib_data_cq_op,
862
 					IPOIB_DATA_NUM_SEND_WQES,
853
 					IPOIB_DATA_NUM_SEND_WQES,
863
-					ipoib_data_complete_send,
864
 					IPOIB_DATA_NUM_RECV_WQES,
854
 					IPOIB_DATA_NUM_RECV_WQES,
865
-					ipoib_data_complete_recv,
866
 					IB_GLOBAL_QKEY ) ) != 0 ) {
855
 					IB_GLOBAL_QKEY ) ) != 0 ) {
867
 		DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
856
 		DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
868
 		       ipoib, strerror ( rc ) );
857
 		       ipoib, strerror ( rc ) );

+ 53
- 52
src/include/gpxe/infiniband.h 查看文件

52
 
52
 
53
 struct ib_device;
53
 struct ib_device;
54
 struct ib_queue_pair;
54
 struct ib_queue_pair;
55
+struct ib_address_vector;
55
 struct ib_completion_queue;
56
 struct ib_completion_queue;
56
 
57
 
57
 /** An Infiniband Work Queue */
58
 /** An Infiniband Work Queue */
103
 	IB_MODIFY_QKEY = 0x0001,
104
 	IB_MODIFY_QKEY = 0x0001,
104
 };
105
 };
105
 
106
 
106
-/** An Infiniband completion */
107
-struct ib_completion {
108
-	/** Syndrome
107
+/** An Infiniband Address Vector */
108
+struct ib_address_vector {
109
+	/** Queue Pair Number */
110
+	unsigned long qpn;
111
+	/** Queue key
109
 	 *
112
 	 *
110
-	 * If non-zero, then the completion is in error.
113
+	 * Not specified for received packets.
111
 	 */
114
 	 */
112
-	unsigned int syndrome;
113
-	/** Length */
114
-	size_t len;
115
+	unsigned long qkey;
116
+	/** Local ID */
117
+	unsigned int lid;
118
+	/** Rate
119
+	 *
120
+	 * Not specified for received packets.
121
+	 */
122
+	unsigned int rate;
123
+	/** Service level */
124
+	unsigned int sl;
125
+	/** GID is present */
126
+	unsigned int gid_present;
127
+	/** GID, if present */
128
+	struct ib_gid gid;
115
 };
129
 };
116
 
130
 
117
-/** Infiniband completion syndromes */
118
-enum ib_syndrome {
119
-	IB_SYN_NONE = 0,
120
-	IB_SYN_LOCAL_LENGTH = 1,
121
-	IB_SYN_LOCAL_QP = 2,
122
-	IB_SYN_LOCAL_PROT = 4,
131
+/** Infiniband completion queue operations */
132
+struct ib_completion_queue_operations {
133
+	/**
134
+	 * Complete Send WQE
135
+	 *
136
+	 * @v ibdev		Infiniband device
137
+	 * @v qp		Queue pair
138
+	 * @v iobuf		I/O buffer
139
+	 * @v rc		Completion status code
140
+	 */
141
+	void ( * complete_send ) ( struct ib_device *ibdev,
142
+				   struct ib_queue_pair *qp,
143
+				   struct io_buffer *iobuf, int rc );
144
+	/**
145
+	 * Complete Receive WQE
146
+	 *
147
+	 * @v ibdev		Infiniband device
148
+	 * @v qp		Queue pair
149
+	 * @v av		Address vector, or NULL
150
+	 * @v iobuf		I/O buffer
151
+	 * @v rc		Completion status code
152
+	 */
153
+	void ( * complete_recv ) ( struct ib_device *ibdev,
154
+				   struct ib_queue_pair *qp,
155
+				   struct ib_address_vector *av,
156
+				   struct io_buffer *iobuf, int rc );
123
 };
157
 };
124
 
158
 
125
-/** An Infiniband completion handler
126
- *
127
- * @v ibdev		Infiniband device
128
- * @v qp		Queue pair
129
- * @v completion	Completion
130
- * @v iobuf		I/O buffer
131
- */
132
-typedef void ( * ib_completer_t ) ( struct ib_device *ibdev,
133
-				    struct ib_queue_pair *qp,
134
-				    struct ib_completion *completion,
135
-				    struct io_buffer *iobuf );
136
-
137
 /** An Infiniband Completion Queue */
159
 /** An Infiniband Completion Queue */
138
 struct ib_completion_queue {
160
 struct ib_completion_queue {
139
 	/** Completion queue number */
161
 	/** Completion queue number */
150
 	unsigned long next_idx;
172
 	unsigned long next_idx;
151
 	/** List of work queues completing to this queue */
173
 	/** List of work queues completing to this queue */
152
 	struct list_head work_queues;
174
 	struct list_head work_queues;
153
-	/** Send completion handler */
154
-	ib_completer_t complete_send;
155
-	/** Receive completion handler */
156
-	ib_completer_t complete_recv;
175
+	/** Completion queue operations */
176
+	struct ib_completion_queue_operations *op;
157
 	/** Driver private data */
177
 	/** Driver private data */
158
 	void *drv_priv;
178
 	void *drv_priv;
159
 };
179
 };
160
 
180
 
161
-/** An Infiniband Address Vector */
162
-struct ib_address_vector {
163
-	/** Destination Queue Pair */
164
-	unsigned int dest_qp;
165
-	/** Queue key */
166
-	unsigned long qkey;
167
-	/** Destination Local ID */
168
-	unsigned int dlid;
169
-	/** Rate */
170
-	unsigned int rate;
171
-	/** Service level */
172
-	unsigned int sl;
173
-	/** GID is present */
174
-	unsigned int gid_present;
175
-	/** GID */
176
-	struct ib_gid gid;
177
-};
178
-
179
 struct ib_mad_hdr;
181
 struct ib_mad_hdr;
180
 
182
 
181
 /**
183
 /**
344
 
346
 
345
 extern struct ib_completion_queue *
347
 extern struct ib_completion_queue *
346
 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
348
 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
347
-	       ib_completer_t complete_send, ib_completer_t complete_recv );
349
+	       struct ib_completion_queue_operations *op );
348
 extern void ib_destroy_cq ( struct ib_device *ibdev,
350
 extern void ib_destroy_cq ( struct ib_device *ibdev,
349
 			    struct ib_completion_queue *cq );
351
 			    struct ib_completion_queue *cq );
350
 extern struct ib_queue_pair *
352
 extern struct ib_queue_pair *
364
 			  struct io_buffer *iobuf );
366
 			  struct io_buffer *iobuf );
365
 extern void ib_complete_send ( struct ib_device *ibdev,
367
 extern void ib_complete_send ( struct ib_device *ibdev,
366
 			       struct ib_queue_pair *qp,
368
 			       struct ib_queue_pair *qp,
367
-			       struct ib_completion *completion,
368
-			       struct io_buffer *iobuf );
369
+			       struct io_buffer *iobuf, int rc );
369
 extern void ib_complete_recv ( struct ib_device *ibdev,
370
 extern void ib_complete_recv ( struct ib_device *ibdev,
370
 			       struct ib_queue_pair *qp,
371
 			       struct ib_queue_pair *qp,
371
-			       struct ib_completion *completion,
372
-			       struct io_buffer *iobuf );
372
+			       struct ib_address_vector *av,
373
+			       struct io_buffer *iobuf, int rc );
373
 extern struct ib_device * alloc_ibdev ( size_t priv_size );
374
 extern struct ib_device * alloc_ibdev ( size_t priv_size );
374
 extern int register_ibdev ( struct ib_device *ibdev );
375
 extern int register_ibdev ( struct ib_device *ibdev );
375
 extern void unregister_ibdev ( struct ib_device *ibdev );
376
 extern void unregister_ibdev ( struct ib_device *ibdev );

+ 18
- 20
src/net/infiniband.c 查看文件

46
  *
46
  *
47
  * @v ibdev		Infiniband device
47
  * @v ibdev		Infiniband device
48
  * @v num_cqes		Number of completion queue entries
48
  * @v num_cqes		Number of completion queue entries
49
- * @v complete_send	Send completion handler
50
- * @v complete_recv	Receive completion handler
49
+ * @v op		Completion queue operations
51
  * @ret cq		New completion queue
50
  * @ret cq		New completion queue
52
  */
51
  */
53
 struct ib_completion_queue *
52
 struct ib_completion_queue *
54
 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
53
 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
55
-	       ib_completer_t complete_send, ib_completer_t complete_recv ) {
54
+	       struct ib_completion_queue_operations *op ) {
56
 	struct ib_completion_queue *cq;
55
 	struct ib_completion_queue *cq;
57
 	int rc;
56
 	int rc;
58
 
57
 
64
 		return NULL;
63
 		return NULL;
65
 	cq->num_cqes = num_cqes;
64
 	cq->num_cqes = num_cqes;
66
 	INIT_LIST_HEAD ( &cq->work_queues );
65
 	INIT_LIST_HEAD ( &cq->work_queues );
67
-	cq->complete_send = complete_send;
68
-	cq->complete_recv = complete_recv;
66
+	cq->op = op;
69
 
67
 
70
 	/* Perform device-specific initialisation and get CQN */
68
 	/* Perform device-specific initialisation and get CQN */
71
 	if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
69
 	if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
195
  * @v qp		Queue pair
193
  * @v qp		Queue pair
196
  */
194
  */
197
 void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
195
 void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
198
-	struct ib_completion completion = {
199
-		.syndrome = IB_SYN_LOCAL_QP,
200
-	};
201
 	struct io_buffer *iobuf;
196
 	struct io_buffer *iobuf;
202
 	unsigned int i;
197
 	unsigned int i;
203
 
198
 
210
 	/* Complete any remaining I/O buffers with errors */
205
 	/* Complete any remaining I/O buffers with errors */
211
 	for ( i = 0 ; i < qp->send.num_wqes ; i++ ) {
206
 	for ( i = 0 ; i < qp->send.num_wqes ; i++ ) {
212
 		if ( ( iobuf = qp->send.iobufs[i] ) != NULL )
207
 		if ( ( iobuf = qp->send.iobufs[i] ) != NULL )
213
-			ib_complete_send ( ibdev, qp, &completion, iobuf );
208
+			ib_complete_send ( ibdev, qp, iobuf, -ECANCELED );
214
 	}
209
 	}
215
 	for ( i = 0 ; i < qp->recv.num_wqes ; i++ ) {
210
 	for ( i = 0 ; i < qp->recv.num_wqes ; i++ ) {
216
-		if ( ( iobuf = qp->recv.iobufs[i] ) != NULL )
217
-			ib_complete_recv ( ibdev, qp, &completion, iobuf );
211
+		if ( ( iobuf = qp->recv.iobufs[i] ) != NULL ) {
212
+			ib_complete_recv ( ibdev, qp, NULL, iobuf,
213
+					   -ECANCELED );
214
+		}
218
 	}
215
 	}
219
 
216
 
220
 	/* Remove work queues from completion queue */
217
 	/* Remove work queues from completion queue */
254
  * @ret rc		Return status code
251
  * @ret rc		Return status code
255
  */
252
  */
256
 int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
253
 int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
257
-		   struct ib_address_vector *av, struct io_buffer *iobuf ) {
254
+		   struct ib_address_vector *av,
255
+		   struct io_buffer *iobuf ) {
258
 	int rc;
256
 	int rc;
259
 
257
 
260
 	/* Check queue fill level */
258
 	/* Check queue fill level */
310
  *
308
  *
311
  * @v ibdev		Infiniband device
309
  * @v ibdev		Infiniband device
312
  * @v qp		Queue pair
310
  * @v qp		Queue pair
313
- * @v completion	Completion
314
  * @v iobuf		I/O buffer
311
  * @v iobuf		I/O buffer
312
+ * @v rc		Completion status code
315
  */
313
  */
316
 void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
314
 void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
317
-			struct ib_completion *completion,
318
-			struct io_buffer *iobuf ) {
319
-	qp->send.cq->complete_send ( ibdev, qp, completion, iobuf );
315
+			struct io_buffer *iobuf, int rc ) {
316
+	qp->send.cq->op->complete_send ( ibdev, qp, iobuf, rc );
320
 	qp->send.fill--;
317
 	qp->send.fill--;
321
 }
318
 }
322
 
319
 
325
  *
322
  *
326
  * @v ibdev		Infiniband device
323
  * @v ibdev		Infiniband device
327
  * @v qp		Queue pair
324
  * @v qp		Queue pair
328
- * @v completion	Completion
325
+ * @v av		Address vector
329
  * @v iobuf		I/O buffer
326
  * @v iobuf		I/O buffer
327
+ * @v rc		Completion status code
330
  */
328
  */
331
 void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
329
 void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
332
-			struct ib_completion *completion,
333
-			struct io_buffer *iobuf ) {
334
-	qp->recv.cq->complete_recv ( ibdev, qp, completion, iobuf );
330
+			struct ib_address_vector *av,
331
+			struct io_buffer *iobuf, int rc ) {
332
+	qp->recv.cq->op->complete_recv ( ibdev, qp, av, iobuf, rc );
335
 	qp->recv.fill--;
333
 	qp->recv.fill--;
336
 }
334
 }
337
 
335
 

正在加载...
取消
保存