@@ -31,6 +31,9 @@ DECLARE_DRV_CMD(mana_create_qp_ex, IB_USER_VERBS_EX_CMD_CREATE_QP,
3131DECLARE_DRV_CMD (mana_create_rc_qp , IB_USER_VERBS_CMD_CREATE_QP ,
3232 mana_ib_create_rc_qp , mana_ib_create_rc_qp_resp );
3333
34+ DECLARE_DRV_CMD (mana_create_uc_qp , IB_USER_VERBS_CMD_CREATE_QP ,
35+ mana_ib_create_uc_qp , mana_ib_create_uc_qp_resp );
36+
3437static struct ibv_qp * mana_create_qp_raw (struct ibv_pd * ibpd ,
3538 struct ibv_qp_init_attr * attr )
3639{
@@ -216,56 +219,149 @@ static uint32_t get_queue_size(struct ibv_qp_init_attr *attr, enum user_queue_ty
216219 uint32_t size = 0 ;
217220 uint32_t sges = 0 ;
218221
219- if (attr -> qp_type == IBV_QPT_RC ) {
220- switch (type ) {
221- case USER_RNIC_SEND_QUEUE_REQUESTER :
222- /* WQE must have at least one SGE */
223- /* For write with imm we need one extra SGE */
224- sges = max (1U , attr -> cap .max_send_sge ) + 1 ;
225- size = attr -> cap .max_send_wr * get_large_wqe_size (sges );
226- break ;
227- case USER_RNIC_SEND_QUEUE_RESPONDER :
228- size = MANA_PAGE_SIZE ;
229- break ;
230- case USER_RNIC_RECV_QUEUE_REQUESTER :
231- size = MANA_PAGE_SIZE ;
232- break ;
233- case USER_RNIC_RECV_QUEUE_RESPONDER :
234- /* WQE must have at least one SGE */
235- sges = max (1U , attr -> cap .max_recv_sge );
236- size = attr -> cap .max_recv_wr * get_wqe_size (sges );
237- break ;
238- default :
239- return 0 ;
240- }
222+ switch (type ) {
223+ case USER_RNIC_SEND_QUEUE_REQUESTER :
224+ /* WQE must have at least one SGE */
225+ /* For write with imm we need one extra SGE */
226+ sges = max (1U , attr -> cap .max_send_sge ) + 1 ;
227+ size = align_hw_size (attr -> cap .max_send_wr * get_large_wqe_size (sges ));
228+ break ;
229+ case USER_RNIC_SEND_QUEUE_RESPONDER :
230+ if (attr -> qp_type == IBV_QPT_RC )
231+ size = align_hw_size (MANA_PAGE_SIZE );
232+ break ;
233+ case USER_RNIC_RECV_QUEUE_REQUESTER :
234+ if (attr -> qp_type == IBV_QPT_RC )
235+ size = align_hw_size (MANA_PAGE_SIZE );
236+ break ;
237+ case USER_RNIC_RECV_QUEUE_RESPONDER :
238+ /* WQE must have at least one SGE */
239+ sges = max (1U , attr -> cap .max_recv_sge );
240+ size = align_hw_size (attr -> cap .max_recv_wr * get_wqe_size (sges ));
241+ break ;
242+ case USER_RNIC_SEND_QUEUE_MM :
243+ sges = max (1U , attr -> cap .max_send_sge ) + 1 ;
244+ size = align_hw_size (attr -> cap .max_send_wr * get_large_wqe_size (sges ));
245+ break ;
246+ default :
247+ return 0 ;
241248 }
242249
243- size = align_hw_size (size );
244-
245250 if (attr -> qp_type == IBV_QPT_RC && type == USER_RNIC_SEND_QUEUE_REQUESTER )
246251 size += sizeof (struct mana_ib_rollback_shared_mem );
247252
248253 return size ;
249254}
250255
251- static struct ibv_qp * mana_create_qp_rnic ( struct ibv_pd * ibpd ,
252- struct ibv_qp_init_attr * attr )
256+ static int mana_create_cmd_qp_rc ( struct mana_qp * qp , struct ibv_pd * ibpd ,
257+ struct ibv_qp_init_attr * attr )
253258{
254- struct mana_context * ctx = to_mctx (ibpd -> context );
255259 struct mana_ib_create_rc_qp_resp * qp_resp_drv ;
256260 struct mana_create_rc_qp_resp qp_resp = {};
257261 struct mana_ib_create_rc_qp * qp_cmd_drv ;
258262 struct mana_create_rc_qp qp_cmd = {};
263+ int ret , i ;
264+
265+ qp_cmd_drv = & qp_cmd .drv_payload ;
266+ qp_resp_drv = & qp_resp .drv_payload ;
267+
268+ for (i = 0 ; i < USER_RNIC_QUEUE_TYPE_MAX ; ++ i ) {
269+ if (i == USER_RNIC_SEND_QUEUE_MM )
270+ continue ;
271+ qp_cmd_drv -> queue_buf [i ] = (uintptr_t )qp -> rnic_qp .queues [i ].buffer ;
272+ qp_cmd_drv -> queue_size [i ] = qp -> rnic_qp .queues [i ].size ;
273+ }
274+
275+ ret = ibv_cmd_create_qp (ibpd , & qp -> ibqp .qp , attr , & qp_cmd .ibv_cmd ,
276+ sizeof (qp_cmd ), & qp_resp .ibv_resp ,
277+ sizeof (qp_resp ));
278+ if (ret ) {
279+ verbs_err (verbs_get_ctx (ibpd -> context ), "Create QP failed\n" );
280+ return ret ;
281+ }
282+
283+ for (i = 0 ; i < USER_RNIC_QUEUE_TYPE_MAX ; ++ i ) {
284+ if (i == USER_RNIC_SEND_QUEUE_MM )
285+ continue ;
286+ qp -> rnic_qp .queues [i ].id = qp_resp_drv -> queue_id [i ];
287+ }
288+
289+ return 0 ;
290+ }
291+
292+ enum {
293+ MANA_UC_UDATA_SQR = 0 ,
294+ MANA_UC_UDATA_RQR = 1 ,
295+ MANA_UC_UDATA_SMQ = 2 ,
296+ };
297+
298+ static int mana_create_cmd_qp_uc (struct mana_qp * qp , struct ibv_pd * ibpd ,
299+ struct ibv_qp_init_attr * attr )
300+ {
301+ struct mana_ib_create_uc_qp_resp * qp_resp_drv ;
302+ struct mana_create_uc_qp_resp qp_resp = {};
303+ struct mana_ib_create_uc_qp * qp_cmd_drv ;
304+ struct mana_create_uc_qp qp_cmd = {};
305+ int ret ;
306+
307+ qp_cmd_drv = & qp_cmd .drv_payload ;
308+ qp_resp_drv = & qp_resp .drv_payload ;
309+
310+ qp_cmd_drv -> queue_buf [MANA_UC_UDATA_SQR ] =
311+ (uintptr_t )qp -> rnic_qp .queues [USER_RNIC_SEND_QUEUE_REQUESTER ].buffer ;
312+ qp_cmd_drv -> queue_size [MANA_UC_UDATA_SQR ] =
313+ qp -> rnic_qp .queues [USER_RNIC_SEND_QUEUE_REQUESTER ].size ;
314+
315+ qp_cmd_drv -> queue_buf [MANA_UC_UDATA_RQR ] =
316+ (uintptr_t )qp -> rnic_qp .queues [USER_RNIC_RECV_QUEUE_RESPONDER ].buffer ;
317+ qp_cmd_drv -> queue_size [MANA_UC_UDATA_RQR ] =
318+ qp -> rnic_qp .queues [USER_RNIC_RECV_QUEUE_RESPONDER ].size ;
319+
320+ qp_cmd_drv -> queue_buf [MANA_UC_UDATA_SMQ ] =
321+ (uintptr_t )qp -> rnic_qp .queues [USER_RNIC_SEND_QUEUE_MM ].buffer ;
322+ qp_cmd_drv -> queue_size [MANA_UC_UDATA_SMQ ] =
323+ qp -> rnic_qp .queues [USER_RNIC_SEND_QUEUE_MM ].size ;
324+
325+ ret = ibv_cmd_create_qp (ibpd , & qp -> ibqp .qp , attr , & qp_cmd .ibv_cmd ,
326+ sizeof (qp_cmd ), & qp_resp .ibv_resp ,
327+ sizeof (qp_resp ));
328+ if (ret ) {
329+ verbs_err (verbs_get_ctx (ibpd -> context ), "Create QP failed\n" );
330+ return ret ;
331+ }
332+
333+ qp -> rnic_qp .queues [USER_RNIC_SEND_QUEUE_REQUESTER ].id =
334+ qp_resp_drv -> queue_id [MANA_UC_UDATA_SQR ];
335+ qp -> rnic_qp .queues [USER_RNIC_RECV_QUEUE_RESPONDER ].id =
336+ qp_resp_drv -> queue_id [MANA_UC_UDATA_RQR ];
337+ qp -> rnic_qp .queues [USER_RNIC_SEND_QUEUE_MM ].id =
338+ qp_resp_drv -> queue_id [MANA_UC_UDATA_SMQ ];
339+
340+ return 0 ;
341+ }
342+
343+ static int mana_create_cmd_qp (struct mana_qp * qp , struct ibv_pd * ibpd ,
344+ struct ibv_qp_init_attr * attr )
345+ {
346+ if (attr -> qp_type == IBV_QPT_RC )
347+ return mana_create_cmd_qp_rc (qp , ibpd , attr );
348+ else if (attr -> qp_type == IBV_QPT_UC )
349+ return mana_create_cmd_qp_uc (qp , ibpd , attr );
350+ else
351+ return - EOPNOTSUPP ;
352+ }
353+
354+ static struct ibv_qp * mana_create_qp_rnic (struct ibv_pd * ibpd ,
355+ struct ibv_qp_init_attr * attr )
356+ {
357+ struct mana_context * ctx = to_mctx (ibpd -> context );
259358 struct mana_qp * qp ;
260359 int ret , i ;
261360
262361 qp = calloc (1 , sizeof (* qp ));
263362 if (!qp )
264363 return NULL ;
265364
266- qp_cmd_drv = & qp_cmd .drv_payload ;
267- qp_resp_drv = & qp_resp .drv_payload ;
268-
269365 pthread_spin_init (& qp -> sq_lock , PTHREAD_PROCESS_PRIVATE );
270366 pthread_spin_init (& qp -> rq_lock , PTHREAD_PROCESS_PRIVATE );
271367 qp -> sq_sig_all = attr -> sq_sig_all ;
@@ -291,29 +387,18 @@ static struct ibv_qp *mana_create_qp_rnic(struct ibv_pd *ibpd,
291387
292388 if (qp -> rnic_qp .queues [i ].size != 0 && !qp -> rnic_qp .queues [i ].buffer ) {
293389 verbs_err (verbs_get_ctx (ibpd -> context ),
294- "Failed to allocate memory for RC queue %d\n" , i );
390+ "Failed to allocate memory for queue %d\n" , i );
295391 errno = ENOMEM ;
296392 goto destroy_queues ;
297393 }
298-
299- qp_cmd_drv -> queue_buf [i ] = (uintptr_t )qp -> rnic_qp .queues [i ].buffer ;
300- qp_cmd_drv -> queue_size [i ] = qp -> rnic_qp .queues [i ].size ;
301394 }
302395
303- mana_ib_init_rb_shmem (qp );
304-
305- ret = ibv_cmd_create_qp (ibpd , & qp -> ibqp .qp , attr , & qp_cmd .ibv_cmd ,
306- sizeof (qp_cmd ), & qp_resp .ibv_resp ,
307- sizeof (qp_resp ));
396+ ret = mana_create_cmd_qp (qp , ibpd , attr );
308397 if (ret ) {
309- verbs_err (verbs_get_ctx (ibpd -> context ), "Create QP failed\n" );
310398 errno = ret ;
311- goto free_rb ;
399+ goto destroy_queues ;
312400 }
313401
314- for (i = 0 ; i < USER_RNIC_QUEUE_TYPE_MAX ; ++ i )
315- qp -> rnic_qp .queues [i ].id = qp_resp_drv -> queue_id [i ];
316-
317402 qp -> ibqp .qp .qp_num = qp -> rnic_qp .queues [USER_RNIC_RECV_QUEUE_RESPONDER ].id ;
318403
319404 ret = mana_store_qp (ctx , qp );
@@ -322,12 +407,12 @@ static struct ibv_qp *mana_create_qp_rnic(struct ibv_pd *ibpd,
322407 goto destroy_qp ;
323408 }
324409
410+ mana_ib_init_rb_shmem (qp );
411+
325412 return & qp -> ibqp .qp ;
326413
327414destroy_qp :
328415 ibv_cmd_destroy_qp (& qp -> ibqp .qp );
329- free_rb :
330- mana_ib_deinit_rb_shmem (qp );
331416destroy_queues :
332417 while (i -- > 0 )
333418 mana_dealloc_mem (qp -> rnic_qp .queues [i ].buffer , qp -> rnic_qp .queues [i ].size );
@@ -346,6 +431,7 @@ struct ibv_qp *mana_create_qp(struct ibv_pd *ibpd,
346431 case IBV_QPT_RAW_PACKET :
347432 return mana_create_qp_raw (ibpd , attr );
348433 case IBV_QPT_RC :
434+ case IBV_QPT_UC :
349435 return mana_create_qp_rnic (ibpd , attr );
350436 default :
351437 verbs_err (verbs_get_ctx (ibpd -> context ),
@@ -382,7 +468,8 @@ static void mana_ib_modify_rnic_qp(struct mana_qp *qp, struct ibv_qp_attr *attr,
382468 if (attr_mask & IBV_QP_SQ_PSN ) {
383469 qp -> sq_ssn = 1 ;
384470 qp -> sq_psn = attr -> sq_psn ;
385- gdma_arm_normal_cqe (mana_ib_get_rreq (qp ), attr -> sq_psn );
471+ if (qp -> ibqp .qp .qp_type == IBV_QPT_RC )
472+ gdma_arm_normal_cqe (mana_ib_get_rreq (qp ), attr -> sq_psn );
386473 }
387474 break ;
388475 default :
@@ -397,7 +484,7 @@ int mana_modify_qp(struct ibv_qp *ibqp, struct ibv_qp_attr *attr, int attr_mask)
397484 struct ibv_modify_qp cmd = {};
398485 int err ;
399486
400- if (ibqp -> qp_type != IBV_QPT_RC )
487+ if (ibqp -> qp_type != IBV_QPT_RC && ibqp -> qp_type != IBV_QPT_UC )
401488 return EOPNOTSUPP ;
402489
403490 pthread_spin_lock (& qp -> sq_lock );
@@ -443,7 +530,7 @@ int mana_destroy_qp(struct ibv_qp *ibqp)
443530 struct mana_context * ctx = to_mctx (ibqp -> context );
444531 int ret , i ;
445532
446- if (ibqp -> qp_type == IBV_QPT_RC ) {
533+ if (ibqp -> qp_type == IBV_QPT_RC || ibqp -> qp_type == IBV_QPT_UC ) {
447534 mana_remove_qp (ctx , qp );
448535 mana_drain_cqes (qp );
449536 }
@@ -459,6 +546,7 @@ int mana_destroy_qp(struct ibv_qp *ibqp)
459546 ctx -> extern_alloc .free (qp -> raw_qp .send_buf , ctx -> extern_alloc .data );
460547 break ;
461548 case IBV_QPT_RC :
549+ case IBV_QPT_UC :
462550 pthread_spin_destroy (& qp -> sq_lock );
463551 pthread_spin_destroy (& qp -> rq_lock );
464552 destroy_shadow_queue (& qp -> shadow_sq );
0 commit comments