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