Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #define _GNU_SOURCE
12 : #include <unistd.h>
13 : #include <stdlib.h>
14 : #include <dlfcn.h>
15 : #include <fcntl.h>
16 :
17 : #include "securec.h"
18 : #include "rs.h"
19 : #include "ra_rs_err.h"
20 : #include "rs_rdma_inner.h"
21 : #include "rs_inner.h"
22 : #include "verbs_exp.h"
23 : #include "dl_hal_function.h"
24 : #include "dl_ibverbs_function.h"
25 : #include "rs_drv_rdma.h"
26 :
27 : int gMaxCqeNum = 0;
28 : #define INVALID_EVENT -1
29 :
30 : struct ibv_wc gWcBuf[RS_WC_NUM];
31 :
32 : struct RsCqeErrInfo gRsCqeErr;
33 :
34 41 : int RsDrvInitCqeErrInfo(void)
35 : {
36 41 : struct RsCqeErrInfo *errInfo = &gRsCqeErr;
37 : int ret;
38 :
39 41 : ret = pthread_mutex_init(&errInfo->mutex, NULL);
40 41 : CHK_PRT_RETURN(ret, hccp_err("rscb mutex_init failed ret %d!, normal ret 0", ret), -ESYSFUNC);
41 41 : ret = memset_s(&errInfo->info, sizeof(struct CqeErrInfo), 0, sizeof(struct CqeErrInfo));
42 41 : if (ret != 0) {
43 0 : pthread_mutex_destroy(&errInfo->mutex);
44 : }
45 41 : CHK_PRT_RETURN(ret, hccp_err("memset_s failed ret[%d]", ret), -ESAFEFUNC);
46 41 : return 0;
47 : }
48 :
49 41 : void RsDrvDeinitCqeErrInfo(void)
50 : {
51 41 : struct RsCqeErrInfo *errInfo = &gRsCqeErr;
52 :
53 41 : pthread_mutex_destroy(&errInfo->mutex);
54 41 : return;
55 : }
56 :
57 2 : STATIC void RsDrvSaveCqeErrInfo(uint32_t status, struct RsQpCb *qpCb)
58 : {
59 2 : struct RsCqeErrInfo *errInfo = &gRsCqeErr;
60 2 : struct CqeErrInfo *tempInfo = &errInfo->info;
61 :
62 2 : RS_PTHREAD_MUTEX_LOCK(&errInfo->mutex);
63 2 : if (tempInfo->status != 0) {
64 1 : RS_PTHREAD_MUTEX_ULOCK(&errInfo->mutex);
65 1 : hccp_run_info("over status=[0x%x], drop qpn[0x%x] err cqe status=[0x%x]", tempInfo->status, qpCb->qpInfoLo.qpn,
66 : status);
67 1 : return;
68 : }
69 1 : tempInfo->status = status;
70 1 : tempInfo->qpn = (uint32_t)qpCb->qpInfoLo.qpn;
71 1 : RsGetCurTime(&tempInfo->time);
72 1 : RS_PTHREAD_MUTEX_ULOCK(&errInfo->mutex);
73 :
74 1 : return;
75 : }
76 :
77 1 : STATIC void RsDrvSaveQpCqeErrInfo(uint32_t status, struct RsQpCb *qpCb)
78 : {
79 1 : RS_PTHREAD_MUTEX_LOCK(&qpCb->cqeErrInfo.mutex);
80 1 : if (qpCb->cqeErrInfo.info.status != 0) {
81 0 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->cqeErrInfo.mutex);
82 0 : return;
83 : }
84 1 : qpCb->cqeErrInfo.info.status = status;
85 1 : qpCb->cqeErrInfo.info.qpn = (uint32_t)qpCb->qpInfoLo.qpn;
86 1 : RsGetCurTime(&qpCb->cqeErrInfo.info.time);
87 1 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->cqeErrInfo.mutex);
88 :
89 1 : RS_PTHREAD_MUTEX_LOCK(&qpCb->rdevCb->cqeErrCntMutex);
90 1 : qpCb->rdevCb->cqeErrCnt++;
91 1 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->rdevCb->cqeErrCntMutex);
92 :
93 1 : return;
94 : }
95 :
96 4 : int RsDrvGetCqeErrInfo(struct CqeErrInfo *info)
97 : {
98 4 : struct RsCqeErrInfo *errInfo = &gRsCqeErr;
99 4 : struct CqeErrInfo *tempInfo = &errInfo->info;
100 : int ret;
101 :
102 4 : CHK_PRT_RETURN(info == NULL, hccp_err("info is NULL"), -EINVAL);
103 :
104 4 : RS_PTHREAD_MUTEX_LOCK(&errInfo->mutex);
105 4 : if (tempInfo->status == 0) {
106 1 : RS_PTHREAD_MUTEX_ULOCK(&errInfo->mutex);
107 1 : return 0;
108 : }
109 3 : hccp_run_info("status=[%u]", tempInfo->status);
110 3 : ret = memcpy_s(info, sizeof(struct CqeErrInfo), &errInfo->info, sizeof(struct CqeErrInfo));
111 3 : if (ret) {
112 1 : hccp_err("memcpy_s failed");
113 1 : RS_PTHREAD_MUTEX_ULOCK(&errInfo->mutex);
114 1 : return -ESAFEFUNC;
115 : }
116 :
117 2 : ret = memset_s(&errInfo->info, sizeof(struct CqeErrInfo), 0, sizeof(struct CqeErrInfo));
118 2 : RS_PTHREAD_MUTEX_ULOCK(&errInfo->mutex);
119 2 : CHK_PRT_RETURN(ret, hccp_err("memset_s failed ret[%d], buf len:%u", ret, sizeof(struct CqeErrInfo)), -ESAFEFUNC);
120 1 : return 0;
121 : }
122 :
123 2 : STATIC void RsRdmaRetryTimeoutExceptionCheck(struct SensorNode *sensorNode, struct ibv_wc *wc)
124 : {
125 2 : int ret = 0;
126 :
127 2 : if (wc->status != IBV_WC_RETRY_EXC_ERR) {
128 1 : return;
129 : }
130 :
131 1 : ret = RsRetryTimeoutExceptionCheck(sensorNode);
132 :
133 1 : hccp_warn("update sensor state logic_devid(%u), qpn(%u), sensorUpdateCnt(%d), ret(%d)\n", sensorNode->logicDevid,
134 : wc->qp_num, sensorNode->sensorUpdateCnt, ret);
135 : }
136 :
137 1 : STATIC void RsCqeCallbackProcess(struct RsQpCb *qpCb, struct ibv_wc *wc, struct ibv_cq *evCq)
138 : {
139 1 : if (wc->status != IBV_WC_SUCCESS && wc->status != IBV_WC_WR_FLUSH_ERR) {
140 1 : hccp_err("Failed status [%s] [%u], wr[%llu]", RsIbvWcStatusStr(wc->status), wc->status, wc->wr_id);
141 1 : RsDrvSaveCqeErrInfo(wc->status, qpCb);
142 1 : RsDrvSaveQpCqeErrInfo(wc->status, qpCb);
143 1 : RsRdmaRetryTimeoutExceptionCheck(&qpCb->rdevCb->rsCb->sensorNode, wc);
144 : }
145 :
146 1 : return;
147 : }
148 :
149 1 : void RsDrvPollSrqCqHandle(struct RsQpCb *qpCb)
150 : {
151 1 : struct ibv_cq *evCq = NULL;
152 1 : void *evCtx = NULL;
153 :
154 1 : if (RsIbvGetCqEvent(qpCb->srqContext->channel, &evCq, &evCtx)) {
155 0 : hccp_err("Failed to get cq_event");
156 0 : return;
157 : }
158 :
159 1 : if (evCq != qpCb->ibRecvCq || evCtx == NULL) {
160 1 : hccp_err("CQ event for unknown CQ");
161 1 : return;
162 : }
163 :
164 0 : ++qpCb->srqContext->numRecvCqEvents;
165 :
166 0 : struct event_summary *evCtxTmp = (struct event_summary *)evCtx;
167 0 : if ((int)evCtxTmp->event_id != INVALID_EVENT) {
168 0 : hccp_info("SubmitEvent: event id:%d, pid:%d, grp id:%u, dev id:%u", evCtxTmp->event_id, evCtxTmp->pid,
169 : evCtxTmp->grp_id, qpCb->rdevCb->rsCb->chipId);
170 0 : int ret = DlHalEschedSubmitEvent(qpCb->rdevCb->rsCb->chipId, evCtx);
171 0 : if (ret) {
172 0 : hccp_warn("halEschedSubmitEvent unsuccessful, ret:%d", ret);
173 : }
174 : }
175 :
176 0 : return;
177 : }
178 :
179 9 : void RsDrvPollCqHandle(struct RsQpCb *qpCb)
180 : {
181 9 : struct ibv_cq *evCq = NULL;
182 9 : void *evCtx = NULL;
183 : int ne, i;
184 :
185 9 : if (RsIbvGetCqEvent(qpCb->channel, &evCq, &evCtx)) {
186 0 : hccp_err("Failed to get cq_event");
187 0 : return;
188 : }
189 :
190 9 : if (evCq != qpCb->ibSendCq && evCq != qpCb->ibRecvCq) {
191 1 : hccp_err("CQ event for unknown CQ");
192 1 : return;
193 : }
194 :
195 8 : if (evCq == qpCb->ibRecvCq) {
196 0 : ++qpCb->numRecvCqEvents;
197 : } else {
198 8 : ++qpCb->numSendCqEvents;
199 : }
200 :
201 8 : if (evCtx != NULL) {
202 0 : struct event_summary *evCtxTmp = (struct event_summary *)evCtx;
203 0 : if ((int)(evCtxTmp->event_id) != INVALID_EVENT) {
204 0 : hccp_info("SubmitEvent: event id:%d, pid:%d, grp id:%u, dev id:%u", evCtxTmp->event_id, evCtxTmp->pid,
205 : evCtxTmp->grp_id, qpCb->rdevCb->rsCb->chipId);
206 0 : int ret = DlHalEschedSubmitEvent(qpCb->rdevCb->rsCb->chipId, evCtx);
207 0 : if (ret) {
208 0 : hccp_warn("halEschedSubmitEvent unsuccessful, ret:%d", ret);
209 : }
210 : }
211 0 : return;
212 : }
213 :
214 8 : ne = ibv_poll_cq(evCq, RS_WC_NUM, gWcBuf);
215 8 : if (ne > RS_WC_NUM || ne < 0) {
216 3 : hccp_err("poll CQ failed %d", ne);
217 3 : return;
218 : }
219 5 : if (gMaxCqeNum < ne) {
220 1 : gMaxCqeNum = ne;
221 1 : hccp_run_info("rs_drv_poll_cq_handle: max_cqe_num=[%d]", gMaxCqeNum);
222 : }
223 :
224 5 : if (ibv_req_notify_cq(evCq, 0)) {
225 3 : hccp_err("Couldn't request CQ notification");
226 3 : return;
227 : }
228 2 : qpCb->rdevCb->pollCqeNum += ne;
229 2 : for (i = 0; i < ne; ++i) {
230 0 : RsCqeCallbackProcess(qpCb, &(gWcBuf[i]), evCq);
231 : }
232 2 : return;
233 : }
234 :
235 98 : int RsDrvCompareIpGid(int family, union HccpIpAddr localIp, union ibv_gid *gid)
236 : {
237 : unsigned int gidV4[RS_GID_SEQ_NUM];
238 :
239 98 : if (family == AF_INET6) {
240 0 : if (memcmp(gid, &(localIp.addr6), sizeof(union ibv_gid)) == 0) {
241 0 : return 0;
242 : }
243 : } else {
244 98 : gidV4[RS_GID_SEQ_ZERO] = 0;
245 98 : gidV4[RS_GID_SEQ_ONE] = 0;
246 : /* The gid format generated by ipv4 is filled with 0xFFFF in [33, 48] */
247 98 : gidV4[RS_GID_SEQ_TWO] = htonl(0x0000FFFF);
248 98 : gidV4[RS_GID_SEQ_THREE] = localIp.addr.s_addr;
249 98 : if (memcmp(gid, &(gidV4), sizeof(union ibv_gid)) == 0) {
250 93 : return 0;
251 : }
252 : }
253 :
254 5 : return -ENODEV;
255 : }
256 :
257 69 : int RsDrvGetGidIndex(struct RsRdevCb *rdevCb, struct ibv_port_attr *attr, int *idx)
258 : {
259 : static const char *portStates[] = {"Nop", "Down", "Init", "Armed", "", "Active Defer"};
260 : enum ibv_gid_type_sysfs type;
261 : union ibv_gid gidTmp;
262 69 : int gidIdx = -1;
263 : int ret;
264 : int i;
265 :
266 69 : ret = RsIbvQueryPort(rdevCb->ibCtx, rdevCb->ibPort, attr);
267 69 : CHK_PRT_RETURN(ret, hccp_err("ibv_query_port failed ret[%d]", ret), -EOPENSRC);
268 :
269 : // link maybe suffer from intermittent disconnection, should continue process
270 68 : if (attr->state != IBV_PORT_ACTIVE) {
271 0 : hccp_warn("port number %u state is %s", rdevCb->ibPort, portStates[attr->state]);
272 : }
273 :
274 139 : for (i = 0; i < attr->gid_tbl_len; i++) {
275 135 : ret = RsIbvQueryGidType(rdevCb->ibCtx, rdevCb->ibPort, (unsigned int)i, &type);
276 135 : CHK_PRT_RETURN(ret, hccp_err("query gid type failed i %d, ret %d", i, ret), -EOPENSRC);
277 134 : if (type != IBV_GID_TYPE_SYSFS_ROCE_V2) {
278 67 : continue;
279 : }
280 :
281 67 : ret = RsIbvQueryGid(rdevCb->ibCtx, rdevCb->ibPort, i, &gidTmp);
282 67 : CHK_PRT_RETURN(ret, hccp_err("query gid failed i %d, ret %d", i, ret), -EOPENSRC);
283 :
284 66 : ret = RsDrvCompareIpGid((int)rdevCb->localIp.family, rdevCb->localIp.binAddr, &gidTmp);
285 66 : if (ret == 0) {
286 62 : gidIdx = i;
287 62 : break;
288 : }
289 : }
290 :
291 66 : if (gidIdx == -1) {
292 4 : hccp_err("get idx failed, attr->gid_tbl_len:%d", attr->gid_tbl_len);
293 4 : return -ENODEV;
294 : }
295 :
296 62 : hccp_dbg("GID index is %d", gidIdx);
297 62 : *idx = gidIdx;
298 62 : return 0;
299 : }
300 :
301 93 : STATIC int RsDrvGetSupportLite(struct RsRdevCb *rdevCb, int qpMode, unsigned int aiOpSupport)
302 : {
303 : // bypass rdma lite when ai_op_support was set
304 93 : if (aiOpSupport == 1) {
305 8 : return 0;
306 : }
307 :
308 85 : if (qpMode == RA_RS_OP_QP_MODE || qpMode == RA_RS_OP_QP_MODE_EXT) {
309 4 : return rdevCb->supportLite;
310 : }
311 :
312 81 : return 0;
313 : }
314 :
315 51 : int RsDrvCreateCqWithAttrs(struct RsQpCb *qpCb, int isExt, struct CqExtAttr *cqAttr)
316 : {
317 51 : int sendEqNum = cqAttr->sendCqCompVector;
318 51 : int recvEqNum = cqAttr->recvCqCompVector;
319 51 : struct rdma_lite_device_cq_init_attr attr = {
320 51 : .cq_type = qpCb->qpMode,
321 : .part_id = 0,
322 : .lite_op_supported = 0,
323 51 : .mem_align = qpCb->memAlign,
324 51 : .mem_idx = qpCb->memResp.memData.mem_idx,
325 51 : .ai_op_support = qpCb->aiOpSupport,
326 51 : .grp_id = qpCb->grpId,
327 51 : .cq_cstm_flag = qpCb->cqCstmFlag,
328 51 : .use_resv_mem = qpCb->useResvMem,
329 51 : .resv_mem_pool_id = qpCb->resvMemPoolId,
330 : };
331 51 : struct ibv_comp_channel *channel = qpCb->channel;
332 :
333 51 : attr.lite_op_supported = RsDrvGetSupportLite(qpCb->rdevCb, qpCb->qpMode, qpCb->aiOpSupport);
334 : // caller poll cq
335 51 : if (attr.lite_op_supported != 0 || attr.cq_cstm_flag != 0) {
336 4 : channel = NULL;
337 4 : sendEqNum = 0;
338 4 : recvEqNum = 0;
339 : }
340 :
341 51 : hccp_dbg("create cq start");
342 51 : if (isExt == 1) {
343 7 : qpCb->ibSendCq = RsIbvExpCreateCq(qpCb->rdevCb->ibCtx, cqAttr->sendCqDepth, NULL, channel, sendEqNum, &attr,
344 : &qpCb->qpResp.sendCqData);
345 7 : hccp_info("rs_ibv_exp_create_cq");
346 : } else {
347 44 : qpCb->ibSendCq = RsIbvCreateCq(qpCb->rdevCb->ibCtx, cqAttr->sendCqDepth, NULL, channel, sendEqNum);
348 : }
349 :
350 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
351 51 : CHK_PRT_RETURN(qpCb->ibSendCq == NULL, hccp_err("ibv create send cq failed"), -ENOMEM);
352 :
353 50 : if (isExt == 1) {
354 7 : qpCb->ibRecvCq = RsIbvExpCreateCq(qpCb->rdevCb->ibCtx, cqAttr->recvCqDepth, NULL, channel, recvEqNum, &attr,
355 : &qpCb->qpResp.recvCqData);
356 7 : hccp_info("rs_ibv_exp_create_cq");
357 : } else {
358 43 : qpCb->ibRecvCq = RsIbvCreateCq(qpCb->rdevCb->ibCtx, cqAttr->recvCqDepth, NULL, channel, recvEqNum);
359 : }
360 :
361 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
362 50 : if (qpCb->ibRecvCq == NULL) {
363 3 : hccp_err("ibv create recv cq failed");
364 3 : (void)RsIbvDestroyCq(qpCb->ibSendCq);
365 3 : return -ENOMEM;
366 : }
367 :
368 47 : hccp_info("create cq success");
369 47 : return 0;
370 : }
371 :
372 : #define RS_DRV_CQ_DEPTH 16384
373 : #define RS_DRV_CQ_128_DEPTH 128
374 : #define RS_DRV_CQ_32K_DEPTH 32768
375 :
376 47 : int RsDrvCreateCq(struct RsQpCb *qpCb, int isExt)
377 : {
378 47 : struct CqExtAttr cqAttr = {0};
379 :
380 47 : cqAttr.sendCqDepth = qpCb->sendCqDepth;
381 47 : cqAttr.sendCqCompVector = qpCb->eqNum;
382 47 : cqAttr.recvCqDepth = qpCb->recvCqDepth;
383 47 : cqAttr.recvCqCompVector = qpCb->eqNum;
384 :
385 47 : return RsDrvCreateCqWithAttrs(qpCb, isExt, &cqAttr);
386 : }
387 :
388 110 : void RsDrvEventDestroy(struct event_summary *event)
389 : {
390 110 : if (event != NULL) {
391 9 : free(event);
392 9 : event = NULL;
393 : }
394 110 : }
395 :
396 47 : void RsDrvDestroyCq(struct RsQpCb *qpCb)
397 : {
398 47 : (void)RsIbvDestroyCq(qpCb->ibRecvCq);
399 47 : (void)RsIbvDestroyCq(qpCb->ibSendCq);
400 47 : (void)RsDrvEventDestroy(qpCb->recvEvent);
401 47 : (void)RsDrvEventDestroy(qpCb->sendEvent);
402 47 : }
403 :
404 3 : int RsDrvQpStateModifytoReset(struct RsQpCb *qpCb)
405 : {
406 3 : struct ibv_qp_init_attr qpInitAttr = {0};
407 3 : struct ibv_qp_attr attr = {0};
408 : int ret;
409 :
410 3 : attr.qp_state = IBV_QPS_RESET;
411 3 : ret = RsIbvModifyQp(qpCb->ibQp, &attr, IBV_QP_STATE);
412 3 : CHK_PRT_RETURN(ret, hccp_err("[modify]qpn[%d] modify to reset failed, ret %d", qpCb->qpInfoLo.qpn, ret), ret);
413 :
414 3 : (void)memset_s(&attr, sizeof(struct ibv_qp_attr), 0, sizeof(struct ibv_qp_attr));
415 :
416 3 : ret = RsIbvQueryQp(qpCb->ibQp, &attr, IBV_QP_STATE, &qpInitAttr);
417 3 : if ((ret != 0) || attr.qp_state != IBV_QPS_RESET) {
418 1 : hccp_err("query qpn[%d] attr failed, ret %d or qp state %d is not RESET", qpCb->qpInfoLo.qpn, ret,
419 : attr.qp_state);
420 1 : return ret;
421 : }
422 :
423 2 : hccp_info("qpn[%d] modify to reset success", qpCb->qpInfoLo.qpn);
424 2 : return 0;
425 : }
426 :
427 21 : int RsDrvQpStateModifytoInit(struct RsQpCb *qpCb, struct ibv_qp_attr *attr)
428 : {
429 : int ret;
430 :
431 21 : attr->qp_state = IBV_QPS_INIT;
432 21 : attr->pkey_index = 0;
433 21 : attr->port_num = qpCb->rdevCb->ibPort;
434 21 : attr->qp_access_flags = DEFAULT_ACCESS_FLAG;
435 21 : ret = RsIbvModifyQp(qpCb->ibQp, attr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS);
436 21 : CHK_PRT_RETURN(ret, hccp_err("[modify]qpn[%d] modify to init failed, ret %d", qpCb->qpInfoLo.qpn, ret), ret);
437 :
438 20 : hccp_info("qpn[%d] modify to init success", qpCb->qpInfoLo.qpn);
439 20 : return 0;
440 : }
441 :
442 22 : enum ibv_mtu RsDrvSetMtu(struct RsQpCb *qpCb)
443 : {
444 : int ret;
445 22 : struct ibv_port_attr portAttr = {0};
446 : enum ibv_mtu currMtu;
447 :
448 22 : ret = RsIbvQueryPort(qpCb->rdevCb->ibCtx, qpCb->rdevCb->ibPort, &portAttr);
449 22 : CHK_PRT_RETURN(ret, hccp_err("Error when trying to query port, ret[%d]", ret), -EOPENSRC);
450 : #ifndef CA_CONFIG_LLT
451 : currMtu = portAttr.active_mtu;
452 : #else
453 21 : currMtu = IBV_MTU_1024;
454 : #endif
455 :
456 21 : return currMtu;
457 : }
458 :
459 20 : int RsDrvQpStateModifytoRtr(struct RsQpCb *qpCb, struct ibv_qp_attr *attr)
460 : {
461 20 : struct ibv_port_attr portAttr = {0};
462 : int ret;
463 :
464 20 : attr->qp_state = IBV_QPS_RTR;
465 20 : attr->dest_qp_num = (uint32_t)qpCb->qpInfoRem.qpn;
466 20 : attr->rq_psn = (uint32_t)qpCb->qpInfoRem.psn;
467 20 : attr->min_rnr_timer = RS_QP_ATTR_MIN_RNR_TIMER;
468 20 : (attr->ah_attr).is_global = 0;
469 20 : (attr->ah_attr).dlid = qpCb->qpInfoRem.lid;
470 20 : (attr->ah_attr).sl = qpCb->qosAttr.sl;
471 20 : (attr->ah_attr).src_path_bits = 0;
472 20 : (attr->ah_attr).port_num = qpCb->rdevCb->ibPort;
473 :
474 20 : attr->path_mtu = RsDrvSetMtu(qpCb);
475 20 : if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
476 4 : attr->max_dest_rd_atomic = RS_MAX_RD_ATOMIC_NUM_PEER_ONLINE;
477 : } else {
478 16 : attr->max_dest_rd_atomic = RS_MAX_RD_ATOMIC_NUM;
479 16 : CHK_PRT_RETURN(attr->path_mtu < IBV_MTU_1024,
480 : hccp_err("qpn[%d] failed to set mtu, mtu[%d] < [%d]", qpCb->qpInfoLo.qpn, attr->path_mtu, IBV_MTU_1024),
481 : -EPERM);
482 : }
483 :
484 : // get gid_idx dynamically
485 20 : ret = RsDrvGetGidIndex(qpCb->rdevCb, &portAttr, &qpCb->qpInfoLo.gidIdx);
486 20 : CHK_PRT_RETURN(ret,
487 : hccp_err("rs_drv_get_gid_index failed ret[%d], qpn[%d] gidIdx[%d]", ret, qpCb->qpInfoLo.qpn,
488 : qpCb->qpInfoLo.gidIdx),
489 : ret);
490 :
491 19 : if (qpCb->qpInfoRem.gid.global.interface_id) {
492 16 : attr->ah_attr.is_global = 1;
493 16 : attr->ah_attr.grh.hop_limit = 1;
494 16 : attr->ah_attr.grh.dgid = qpCb->qpInfoRem.gid;
495 16 : attr->ah_attr.grh.sgid_index = qpCb->qpInfoLo.gidIdx;
496 : }
497 :
498 19 : (attr->ah_attr).grh.traffic_class = qpCb->qosAttr.tc;
499 19 : ret = RsIbvModifyQp(qpCb->ibQp, attr,
500 : IBV_QP_STATE | IBV_QP_AV | IBV_QP_PATH_MTU | IBV_QP_DEST_QPN | IBV_QP_RQ_PSN | IBV_QP_MAX_DEST_RD_ATOMIC |
501 : IBV_QP_MIN_RNR_TIMER);
502 19 : CHK_PRT_RETURN(ret,
503 : hccp_err("qpn[%d] failed to modify QP to RTR, ibv_modify_qp failed ret[%d], errno[%d]", qpCb->qpInfoLo.qpn, ret,
504 : errno),
505 : -EOPENSRC);
506 18 : hccp_info("qp qos attr: qpn[%d] tc[%u] sl[%u]", qpCb->qpInfoLo.qpn, qpCb->qosAttr.tc, qpCb->qosAttr.sl);
507 18 : return 0;
508 : }
509 :
510 18 : int RsDrvQpStateModifytoRts(struct RsQpCb *qpCb, struct ibv_qp_attr *attr)
511 : {
512 : int ret;
513 18 : attr->qp_state = IBV_QPS_RTS;
514 18 : attr->timeout = (uint8_t)qpCb->timeout;
515 18 : attr->retry_cnt = (uint8_t)qpCb->retryCnt;
516 18 : attr->rnr_retry = RS_QP_ATTR_RNR_RETRY;
517 18 : attr->sq_psn = (uint32_t)qpCb->qpInfoLo.psn;
518 18 : if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
519 3 : attr->max_rd_atomic = RS_MAX_RD_ATOMIC_NUM_PEER_ONLINE;
520 : } else {
521 15 : attr->max_rd_atomic = RS_MAX_RD_ATOMIC_NUM;
522 : }
523 18 : ret = RsIbvModifyQp(qpCb->ibQp, attr,
524 : IBV_QP_STATE | IBV_QP_TIMEOUT | IBV_QP_RETRY_CNT | IBV_QP_RNR_RETRY | IBV_QP_SQ_PSN | IBV_QP_MAX_QP_RD_ATOMIC);
525 18 : CHK_PRT_RETURN(ret,
526 : hccp_err("qpn[%d] failed to modify QP to RTS, ibv_modify_qp failed ret[%d]", qpCb->qpInfoLo.qpn, ret),
527 : -EOPENSRC);
528 18 : hccp_info("qp rdma attr: qpn[%d] timeout[%u] retrycnt[%u]", qpCb->qpInfoLo.qpn, qpCb->timeout, qpCb->retryCnt);
529 18 : return 0;
530 : }
531 :
532 6 : struct ibv_mr *RsDrvMrReg(struct ibv_pd *pd, char *addr, size_t length, int access)
533 : {
534 6 : return RsIbvRegMr(pd, addr, length, access);
535 : }
536 :
537 5 : struct ibv_mr *RsDrvExpMrReg(struct ibv_pd *pd, char *addr, size_t length, int access,
538 : struct roce_process_sign roceSign)
539 : {
540 5 : return RsIbvExpRegMr(pd, addr, length, access, roceSign);
541 : }
542 :
543 38 : int RsDrvMrDereg(struct ibv_mr *ibMr)
544 : {
545 38 : return RsIbvDeregMr(ibMr);
546 : }
547 :
548 : #ifdef CUSTOM_INTERFACE
549 2 : STATIC int RsOpenBackupIbCtx(struct RsRdevCb *rdevCb)
550 : {
551 2 : struct ibv_context *ibCtxTmp = NULL;
552 2 : struct rdev rdevInfo = {0};
553 2 : int gidIndex = -1;
554 : int ret;
555 : int i;
556 :
557 2 : (void)memcpy_s(&rdevInfo, sizeof(struct rdev), &rdevCb->backupInfo.rdevInfo, sizeof(struct rdev));
558 2 : for (i = 0; (i < rdevCb->devNum) && (rdevCb->devList[i] != NULL); ++i) {
559 1 : ibCtxTmp = RsIbvOpenDevice(rdevCb->devList[i]);
560 1 : CHK_PRT_RETURN(ibCtxTmp == NULL, hccp_err("ibv_open_device with backup failed, errno:%d", errno), -ENODEV);
561 1 : ret = RsQueryGid(rdevInfo, ibCtxTmp, rdevCb->ibPort, &gidIndex);
562 1 : if (ret == 0) {
563 1 : rdevCb->backupInfo.ibCtx = ibCtxTmp;
564 1 : return 0;
565 0 : } else if (ret == -EEXIST) {
566 0 : RsIbvCloseDevice(ibCtxTmp);
567 : } else {
568 0 : RsIbvCloseDevice(ibCtxTmp);
569 0 : hccp_err("rs_query_gid failed, ret:%d", ret);
570 0 : return ret;
571 : }
572 : }
573 :
574 1 : CHK_PRT_RETURN(i == rdevCb->devNum,
575 : hccp_err("can not find ib_ctx for phyId[%u] local_ip[0x%x] in dev_list!", rdevInfo.phyId,
576 : rdevInfo.localIp.addr.s_addr),
577 : -EEXIST);
578 0 : return 0;
579 : }
580 :
581 30 : void RsCloseBackupIbCtx(struct RsRdevCb *rdevCb)
582 : {
583 : // no need to close backup device
584 30 : if (!rdevCb->backupInfo.backupFlag || rdevCb->backupInfo.ibCtx == NULL) {
585 29 : return;
586 : }
587 :
588 1 : RsIbvCloseDevice(rdevCb->backupInfo.ibCtx);
589 : }
590 : #endif
591 :
592 30 : STATIC int RsDrvQueryNotify(struct RsRdevCb *rdevCb)
593 : {
594 30 : int ret = 0;
595 :
596 30 : if (rdevCb->notifyType == NO_USE) {
597 2 : return 0;
598 : }
599 :
600 : #ifdef CUSTOM_INTERFACE
601 28 : if (RsIsCustomInterfaceSupported()) {
602 28 : if (rdevCb->backupInfo.backupFlag) {
603 : // open backup device to get ib_ctx to get backup notify va and size
604 2 : ret = RsOpenBackupIbCtx(rdevCb);
605 2 : CHK_PRT_RETURN(ret, hccp_err("rs_open_backup_ib_ctx failed, ret:%d", ret), ret);
606 :
607 2 : ret = RsIbvExpQueryNotify(rdevCb->backupInfo.ibCtx, &rdevCb->notifyVaBase, &rdevCb->notifySize);
608 2 : if (ret != 0) {
609 1 : RsCloseBackupIbCtx(rdevCb);
610 1 : hccp_err("rs_ibv_exp_query_notify with backup ctx failed, ret:%d", ret);
611 1 : return ret;
612 : }
613 : } else {
614 26 : ret = RsIbvExpQueryNotify(rdevCb->ibCtx, &rdevCb->notifyVaBase, &rdevCb->notifySize);
615 26 : CHK_PRT_RETURN(ret, hccp_err("rs_ibv_exp_query_notify failed, ret:%d", ret), ret);
616 : }
617 : }
618 : #endif
619 27 : hccp_info("chip_id:%u, RsDrvQueryNotify ok, notify va:0x%llx, size:%llu", rdevCb->rsCb->chipId,
620 : rdevCb->notifyVaBase, rdevCb->notifySize);
621 27 : return ret;
622 : }
623 :
624 30 : int RsDrvQueryNotifyAndAllocPd(struct RsRdevCb *rdevCb)
625 : {
626 30 : int ret = 0;
627 :
628 30 : ret = RsDrvQueryNotify(rdevCb);
629 30 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_query_notify failed, ret %d", ret), ret);
630 :
631 29 : rdevCb->ibPd = RsIbvAllocPd(rdevCb->ibCtx);
632 29 : if (rdevCb->ibPd == NULL) {
633 : #ifdef CUSTOM_INTERFACE
634 0 : if (RsIsCustomInterfaceSupported()) {
635 0 : RsCloseBackupIbCtx(rdevCb);
636 : }
637 : #endif
638 0 : hccp_err("rs_ibv_alloc_pd failed, errno:%d", errno);
639 0 : return -ENOMEM;
640 : }
641 :
642 29 : return 0;
643 : }
644 :
645 29 : int RsDrvRegNotifyMr(struct RsRdevCb *rdevCb)
646 : {
647 29 : struct roce_process_sign roceSign = {0};
648 29 : int access = DEFAULT_ACCESS_FLAG;
649 : (void)roceSign;
650 29 : rdevCb->notifyAccess = access;
651 29 : switch (rdevCb->notifyType) {
652 2 : case NO_USE:
653 2 : return 0;
654 27 : case NOTIFY: {
655 27 : rdevCb->notifyMr = RsIbvRegMr(rdevCb->ibPd, (void *)(uintptr_t)rdevCb->notifyVaBase, rdevCb->notifySize,
656 : access);
657 27 : break;
658 : }
659 0 : case EVENTID: {
660 : #ifdef CUSTOM_INTERFACE
661 0 : if (RsIsCustomInterfaceSupported()) {
662 0 : rdevCb->notifyMr = RsIbvExpRegMr(rdevCb->ibPd, (void *)(uintptr_t)rdevCb->notifyVaBase,
663 0 : rdevCb->notifySize, access, roceSign);
664 : } else {
665 0 : return 0;
666 : }
667 0 : break;
668 : #else
669 : return 0;
670 : #endif
671 : }
672 0 : default: {
673 0 : hccp_err("rs_drv_reg_notify_mr failed! notify_type = %u", rdevCb->notifyType);
674 0 : return -EINVAL;
675 : }
676 : }
677 :
678 27 : CHK_PRT_RETURN(rdevCb->notifyMr == NULL,
679 : hccp_err("ibv_reg_mr addr[0x%llx] len[%llu] errno[%d]failed", rdevCb->notifyVaBase, rdevCb->notifySize, errno),
680 : -EACCES);
681 :
682 27 : hccp_info("ibv_reg_mr ok");
683 27 : return 0;
684 : }
685 :
686 0 : STATIC void RsBuildRecvWr(struct RecvWrlistData *wr, struct ibv_sge *list, struct ibv_recv_wr *ibWr)
687 : {
688 0 : list->addr = (uintptr_t)wr->memList.addr;
689 0 : list->length = wr->memList.len;
690 0 : list->lkey = wr->memList.lkey;
691 :
692 0 : ibWr->sg_list = list;
693 0 : ibWr->wr_id = wr->wrId;
694 0 : ibWr->num_sge = 1; /* only support one sge */
695 0 : return;
696 : }
697 :
698 0 : int RsDrvPostRecv(struct RsQpCb *qpCb, struct RecvWrlistData *wr, unsigned int recvNum, unsigned int *completeNum)
699 : {
700 0 : int ret = 0;
701 : unsigned int i, index;
702 0 : struct ibv_recv_wr *badWr = NULL;
703 :
704 0 : CHK_PRT_RETURN(recvNum == 0, hccp_err("recv_num[%u] is invalid!", recvNum), -EINVAL);
705 :
706 0 : struct ibv_recv_wr *recvWr = (struct ibv_recv_wr *)calloc(recvNum, sizeof(struct ibv_recv_wr));
707 0 : CHK_PRT_RETURN(recvWr == NULL, hccp_err("calloc recv_wr failed!"), -ENOSPC);
708 :
709 0 : struct ibv_sge *list = (struct ibv_sge *)calloc(recvNum, sizeof(struct ibv_sge));
710 0 : if (list == NULL) {
711 0 : hccp_err("calloc list failed!");
712 0 : ret = -ENOSPC;
713 0 : goto alloc_sge_fail;
714 : }
715 :
716 0 : for (i = 0; i < recvNum; i++) {
717 0 : RsBuildRecvWr(&wr[i], &list[i], &recvWr[i]);
718 0 : index = i + 1; // for fix pclint warning
719 0 : recvWr[i].next = (i < recvNum - 1) ? &(recvWr[index]) : NULL;
720 : }
721 :
722 0 : ret = RsIbvPostRecv(qpCb->ibQp, recvWr, &badWr);
723 0 : if (ret == 0) {
724 0 : *completeNum = recvNum;
725 0 : } else if (ret == -ENOMEM) {
726 0 : *completeNum = (unsigned int)((void *)badWr - (void *)recvWr) / sizeof(struct ibv_recv_wr);
727 0 : hccp_dbg("post recv wqe overflow, completeNum[%d]", *completeNum);
728 : } else {
729 0 : hccp_err("ibv_post_recv failed, ret[%d]", ret);
730 0 : *completeNum = 0;
731 : }
732 0 : qpCb->recvWrNum = qpCb->recvWrNum + (*completeNum);
733 :
734 0 : free(list);
735 0 : list = NULL;
736 :
737 0 : alloc_sge_fail:
738 0 : free(recvWr);
739 0 : recvWr = NULL;
740 0 : return (ret == -ENOMEM) ? 0 : ret;
741 : }
742 :
743 4 : int RsDrvSendExp(struct RsQpCb *qpCb, struct RsMrCb *mrCb, struct RsMrCb *remMrCb, struct SendWr *wr,
744 : struct SendWrRsp *wrRsp)
745 : {
746 : int i;
747 : int ret;
748 : struct ibv_sge list[RS_SGLIST_MAX];
749 4 : struct ibv_send_wr ibWr = {
750 : .sg_list = list,
751 4 : .opcode = wr->op,
752 4 : .send_flags = wr->sendFlag,
753 : };
754 4 : struct ibv_send_wr *badWr = NULL;
755 4 : struct wr_exp_rsp expRsp = {0};
756 :
757 8 : for (i = 0; i < wr->bufNum && i < RS_SGLIST_MAX; i++) {
758 4 : list[i].addr = (uintptr_t)wr->bufList[i].addr;
759 4 : list[i].length = wr->bufList[i].len;
760 4 : list[i].lkey = mrCb->ibMr->lkey;
761 : }
762 :
763 4 : ibWr.num_sge = i;
764 4 : ibWr.wr_id = mrCb->wrId;
765 : // send op has no rem_mr, no need to assign
766 4 : if (wr->op != RA_WR_SEND && wr->op != RA_WR_SEND_WITH_IMM) {
767 4 : ibWr.wr.rdma.rkey = remMrCb->mrInfo.rkey;
768 4 : ibWr.wr.rdma.remote_addr = wr->dstAddr;
769 : }
770 :
771 4 : ret = RsIbvExpPostSend(qpCb->ibQp, &ibWr, &badWr, &expRsp);
772 4 : if (ret) {
773 0 : hccp_err("rs_ibv_exp_post_send failed ret %d", ret);
774 : }
775 :
776 4 : if (qpCb->qpMode == RA_RS_GDR_TMPL_QP_MODE) {
777 3 : wrRsp->wqeTmp.sqIndex = (unsigned int)qpCb->sqIndex;
778 3 : wrRsp->wqeTmp.wqeIndex = expRsp.wqe_index;
779 1 : } else if (qpCb->qpMode == RA_RS_OP_QP_MODE || qpCb->qpMode == RA_RS_OP_QP_MODE_EXT ||
780 0 : qpCb->qpMode == RA_RS_GDR_ASYN_QP_MODE) {
781 1 : wrRsp->db.dbIndex = (unsigned int)qpCb->dbIndex;
782 1 : wrRsp->db.dbInfo = expRsp.db_info;
783 : }
784 :
785 4 : return ret;
786 : }
787 :
788 45 : STATIC int RsDrvQpQueryInfo(struct RsQpCb *qpCb, struct RsRdevCb *rdevCb, struct ibv_port_attr *attr,
789 : struct ibv_qp_attr *qpAttr, union ibv_gid *gidTmp)
790 : {
791 : int ret;
792 : /* modify qp state */
793 45 : ret = memset_s(qpAttr, sizeof(struct ibv_qp_attr), 0, sizeof(struct ibv_qp_attr));
794 45 : CHK_PRT_RETURN(ret, hccp_err("memset_s failed ret[%d], buf len:%u", ret, sizeof(struct ibv_qp_attr)), -ESAFEFUNC);
795 44 : qpAttr->qp_state = IBV_QPS_INIT;
796 44 : qpAttr->pkey_index = 0;
797 44 : qpAttr->port_num = rdevCb->ibPort;
798 44 : qpAttr->qp_access_flags = DEFAULT_ACCESS_FLAG;
799 44 : ret = RsIbvModifyQp(qpCb->ibQp, qpAttr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS);
800 44 : CHK_PRT_RETURN(ret, hccp_err("ibv_modify_qp failed ret[%d]", ret), -EOPENSRC);
801 :
802 : /* prepare qp info for exchange */
803 43 : ret = RsDrvGetGidIndex(rdevCb, attr, &qpCb->qpInfoLo.gidIdx);
804 43 : CHK_PRT_RETURN(ret,
805 : hccp_err("rs_drv_get_gid_index failed ret[%d] qpn[%u] gid_idx[%d]", ret, qpCb->ibQp->qp_num,
806 : qpCb->qpInfoLo.gidIdx),
807 : ret);
808 :
809 41 : ret = RsIbvQueryGid(rdevCb->ibCtx, rdevCb->ibPort, qpCb->qpInfoLo.gidIdx, gidTmp);
810 41 : CHK_PRT_RETURN(ret, hccp_err("ibv_query_gid failed ret[%d]", ret), -EOPENSRC);
811 40 : return 0;
812 : }
813 :
814 41 : RS_ATTRI_VISI_DEF int RsDrvGetRandomNum(int *randNum)
815 : {
816 : int randFd;
817 41 : int ret = 0;
818 41 : int retClose = 0;
819 :
820 41 : randFd = open("/dev/urandom", O_RDONLY, S_IRUSR);
821 41 : CHK_PRT_RETURN(randFd < 0, hccp_err("open random failed ret[%d] rand_fd[%d]", errno, randFd), -EFILEOPER);
822 : do {
823 39 : ret = read(randFd, randNum, sizeof(int));
824 39 : } while ((ret < 0) && (errno == EINTR));
825 :
826 39 : if (ret < 0) {
827 1 : hccp_err("get random failed ret[%d]", ret);
828 1 : RS_CLOSE_RETRY_FOR_EINTR(retClose, randFd);
829 1 : return -EFILEOPER;
830 : }
831 :
832 38 : RS_CLOSE_RETRY_FOR_EINTR(retClose, randFd);
833 38 : return 0;
834 : }
835 :
836 45 : int RsDrvQpInfoRelated(struct RsQpCb *qpCb, struct RsRdevCb *rdevCb, struct ibv_port_attr *attr,
837 : struct ibv_qp_attr *qpAttr)
838 : {
839 : int ret;
840 : union ibv_gid gidTmp;
841 : int randNum;
842 :
843 45 : ret = RsDrvQpQueryInfo(qpCb, rdevCb, attr, qpAttr, &gidTmp);
844 45 : CHK_PRT_RETURN(ret, hccp_err("query qp info failed, ret %d", ret), ret);
845 :
846 40 : ret = RsDrvGetRandomNum(&randNum);
847 40 : CHK_PRT_RETURN(ret, hccp_err("get random num failed, ret %d", ret), ret);
848 :
849 37 : qpCb->qpInfoLo.cmd = (unsigned int)RS_CMD_QP_INFO;
850 37 : qpCb->qpInfoLo.lid = attr->lid;
851 37 : qpCb->qpInfoLo.psn = (unsigned int)randNum & 0xffffff;
852 37 : qpCb->qpInfoLo.qpn = (int)qpCb->ibQp->qp_num;
853 37 : if (rdevCb->notifyType != NO_USE && rdevCb->notifyMr != NULL) {
854 36 : qpCb->qpInfoLo.notifyMr.addr = rdevCb->notifyVaBase;
855 36 : qpCb->qpInfoLo.notifyMr.len = rdevCb->notifySize;
856 36 : qpCb->qpInfoLo.notifyMr.rkey = rdevCb->notifyMr->rkey;
857 : } else {
858 1 : qpCb->qpInfoLo.notifyMr.addr = 0;
859 1 : qpCb->qpInfoLo.notifyMr.len = 0;
860 1 : qpCb->qpInfoLo.notifyMr.rkey = 0;
861 : }
862 :
863 37 : ret = memcpy_s(qpCb->qpInfoLo.gid.raw, sizeof(qpCb->qpInfoLo.gid.raw), gidTmp.raw, sizeof(gidTmp.raw));
864 37 : CHK_PRT_RETURN(ret,
865 : hccp_err("memcpy_s raw failed, ret:%d, dst_len:%u, src_len:%d", ret, sizeof(qpCb->qpInfoLo.gid.raw),
866 : RS_QP_ATTR_GID_LEN),
867 : -ESAFEFUNC);
868 36 : return 0;
869 : }
870 :
871 40 : STATIC int RsDrvExpQpCreateInit(struct ibv_exp_qp_init_attr *qpInitAttr, struct RsQpCb *qpCb,
872 : struct ibv_port_attr *attr)
873 : {
874 : int ret;
875 40 : ret = memset_s(attr, sizeof(struct ibv_port_attr), 0, sizeof(struct ibv_port_attr));
876 40 : CHK_PRT_RETURN(ret, hccp_err("memset_s for attr failed, ret:%d", ret), -ESAFEFUNC);
877 39 : ret = memset_s(qpInitAttr, sizeof(struct ibv_exp_qp_init_attr), 0, sizeof(struct ibv_exp_qp_init_attr));
878 39 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ESAFEFUNC);
879 :
880 38 : qpInitAttr->attr.qp_type = IBV_QPT_RC;
881 38 : qpInitAttr->attr.send_cq = qpCb->ibSendCq;
882 38 : qpInitAttr->attr.recv_cq = qpCb->ibRecvCq;
883 38 : qpInitAttr->attr.cap.max_inline_data = QP_DEFAULT_MAX_CAP_INLINE_DATA;
884 38 : qpInitAttr->attr.cap.max_send_wr = qpCb->txDepth;
885 38 : qpInitAttr->attr.cap.max_send_sge = qpCb->sendSgeNum;
886 38 : qpInitAttr->attr.cap.max_recv_wr = qpCb->rxDepth;
887 38 : qpInitAttr->attr.cap.max_recv_sge = qpCb->recvSgeNum;
888 :
889 38 : return 0;
890 : }
891 :
892 40 : STATIC int RsDrvExpQpCreate(struct RsQpCb *qpCb, int qpMode)
893 : {
894 : int ret;
895 : struct ibv_qp_attr qpAttr;
896 : struct ibv_exp_qp_init_attr qpInitAttr;
897 40 : struct RsRdevCb *rdevCb = NULL;
898 : struct ibv_port_attr attr;
899 :
900 40 : hccp_dbg("qp exp create begin..");
901 40 : rdevCb = qpCb->rdevCb;
902 40 : qpCb->qpMode = qpMode;
903 40 : ret = RsDrvExpQpCreateInit(&qpInitAttr, qpCb, &attr);
904 40 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_qp_create_init failed, ret:%d", ret), ret);
905 :
906 38 : qpInitAttr.gdr_enable = qpMode;
907 38 : qpInitAttr.lite_op_support = RsDrvGetSupportLite(rdevCb, qpCb->qpMode, qpCb->aiOpSupport);
908 38 : qpInitAttr.mem_align = qpCb->memAlign;
909 38 : qpInitAttr.mem_idx = qpCb->memResp.memData.mem_idx;
910 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
911 38 : qpCb->ibQp = RsIbvExpCreateQp(qpCb->ibPd, &qpInitAttr, &qpCb->qpResp.qpData);
912 38 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_exp_create_qp failed"), -ENOMEM);
913 :
914 37 : qpCb->dbIndex = (qpMode == RA_RS_OP_QP_MODE || qpMode == RA_RS_GDR_ASYN_QP_MODE) ? qpCb->qpResp.qpData.qp_info : 0;
915 37 : qpCb->sqIndex = (qpMode == RA_RS_GDR_TMPL_QP_MODE) ? qpCb->qpResp.qpData.qp_info : 0;
916 37 : hccp_info("db index is [%d], sq index is [%d]", qpCb->dbIndex, qpCb->sqIndex);
917 :
918 : /* query qp attr */
919 37 : ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, &qpInitAttr.attr);
920 37 : if (ret) {
921 1 : hccp_err("query qp attr failed ret %d", ret);
922 1 : ret = -EOPENSRC;
923 1 : goto exp_init_qp_err;
924 : }
925 :
926 36 : ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
927 36 : if (ret) {
928 9 : hccp_err("qp info related failed %d", ret);
929 9 : goto exp_init_qp_err;
930 : }
931 :
932 27 : hccp_info("chip_id %u, rdevIndex:%u, qp[%d] create succ.", qpCb->rdevCb->rsCb->chipId, qpCb->rdevCb->rdevIndex,
933 : qpCb->qpInfoLo.qpn);
934 :
935 27 : return 0;
936 :
937 10 : exp_init_qp_err:
938 10 : (void)RsIbvDestroyQp(qpCb->ibQp);
939 10 : return ret;
940 : }
941 :
942 4 : STATIC int RsDrvNormalQpCreateInit(struct ibv_qp_init_attr *qpInitAttr, struct RsQpCb *qpCb, struct ibv_port_attr *attr)
943 : {
944 : int ret;
945 4 : ret = memset_s(attr, sizeof(struct ibv_port_attr), 0, sizeof(struct ibv_port_attr));
946 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for attr failed, ret:%d", ret), -ESAFEFUNC);
947 4 : ret = memset_s(qpInitAttr, sizeof(struct ibv_qp_init_attr), 0, sizeof(struct ibv_qp_init_attr));
948 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ESAFEFUNC);
949 :
950 4 : qpInitAttr->qp_type = IBV_QPT_RC;
951 4 : qpInitAttr->send_cq = qpCb->ibSendCq;
952 4 : qpInitAttr->recv_cq = qpCb->ibRecvCq;
953 4 : qpInitAttr->cap.max_inline_data = QP_DEFAULT_MAX_CAP_INLINE_DATA;
954 4 : qpInitAttr->cap.max_send_wr = qpCb->txDepth;
955 4 : qpInitAttr->cap.max_send_sge = qpCb->sendSgeNum;
956 4 : qpInitAttr->cap.max_recv_wr = qpCb->rxDepth;
957 4 : qpInitAttr->cap.max_recv_sge = qpCb->recvSgeNum;
958 4 : return 0;
959 : }
960 :
961 2 : STATIC int RsDrvQpNormal(struct RsQpCb *qpCb, int qpMode)
962 : {
963 : int ret;
964 : struct ibv_qp_attr qpAttr;
965 : struct ibv_qp_init_attr qpInitAttr;
966 2 : struct RsRdevCb *rdevCb = NULL;
967 : struct ibv_port_attr attr;
968 :
969 2 : hccp_dbg("qp normal create begin..");
970 2 : rdevCb = qpCb->rdevCb;
971 2 : qpCb->qpMode = qpMode;
972 2 : ret = RsDrvNormalQpCreateInit(&qpInitAttr, qpCb, &attr);
973 2 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_normal_qp_create_init failed, ret:%d", ret), ret);
974 :
975 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
976 2 : qpCb->ibQp = RsIbvCreateQp(qpCb->ibPd, &qpInitAttr);
977 2 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_create_qp failed, errno=%d", errno), -ENOMEM);
978 :
979 : /* query qp attr */
980 2 : ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, &qpInitAttr);
981 2 : if (ret) {
982 0 : hccp_err("query qp attr failed ret %d", ret);
983 0 : ret = -EOPENSRC;
984 0 : goto normal_init_qp_err;
985 : }
986 :
987 2 : ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
988 2 : if (ret) {
989 0 : hccp_err("qp info related failed %d", ret);
990 0 : goto normal_init_qp_err;
991 : }
992 :
993 2 : hccp_info("chip_id %u, rdevIndex:%u, qp[%d] create succ.", qpCb->rdevCb->rsCb->chipId, qpCb->rdevCb->rdevIndex,
994 : qpCb->qpInfoLo.qpn);
995 :
996 2 : return 0;
997 :
998 0 : normal_init_qp_err:
999 0 : (void)RsIbvDestroyQp(qpCb->ibQp);
1000 0 : return ret;
1001 : }
1002 :
1003 42 : int RsDrvQpCreate(struct RsQpCb *qpCb, struct RsQpNorm *qpNorm)
1004 : {
1005 : int ret;
1006 42 : if (qpNorm->isExp != 0 && qpNorm->qpMode != RA_RS_NOR_QP_MODE) {
1007 40 : ret = RsDrvExpQpCreate(qpCb, qpNorm->qpMode);
1008 : } else {
1009 2 : ret = RsDrvQpNormal(qpCb, qpNorm->qpMode);
1010 : }
1011 :
1012 42 : return ret;
1013 : }
1014 :
1015 4 : STATIC int RsDrvExpQpCreateInitWithAttrs(struct ibv_exp_qp_init_attr *qpInitAttr, struct RsQpCb *qpCb,
1016 : struct ibv_port_attr *attr, struct RsQpNormWithAttrs *qpNorm)
1017 : {
1018 : int ret;
1019 :
1020 4 : ret = memset_s(attr, sizeof(struct ibv_port_attr), 0, sizeof(struct ibv_port_attr));
1021 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for attr failed, ret:%d", ret), -ESAFEFUNC);
1022 4 : ret = memset_s(qpInitAttr, sizeof(struct ibv_exp_qp_init_attr), 0, sizeof(struct ibv_exp_qp_init_attr));
1023 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ESAFEFUNC);
1024 :
1025 4 : qpInitAttr->attr.send_cq = qpCb->ibSendCq;
1026 4 : qpInitAttr->attr.recv_cq = qpCb->ibRecvCq;
1027 :
1028 4 : ret = memcpy_s(&qpInitAttr->attr.cap, sizeof(struct ibv_qp_cap), &qpNorm->extAttrs.qpAttr.cap,
1029 : sizeof(struct ibv_qp_cap));
1030 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ENOMEM);
1031 4 : qpInitAttr->attr.qp_type = qpNorm->extAttrs.qpAttr.qp_type;
1032 4 : qpInitAttr->attr.sq_sig_all = qpNorm->extAttrs.qpAttr.sq_sig_all;
1033 4 : qpInitAttr->udp_sport = qpCb->udpSport;
1034 4 : qpInitAttr->use_resv_mem = qpNorm->extAttrs.cstmFlag.bs.useResvMem;
1035 4 : qpInitAttr->resv_mem_pool_id = qpNorm->extAttrs.resvMemPoolId;
1036 :
1037 4 : return 0;
1038 : }
1039 :
1040 4 : STATIC int RsDrvExpQpCreateWithAttrs(struct RsQpCb *qpCb, struct RsQpNormWithAttrs *qpNorm)
1041 : {
1042 : int ret;
1043 : struct ibv_port_attr attr;
1044 : struct ibv_qp_attr qpAttr;
1045 4 : struct RsRdevCb *rdevCb = NULL;
1046 : struct ibv_exp_qp_init_attr qpInitAttr;
1047 :
1048 4 : hccp_dbg("qp exp create begin..");
1049 4 : rdevCb = qpCb->rdevCb;
1050 4 : ret = RsDrvExpQpCreateInitWithAttrs(&qpInitAttr, qpCb, &attr, qpNorm);
1051 4 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_qp_create_init failed, ret:%d", ret), ret);
1052 :
1053 4 : qpInitAttr.gdr_enable = qpCb->qpMode;
1054 4 : qpInitAttr.lite_op_support = RsDrvGetSupportLite(rdevCb, qpCb->qpMode, qpCb->aiOpSupport);
1055 4 : qpInitAttr.mem_align = qpCb->memAlign;
1056 4 : qpInitAttr.mem_idx = qpCb->memResp.memData.mem_idx;
1057 4 : qpInitAttr.ai_op_support = qpCb->aiOpSupport;
1058 4 : qpInitAttr.grp_id = qpCb->grpId;
1059 4 : qpInitAttr.qp_cstm_flag = qpCb->aiOpSupport;
1060 :
1061 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
1062 4 : qpCb->ibQp = RsIbvExpCreateQp(qpCb->ibPd, &qpInitAttr, &qpCb->qpResp.qpData);
1063 4 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_exp_create_qp failed"), -ENOMEM);
1064 :
1065 4 : qpCb->dbIndex = (qpCb->qpMode == RA_RS_OP_QP_MODE || qpCb->qpMode == RA_RS_GDR_ASYN_QP_MODE)
1066 : ? qpCb->qpResp.qpData.qp_info
1067 8 : : 0;
1068 4 : qpCb->sqIndex = (qpCb->qpMode == RA_RS_GDR_TMPL_QP_MODE) ? qpCb->qpResp.qpData.qp_info : 0;
1069 4 : hccp_info("db index is [%d], sq index is [%d]", qpCb->dbIndex, qpCb->sqIndex);
1070 :
1071 : /* query qp attr */
1072 4 : ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, &qpInitAttr.attr);
1073 4 : if (ret) {
1074 0 : hccp_err("query qp attr failed ret %d", ret);
1075 0 : ret = -EOPENSRC;
1076 0 : goto exp_init_qp_err;
1077 : }
1078 :
1079 4 : ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
1080 4 : if (ret) {
1081 0 : hccp_err("qp info related failed %d", ret);
1082 0 : goto exp_init_qp_err;
1083 : }
1084 :
1085 4 : hccp_info("chip_id %u, rdevIndex:%u, qp[%d] create succ.", qpCb->rdevCb->rsCb->chipId, qpCb->rdevCb->rdevIndex,
1086 : qpCb->qpInfoLo.qpn);
1087 :
1088 4 : return 0;
1089 :
1090 0 : exp_init_qp_err:
1091 0 : (void)RsIbvDestroyQp(qpCb->ibQp);
1092 0 : return ret;
1093 : }
1094 :
1095 0 : STATIC int RsDrvNormalQpCreateInitWithAttrs(struct ibv_qp_init_attr *qpInitAttr, struct RsQpCb *qpCb,
1096 : struct ibv_port_attr *attr, struct RsQpNormWithAttrs *qpNorm)
1097 : {
1098 : int ret;
1099 :
1100 0 : ret = memset_s(attr, sizeof(struct ibv_port_attr), 0, sizeof(struct ibv_port_attr));
1101 0 : CHK_PRT_RETURN(ret, hccp_err("memset_s for attr failed, ret:%d", ret), -ESAFEFUNC);
1102 0 : ret = memset_s(qpInitAttr, sizeof(struct ibv_qp_init_attr), 0, sizeof(struct ibv_qp_init_attr));
1103 0 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ESAFEFUNC);
1104 :
1105 0 : qpInitAttr->send_cq = qpCb->ibSendCq;
1106 0 : qpInitAttr->recv_cq = qpCb->ibRecvCq;
1107 :
1108 0 : ret = memcpy_s(&qpInitAttr->cap, sizeof(struct ibv_qp_cap), &qpNorm->extAttrs.qpAttr.cap,
1109 : sizeof(struct ibv_qp_cap));
1110 0 : CHK_PRT_RETURN(ret, hccp_err("memcpy_s for qp_init_attr failed, ret:%d", ret), -ENOMEM);
1111 0 : qpInitAttr->qp_type = qpNorm->extAttrs.qpAttr.qp_type;
1112 0 : qpInitAttr->sq_sig_all = qpNorm->extAttrs.qpAttr.sq_sig_all;
1113 0 : return ret;
1114 : }
1115 :
1116 0 : STATIC int RsDrvQpNormalWithAttrs(struct RsQpCb *qpCb, struct RsQpNormWithAttrs *qpNorm)
1117 : {
1118 : int ret;
1119 : struct ibv_port_attr attr;
1120 : struct ibv_qp_attr qpAttr;
1121 : struct ibv_qp_init_attr qpInitAttr;
1122 0 : struct RsRdevCb *rdevCb = NULL;
1123 :
1124 0 : hccp_dbg("qp normal create begin..");
1125 0 : rdevCb = qpCb->rdevCb;
1126 0 : ret = RsDrvNormalQpCreateInitWithAttrs(&qpInitAttr, qpCb, &attr, qpNorm);
1127 0 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_normal_qp_create_init failed, ret:%d", ret), ret);
1128 :
1129 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
1130 0 : qpCb->ibQp = RsIbvCreateQp(qpCb->ibPd, &qpInitAttr);
1131 0 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_create_qp failed, errno=%d", errno), -ENOMEM);
1132 :
1133 : /* query qp attr */
1134 0 : ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, &qpInitAttr);
1135 0 : if (ret) {
1136 0 : hccp_err("query qp attr failed ret %d", ret);
1137 0 : ret = -EOPENSRC;
1138 0 : goto normal_init_qp_err;
1139 : }
1140 :
1141 0 : ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
1142 0 : if (ret) {
1143 0 : hccp_err("qp info related failed ret %d", ret);
1144 0 : goto normal_init_qp_err;
1145 : }
1146 :
1147 0 : hccp_info("chip_id %u, rdevIndex:%u, qp[%d] create succ.", qpCb->rdevCb->rsCb->chipId, qpCb->rdevCb->rdevIndex,
1148 : qpCb->qpInfoLo.qpn);
1149 :
1150 0 : return 0;
1151 :
1152 0 : normal_init_qp_err:
1153 0 : (void)RsIbvDestroyQp(qpCb->ibQp);
1154 0 : return ret;
1155 : }
1156 :
1157 4 : int RsDrvQpCreateWithAttrs(struct RsQpCb *qpCb, struct RsQpNormWithAttrs *qpNorm)
1158 : {
1159 : int ret;
1160 :
1161 : // ignore qp_mode when ai_op_support set
1162 4 : if ((qpNorm->isExp != 0 && qpNorm->extAttrs.qpMode != RA_RS_NOR_QP_MODE) || (qpNorm->aiOpSupport != 0)) {
1163 4 : ret = RsDrvExpQpCreateWithAttrs(qpCb, qpNorm);
1164 : } else {
1165 0 : ret = RsDrvQpNormalWithAttrs(qpCb, qpNorm);
1166 : }
1167 :
1168 4 : return ret;
1169 : }
1170 :
1171 35 : void RsDrvQpDestroy(struct RsQpCb *qpCb)
1172 : {
1173 35 : (void)RsIbvDestroyQp(qpCb->ibQp);
1174 35 : }
1175 :
1176 10 : int RsQueryEvent(int cqEventId, struct event_summary **event)
1177 : {
1178 10 : *event = calloc(1, sizeof(struct event_summary));
1179 10 : if ((*event) == NULL) {
1180 1 : return -ENOMEM;
1181 : }
1182 :
1183 9 : (*event)->pid = getpid();
1184 9 : (*event)->grp_id = 6; // 6: 通信库使用的事件调度group
1185 9 : (*event)->event_id = cqEventId;
1186 9 : (*event)->subevent_id = 0;
1187 9 : (*event)->msg_len = 0;
1188 9 : (*event)->msg = NULL;
1189 9 : (*event)->dst_engine = ACPU_DEVICE;
1190 9 : (*event)->policy = ONLY;
1191 9 : hccp_info("pid:%d, cqEventId:%d", (*event)->pid, cqEventId);
1192 : unsigned int i;
1193 36 : for (i = 0; i < EVENT_SUMMARY_RSV; i++) {
1194 27 : (*event)->rsv[i] = 0;
1195 : }
1196 :
1197 9 : return 0;
1198 : }
1199 :
1200 8 : int RsDrvCreateCqEvent(struct RsCqContext *cqContext, struct CqAttr *attr)
1201 : {
1202 : int ret;
1203 :
1204 8 : hccp_info("create cq event start cq_create_mode [%d]", cqContext->cqCreateMode);
1205 :
1206 8 : if (cqContext->cqCreateMode == RS_NORMAL_CQ_CREATE || cqContext->cqCreateMode == RS_SQ_CQ_CREATE) {
1207 6 : ret = RsQueryEvent(attr->sendCqEventId, &(cqContext->sendEvent));
1208 6 : CHK_PRT_RETURN(ret, hccp_err("rs_query_event send_event failed! ret:%d", ret), ret);
1209 :
1210 5 : cqContext->ibSendCq = RsIbvCreateCq(cqContext->rdevCb->ibCtx, attr->sendCqDepth, cqContext->sendEvent,
1211 : cqContext->channel, cqContext->eqNum);
1212 5 : if (cqContext->ibSendCq == NULL) {
1213 1 : hccp_err("rs_drv_create_cq_event ibv create send cq failed, sendCqEventId:%d", attr->sendCqEventId);
1214 1 : goto create_cq_even_err;
1215 : }
1216 :
1217 4 : ret = ibv_req_notify_cq(cqContext->ibSendCq, 0);
1218 4 : if (ret) {
1219 1 : hccp_err("Couldn't request send CQ notification, ret:%d", ret);
1220 1 : goto create_cq_even_err;
1221 : }
1222 3 : *attr->ibSendCq = cqContext->ibSendCq;
1223 : }
1224 :
1225 5 : if (cqContext->cqCreateMode == RS_NORMAL_CQ_CREATE || cqContext->cqCreateMode == RS_SRQ_CQ_CREATE) {
1226 4 : ret = RsQueryEvent(attr->recvCqEventId, &(cqContext->recvEvent));
1227 4 : if (ret) {
1228 0 : hccp_err("rs_query_event send_event failed! ret:%d", ret);
1229 0 : goto create_cq_even_err;
1230 : }
1231 :
1232 4 : cqContext->ibRecvCq = RsIbvCreateCq(cqContext->rdevCb->ibCtx, attr->recvCqDepth, cqContext->recvEvent,
1233 : cqContext->channel, cqContext->eqNum);
1234 4 : if (cqContext->ibRecvCq == NULL) {
1235 0 : hccp_err("rs_drv_create_cq_event ibv create recv cq failed, recvCqEventId:%d", attr->recvCqEventId);
1236 0 : goto create_cq_even_err;
1237 : }
1238 :
1239 4 : ret = ibv_req_notify_cq(cqContext->ibRecvCq, 0);
1240 4 : if (ret) {
1241 0 : hccp_err("Couldn't request recv CQ notification, ret:%d", ret);
1242 0 : goto create_cq_even_err;
1243 : }
1244 4 : *attr->ibRecvCq = cqContext->ibRecvCq;
1245 : }
1246 :
1247 5 : hccp_info("create cq event success");
1248 5 : return 0;
1249 :
1250 2 : create_cq_even_err:
1251 2 : if (cqContext->ibRecvCq != NULL) {
1252 0 : (void)RsIbvDestroyCq(cqContext->ibRecvCq);
1253 : }
1254 :
1255 2 : if (cqContext->ibSendCq != NULL) {
1256 1 : (void)RsIbvDestroyCq(cqContext->ibSendCq);
1257 : }
1258 :
1259 2 : (void)RsDrvEventDestroy(cqContext->recvEvent);
1260 :
1261 2 : (void)RsDrvEventDestroy(cqContext->sendEvent);
1262 :
1263 2 : return -EOPENSRC;
1264 : }
1265 :
1266 1 : int RsDrvCreateCqWithChannel(struct RsCqContext *cqContext, struct CqAttr *attr)
1267 : {
1268 1 : hccp_dbg("create cq with channel start");
1269 :
1270 1 : cqContext->ibSendCq = RsIbvCreateCq(cqContext->rdevCb->ibCtx, attr->sendCqDepth, NULL, attr->sendChannel, 1);
1271 1 : if (cqContext->ibSendCq == NULL) {
1272 0 : hccp_err("rs_drv_create_cq_with_channel ibv create send cq failed.");
1273 0 : return -EOPENSRC;
1274 : }
1275 :
1276 1 : cqContext->ibRecvCq = RsIbvCreateCq(cqContext->rdevCb->ibCtx, attr->recvCqDepth, NULL, attr->recvChannel, 1);
1277 1 : if (cqContext->ibRecvCq == NULL) {
1278 0 : hccp_err("rs_drv_create_cq_with_channel ibv create serecvnd cq failed.");
1279 0 : goto create_recv_cq_err;
1280 : }
1281 :
1282 1 : *attr->ibSendCq = cqContext->ibSendCq;
1283 1 : *attr->ibRecvCq = cqContext->ibRecvCq;
1284 1 : hccp_info("create cq with channel success");
1285 1 : return 0;
1286 :
1287 0 : create_recv_cq_err:
1288 0 : (void)RsIbvDestroyCq(cqContext->ibSendCq);
1289 0 : return -EOPENSRC;
1290 : }
1291 :
1292 0 : int RsDrvTypicalCqCreate(struct RsRdevCb *rdevCb, unsigned int cqDepth, unsigned int *cqn, struct ibv_cq **ibCq,
1293 : struct rdma_lite_device_cq_attr *deviceCqAttr)
1294 : {
1295 0 : struct rdma_lite_device_cq_init_attr initAttr = {
1296 : .cq_type = RA_RS_OP_QP_MODE,
1297 0 : .lite_op_supported = rdevCb->supportLite,
1298 : };
1299 :
1300 0 : *ibCq = RsIbvExpCreateCq(rdevCb->ibCtx, (int)cqDepth, NULL, NULL, 0, &initAttr, deviceCqAttr);
1301 0 : if (*ibCq == NULL) {
1302 0 : hccp_err("rs_ibv_exp_create_cq failed, cqDepth[%u]", cqDepth);
1303 0 : return -ENOMEM;
1304 : }
1305 :
1306 0 : *cqn = deviceCqAttr->cqn;
1307 0 : hccp_info("drv typical cq create success, cqn[%u] cqDepth[%u]", *cqn, cqDepth);
1308 0 : return 0;
1309 : }
1310 :
1311 8 : int RsDrvDestroyCqEvent(struct RsCqContext *cqContext)
1312 : {
1313 : int ret;
1314 :
1315 8 : if (cqContext->cqCreateMode == RS_NORMAL_CQ_CREATE || cqContext->cqCreateMode == RS_SRQ_CQ_CREATE) {
1316 7 : ret = RsIbvDestroyCq(cqContext->ibRecvCq);
1317 7 : if (ret) {
1318 1 : hccp_err("rs_ibv_destroy_cq(recv) failed, ret %d", ret);
1319 : }
1320 7 : (void)RsDrvEventDestroy(cqContext->recvEvent);
1321 : }
1322 :
1323 8 : if (cqContext->cqCreateMode == RS_NORMAL_CQ_CREATE || cqContext->cqCreateMode == RS_SQ_CQ_CREATE) {
1324 5 : ret = RsIbvDestroyCq(cqContext->ibSendCq);
1325 5 : if (ret) {
1326 1 : hccp_err("rs_ibv_destroy_cq(send) failed, ret %d", ret);
1327 : }
1328 5 : (void)RsDrvEventDestroy(cqContext->sendEvent);
1329 : }
1330 :
1331 8 : return 0;
1332 : }
1333 :
1334 5 : int RsDrvNormalQpCreate(struct RsQpCb *qpCb, struct ibv_qp_init_attr *qpInitAttr)
1335 : {
1336 : int ret;
1337 : struct ibv_qp_attr qpAttr;
1338 5 : struct RsRdevCb *rdevCb = NULL;
1339 : struct ibv_port_attr attr;
1340 :
1341 5 : hccp_dbg("rs_drv_normal_qp_create begin..");
1342 5 : rdevCb = qpCb->rdevCb;
1343 :
1344 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
1345 5 : qpCb->ibQp = RsIbvCreateQp(qpCb->ibPd, qpInitAttr);
1346 5 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_create_qp failed, errno=%d", errno), -ENOMEM);
1347 :
1348 : /* query qp attr */
1349 4 : ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, qpInitAttr);
1350 4 : if (ret) {
1351 1 : hccp_err("query qp attr failed ret %d", ret);
1352 1 : ret = -EOPENSRC;
1353 1 : goto normal_init_qp_err;
1354 : }
1355 :
1356 3 : ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
1357 3 : if (ret) {
1358 1 : hccp_err("qp info related failed %d", ret);
1359 1 : goto normal_init_qp_err;
1360 : }
1361 :
1362 2 : hccp_info("chip_id %u, rdevIndex:%u, qp[%d] create succ.", qpCb->rdevCb->rsCb->chipId, qpCb->rdevCb->rdevIndex,
1363 : qpCb->qpInfoLo.qpn);
1364 :
1365 2 : return 0;
1366 :
1367 2 : normal_init_qp_err:
1368 2 : (void)RsIbvDestroyQp(qpCb->ibQp);
1369 2 : return ret;
1370 : }
|