Przeglądaj źródła

[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 15 lat temu
rodzic
commit
830e19eb54

+ 27
- 23
src/drivers/infiniband/arbel.c Wyświetl plik

@@ -1006,7 +1006,7 @@ static int arbel_post_send ( struct ib_device *ibdev,
1006 1006
 		     ud_address_vector.pd, ARBEL_GLOBAL_PD,
1007 1007
 		     ud_address_vector.port_number, ibdev->port );
1008 1008
 	MLX_FILL_2 ( &wqe->ud, 1,
1009
-		     ud_address_vector.rlid, av->dlid,
1009
+		     ud_address_vector.rlid, av->lid,
1010 1010
 		     ud_address_vector.g, av->gid_present );
1011 1011
 	MLX_FILL_2 ( &wqe->ud, 2,
1012 1012
 		     ud_address_vector.max_stat_rate,
@@ -1015,7 +1015,7 @@ static int arbel_post_send ( struct ib_device *ibdev,
1015 1015
 	MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1016 1016
 	gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
1017 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 1019
 	MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1020 1020
 	MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1021 1021
 	MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
@@ -1112,7 +1112,6 @@ static int arbel_complete ( struct ib_device *ibdev,
1112 1112
 			    struct ib_completion_queue *cq,
1113 1113
 			    union arbelprm_completion_entry *cqe ) {
1114 1114
 	struct arbel *arbel = ib_get_drvdata ( ibdev );
1115
-	struct ib_completion completion;
1116 1115
 	struct ib_work_queue *wq;
1117 1116
 	struct ib_queue_pair *qp;
1118 1117
 	struct arbel_queue_pair *arbel_qp;
@@ -1120,15 +1119,17 @@ static int arbel_complete ( struct ib_device *ibdev,
1120 1119
 	struct arbel_recv_work_queue *arbel_recv_wq;
1121 1120
 	struct arbelprm_recv_wqe *recv_wqe;
1122 1121
 	struct io_buffer *iobuf;
1122
+	struct ib_address_vector av;
1123
+	struct ib_global_route_header *grh;
1123 1124
 	unsigned int opcode;
1124 1125
 	unsigned long qpn;
1125 1126
 	int is_send;
1126 1127
 	unsigned long wqe_adr;
1127 1128
 	unsigned int wqe_idx;
1129
+	size_t len;
1128 1130
 	int rc = 0;
1129 1131
 
1130 1132
 	/* Parse completion */
1131
-	memset ( &completion, 0, sizeof ( completion ) );
1132 1133
 	qpn = MLX_GET ( &cqe->normal, my_qpn );
1133 1134
 	is_send = MLX_GET ( &cqe->normal, s );
1134 1135
 	wqe_adr = ( MLX_GET ( &cqe->normal, wqe_adr ) << 6 );
@@ -1136,9 +1137,8 @@ static int arbel_complete ( struct ib_device *ibdev,
1136 1137
 	if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
1137 1138
 		/* "s" field is not valid for error opcodes */
1138 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 1142
 		       MLX_GET ( &cqe->error, vendor_code ) );
1143 1143
 		rc = -EIO;
1144 1144
 		/* Don't return immediately; propagate error to completer */
@@ -1176,9 +1176,12 @@ static int arbel_complete ( struct ib_device *ibdev,
1176 1176
 	}
1177 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 1185
 		recv_wqe = &arbel_recv_wq->wqe[wqe_idx].recv;
1183 1186
 		assert ( MLX_GET ( &recv_wqe->data[0], local_address_l ) ==
1184 1187
 			 virt_to_bus ( iobuf->data ) );
@@ -1187,19 +1190,20 @@ static int arbel_complete ( struct ib_device *ibdev,
1187 1190
 		MLX_FILL_1 ( &recv_wqe->data[0], 0, byte_count, 0 );
1188 1191
 		MLX_FILL_1 ( &recv_wqe->data[0], 1,
1189 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 1209
 	return rc;

+ 25
- 21
src/drivers/infiniband/hermon.c Wyświetl plik

@@ -1015,7 +1015,7 @@ static int hermon_post_send ( struct ib_device *ibdev,
1015 1015
 		     ud_address_vector.pd, HERMON_GLOBAL_PD,
1016 1016
 		     ud_address_vector.port_number, ibdev->port );
1017 1017
 	MLX_FILL_2 ( &wqe->ud, 1,
1018
-		     ud_address_vector.rlid, av->dlid,
1018
+		     ud_address_vector.rlid, av->lid,
1019 1019
 		     ud_address_vector.g, av->gid_present );
1020 1020
 	MLX_FILL_1 ( &wqe->ud, 2,
1021 1021
 		     ud_address_vector.max_stat_rate,
@@ -1024,7 +1024,7 @@ static int hermon_post_send ( struct ib_device *ibdev,
1024 1024
 	MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1025 1025
 	gid = ( av->gid_present ? &av->gid : &hermon_no_gid );
1026 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 1028
 	MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1029 1029
 	MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1030 1030
 	MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->reserved_lkey );
@@ -1107,28 +1107,28 @@ static int hermon_complete ( struct ib_device *ibdev,
1107 1107
 			     struct ib_completion_queue *cq,
1108 1108
 			     union hermonprm_completion_entry *cqe ) {
1109 1109
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
1110
-	struct ib_completion completion;
1111 1110
 	struct ib_work_queue *wq;
1112 1111
 	struct ib_queue_pair *qp;
1113 1112
 	struct hermon_queue_pair *hermon_qp;
1114 1113
 	struct io_buffer *iobuf;
1114
+	struct ib_address_vector av;
1115
+	struct ib_global_route_header *grh;
1115 1116
 	unsigned int opcode;
1116 1117
 	unsigned long qpn;
1117 1118
 	int is_send;
1118 1119
 	unsigned int wqe_idx;
1120
+	size_t len;
1119 1121
 	int rc = 0;
1120 1122
 
1121 1123
 	/* Parse completion */
1122
-	memset ( &completion, 0, sizeof ( completion ) );
1123 1124
 	qpn = MLX_GET ( &cqe->normal, qpn );
1124 1125
 	is_send = MLX_GET ( &cqe->normal, s_r );
1125 1126
 	opcode = MLX_GET ( &cqe->normal, opcode );
1126 1127
 	if ( opcode >= HERMON_OPCODE_RECV_ERROR ) {
1127 1128
 		/* "s" field is not valid for error opcodes */
1128 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 1132
 		       MLX_GET ( &cqe->error, vendor_error_syndrome ) );
1133 1133
 		rc = -EIO;
1134 1134
 		/* Don't return immediately; propagate error to completer */
@@ -1155,22 +1155,26 @@ static int hermon_complete ( struct ib_device *ibdev,
1155 1155
 	}
1156 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 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 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 1180
 	return rc;

+ 49
- 60
src/drivers/net/ipoib.c Wyświetl plik

@@ -277,20 +277,18 @@ static void ipoib_destroy_qset ( struct ipoib_device *ipoib,
277 277
  * @v ipoib		IPoIB device
278 278
  * @v qset		Queue set
279 279
  * @v num_cqes		Number of completion queue entries
280
+ * @v cq_op		Completion queue operations
280 281
  * @v num_send_wqes	Number of send work queue entries
281
- * @v complete_send	Send completion handler
282 282
  * @v num_recv_wqes	Number of receive work queue entries
283
- * @v complete_recv	Receive completion handler
284 283
  * @v qkey		Queue key
285 284
  * @ret rc		Return status code
286 285
  */
287 286
 static int ipoib_create_qset ( struct ipoib_device *ipoib,
288 287
 			       struct ipoib_queue_set *qset,
289 288
 			       unsigned int num_cqes,
289
+			       struct ib_completion_queue_operations *cq_op,
290 290
 			       unsigned int num_send_wqes,
291
-			       ib_completer_t complete_send,
292 291
 			       unsigned int num_recv_wqes,
293
-			       ib_completer_t complete_recv,
294 292
 			       unsigned long qkey ) {
295 293
 	struct ib_device *ibdev = ipoib->ibdev;
296 294
 	int rc;
@@ -303,8 +301,7 @@ static int ipoib_create_qset ( struct ipoib_device *ipoib,
303 301
 	qset->recv_max_fill = num_recv_wqes;
304 302
 
305 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 305
 	if ( ! qset->cq ) {
309 306
 		DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
310 307
 		       ipoib );
@@ -391,8 +388,8 @@ static int ipoib_get_path_record ( struct ipoib_device *ipoib,
391 388
 
392 389
 	/* Construct address vector */
393 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 393
 	av.qkey = IB_GLOBAL_QKEY;
397 394
 
398 395
 	/* Post send request */
@@ -451,8 +448,8 @@ static int ipoib_mc_member_record ( struct ipoib_device *ipoib,
451 448
 
452 449
 	/* Construct address vector */
453 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 453
 	av.qkey = IB_GLOBAL_QKEY;
457 454
 
458 455
 	/* Post send request */
@@ -503,8 +500,8 @@ static int ipoib_transmit ( struct net_device *netdev,
503 500
 	av.gid_present = 1;
504 501
 	if ( ipoib_pshdr->peer.qpn == htonl ( IPOIB_BROADCAST_QPN ) ) {
505 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 505
 		gid = &ipoib->broadcast_gid;
509 506
 	} else {
510 507
 		/* Unicast - look in path cache */
@@ -516,8 +513,8 @@ static int ipoib_transmit ( struct net_device *netdev,
516 513
 			netdev_tx_complete ( netdev, iobuf );
517 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 518
 		av.rate = path->rate;
522 519
 		av.sl = path->sl;
523 520
 		gid = &ipoib_pshdr->peer.gid;
@@ -532,17 +529,15 @@ static int ipoib_transmit ( struct net_device *netdev,
532 529
  *
533 530
  * @v ibdev		Infiniband device
534 531
  * @v qp		Queue pair
535
- * @v completion	Completion
536 532
  * @v iobuf		I/O buffer
533
+ * @v rc		Completion status code
537 534
  */
538 535
 static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
539 536
 				       struct ib_queue_pair *qp,
540
-				       struct ib_completion *completion,
541
-				       struct io_buffer *iobuf ) {
537
+				       struct io_buffer *iobuf, int rc ) {
542 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,32 +545,23 @@ static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
550 545
  *
551 546
  * @v ibdev		Infiniband device
552 547
  * @v qp		Queue pair
553
- * @v completion	Completion
548
+ * @v av		Address vector, or NULL
554 549
  * @v iobuf		I/O buffer
550
+ * @v rc		Completion status code
555 551
  */
556 552
 static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
557 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 556
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
561 557
 	struct ipoib_device *ipoib = netdev->priv;
562 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 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 565
 	if ( iob_len ( iobuf ) < sizeof ( struct ipoib_real_hdr ) ) {
580 566
 		DBGC ( ipoib, "IPoIB %p received data packet too short to "
581 567
 		       "contain IPoIB header\n", ipoib );
@@ -590,24 +576,29 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
590 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 586
  * Handle IPoIB metadata send completion
595 587
  *
596 588
  * @v ibdev		Infiniband device
597 589
  * @v qp		Queue pair
598
- * @v completion	Completion
599 590
  * @v iobuf		I/O buffer
591
+ * @v rc		Completion status code
600 592
  */
601 593
 static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
602 594
 				       struct ib_queue_pair *qp,
603
-				       struct ib_completion *completion,
604
-				       struct io_buffer *iobuf ) {
595
+				       struct io_buffer *iobuf, int rc ) {
605 596
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
606 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 603
 	free_iob ( iobuf );
613 604
 }
@@ -673,31 +664,25 @@ static void ipoib_recv_mc_member_record ( struct ipoib_device *ipoib,
673 664
  *
674 665
  * @v ibdev		Infiniband device
675 666
  * @v qp		Queue pair
676
- * @v completion	Completion
667
+ * @v av		Address vector, or NULL
677 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 676
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
684 677
 	struct ipoib_device *ipoib = netdev->priv;
685 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 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 686
 	if ( iob_len ( iobuf ) < sizeof ( *mad ) ) {
702 687
 		DBGC ( ipoib, "IPoIB %p received metadata packet too short "
703 688
 		       "to contain reply\n", ipoib );
@@ -730,6 +715,12 @@ static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
730 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 725
  * Refill IPoIB receive ring
735 726
  *
@@ -846,10 +837,9 @@ static int ipoib_open ( struct net_device *netdev ) {
846 837
 	/* Allocate metadata queue set */
847 838
 	if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
848 839
 					IPOIB_META_NUM_CQES,
840
+					&ipoib_meta_cq_op,
849 841
 					IPOIB_META_NUM_SEND_WQES,
850
-					ipoib_meta_complete_send,
851 842
 					IPOIB_META_NUM_RECV_WQES,
852
-					ipoib_meta_complete_recv,
853 843
 					IB_GLOBAL_QKEY ) ) != 0 ) {
854 844
 		DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
855 845
 		       ipoib, strerror ( rc ) );
@@ -859,10 +849,9 @@ static int ipoib_open ( struct net_device *netdev ) {
859 849
 	/* Allocate data queue set */
860 850
 	if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
861 851
 					IPOIB_DATA_NUM_CQES,
852
+					&ipoib_data_cq_op,
862 853
 					IPOIB_DATA_NUM_SEND_WQES,
863
-					ipoib_data_complete_send,
864 854
 					IPOIB_DATA_NUM_RECV_WQES,
865
-					ipoib_data_complete_recv,
866 855
 					IB_GLOBAL_QKEY ) ) != 0 ) {
867 856
 		DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
868 857
 		       ipoib, strerror ( rc ) );

+ 53
- 52
src/include/gpxe/infiniband.h Wyświetl plik

@@ -52,6 +52,7 @@ struct ib_global_route_header {
52 52
 
53 53
 struct ib_device;
54 54
 struct ib_queue_pair;
55
+struct ib_address_vector;
55 56
 struct ib_completion_queue;
56 57
 
57 58
 /** An Infiniband Work Queue */
@@ -103,37 +104,58 @@ enum ib_queue_pair_mods {
103 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 159
 /** An Infiniband Completion Queue */
138 160
 struct ib_completion_queue {
139 161
 	/** Completion queue number */
@@ -150,32 +172,12 @@ struct ib_completion_queue {
150 172
 	unsigned long next_idx;
151 173
 	/** List of work queues completing to this queue */
152 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 177
 	/** Driver private data */
158 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 181
 struct ib_mad_hdr;
180 182
 
181 183
 /**
@@ -344,7 +346,7 @@ struct ib_device {
344 346
 
345 347
 extern struct ib_completion_queue *
346 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 350
 extern void ib_destroy_cq ( struct ib_device *ibdev,
349 351
 			    struct ib_completion_queue *cq );
350 352
 extern struct ib_queue_pair *
@@ -364,12 +366,11 @@ extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
364 366
 			  struct io_buffer *iobuf );
365 367
 extern void ib_complete_send ( struct ib_device *ibdev,
366 368
 			       struct ib_queue_pair *qp,
367
-			       struct ib_completion *completion,
368
-			       struct io_buffer *iobuf );
369
+			       struct io_buffer *iobuf, int rc );
369 370
 extern void ib_complete_recv ( struct ib_device *ibdev,
370 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 374
 extern struct ib_device * alloc_ibdev ( size_t priv_size );
374 375
 extern int register_ibdev ( struct ib_device *ibdev );
375 376
 extern void unregister_ibdev ( struct ib_device *ibdev );

+ 18
- 20
src/net/infiniband.c Wyświetl plik

@@ -46,13 +46,12 @@ struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices );
46 46
  *
47 47
  * @v ibdev		Infiniband device
48 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 50
  * @ret cq		New completion queue
52 51
  */
53 52
 struct ib_completion_queue *
54 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 55
 	struct ib_completion_queue *cq;
57 56
 	int rc;
58 57
 
@@ -64,8 +63,7 @@ ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
64 63
 		return NULL;
65 64
 	cq->num_cqes = num_cqes;
66 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 68
 	/* Perform device-specific initialisation and get CQN */
71 69
 	if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
@@ -195,9 +193,6 @@ int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
195 193
  * @v qp		Queue pair
196 194
  */
197 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 196
 	struct io_buffer *iobuf;
202 197
 	unsigned int i;
203 198
 
@@ -210,11 +205,13 @@ void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
210 205
 	/* Complete any remaining I/O buffers with errors */
211 206
 	for ( i = 0 ; i < qp->send.num_wqes ; i++ ) {
212 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 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 217
 	/* Remove work queues from completion queue */
@@ -254,7 +251,8 @@ struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
254 251
  * @ret rc		Return status code
255 252
  */
256 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 256
 	int rc;
259 257
 
260 258
 	/* Check queue fill level */
@@ -310,13 +308,12 @@ int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
310 308
  *
311 309
  * @v ibdev		Infiniband device
312 310
  * @v qp		Queue pair
313
- * @v completion	Completion
314 311
  * @v iobuf		I/O buffer
312
+ * @v rc		Completion status code
315 313
  */
316 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 317
 	qp->send.fill--;
321 318
 }
322 319
 
@@ -325,13 +322,14 @@ void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
325 322
  *
326 323
  * @v ibdev		Infiniband device
327 324
  * @v qp		Queue pair
328
- * @v completion	Completion
325
+ * @v av		Address vector
329 326
  * @v iobuf		I/O buffer
327
+ * @v rc		Completion status code
330 328
  */
331 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 333
 	qp->recv.fill--;
336 334
 }
337 335
 

Ładowanie…
Anuluj
Zapisz