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
 		qp->qpn = ( arbel->special_qpn_base + 2 + port_offset );
772
 		qp->qpn = ( arbel->special_qpn_base + 2 + port_offset );
773
 		return 0;
773
 		return 0;
774
 	case IB_QPT_UD:
774
 	case IB_QPT_UD:
775
+	case IB_QPT_RC:
775
 		/* Find a free queue pair number */
776
 		/* Find a free queue pair number */
776
 		qpn_offset = arbel_bitmask_alloc ( arbel->qp_inuse,
777
 		qpn_offset = arbel_bitmask_alloc ( arbel->qp_inuse,
777
 						   ARBEL_MAX_QPS );
778
 						   ARBEL_MAX_QPS );
822
 	[IB_QPT_SMI] = ARBEL_ST_MLX,
823
 	[IB_QPT_SMI] = ARBEL_ST_MLX,
823
 	[IB_QPT_GSI] = ARBEL_ST_MLX,
824
 	[IB_QPT_GSI] = ARBEL_ST_MLX,
824
 	[IB_QPT_UD] = ARBEL_ST_UD,
825
 	[IB_QPT_UD] = ARBEL_ST_UD,
826
+	[IB_QPT_RC] = ARBEL_ST_RC,
825
 };
827
 };
826
 
828
 
827
 /**
829
 /**
948
 	physaddr_t wqe_base_adr;
950
 	physaddr_t wqe_base_adr;
949
 	int rc;
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
 	/* Calculate queue pair number */
965
 	/* Calculate queue pair number */
952
 	if ( ( rc = arbel_alloc_qpn ( ibdev, qp ) ) != 0 )
966
 	if ( ( rc = arbel_alloc_qpn ( ibdev, qp ) ) != 0 )
953
 		goto err_alloc_qpn;
967
 		goto err_alloc_qpn;
1021
 		     ( send_wqe_base_adr >> 6 ) );
1035
 		     ( send_wqe_base_adr >> 6 ) );
1022
 	MLX_FILL_1 ( &qpctx, 35, qpc_eec_data.snd_db_record_index,
1036
 	MLX_FILL_1 ( &qpctx, 35, qpc_eec_data.snd_db_record_index,
1023
 		     arbel_qp->send.doorbell_idx );
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
 	MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
1043
 	MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
1026
 	MLX_FILL_1 ( &qpctx, 42, qpc_eec_data.rcv_wqe_base_adr_l,
1044
 	MLX_FILL_1 ( &qpctx, 42, qpc_eec_data.rcv_wqe_base_adr_l,
1027
 		     ( recv_wqe_base_adr >> 6 ) );
1045
 		     ( recv_wqe_base_adr >> 6 ) );
1084
 		memset ( &qpctx, 0, sizeof ( qpctx ) );
1102
 		memset ( &qpctx, 0, sizeof ( qpctx ) );
1085
 		MLX_FILL_2 ( &qpctx, 4,
1103
 		MLX_FILL_2 ( &qpctx, 4,
1086
 			     qpc_eec_data.mtu, ARBEL_MTU_2048,
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
 		if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn,
1129
 		if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn,
1089
 						      &qpctx ) ) != 0 ) {
1130
 						      &qpctx ) ) != 0 ) {
1090
 			DBGC ( arbel, "Arbel %p QPN %#lx INIT2RTR_QPEE failed:"
1131
 			DBGC ( arbel, "Arbel %p QPN %#lx INIT2RTR_QPEE failed:"
1097
 	/* Transition queue to RTS state, if applicable */
1138
 	/* Transition queue to RTS state, if applicable */
1098
 	if ( arbel_qp->state < ARBEL_QP_ST_RTS ) {
1139
 	if ( arbel_qp->state < ARBEL_QP_ST_RTS ) {
1099
 		memset ( &qpctx, 0, sizeof ( qpctx ) );
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
 		MLX_FILL_1 ( &qpctx, 32,
1150
 		MLX_FILL_1 ( &qpctx, 32,
1101
 			     qpc_eec_data.next_send_psn, qp->send.psn );
1151
 			     qpc_eec_data.next_send_psn, qp->send.psn );
1102
 		if ( ( rc = arbel_cmd_rtr2rts_qpee ( arbel, qp->qpn,
1152
 		if ( ( rc = arbel_cmd_rtr2rts_qpee ( arbel, qp->qpn,
1288
 	return ( offsetof ( typeof ( wqe->mlx ), data[2] ) >> 4 );
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
 /** Work queue entry constructors */
1371
 /** Work queue entry constructors */
1292
 static size_t
1372
 static size_t
1293
 ( * arbel_fill_send_wqe[] ) ( struct ib_device *ibdev,
1373
 ( * arbel_fill_send_wqe[] ) ( struct ib_device *ibdev,
1298
 	[IB_QPT_SMI] = arbel_fill_mlx_send_wqe,
1378
 	[IB_QPT_SMI] = arbel_fill_mlx_send_wqe,
1299
 	[IB_QPT_GSI] = arbel_fill_mlx_send_wqe,
1379
 	[IB_QPT_GSI] = arbel_fill_mlx_send_wqe,
1300
 	[IB_QPT_UD] = arbel_fill_ud_send_wqe,
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
 			    sizeof ( arbel_recv_wq->wqe[0] ) );
1576
 			    sizeof ( arbel_recv_wq->wqe[0] ) );
1496
 		assert ( wqe_idx < qp->recv.num_wqes );
1577
 		assert ( wqe_idx < qp->recv.num_wqes );
1497
 	}
1578
 	}
1579
+
1498
 	DBGCP ( arbel, "Arbel %p CQN %#lx QPN %#lx %s WQE %#lx completed:\n",
1580
 	DBGCP ( arbel, "Arbel %p CQN %#lx QPN %#lx %s WQE %#lx completed:\n",
1499
 		arbel, cq->cqn, qp->qpn, ( is_send ? "send" : "recv" ),
1581
 		arbel, cq->cqn, qp->qpn, ( is_send ? "send" : "recv" ),
1500
 		wqe_idx );
1582
 		wqe_idx );
1542
 			av->gid_present = MLX_GET ( &cqe->normal, g );
1624
 			av->gid_present = MLX_GET ( &cqe->normal, g );
1543
 			memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) );
1625
 			memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) );
1544
 			break;
1626
 			break;
1627
+		case IB_QPT_RC:
1628
+			av = &qp->av;
1629
+			break;
1545
 		default:
1630
 		default:
1546
 			assert ( 0 );
1631
 			assert ( 0 );
1547
 			return -EINVAL;
1632
 			return -EINVAL;
2297
 	log_num_eqs = fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
2382
 	log_num_eqs = fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
2298
 	log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
2383
 	log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
2299
 	log_num_mpts = fls ( arbel->limits.reserved_mrws + 1 - 1 );
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
 	log_num_uars = fls ( arbel->limits.reserved_uars +
2387
 	log_num_uars = fls ( arbel->limits.reserved_uars +
2302
 			     1 /* single UAR used */ - 1 );
2388
 			     1 /* single UAR used */ - 1 );
2303
 	log_num_mcs = ARBEL_LOG_MULTICAST_HASH_SIZE;
2389
 	log_num_mcs = ARBEL_LOG_MULTICAST_HASH_SIZE;
2614
 
2700
 
2615
 	/* Initialise memory protection table */
2701
 	/* Initialise memory protection table */
2616
 	memset ( &mpt, 0, sizeof ( mpt ) );
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
 		     lr, 1,
2708
 		     lr, 1,
2621
-		     lw, 1 );
2709
+		     pa, 1,
2710
+		     r_w, 1 );
2622
 	MLX_FILL_1 ( &mpt, 2, mem_key, key );
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
 	MLX_FILL_1 ( &mpt, 6, reg_wnd_len_h, 0xffffffffUL );
2715
 	MLX_FILL_1 ( &mpt, 6, reg_wnd_len_h, 0xffffffffUL );
2625
 	MLX_FILL_1 ( &mpt, 7, reg_wnd_len_l, 0xffffffffUL );
2716
 	MLX_FILL_1 ( &mpt, 7, reg_wnd_len_l, 0xffffffffUL );
2626
 	if ( ( rc = arbel_cmd_sw2hw_mpt ( arbel, arbel->limits.reserved_mrws,
2717
 	if ( ( rc = arbel_cmd_sw2hw_mpt ( arbel, arbel->limits.reserved_mrws,
2751
 	/* Set up memory protection */
2842
 	/* Set up memory protection */
2752
 	if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 )
2843
 	if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 )
2753
 		goto err_setup_mpt;
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
 	/* Set up event queue */
2848
 	/* Set up event queue */
2756
 	if ( ( rc = arbel_create_eq ( arbel ) ) != 0 )
2849
 	if ( ( rc = arbel_create_eq ( arbel ) ) != 0 )

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

81
 #define ARBEL_HCR_MAP_FA		0x0fff
81
 #define ARBEL_HCR_MAP_FA		0x0fff
82
 
82
 
83
 /* Service types */
83
 /* Service types */
84
+#define ARBEL_ST_RC			0x00
84
 #define ARBEL_ST_UD			0x03
85
 #define ARBEL_ST_UD			0x03
85
 #define ARBEL_ST_MLX			0x07
86
 #define ARBEL_ST_MLX			0x07
86
 
87
 
111
 #define ARBEL_PM_STATE_REARM		0x01
112
 #define ARBEL_PM_STATE_REARM		0x01
112
 #define ARBEL_PM_STATE_MIGRATED		0x03
113
 #define ARBEL_PM_STATE_MIGRATED		0x03
113
 
114
 
115
+#define ARBEL_RETRY_MAX			0x07
116
+
114
 /*
117
 /*
115
  * Datatypes that seem to be missing from the autogenerated documentation
118
  * Datatypes that seem to be missing from the autogenerated documentation
116
  *
119
  *
223
 	uint8_t headers[IB_MAX_HEADER_SIZE];
226
 	uint8_t headers[IB_MAX_HEADER_SIZE];
224
 } __attribute__ (( packed ));
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
 #define ARBEL_MAX_SCATTER 1
235
 #define ARBEL_MAX_SCATTER 1
227
 
236
 
228
 struct arbelprm_recv_wqe {
237
 struct arbelprm_recv_wqe {
324
 	struct arbelprm_wqe_segment_next next;
333
 	struct arbelprm_wqe_segment_next next;
325
 	struct arbelprm_ud_send_wqe ud;
334
 	struct arbelprm_ud_send_wqe ud;
326
 	struct arbelprm_mlx_send_wqe mlx;
335
 	struct arbelprm_mlx_send_wqe mlx;
336
+	struct arbelprm_rc_send_wqe rc;
327
 	uint8_t force_align[ARBEL_SEND_WQE_ALIGN];
337
 	uint8_t force_align[ARBEL_SEND_WQE_ALIGN];
328
 } __attribute__ (( packed ));
338
 } __attribute__ (( packed ));
329
 
339
 

Loading…
Cancel
Save