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 : (void)evCq;
140 1 : if (wc->status != IBV_WC_SUCCESS && wc->status != IBV_WC_WR_FLUSH_ERR) {
141 1 : hccp_err("Failed status [%s] [%u], wr[%llu]", 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", evCtxTmp->event_id, evCtxTmp->pid,
170 : 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", evCtxTmp->event_id, evCtxTmp->pid,
206 : 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 98 : int RsDrvCompareIpGid(int family, union HccpIpAddr localIp, union ibv_gid *gid)
237 : {
238 : unsigned int gidV4[RS_GID_SEQ_NUM];
239 :
240 98 : if (family == AF_INET6) {
241 0 : if (memcmp(gid, &(localIp.addr6), sizeof(union ibv_gid)) == 0) {
242 0 : return 0;
243 : }
244 : } else {
245 98 : gidV4[RS_GID_SEQ_ZERO] = 0;
246 98 : gidV4[RS_GID_SEQ_ONE] = 0;
247 : /* The gid format generated by ipv4 is filled with 0xFFFF in [33, 48] */
248 98 : gidV4[RS_GID_SEQ_TWO] = htonl(0x0000FFFF);
249 98 : gidV4[RS_GID_SEQ_THREE] = localIp.addr.s_addr;
250 98 : if (memcmp(gid, &(gidV4), sizeof(union ibv_gid)) == 0) {
251 93 : return 0;
252 : }
253 : }
254 :
255 5 : return -ENODEV;
256 : }
257 :
258 69 : 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 69 : int gidIdx = -1;
264 : int ret;
265 : int i;
266 :
267 69 : ret = RsIbvQueryPort(rdevCb->ibCtx, rdevCb->ibPort, attr);
268 69 : 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 68 : if (attr->state != IBV_PORT_ACTIVE) {
272 0 : hccp_warn("port number %u state is %s", rdevCb->ibPort, portStates[attr->state]);
273 : }
274 :
275 139 : for (i = 0; i < attr->gid_tbl_len; i++) {
276 135 : ret = RsIbvQueryGidType(rdevCb->ibCtx, rdevCb->ibPort, (unsigned int)i, &type);
277 135 : CHK_PRT_RETURN(ret, hccp_err("query gid type failed i %d, ret %d", i, ret), -EOPENSRC);
278 134 : if (type != IBV_GID_TYPE_SYSFS_ROCE_V2) {
279 67 : continue;
280 : }
281 :
282 67 : ret = RsIbvQueryGid(rdevCb->ibCtx, rdevCb->ibPort, i, &gidTmp);
283 67 : CHK_PRT_RETURN(ret, hccp_err("query gid failed i %d, ret %d", i, ret), -EOPENSRC);
284 :
285 66 : ret = RsDrvCompareIpGid((int)rdevCb->localIp.family, rdevCb->localIp.binAddr, &gidTmp);
286 66 : if (ret == 0) {
287 62 : gidIdx = i;
288 62 : break;
289 : }
290 : }
291 :
292 66 : 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 62 : hccp_dbg("GID index is %d", gidIdx);
298 62 : *idx = gidIdx;
299 62 : return 0;
300 : }
301 :
302 93 : STATIC int RsDrvGetSupportLite(struct RsRdevCb *rdevCb, int qpMode, unsigned int aiOpSupport)
303 : {
304 : // bypass rdma lite when ai_op_support was set
305 93 : if (aiOpSupport == 1) {
306 8 : return 0;
307 : }
308 :
309 85 : if (qpMode == RA_RS_OP_QP_MODE || qpMode == RA_RS_OP_QP_MODE_EXT) {
310 4 : return rdevCb->supportLite;
311 : }
312 :
313 81 : return 0;
314 : }
315 :
316 51 : int RsDrvCreateCqWithAttrs(struct RsQpCb *qpCb, int isExt, struct CqExtAttr *cqAttr)
317 : {
318 51 : int sendEqNum = cqAttr->sendCqCompVector;
319 51 : int recvEqNum = cqAttr->recvCqCompVector;
320 51 : struct rdma_lite_device_cq_init_attr attr = {
321 51 : .cq_type = qpCb->qpMode,
322 : .part_id = 0,
323 : .lite_op_supported = 0,
324 51 : .mem_align = qpCb->memAlign,
325 51 : .mem_idx = qpCb->memResp.memData.mem_idx,
326 51 : .ai_op_support = qpCb->aiOpSupport,
327 51 : .grp_id = qpCb->grpId,
328 51 : .cq_cstm_flag = qpCb->cqCstmFlag,
329 51 : .use_resv_mem = qpCb->useResvMem,
330 51 : .resv_mem_pool_id = qpCb->resvMemPoolId,
331 : };
332 51 : struct ibv_comp_channel *channel = qpCb->channel;
333 :
334 51 : attr.lite_op_supported = RsDrvGetSupportLite(qpCb->rdevCb, qpCb->qpMode, qpCb->aiOpSupport);
335 : // caller poll cq
336 51 : if (attr.lite_op_supported != 0 || attr.cq_cstm_flag != 0) {
337 4 : channel = NULL;
338 4 : sendEqNum = 0;
339 4 : recvEqNum = 0;
340 : }
341 :
342 51 : hccp_dbg("create cq start");
343 51 : if (isExt == 1) {
344 7 : qpCb->ibSendCq = RsIbvExpCreateCq(qpCb->rdevCb->ibCtx, cqAttr->sendCqDepth, NULL, channel, sendEqNum, &attr,
345 : &qpCb->qpResp.sendCqData);
346 7 : hccp_info("rs_ibv_exp_create_cq");
347 : } else {
348 44 : qpCb->ibSendCq = RsIbvCreateCq(qpCb->rdevCb->ibCtx, cqAttr->sendCqDepth, NULL, channel, sendEqNum);
349 : }
350 :
351 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
352 51 : CHK_PRT_RETURN(qpCb->ibSendCq == NULL, hccp_err("ibv create send cq failed"), -ENOMEM);
353 :
354 50 : if (isExt == 1) {
355 7 : qpCb->ibRecvCq = RsIbvExpCreateCq(qpCb->rdevCb->ibCtx, cqAttr->recvCqDepth, NULL, channel, recvEqNum, &attr,
356 : &qpCb->qpResp.recvCqData);
357 7 : hccp_info("rs_ibv_exp_create_cq");
358 : } else {
359 43 : qpCb->ibRecvCq = RsIbvCreateCq(qpCb->rdevCb->ibCtx, cqAttr->recvCqDepth, NULL, channel, recvEqNum);
360 : }
361 :
362 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
363 50 : if (qpCb->ibRecvCq == NULL) {
364 3 : hccp_err("ibv create recv cq failed");
365 3 : (void)RsIbvDestroyCq(qpCb->ibSendCq);
366 3 : return -ENOMEM;
367 : }
368 :
369 47 : hccp_info("create cq success");
370 47 : return 0;
371 : }
372 :
373 : #define RS_DRV_CQ_DEPTH 16384
374 : #define RS_DRV_CQ_128_DEPTH 128
375 : #define RS_DRV_CQ_32K_DEPTH 32768
376 :
377 47 : int RsDrvCreateCq(struct RsQpCb *qpCb, int isExt)
378 : {
379 47 : struct CqExtAttr cqAttr = {0};
380 :
381 47 : cqAttr.sendCqDepth = qpCb->sendCqDepth;
382 47 : cqAttr.sendCqCompVector = qpCb->eqNum;
383 47 : cqAttr.recvCqDepth = qpCb->recvCqDepth;
384 47 : cqAttr.recvCqCompVector = qpCb->eqNum;
385 :
386 47 : return RsDrvCreateCqWithAttrs(qpCb, isExt, &cqAttr);
387 : }
388 :
389 110 : void RsDrvEventDestroy(struct event_summary *event)
390 : {
391 110 : if (event != NULL) {
392 9 : free(event);
393 9 : event = NULL;
394 : }
395 110 : }
396 :
397 47 : void RsDrvDestroyCq(struct RsQpCb *qpCb)
398 : {
399 47 : (void)RsIbvDestroyCq(qpCb->ibRecvCq);
400 47 : (void)RsIbvDestroyCq(qpCb->ibSendCq);
401 47 : (void)RsDrvEventDestroy(qpCb->recvEvent);
402 47 : (void)RsDrvEventDestroy(qpCb->sendEvent);
403 47 : }
404 :
405 3 : int RsDrvQpStateModifytoReset(struct RsQpCb *qpCb)
406 : {
407 3 : struct ibv_qp_init_attr qpInitAttr = {0};
408 3 : struct ibv_qp_attr attr = {0};
409 : int ret;
410 :
411 3 : attr.qp_state = IBV_QPS_RESET;
412 3 : ret = RsIbvModifyQp(qpCb->ibQp, &attr, IBV_QP_STATE);
413 3 : CHK_PRT_RETURN(ret, hccp_err("[modify]qpn[%d] modify to reset failed, ret %d", qpCb->qpInfoLo.qpn, ret), ret);
414 :
415 3 : (void)memset_s(&attr, sizeof(struct ibv_qp_attr), 0, sizeof(struct ibv_qp_attr));
416 :
417 3 : ret = RsIbvQueryQp(qpCb->ibQp, &attr, IBV_QP_STATE, &qpInitAttr);
418 3 : if ((ret != 0) || attr.qp_state != IBV_QPS_RESET) {
419 1 : hccp_err("query qpn[%d] attr failed, ret %d or qp state %d is not RESET", qpCb->qpInfoLo.qpn, ret,
420 : attr.qp_state);
421 1 : return ret;
422 : }
423 :
424 2 : hccp_info("qpn[%d] modify to reset success", qpCb->qpInfoLo.qpn);
425 2 : return 0;
426 : }
427 :
428 21 : int RsDrvQpStateModifytoInit(struct RsQpCb *qpCb, struct ibv_qp_attr *attr)
429 : {
430 : int ret;
431 :
432 21 : attr->qp_state = IBV_QPS_INIT;
433 21 : attr->pkey_index = 0;
434 21 : attr->port_num = qpCb->rdevCb->ibPort;
435 21 : attr->qp_access_flags = DEFAULT_ACCESS_FLAG;
436 21 : ret = RsIbvModifyQp(qpCb->ibQp, attr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS);
437 21 : CHK_PRT_RETURN(ret, hccp_err("[modify]qpn[%d] modify to init failed, ret %d", qpCb->qpInfoLo.qpn, ret), ret);
438 :
439 20 : hccp_info("qpn[%d] modify to init success", qpCb->qpInfoLo.qpn);
440 20 : return 0;
441 : }
442 :
443 22 : enum ibv_mtu RsDrvSetMtu(struct RsQpCb *qpCb)
444 : {
445 : int ret;
446 22 : struct ibv_port_attr portAttr = {0};
447 : enum ibv_mtu currMtu;
448 :
449 22 : ret = RsIbvQueryPort(qpCb->rdevCb->ibCtx, qpCb->rdevCb->ibPort, &portAttr);
450 22 : CHK_PRT_RETURN(ret, hccp_err("Error when trying to query port, ret[%d]", ret), -EOPENSRC);
451 : #ifndef CA_CONFIG_LLT
452 : currMtu = portAttr.active_mtu;
453 : #else
454 21 : currMtu = IBV_MTU_1024;
455 : #endif
456 :
457 21 : return currMtu;
458 : }
459 :
460 20 : int RsDrvQpStateModifytoRtr(struct RsQpCb *qpCb, struct ibv_qp_attr *attr)
461 : {
462 20 : struct ibv_port_attr portAttr = {0};
463 : int ret;
464 :
465 20 : attr->qp_state = IBV_QPS_RTR;
466 20 : attr->dest_qp_num = (uint32_t)qpCb->qpInfoRem.qpn;
467 20 : attr->rq_psn = (uint32_t)qpCb->qpInfoRem.psn;
468 20 : attr->min_rnr_timer = RS_QP_ATTR_MIN_RNR_TIMER;
469 20 : (attr->ah_attr).is_global = 0;
470 20 : (attr->ah_attr).dlid = qpCb->qpInfoRem.lid;
471 20 : (attr->ah_attr).sl = qpCb->qosAttr.sl;
472 20 : (attr->ah_attr).src_path_bits = 0;
473 20 : (attr->ah_attr).port_num = qpCb->rdevCb->ibPort;
474 :
475 20 : attr->path_mtu = RsDrvSetMtu(qpCb);
476 20 : if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
477 4 : attr->max_dest_rd_atomic = RS_MAX_RD_ATOMIC_NUM_PEER_ONLINE;
478 : } else {
479 16 : attr->max_dest_rd_atomic = RS_MAX_RD_ATOMIC_NUM;
480 16 : CHK_PRT_RETURN(attr->path_mtu < IBV_MTU_1024,
481 : hccp_err("qpn[%d] failed to set mtu, mtu[%d] < [%d]", qpCb->qpInfoLo.qpn, attr->path_mtu, IBV_MTU_1024),
482 : -EPERM);
483 : }
484 :
485 : // get gid_idx dynamically
486 20 : ret = RsDrvGetGidIndex(qpCb->rdevCb, &portAttr, &qpCb->qpInfoLo.gidIdx);
487 20 : CHK_PRT_RETURN(ret,
488 : hccp_err("rs_drv_get_gid_index failed ret[%d], qpn[%d] gidIdx[%d]", ret, qpCb->qpInfoLo.qpn,
489 : qpCb->qpInfoLo.gidIdx),
490 : ret);
491 :
492 19 : if (qpCb->qpInfoRem.gid.global.interface_id) {
493 16 : attr->ah_attr.is_global = 1;
494 16 : attr->ah_attr.grh.hop_limit = 1;
495 16 : attr->ah_attr.grh.dgid = qpCb->qpInfoRem.gid;
496 16 : attr->ah_attr.grh.sgid_index = qpCb->qpInfoLo.gidIdx;
497 : }
498 :
499 19 : (attr->ah_attr).grh.traffic_class = qpCb->qosAttr.tc;
500 19 : ret = RsIbvModifyQp(qpCb->ibQp, attr,
501 : IBV_QP_STATE | IBV_QP_AV | IBV_QP_PATH_MTU | IBV_QP_DEST_QPN | IBV_QP_RQ_PSN | IBV_QP_MAX_DEST_RD_ATOMIC |
502 : IBV_QP_MIN_RNR_TIMER);
503 19 : CHK_PRT_RETURN(ret,
504 : hccp_err("qpn[%d] failed to modify QP to RTR, ibv_modify_qp failed ret[%d], errno[%d]", qpCb->qpInfoLo.qpn, ret,
505 : errno),
506 : -EOPENSRC);
507 18 : hccp_info("qp qos attr: qpn[%d] tc[%u] sl[%u]", qpCb->qpInfoLo.qpn, qpCb->qosAttr.tc, qpCb->qosAttr.sl);
508 18 : return 0;
509 : }
510 :
511 18 : int RsDrvQpStateModifytoRts(struct RsQpCb *qpCb, struct ibv_qp_attr *attr)
512 : {
513 : int ret;
514 18 : attr->qp_state = IBV_QPS_RTS;
515 18 : attr->timeout = (uint8_t)qpCb->timeout;
516 18 : attr->retry_cnt = (uint8_t)qpCb->retryCnt;
517 18 : attr->rnr_retry = RS_QP_ATTR_RNR_RETRY;
518 18 : attr->sq_psn = (uint32_t)qpCb->qpInfoLo.psn;
519 18 : if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
520 3 : attr->max_rd_atomic = RS_MAX_RD_ATOMIC_NUM_PEER_ONLINE;
521 : } else {
522 15 : attr->max_rd_atomic = RS_MAX_RD_ATOMIC_NUM;
523 : }
524 18 : ret = RsIbvModifyQp(qpCb->ibQp, attr,
525 : IBV_QP_STATE | IBV_QP_TIMEOUT | IBV_QP_RETRY_CNT | IBV_QP_RNR_RETRY | IBV_QP_SQ_PSN | IBV_QP_MAX_QP_RD_ATOMIC);
526 18 : CHK_PRT_RETURN(ret,
527 : hccp_err("qpn[%d] failed to modify QP to RTS, ibv_modify_qp failed ret[%d]", qpCb->qpInfoLo.qpn, ret),
528 : -EOPENSRC);
529 18 : hccp_info("qp rdma attr: qpn[%d] timeout[%u] retrycnt[%u]", qpCb->qpInfoLo.qpn, qpCb->timeout, qpCb->retryCnt);
530 18 : return 0;
531 : }
532 :
533 6 : struct ibv_mr *RsDrvMrReg(struct ibv_pd *pd, char *addr, size_t length, int access)
534 : {
535 6 : return RsIbvRegMr(pd, addr, length, access);
536 : }
537 :
538 5 : struct ibv_mr *RsDrvExpMrReg(struct ibv_pd *pd, char *addr, size_t length, int access,
539 : struct roce_process_sign roceSign)
540 : {
541 5 : return RsIbvExpRegMr(pd, addr, length, access, roceSign);
542 : }
543 :
544 38 : int RsDrvMrDereg(struct ibv_mr *ibMr)
545 : {
546 38 : return RsIbvDeregMr(ibMr);
547 : }
548 :
549 : #ifdef CUSTOM_INTERFACE
550 2 : STATIC int RsOpenBackupIbCtx(struct RsRdevCb *rdevCb)
551 : {
552 2 : struct ibv_context *ibCtxTmp = NULL;
553 2 : struct rdev rdevInfo = {0};
554 2 : int gidIndex = -1;
555 : int ret;
556 : int i;
557 :
558 2 : (void)memcpy_s(&rdevInfo, sizeof(struct rdev), &rdevCb->backupInfo.rdevInfo, sizeof(struct rdev));
559 2 : for (i = 0; (i < rdevCb->devNum) && (rdevCb->devList[i] != NULL); ++i) {
560 1 : ibCtxTmp = RsIbvOpenDevice(rdevCb->devList[i]);
561 1 : CHK_PRT_RETURN(ibCtxTmp == NULL, hccp_err("ibv_open_device with backup failed, errno:%d", errno), -ENODEV);
562 1 : ret = RsQueryGid(rdevInfo, ibCtxTmp, rdevCb->ibPort, &gidIndex);
563 1 : if (ret == 0) {
564 1 : rdevCb->backupInfo.ibCtx = ibCtxTmp;
565 1 : return 0;
566 0 : } else if (ret == -EEXIST) {
567 0 : RsIbvCloseDevice(ibCtxTmp);
568 : } else {
569 0 : RsIbvCloseDevice(ibCtxTmp);
570 0 : hccp_err("rs_query_gid failed, ret:%d", ret);
571 0 : return ret;
572 : }
573 : }
574 :
575 1 : CHK_PRT_RETURN(i == rdevCb->devNum,
576 : hccp_err("can not find ib_ctx for phyId[%u] local_ip[0x%x] in dev_list!", rdevInfo.phyId,
577 : rdevInfo.localIp.addr.s_addr),
578 : -EEXIST);
579 0 : return 0;
580 : }
581 :
582 30 : void RsCloseBackupIbCtx(struct RsRdevCb *rdevCb)
583 : {
584 : // no need to close backup device
585 30 : if (!rdevCb->backupInfo.backupFlag || rdevCb->backupInfo.ibCtx == NULL) {
586 29 : return;
587 : }
588 :
589 1 : RsIbvCloseDevice(rdevCb->backupInfo.ibCtx);
590 : }
591 : #endif
592 :
593 30 : STATIC int RsDrvQueryNotify(struct RsRdevCb *rdevCb)
594 : {
595 30 : int ret = 0;
596 :
597 30 : if (rdevCb->notifyType == NO_USE) {
598 2 : return 0;
599 : }
600 :
601 : #ifdef CUSTOM_INTERFACE
602 28 : if (RsIsCustomInterfaceSupported()) {
603 28 : if (rdevCb->backupInfo.backupFlag) {
604 : // open backup device to get ib_ctx to get backup notify va and size
605 2 : ret = RsOpenBackupIbCtx(rdevCb);
606 2 : CHK_PRT_RETURN(ret, hccp_err("rs_open_backup_ib_ctx failed, ret:%d", ret), ret);
607 :
608 2 : ret = RsIbvExpQueryNotify(rdevCb->backupInfo.ibCtx, &rdevCb->notifyVaBase, &rdevCb->notifySize);
609 2 : if (ret != 0) {
610 1 : RsCloseBackupIbCtx(rdevCb);
611 1 : hccp_err("rs_ibv_exp_query_notify with backup ctx failed, ret:%d", ret);
612 1 : return ret;
613 : }
614 : } else {
615 26 : ret = RsIbvExpQueryNotify(rdevCb->ibCtx, &rdevCb->notifyVaBase, &rdevCb->notifySize);
616 26 : CHK_PRT_RETURN(ret, hccp_err("rs_ibv_exp_query_notify failed, ret:%d", ret), ret);
617 : }
618 : }
619 : #endif
620 27 : hccp_info("chip_id:%u, RsDrvQueryNotify ok, notify va:0x%llx, size:%llu", rdevCb->rsCb->chipId,
621 : rdevCb->notifyVaBase, rdevCb->notifySize);
622 27 : return ret;
623 : }
624 :
625 30 : int RsDrvQueryNotifyAndAllocPd(struct RsRdevCb *rdevCb)
626 : {
627 30 : int ret = 0;
628 :
629 30 : ret = RsDrvQueryNotify(rdevCb);
630 30 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_query_notify failed, ret %d", ret), ret);
631 :
632 29 : rdevCb->ibPd = RsIbvAllocPd(rdevCb->ibCtx);
633 29 : if (rdevCb->ibPd == NULL) {
634 : #ifdef CUSTOM_INTERFACE
635 0 : if (RsIsCustomInterfaceSupported()) {
636 0 : RsCloseBackupIbCtx(rdevCb);
637 : }
638 : #endif
639 0 : hccp_err("rs_ibv_alloc_pd failed, errno:%d", errno);
640 0 : return -ENOMEM;
641 : }
642 :
643 29 : return 0;
644 : }
645 :
646 29 : int RsDrvRegNotifyMr(struct RsRdevCb *rdevCb)
647 : {
648 29 : struct roce_process_sign roceSign = {0};
649 29 : int access = DEFAULT_ACCESS_FLAG;
650 : (void)roceSign;
651 29 : rdevCb->notifyAccess = access;
652 29 : switch (rdevCb->notifyType) {
653 2 : case NO_USE:
654 2 : return 0;
655 27 : case NOTIFY: {
656 27 : rdevCb->notifyMr = RsIbvRegMr(rdevCb->ibPd, (void *)(uintptr_t)rdevCb->notifyVaBase, rdevCb->notifySize,
657 : access);
658 27 : 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 27 : CHK_PRT_RETURN(rdevCb->notifyMr == NULL,
680 : hccp_err("ibv_reg_mr addr[0x%llx] len[%llu] errno[%d]failed", rdevCb->notifyVaBase, rdevCb->notifySize, errno),
681 : -EACCES);
682 :
683 27 : hccp_info("ibv_reg_mr ok");
684 27 : return 0;
685 : }
686 :
687 0 : STATIC void RsBuildRecvWr(struct RecvWrlistData *wr, struct ibv_sge *list, struct ibv_recv_wr *ibWr)
688 : {
689 0 : list->addr = (uintptr_t)wr->memList.addr;
690 0 : list->length = wr->memList.len;
691 0 : list->lkey = wr->memList.lkey;
692 :
693 0 : ibWr->sg_list = list;
694 0 : ibWr->wr_id = wr->wrId;
695 0 : ibWr->num_sge = 1; /* only support one sge */
696 0 : return;
697 : }
698 :
699 0 : int RsDrvPostRecv(struct RsQpCb *qpCb, struct RecvWrlistData *wr, unsigned int recvNum, 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, struct RsMrCb *remMrCb, struct SendWr *wr,
745 : 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 || qpCb->qpMode == RA_RS_OP_QP_MODE_EXT ||
781 0 : qpCb->qpMode == RA_RS_GDR_ASYN_QP_MODE) {
782 1 : wrRsp->db.dbIndex = (unsigned int)qpCb->dbIndex;
783 1 : wrRsp->db.dbInfo = expRsp.db_info;
784 : }
785 :
786 4 : return ret;
787 : }
788 :
789 45 : STATIC int RsDrvQpQueryInfo(struct RsQpCb *qpCb, struct RsRdevCb *rdevCb, struct ibv_port_attr *attr,
790 : struct ibv_qp_attr *qpAttr, union ibv_gid *gidTmp)
791 : {
792 : int ret;
793 : /* modify qp state */
794 45 : ret = memset_s(qpAttr, sizeof(struct ibv_qp_attr), 0, sizeof(struct ibv_qp_attr));
795 45 : CHK_PRT_RETURN(ret, hccp_err("memset_s failed ret[%d], buf len:%u", ret, sizeof(struct ibv_qp_attr)), -ESAFEFUNC);
796 44 : qpAttr->qp_state = IBV_QPS_INIT;
797 44 : qpAttr->pkey_index = 0;
798 44 : qpAttr->port_num = rdevCb->ibPort;
799 44 : qpAttr->qp_access_flags = DEFAULT_ACCESS_FLAG;
800 44 : ret = RsIbvModifyQp(qpCb->ibQp, qpAttr, IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS);
801 44 : CHK_PRT_RETURN(ret, hccp_err("ibv_modify_qp failed ret[%d]", ret), -EOPENSRC);
802 :
803 : /* prepare qp info for exchange */
804 43 : ret = RsDrvGetGidIndex(rdevCb, attr, &qpCb->qpInfoLo.gidIdx);
805 43 : CHK_PRT_RETURN(ret,
806 : hccp_err("rs_drv_get_gid_index failed ret[%d] qpn[%u] gid_idx[%d]", ret, qpCb->ibQp->qp_num,
807 : qpCb->qpInfoLo.gidIdx),
808 : ret);
809 :
810 41 : ret = RsIbvQueryGid(rdevCb->ibCtx, rdevCb->ibPort, qpCb->qpInfoLo.gidIdx, gidTmp);
811 41 : CHK_PRT_RETURN(ret, hccp_err("ibv_query_gid failed ret[%d]", ret), -EOPENSRC);
812 40 : return 0;
813 : }
814 :
815 41 : RS_ATTRI_VISI_DEF int RsDrvGetRandomNum(int *randNum)
816 : {
817 : int randFd;
818 41 : int ret = 0;
819 41 : int retClose = 0;
820 :
821 41 : randFd = open("/dev/urandom", O_RDONLY, S_IRUSR);
822 41 : CHK_PRT_RETURN(randFd < 0, hccp_err("open random failed ret[%d] rand_fd[%d]", errno, randFd), -EFILEOPER);
823 : do {
824 39 : ret = read(randFd, randNum, sizeof(int));
825 39 : } while ((ret < 0) && (errno == EINTR));
826 :
827 39 : 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 38 : RS_CLOSE_RETRY_FOR_EINTR(retClose, randFd);
834 38 : return 0;
835 : }
836 :
837 45 : int RsDrvQpInfoRelated(struct RsQpCb *qpCb, struct RsRdevCb *rdevCb, struct ibv_port_attr *attr,
838 : struct ibv_qp_attr *qpAttr)
839 : {
840 : int ret;
841 : union ibv_gid gidTmp;
842 : int randNum;
843 :
844 45 : ret = RsDrvQpQueryInfo(qpCb, rdevCb, attr, qpAttr, &gidTmp);
845 45 : CHK_PRT_RETURN(ret, hccp_err("query qp info failed, ret %d", ret), ret);
846 :
847 40 : ret = RsDrvGetRandomNum(&randNum);
848 40 : CHK_PRT_RETURN(ret, hccp_err("get random num failed, ret %d", ret), ret);
849 :
850 37 : qpCb->qpInfoLo.cmd = (unsigned int)RS_CMD_QP_INFO;
851 37 : qpCb->qpInfoLo.lid = attr->lid;
852 37 : qpCb->qpInfoLo.psn = (unsigned int)randNum & 0xffffff;
853 37 : qpCb->qpInfoLo.qpn = (int)qpCb->ibQp->qp_num;
854 37 : if (rdevCb->notifyType != NO_USE && rdevCb->notifyMr != NULL) {
855 36 : qpCb->qpInfoLo.notifyMr.addr = rdevCb->notifyVaBase;
856 36 : qpCb->qpInfoLo.notifyMr.len = rdevCb->notifySize;
857 36 : qpCb->qpInfoLo.notifyMr.rkey = rdevCb->notifyMr->rkey;
858 : } else {
859 1 : qpCb->qpInfoLo.notifyMr.addr = 0;
860 1 : qpCb->qpInfoLo.notifyMr.len = 0;
861 1 : qpCb->qpInfoLo.notifyMr.rkey = 0;
862 : }
863 :
864 37 : ret = memcpy_s(qpCb->qpInfoLo.gid.raw, sizeof(qpCb->qpInfoLo.gid.raw), gidTmp.raw, sizeof(gidTmp.raw));
865 37 : CHK_PRT_RETURN(ret,
866 : hccp_err("memcpy_s raw failed, ret:%d, dst_len:%u, src_len:%d", ret, sizeof(qpCb->qpInfoLo.gid.raw),
867 : RS_QP_ATTR_GID_LEN),
868 : -ESAFEFUNC);
869 36 : return 0;
870 : }
871 :
872 40 : STATIC int RsDrvExpQpCreateInit(struct ibv_exp_qp_init_attr *qpInitAttr, struct RsQpCb *qpCb,
873 : struct ibv_port_attr *attr)
874 : {
875 : int ret;
876 40 : ret = memset_s(attr, sizeof(struct ibv_port_attr), 0, sizeof(struct ibv_port_attr));
877 40 : CHK_PRT_RETURN(ret, hccp_err("memset_s for attr failed, ret:%d", ret), -ESAFEFUNC);
878 39 : ret = memset_s(qpInitAttr, sizeof(struct ibv_exp_qp_init_attr), 0, sizeof(struct ibv_exp_qp_init_attr));
879 39 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ESAFEFUNC);
880 :
881 38 : qpInitAttr->attr.qp_type = IBV_QPT_RC;
882 38 : qpInitAttr->attr.send_cq = qpCb->ibSendCq;
883 38 : qpInitAttr->attr.recv_cq = qpCb->ibRecvCq;
884 38 : qpInitAttr->attr.cap.max_inline_data = QP_DEFAULT_MAX_CAP_INLINE_DATA;
885 38 : qpInitAttr->attr.cap.max_send_wr = qpCb->txDepth;
886 38 : qpInitAttr->attr.cap.max_send_sge = qpCb->sendSgeNum;
887 38 : qpInitAttr->attr.cap.max_recv_wr = qpCb->rxDepth;
888 38 : qpInitAttr->attr.cap.max_recv_sge = qpCb->recvSgeNum;
889 :
890 38 : return 0;
891 : }
892 :
893 40 : STATIC int RsDrvExpQpCreate(struct RsQpCb *qpCb, int qpMode)
894 : {
895 : int ret;
896 : struct ibv_qp_attr qpAttr;
897 : struct ibv_exp_qp_init_attr qpInitAttr;
898 40 : struct RsRdevCb *rdevCb = NULL;
899 : struct ibv_port_attr attr;
900 :
901 40 : hccp_dbg("qp exp create begin..");
902 40 : rdevCb = qpCb->rdevCb;
903 40 : qpCb->qpMode = qpMode;
904 40 : ret = RsDrvExpQpCreateInit(&qpInitAttr, qpCb, &attr);
905 40 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_qp_create_init failed, ret:%d", ret), ret);
906 :
907 38 : qpInitAttr.gdr_enable = qpMode;
908 38 : qpInitAttr.lite_op_support = RsDrvGetSupportLite(rdevCb, qpCb->qpMode, qpCb->aiOpSupport);
909 38 : qpInitAttr.mem_align = qpCb->memAlign;
910 38 : qpInitAttr.mem_idx = qpCb->memResp.memData.mem_idx;
911 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
912 38 : qpCb->ibQp = RsIbvExpCreateQp(qpCb->ibPd, &qpInitAttr, &qpCb->qpResp.qpData);
913 38 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_exp_create_qp failed"), -ENOMEM);
914 :
915 37 : qpCb->dbIndex = (qpMode == RA_RS_OP_QP_MODE || qpMode == RA_RS_GDR_ASYN_QP_MODE) ? qpCb->qpResp.qpData.qp_info : 0;
916 37 : qpCb->sqIndex = (qpMode == RA_RS_GDR_TMPL_QP_MODE) ? qpCb->qpResp.qpData.qp_info : 0;
917 37 : hccp_info("db index is [%d], sq index is [%d]", qpCb->dbIndex, qpCb->sqIndex);
918 :
919 : /* query qp attr */
920 37 : ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, &qpInitAttr.attr);
921 37 : 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 36 : ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
928 36 : if (ret) {
929 9 : hccp_err("qp info related failed %d", ret);
930 9 : goto exp_init_qp_err;
931 : }
932 :
933 27 : hccp_info("chip_id %u, rdevIndex:%u, qp[%d] create succ.", qpCb->rdevCb->rsCb->chipId, qpCb->rdevCb->rdevIndex,
934 : qpCb->qpInfoLo.qpn);
935 :
936 27 : 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, struct RsQpCb *qpCb, struct ibv_port_attr *attr)
944 : {
945 : int ret;
946 4 : ret = memset_s(attr, sizeof(struct ibv_port_attr), 0, sizeof(struct ibv_port_attr));
947 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for attr failed, ret:%d", ret), -ESAFEFUNC);
948 4 : ret = memset_s(qpInitAttr, sizeof(struct ibv_qp_init_attr), 0, sizeof(struct ibv_qp_init_attr));
949 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ESAFEFUNC);
950 :
951 4 : qpInitAttr->qp_type = IBV_QPT_RC;
952 4 : qpInitAttr->send_cq = qpCb->ibSendCq;
953 4 : qpInitAttr->recv_cq = qpCb->ibRecvCq;
954 4 : qpInitAttr->cap.max_inline_data = QP_DEFAULT_MAX_CAP_INLINE_DATA;
955 4 : qpInitAttr->cap.max_send_wr = qpCb->txDepth;
956 4 : qpInitAttr->cap.max_send_sge = qpCb->sendSgeNum;
957 4 : qpInitAttr->cap.max_recv_wr = qpCb->rxDepth;
958 4 : qpInitAttr->cap.max_recv_sge = qpCb->recvSgeNum;
959 4 : return 0;
960 : }
961 :
962 2 : STATIC int RsDrvQpNormal(struct RsQpCb *qpCb, int qpMode)
963 : {
964 : int ret;
965 : struct ibv_qp_attr qpAttr;
966 : struct ibv_qp_init_attr qpInitAttr;
967 2 : struct RsRdevCb *rdevCb = NULL;
968 : struct ibv_port_attr attr;
969 :
970 2 : hccp_dbg("qp normal create begin..");
971 2 : rdevCb = qpCb->rdevCb;
972 2 : qpCb->qpMode = qpMode;
973 2 : ret = RsDrvNormalQpCreateInit(&qpInitAttr, qpCb, &attr);
974 2 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_normal_qp_create_init failed, ret:%d", ret), ret);
975 :
976 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
977 2 : qpCb->ibQp = RsIbvCreateQp(qpCb->ibPd, &qpInitAttr);
978 2 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_create_qp failed, errno=%d", errno), -ENOMEM);
979 :
980 : /* query qp attr */
981 2 : ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, &qpInitAttr);
982 2 : if (ret) {
983 0 : hccp_err("query qp attr failed ret %d", ret);
984 0 : ret = -EOPENSRC;
985 0 : goto normal_init_qp_err;
986 : }
987 :
988 2 : ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
989 2 : if (ret) {
990 0 : hccp_err("qp info related failed %d", ret);
991 0 : goto normal_init_qp_err;
992 : }
993 :
994 2 : hccp_info("chip_id %u, rdevIndex:%u, qp[%d] create succ.", qpCb->rdevCb->rsCb->chipId, qpCb->rdevCb->rdevIndex,
995 : qpCb->qpInfoLo.qpn);
996 :
997 2 : return 0;
998 :
999 0 : normal_init_qp_err:
1000 0 : (void)RsIbvDestroyQp(qpCb->ibQp);
1001 0 : return ret;
1002 : }
1003 :
1004 42 : int RsDrvQpCreate(struct RsQpCb *qpCb, struct RsQpNorm *qpNorm)
1005 : {
1006 : int ret;
1007 42 : if (qpNorm->isExp != 0 && qpNorm->qpMode != RA_RS_NOR_QP_MODE) {
1008 40 : ret = RsDrvExpQpCreate(qpCb, qpNorm->qpMode);
1009 : } else {
1010 2 : ret = RsDrvQpNormal(qpCb, qpNorm->qpMode);
1011 : }
1012 :
1013 42 : return ret;
1014 : }
1015 :
1016 4 : STATIC int RsDrvExpQpCreateInitWithAttrs(struct ibv_exp_qp_init_attr *qpInitAttr, struct RsQpCb *qpCb,
1017 : struct ibv_port_attr *attr, struct RsQpNormWithAttrs *qpNorm)
1018 : {
1019 : int ret;
1020 :
1021 4 : ret = memset_s(attr, sizeof(struct ibv_port_attr), 0, sizeof(struct ibv_port_attr));
1022 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for attr failed, ret:%d", ret), -ESAFEFUNC);
1023 4 : ret = memset_s(qpInitAttr, sizeof(struct ibv_exp_qp_init_attr), 0, sizeof(struct ibv_exp_qp_init_attr));
1024 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ESAFEFUNC);
1025 :
1026 4 : qpInitAttr->attr.send_cq = qpCb->ibSendCq;
1027 4 : qpInitAttr->attr.recv_cq = qpCb->ibRecvCq;
1028 :
1029 4 : ret = memcpy_s(&qpInitAttr->attr.cap, sizeof(struct ibv_qp_cap), &qpNorm->extAttrs.qpAttr.cap,
1030 : sizeof(struct ibv_qp_cap));
1031 4 : CHK_PRT_RETURN(ret, hccp_err("memset_s for qp_init_attr failed, ret:%d", ret), -ENOMEM);
1032 4 : qpInitAttr->attr.qp_type = qpNorm->extAttrs.qpAttr.qp_type;
1033 4 : qpInitAttr->attr.sq_sig_all = qpNorm->extAttrs.qpAttr.sq_sig_all;
1034 4 : qpInitAttr->udp_sport = qpCb->udpSport;
1035 4 : qpInitAttr->use_resv_mem = qpNorm->extAttrs.cstmFlag.bs.useResvMem;
1036 4 : qpInitAttr->resv_mem_pool_id = qpNorm->extAttrs.resvMemPoolId;
1037 :
1038 4 : return 0;
1039 : }
1040 :
1041 4 : STATIC int RsDrvExpQpCreateWithAttrs(struct RsQpCb *qpCb, struct RsQpNormWithAttrs *qpNorm)
1042 : {
1043 : int ret;
1044 : struct ibv_port_attr attr;
1045 : struct ibv_qp_attr qpAttr;
1046 4 : struct RsRdevCb *rdevCb = NULL;
1047 : struct ibv_exp_qp_init_attr qpInitAttr;
1048 :
1049 4 : hccp_dbg("qp exp create begin..");
1050 4 : rdevCb = qpCb->rdevCb;
1051 4 : ret = RsDrvExpQpCreateInitWithAttrs(&qpInitAttr, qpCb, &attr, qpNorm);
1052 4 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_qp_create_init failed, ret:%d", ret), ret);
1053 :
1054 4 : qpInitAttr.gdr_enable = qpCb->qpMode;
1055 4 : qpInitAttr.lite_op_support = RsDrvGetSupportLite(rdevCb, qpCb->qpMode, qpCb->aiOpSupport);
1056 4 : qpInitAttr.mem_align = qpCb->memAlign;
1057 4 : qpInitAttr.mem_idx = qpCb->memResp.memData.mem_idx;
1058 4 : qpInitAttr.ai_op_support = qpCb->aiOpSupport;
1059 4 : qpInitAttr.grp_id = qpCb->grpId;
1060 4 : qpInitAttr.qp_cstm_flag = qpCb->aiOpSupport;
1061 :
1062 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
1063 4 : qpCb->ibQp = RsIbvExpCreateQp(qpCb->ibPd, &qpInitAttr, &qpCb->qpResp.qpData);
1064 4 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_exp_create_qp failed"), -ENOMEM);
1065 :
1066 4 : qpCb->dbIndex = (qpCb->qpMode == RA_RS_OP_QP_MODE || qpCb->qpMode == RA_RS_GDR_ASYN_QP_MODE)
1067 : ? qpCb->qpResp.qpData.qp_info
1068 8 : : 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, qpCb->rdevCb->rdevIndex,
1087 : 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, struct RsQpCb *qpCb,
1097 : 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, qpCb->rdevCb->rdevIndex,
1149 : 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 35 : void RsDrvQpDestroy(struct RsQpCb *qpCb)
1173 : {
1174 35 : (void)RsIbvDestroyQp(qpCb->ibQp);
1175 35 : }
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 5 : cqContext->ibSendCq = RsIbvCreateCq(cqContext->rdevCb->ibCtx, attr->sendCqDepth, cqContext->sendEvent,
1212 : 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 4 : cqContext->ibRecvCq = RsIbvCreateCq(cqContext->rdevCb->ibCtx, attr->recvCqDepth, cqContext->recvEvent,
1234 : 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, NULL, attr->sendChannel, 1);
1272 1 : if (cqContext->ibSendCq == NULL) {
1273 0 : hccp_err("rs_drv_create_cq_with_channel ibv create send cq failed.");
1274 0 : return -EOPENSRC;
1275 : }
1276 :
1277 1 : cqContext->ibRecvCq = RsIbvCreateCq(cqContext->rdevCb->ibCtx, attr->recvCqDepth, NULL, attr->recvChannel, 1);
1278 1 : if (cqContext->ibRecvCq == NULL) {
1279 0 : hccp_err("rs_drv_create_cq_with_channel ibv create serecvnd cq failed.");
1280 0 : goto create_recv_cq_err;
1281 : }
1282 :
1283 1 : *attr->ibSendCq = cqContext->ibSendCq;
1284 1 : *attr->ibRecvCq = cqContext->ibRecvCq;
1285 1 : hccp_info("create cq with channel success");
1286 1 : return 0;
1287 :
1288 0 : create_recv_cq_err:
1289 0 : (void)RsIbvDestroyCq(cqContext->ibSendCq);
1290 0 : return -EOPENSRC;
1291 : }
1292 :
1293 0 : int RsDrvTypicalCqCreate(struct RsRdevCb *rdevCb, unsigned int cqDepth, unsigned int *cqn, struct ibv_cq **ibCq,
1294 : struct rdma_lite_device_cq_attr *deviceCqAttr)
1295 : {
1296 0 : struct rdma_lite_device_cq_init_attr initAttr = {
1297 : .cq_type = RA_RS_OP_QP_MODE,
1298 0 : .lite_op_supported = rdevCb->supportLite,
1299 : };
1300 :
1301 0 : *ibCq = RsIbvExpCreateCq(rdevCb->ibCtx, (int)cqDepth, NULL, NULL, 0, &initAttr, deviceCqAttr);
1302 0 : if (*ibCq == NULL) {
1303 0 : hccp_err("rs_ibv_exp_create_cq failed, cqDepth[%u]", cqDepth);
1304 0 : return -ENOMEM;
1305 : }
1306 :
1307 0 : *cqn = deviceCqAttr->cqn;
1308 0 : hccp_info("drv typical cq create success, cqn[%u] cqDepth[%u]", *cqn, cqDepth);
1309 0 : return 0;
1310 : }
1311 :
1312 8 : int RsDrvDestroyCqEvent(struct RsCqContext *cqContext)
1313 : {
1314 : int ret;
1315 :
1316 8 : if (cqContext->cqCreateMode == RS_NORMAL_CQ_CREATE || cqContext->cqCreateMode == RS_SRQ_CQ_CREATE) {
1317 7 : ret = RsIbvDestroyCq(cqContext->ibRecvCq);
1318 7 : if (ret) {
1319 1 : hccp_err("rs_ibv_destroy_cq(recv) failed, ret %d", ret);
1320 : }
1321 7 : (void)RsDrvEventDestroy(cqContext->recvEvent);
1322 : }
1323 :
1324 8 : if (cqContext->cqCreateMode == RS_NORMAL_CQ_CREATE || cqContext->cqCreateMode == RS_SQ_CQ_CREATE) {
1325 5 : ret = RsIbvDestroyCq(cqContext->ibSendCq);
1326 5 : if (ret) {
1327 1 : hccp_err("rs_ibv_destroy_cq(send) failed, ret %d", ret);
1328 : }
1329 5 : (void)RsDrvEventDestroy(cqContext->sendEvent);
1330 : }
1331 :
1332 8 : return 0;
1333 : }
1334 :
1335 5 : int RsDrvNormalQpCreate(struct RsQpCb *qpCb, struct ibv_qp_init_attr *qpInitAttr)
1336 : {
1337 : int ret;
1338 : struct ibv_qp_attr qpAttr;
1339 5 : struct RsRdevCb *rdevCb = NULL;
1340 : struct ibv_port_attr attr;
1341 :
1342 5 : hccp_dbg("rs_drv_normal_qp_create begin..");
1343 5 : rdevCb = qpCb->rdevCb;
1344 :
1345 : /* A return value of NULL indicates an OutOfMemoryError(OOM) has occurred */
1346 5 : qpCb->ibQp = RsIbvCreateQp(qpCb->ibPd, qpInitAttr);
1347 5 : CHK_PRT_RETURN(qpCb->ibQp == NULL, hccp_err("rs_ibv_create_qp failed, errno=%d", errno), -ENOMEM);
1348 :
1349 : /* query qp attr */
1350 4 : ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, qpInitAttr);
1351 4 : if (ret) {
1352 1 : hccp_err("query qp attr failed ret %d", ret);
1353 1 : ret = -EOPENSRC;
1354 1 : goto normal_init_qp_err;
1355 : }
1356 :
1357 3 : ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
1358 3 : if (ret) {
1359 1 : hccp_err("qp info related failed %d", ret);
1360 1 : goto normal_init_qp_err;
1361 : }
1362 :
1363 2 : hccp_info("chip_id %u, rdevIndex:%u, qp[%d] create succ.", qpCb->rdevCb->rsCb->chipId, qpCb->rdevCb->rdevIndex,
1364 : qpCb->qpInfoLo.qpn);
1365 :
1366 2 : return 0;
1367 :
1368 2 : normal_init_qp_err:
1369 2 : (void)RsIbvDestroyQp(qpCb->ibQp);
1370 2 : return ret;
1371 : }
|