Browse Source

[arbel] Add (not-yet-functional) support for RC queue pairs

Arbel seems to crash the system as soon as the first send WQE
completes on an RC queue pair.  (NOPs complete successfully, so this
is a problem specific to the work queue rather than the completion
queue.)  The cause of this problem has remained unknown for over a
year.

Check in the non-functioning code to avoid bit-rot, and in the hope
that someone will find the fix.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
7a84cc593a
2 changed files with 111 additions and 8 deletions
  1. 101
    8
      src/drivers/infiniband/arbel.c
  2. 10
    0
      src/drivers/infiniband/arbel.h

+ 101
- 8
src/drivers/infiniband/arbel.c View File

@@ -772,6 +772,7 @@ static int arbel_alloc_qpn ( struct ib_device *ibdev,
772 772
 		qp->qpn = ( arbel->special_qpn_base + 2 + port_offset );
773 773
 		return 0;
774 774
 	case IB_QPT_UD:
775
+	case IB_QPT_RC:
775 776
 		/* Find a free queue pair number */
776 777
 		qpn_offset = arbel_bitmask_alloc ( arbel->qp_inuse,
777 778
 						   ARBEL_MAX_QPS );
@@ -822,6 +823,7 @@ static uint8_t arbel_qp_st[] = {
822 823
 	[IB_QPT_SMI] = ARBEL_ST_MLX,
823 824
 	[IB_QPT_GSI] = ARBEL_ST_MLX,
824 825
 	[IB_QPT_UD] = ARBEL_ST_UD,
826
+	[IB_QPT_RC] = ARBEL_ST_RC,
825 827
 };
826 828
 
827 829
 /**
@@ -948,6 +950,18 @@ static int arbel_create_qp ( struct ib_device *ibdev,
948 950
 	physaddr_t wqe_base_adr;
949 951
 	int rc;
950 952
 
953
+	/* Warn about dysfunctional code
954
+	 *
955
+	 * Arbel seems to crash the system as soon as the first send
956
+	 * WQE completes on an RC queue pair.  (NOPs complete
957
+	 * successfully, so this is a problem specific to the work
958
+	 * queue rather than the completion queue.)  The cause of this
959
+	 * problem has remained unknown for over a year.  Patches to
960
+	 * fix this are welcome.
961
+	 */
962
+	if ( qp->type == IB_QPT_RC )
963
+		DBG ( "*** WARNING: Arbel RC support is non-functional ***\n" );
964
+
951 965
 	/* Calculate queue pair number */
952 966
 	if ( ( rc = arbel_alloc_qpn ( ibdev, qp ) ) != 0 )
953 967
 		goto err_alloc_qpn;
@@ -1021,7 +1035,11 @@ static int arbel_create_qp ( struct ib_device *ibdev,
1021 1035
 		     ( send_wqe_base_adr >> 6 ) );
1022 1036
 	MLX_FILL_1 ( &qpctx, 35, qpc_eec_data.snd_db_record_index,
1023 1037
 		     arbel_qp->send.doorbell_idx );
1024
-	MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.rsc, 1 );
1038
+	MLX_FILL_4 ( &qpctx, 38,
1039
+		     qpc_eec_data.rre, 1,
1040
+		     qpc_eec_data.rwe, 1,
1041
+		     qpc_eec_data.rae, 1,
1042
+		     qpc_eec_data.rsc, 1 );
1025 1043
 	MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
1026 1044
 	MLX_FILL_1 ( &qpctx, 42, qpc_eec_data.rcv_wqe_base_adr_l,
1027 1045
 		     ( recv_wqe_base_adr >> 6 ) );
@@ -1084,7 +1102,30 @@ static int arbel_modify_qp ( struct ib_device *ibdev,
1084 1102
 		memset ( &qpctx, 0, sizeof ( qpctx ) );
1085 1103
 		MLX_FILL_2 ( &qpctx, 4,
1086 1104
 			     qpc_eec_data.mtu, ARBEL_MTU_2048,
1087
-			     qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
1105
+			     qpc_eec_data.msg_max, 31 );
1106
+		MLX_FILL_1 ( &qpctx, 7,
1107
+			     qpc_eec_data.remote_qpn_een, qp->av.qpn );
1108
+		MLX_FILL_2 ( &qpctx, 11,
1109
+			     qpc_eec_data.primary_address_path.rnr_retry,
1110
+			     ARBEL_RETRY_MAX,
1111
+			     qpc_eec_data.primary_address_path.rlid,
1112
+			     qp->av.lid );
1113
+		MLX_FILL_2 ( &qpctx, 12,
1114
+			     qpc_eec_data.primary_address_path.ack_timeout,
1115
+			     14 /* 4.096us * 2^(14) = 67ms */,
1116
+			     qpc_eec_data.primary_address_path.max_stat_rate,
1117
+			     arbel_rate ( &qp->av ) );
1118
+		memcpy ( &qpctx.u.dwords[14], &qp->av.gid,
1119
+			 sizeof ( qp->av.gid ) );
1120
+		MLX_FILL_1 ( &qpctx, 30,
1121
+			     qpc_eec_data.retry_count, ARBEL_RETRY_MAX );
1122
+		MLX_FILL_1 ( &qpctx, 39,
1123
+			     qpc_eec_data.next_rcv_psn, qp->recv.psn );
1124
+		MLX_FILL_1 ( &qpctx, 40,
1125
+			     qpc_eec_data.ra_buff_indx,
1126
+			     ( arbel->limits.reserved_rdbs +
1127
+			       ( ( qp->qpn & ~ARBEL_QPN_RANDOM_MASK ) -
1128
+				 arbel->special_qpn_base ) ) );
1088 1129
 		if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn,
1089 1130
 						      &qpctx ) ) != 0 ) {
1090 1131
 			DBGC ( arbel, "Arbel %p QPN %#lx INIT2RTR_QPEE failed:"
@@ -1097,6 +1138,15 @@ static int arbel_modify_qp ( struct ib_device *ibdev,
1097 1138
 	/* Transition queue to RTS state, if applicable */
1098 1139
 	if ( arbel_qp->state < ARBEL_QP_ST_RTS ) {
1099 1140
 		memset ( &qpctx, 0, sizeof ( qpctx ) );
1141
+		MLX_FILL_1 ( &qpctx, 11,
1142
+			     qpc_eec_data.primary_address_path.rnr_retry,
1143
+			     ARBEL_RETRY_MAX );
1144
+		MLX_FILL_1 ( &qpctx, 12,
1145
+			     qpc_eec_data.primary_address_path.ack_timeout,
1146
+			     14 /* 4.096us * 2^(14) = 67ms */ );
1147
+		MLX_FILL_2 ( &qpctx, 30,
1148
+			     qpc_eec_data.retry_count, ARBEL_RETRY_MAX,
1149
+			     qpc_eec_data.sic, 1 );
1100 1150
 		MLX_FILL_1 ( &qpctx, 32,
1101 1151
 			     qpc_eec_data.next_send_psn, qp->send.psn );
1102 1152
 		if ( ( rc = arbel_cmd_rtr2rts_qpee ( arbel, qp->qpn,
@@ -1288,6 +1338,36 @@ static size_t arbel_fill_mlx_send_wqe ( struct ib_device *ibdev,
1288 1338
 	return ( offsetof ( typeof ( wqe->mlx ), data[2] ) >> 4 );
1289 1339
 }
1290 1340
 
1341
+/**
1342
+ * Construct RC send work queue entry
1343
+ *
1344
+ * @v ibdev		Infiniband device
1345
+ * @v qp		Queue pair
1346
+ * @v av		Address vector
1347
+ * @v iobuf		I/O buffer
1348
+ * @v wqe		Send work queue entry
1349
+ * @v next		Previous work queue entry's "next" field
1350
+ * @ret nds		Work queue entry size
1351
+ */
1352
+static size_t arbel_fill_rc_send_wqe ( struct ib_device *ibdev,
1353
+				       struct ib_queue_pair *qp __unused,
1354
+				       struct ib_address_vector *av __unused,
1355
+				       struct io_buffer *iobuf,
1356
+				       union arbel_send_wqe *wqe ) {
1357
+	struct arbel *arbel = ib_get_drvdata ( ibdev );
1358
+
1359
+	/* Construct this work queue entry */
1360
+	MLX_FILL_1 ( &wqe->rc.ctrl, 0, always1, 1 );
1361
+	MLX_FILL_1 ( &wqe->rc.data[0], 0, byte_count, iob_len ( iobuf ) );
1362
+	MLX_FILL_1 ( &wqe->rc.data[0], 1, l_key, arbel->lkey );
1363
+	MLX_FILL_H ( &wqe->rc.data[0], 2,
1364
+		     local_address_h, virt_to_bus ( iobuf->data ) );
1365
+	MLX_FILL_1 ( &wqe->rc.data[0], 3,
1366
+		     local_address_l, virt_to_bus ( iobuf->data ) );
1367
+
1368
+	return ( offsetof ( typeof ( wqe->rc ), data[1] ) >> 4 );
1369
+}
1370
+
1291 1371
 /** Work queue entry constructors */
1292 1372
 static size_t
1293 1373
 ( * arbel_fill_send_wqe[] ) ( struct ib_device *ibdev,
@@ -1298,6 +1378,7 @@ static size_t
1298 1378
 	[IB_QPT_SMI] = arbel_fill_mlx_send_wqe,
1299 1379
 	[IB_QPT_GSI] = arbel_fill_mlx_send_wqe,
1300 1380
 	[IB_QPT_UD] = arbel_fill_ud_send_wqe,
1381
+	[IB_QPT_RC] = arbel_fill_rc_send_wqe,
1301 1382
 };
1302 1383
 
1303 1384
 /**
@@ -1495,6 +1576,7 @@ static int arbel_complete ( struct ib_device *ibdev,
1495 1576
 			    sizeof ( arbel_recv_wq->wqe[0] ) );
1496 1577
 		assert ( wqe_idx < qp->recv.num_wqes );
1497 1578
 	}
1579
+
1498 1580
 	DBGCP ( arbel, "Arbel %p CQN %#lx QPN %#lx %s WQE %#lx completed:\n",
1499 1581
 		arbel, cq->cqn, qp->qpn, ( is_send ? "send" : "recv" ),
1500 1582
 		wqe_idx );
@@ -1542,6 +1624,9 @@ static int arbel_complete ( struct ib_device *ibdev,
1542 1624
 			av->gid_present = MLX_GET ( &cqe->normal, g );
1543 1625
 			memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) );
1544 1626
 			break;
1627
+		case IB_QPT_RC:
1628
+			av = &qp->av;
1629
+			break;
1545 1630
 		default:
1546 1631
 			assert ( 0 );
1547 1632
 			return -EINVAL;
@@ -2297,7 +2382,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
2297 2382
 	log_num_eqs = fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
2298 2383
 	log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
2299 2384
 	log_num_mpts = fls ( arbel->limits.reserved_mrws + 1 - 1 );
2300
-	log_num_rdbs = fls ( arbel->limits.reserved_rdbs - 1 );
2385
+	log_num_rdbs = fls ( arbel->limits.reserved_rdbs +
2386
+			     ARBEL_RSVD_SPECIAL_QPS + ARBEL_MAX_QPS - 1 );
2301 2387
 	log_num_uars = fls ( arbel->limits.reserved_uars +
2302 2388
 			     1 /* single UAR used */ - 1 );
2303 2389
 	log_num_mcs = ARBEL_LOG_MULTICAST_HASH_SIZE;
@@ -2614,13 +2700,18 @@ static int arbel_setup_mpt ( struct arbel *arbel ) {
2614 2700
 
2615 2701
 	/* Initialise memory protection table */
2616 2702
 	memset ( &mpt, 0, sizeof ( mpt ) );
2617
-	MLX_FILL_4 ( &mpt, 0,
2618
-		     r_w, 1,
2619
-		     pa, 1,
2703
+	MLX_FILL_7 ( &mpt, 0,
2704
+		     a, 1,
2705
+		     rw, 1,
2706
+		     rr, 1,
2707
+		     lw, 1,
2620 2708
 		     lr, 1,
2621
-		     lw, 1 );
2709
+		     pa, 1,
2710
+		     r_w, 1 );
2622 2711
 	MLX_FILL_1 ( &mpt, 2, mem_key, key );
2623
-	MLX_FILL_1 ( &mpt, 3, pd, ARBEL_GLOBAL_PD );
2712
+	MLX_FILL_2 ( &mpt, 3,
2713
+		     pd, ARBEL_GLOBAL_PD,
2714
+		     rae, 1 );
2624 2715
 	MLX_FILL_1 ( &mpt, 6, reg_wnd_len_h, 0xffffffffUL );
2625 2716
 	MLX_FILL_1 ( &mpt, 7, reg_wnd_len_l, 0xffffffffUL );
2626 2717
 	if ( ( rc = arbel_cmd_sw2hw_mpt ( arbel, arbel->limits.reserved_mrws,
@@ -2751,6 +2842,8 @@ static int arbel_probe ( struct pci_device *pci ) {
2751 2842
 	/* Set up memory protection */
2752 2843
 	if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 )
2753 2844
 		goto err_setup_mpt;
2845
+	for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ )
2846
+		arbel->ibdev[i]->rdma_key = arbel->lkey;
2754 2847
 
2755 2848
 	/* Set up event queue */
2756 2849
 	if ( ( rc = arbel_create_eq ( arbel ) ) != 0 )

+ 10
- 0
src/drivers/infiniband/arbel.h View File

@@ -81,6 +81,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
81 81
 #define ARBEL_HCR_MAP_FA		0x0fff
82 82
 
83 83
 /* Service types */
84
+#define ARBEL_ST_RC			0x00
84 85
 #define ARBEL_ST_UD			0x03
85 86
 #define ARBEL_ST_MLX			0x07
86 87
 
@@ -111,6 +112,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
111 112
 #define ARBEL_PM_STATE_REARM		0x01
112 113
 #define ARBEL_PM_STATE_MIGRATED		0x03
113 114
 
115
+#define ARBEL_RETRY_MAX			0x07
116
+
114 117
 /*
115 118
  * Datatypes that seem to be missing from the autogenerated documentation
116 119
  *
@@ -223,6 +226,12 @@ struct arbelprm_mlx_send_wqe {
223 226
 	uint8_t headers[IB_MAX_HEADER_SIZE];
224 227
 } __attribute__ (( packed ));
225 228
 
229
+struct arbelprm_rc_send_wqe {
230
+	struct arbelprm_wqe_segment_next next;
231
+	struct arbelprm_wqe_segment_ctrl_send ctrl;
232
+	struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER];
233
+} __attribute__ (( packed ));
234
+
226 235
 #define ARBEL_MAX_SCATTER 1
227 236
 
228 237
 struct arbelprm_recv_wqe {
@@ -324,6 +333,7 @@ union arbel_send_wqe {
324 333
 	struct arbelprm_wqe_segment_next next;
325 334
 	struct arbelprm_ud_send_wqe ud;
326 335
 	struct arbelprm_mlx_send_wqe mlx;
336
+	struct arbelprm_rc_send_wqe rc;
327 337
 	uint8_t force_align[ARBEL_SEND_WQE_ALIGN];
328 338
 } __attribute__ (( packed ));
329 339
 

Loading…
Cancel
Save