Skip to content

Commit 7a84cc5

Browse files
committed
[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>
1 parent aaf7a35 commit 7a84cc5

File tree

2 files changed

+111
-8
lines changed

2 files changed

+111
-8
lines changed

src/drivers/infiniband/arbel.c

Lines changed: 101 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ static int arbel_alloc_qpn ( struct ib_device *ibdev,
772772
qp->qpn = ( arbel->special_qpn_base + 2 + port_offset );
773773
return 0;
774774
case IB_QPT_UD:
775+
case IB_QPT_RC:
775776
/* Find a free queue pair number */
776777
qpn_offset = arbel_bitmask_alloc ( arbel->qp_inuse,
777778
ARBEL_MAX_QPS );
@@ -822,6 +823,7 @@ static uint8_t arbel_qp_st[] = {
822823
[IB_QPT_SMI] = ARBEL_ST_MLX,
823824
[IB_QPT_GSI] = ARBEL_ST_MLX,
824825
[IB_QPT_UD] = ARBEL_ST_UD,
826+
[IB_QPT_RC] = ARBEL_ST_RC,
825827
};
826828

827829
/**
@@ -948,6 +950,18 @@ static int arbel_create_qp ( struct ib_device *ibdev,
948950
physaddr_t wqe_base_adr;
949951
int rc;
950952

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+
951965
/* Calculate queue pair number */
952966
if ( ( rc = arbel_alloc_qpn ( ibdev, qp ) ) != 0 )
953967
goto err_alloc_qpn;
@@ -1021,7 +1035,11 @@ static int arbel_create_qp ( struct ib_device *ibdev,
10211035
( send_wqe_base_adr >> 6 ) );
10221036
MLX_FILL_1 ( &qpctx, 35, qpc_eec_data.snd_db_record_index,
10231037
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 );
10251043
MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
10261044
MLX_FILL_1 ( &qpctx, 42, qpc_eec_data.rcv_wqe_base_adr_l,
10271045
( recv_wqe_base_adr >> 6 ) );
@@ -1084,7 +1102,30 @@ static int arbel_modify_qp ( struct ib_device *ibdev,
10841102
memset ( &qpctx, 0, sizeof ( qpctx ) );
10851103
MLX_FILL_2 ( &qpctx, 4,
10861104
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 ) ) );
10881129
if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn,
10891130
&qpctx ) ) != 0 ) {
10901131
DBGC ( arbel, "Arbel %p QPN %#lx INIT2RTR_QPEE failed:"
@@ -1097,6 +1138,15 @@ static int arbel_modify_qp ( struct ib_device *ibdev,
10971138
/* Transition queue to RTS state, if applicable */
10981139
if ( arbel_qp->state < ARBEL_QP_ST_RTS ) {
10991140
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 );
11001150
MLX_FILL_1 ( &qpctx, 32,
11011151
qpc_eec_data.next_send_psn, qp->send.psn );
11021152
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,
12881338
return ( offsetof ( typeof ( wqe->mlx ), data[2] ) >> 4 );
12891339
}
12901340

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+
12911371
/** Work queue entry constructors */
12921372
static size_t
12931373
( * arbel_fill_send_wqe[] ) ( struct ib_device *ibdev,
@@ -1298,6 +1378,7 @@ static size_t
12981378
[IB_QPT_SMI] = arbel_fill_mlx_send_wqe,
12991379
[IB_QPT_GSI] = arbel_fill_mlx_send_wqe,
13001380
[IB_QPT_UD] = arbel_fill_ud_send_wqe,
1381+
[IB_QPT_RC] = arbel_fill_rc_send_wqe,
13011382
};
13021383

13031384
/**
@@ -1495,6 +1576,7 @@ static int arbel_complete ( struct ib_device *ibdev,
14951576
sizeof ( arbel_recv_wq->wqe[0] ) );
14961577
assert ( wqe_idx < qp->recv.num_wqes );
14971578
}
1579+
14981580
DBGCP ( arbel, "Arbel %p CQN %#lx QPN %#lx %s WQE %#lx completed:\n",
14991581
arbel, cq->cqn, qp->qpn, ( is_send ? "send" : "recv" ),
15001582
wqe_idx );
@@ -1542,6 +1624,9 @@ static int arbel_complete ( struct ib_device *ibdev,
15421624
av->gid_present = MLX_GET ( &cqe->normal, g );
15431625
memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) );
15441626
break;
1627+
case IB_QPT_RC:
1628+
av = &qp->av;
1629+
break;
15451630
default:
15461631
assert ( 0 );
15471632
return -EINVAL;
@@ -2297,7 +2382,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
22972382
log_num_eqs = fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
22982383
log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
22992384
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 );
23012387
log_num_uars = fls ( arbel->limits.reserved_uars +
23022388
1 /* single UAR used */ - 1 );
23032389
log_num_mcs = ARBEL_LOG_MULTICAST_HASH_SIZE;
@@ -2614,13 +2700,18 @@ static int arbel_setup_mpt ( struct arbel *arbel ) {
26142700

26152701
/* Initialise memory protection table */
26162702
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,
26202708
lr, 1,
2621-
lw, 1 );
2709+
pa, 1,
2710+
r_w, 1 );
26222711
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 );
26242715
MLX_FILL_1 ( &mpt, 6, reg_wnd_len_h, 0xffffffffUL );
26252716
MLX_FILL_1 ( &mpt, 7, reg_wnd_len_l, 0xffffffffUL );
26262717
if ( ( rc = arbel_cmd_sw2hw_mpt ( arbel, arbel->limits.reserved_mrws,
@@ -2751,6 +2842,8 @@ static int arbel_probe ( struct pci_device *pci ) {
27512842
/* Set up memory protection */
27522843
if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 )
27532844
goto err_setup_mpt;
2845+
for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ )
2846+
arbel->ibdev[i]->rdma_key = arbel->lkey;
27542847

27552848
/* Set up event queue */
27562849
if ( ( rc = arbel_create_eq ( arbel ) ) != 0 )

src/drivers/infiniband/arbel.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
8181
#define ARBEL_HCR_MAP_FA 0x0fff
8282

8383
/* Service types */
84+
#define ARBEL_ST_RC 0x00
8485
#define ARBEL_ST_UD 0x03
8586
#define ARBEL_ST_MLX 0x07
8687

@@ -111,6 +112,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
111112
#define ARBEL_PM_STATE_REARM 0x01
112113
#define ARBEL_PM_STATE_MIGRATED 0x03
113114

115+
#define ARBEL_RETRY_MAX 0x07
116+
114117
/*
115118
* Datatypes that seem to be missing from the autogenerated documentation
116119
*
@@ -223,6 +226,12 @@ struct arbelprm_mlx_send_wqe {
223226
uint8_t headers[IB_MAX_HEADER_SIZE];
224227
} __attribute__ (( packed ));
225228

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+
226235
#define ARBEL_MAX_SCATTER 1
227236

228237
struct arbelprm_recv_wqe {
@@ -324,6 +333,7 @@ union arbel_send_wqe {
324333
struct arbelprm_wqe_segment_next next;
325334
struct arbelprm_ud_send_wqe ud;
326335
struct arbelprm_mlx_send_wqe mlx;
336+
struct arbelprm_rc_send_wqe rc;
327337
uint8_t force_align[ARBEL_SEND_WQE_ALIGN];
328338
} __attribute__ (( packed ));
329339

0 commit comments

Comments
 (0)