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 <netinet/in.h>
15 : #include <arpa/inet.h>
16 : #include <dlfcn.h>
17 : #include <sys/types.h>
18 : #include <sys/stat.h>
19 : #include <sys/epoll.h>
20 : #include <sys/eventfd.h>
21 : #include <sys/socket.h>
22 : #include <errno.h>
23 : #include "securec.h"
24 : #include "rs.h"
25 : #include "ra_rs_err.h"
26 : #include "rs_common_inner.h"
27 : #include "rs_inner.h"
28 : #include "rs_rdma_inner.h"
29 : #include "rs_epoll.h"
30 : #include "dl_hal_function.h"
31 : #include "dl_ibverbs_function.h"
32 : #include "rs_drv_socket.h"
33 : #include "rs_drv_rdma.h"
34 : #include "rs_rdma.h"
35 :
36 : unsigned int gRsSendWrNum = 0;
37 :
38 : STATIC struct RsListHead gRsTypicalCqList;
39 : STATIC pthread_mutex_t gRsTypicalCqMutex = PTHREAD_MUTEX_INITIALIZER;
40 :
41 2 : STATIC void RsBufPrint(char *addr, int len)
42 : {
43 : int i;
44 :
45 130 : for (i = 0; i < len; i++) {
46 128 : hccp_info("0x%02x ", *(addr + i));
47 : }
48 2 : }
49 :
50 130 : STATIC int RsGetQpcb(struct RsRdevCb *rdevCb, uint32_t qpn, struct RsQpCb **qpCb)
51 : {
52 130 : struct RsQpCb *qpCbTmp = NULL;
53 130 : struct RsQpCb *qpCbTmp2 = NULL;
54 :
55 130 : RS_LIST_GET_HEAD_ENTRY(qpCbTmp, qpCbTmp2, &rdevCb->qpList, list, struct RsQpCb);
56 172 : for (; (&qpCbTmp->list) != &rdevCb->qpList;
57 42 : qpCbTmp = qpCbTmp2, qpCbTmp2 = list_entry(qpCbTmp2->list.next, struct RsQpCb, list)) {
58 164 : if (qpCbTmp->ibQp->qp_num == qpn) {
59 122 : *qpCb = qpCbTmp;
60 122 : return 0;
61 : }
62 : }
63 :
64 8 : *qpCb = NULL;
65 8 : hccp_err("qp_cb for qp %u do not available!", qpn);
66 :
67 8 : return -ENODEV;
68 : }
69 :
70 132 : int RsQpn2qpcb(unsigned int phyId, unsigned int rdevIndex, uint32_t qpn, struct RsQpCb **qpCb)
71 : {
72 : int ret;
73 : unsigned int chipId;
74 132 : struct rs_cb *rsCb = NULL;
75 132 : struct RsRdevCb *rdevCb = NULL;
76 :
77 132 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs set param error! phyId:%u", phyId), -EINVAL);
78 :
79 130 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
80 130 : CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret:%d",
81 : phyId, ret), ret);
82 :
83 130 : ret = RsDev2rscb(chipId, &rsCb, false);
84 130 : CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb get rs_cb failed, ret:%d", ret), -ENODEV);
85 :
86 130 : ret = RsGetRdevCb(rsCb, rdevIndex, &rdevCb);
87 130 : CHK_PRT_RETURN(ret, hccp_err("rs_get_rdev_cb failed! ret:%d, rdevIndex:%u", ret, rdevIndex), ret);
88 :
89 130 : ret = RsGetQpcb(rdevCb, qpn, qpCb);
90 130 : CHK_PRT_RETURN(ret, hccp_err("rs_get_qpcb failed! ret:%d, qpn:%u", ret, qpn), ret);
91 :
92 122 : return 0;
93 : }
94 :
95 44 : STATIC int RsGetMrcb(struct RsQpCb *qpCb, uint64_t addr, struct RsMrCb **mrCb,
96 : struct RsListHead *mrList)
97 : {
98 44 : struct RsMrCb *mrTmp = NULL;
99 44 : struct RsMrCb *mrTmp2 = NULL;
100 :
101 44 : RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
102 44 : RS_LIST_GET_HEAD_ENTRY(mrTmp, mrTmp2, mrList, list, struct RsMrCb);
103 86 : for (; (&mrTmp->list) != mrList;
104 42 : mrTmp = mrTmp2, mrTmp2 = list_entry(mrTmp2->list.next, struct RsMrCb, list)) {
105 66 : if ((mrTmp->mrInfo.addr <= addr) && (addr < mrTmp->mrInfo.addr + mrTmp->mrInfo.len)) {
106 24 : *mrCb = mrTmp;
107 24 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
108 24 : return 0;
109 : }
110 : }
111 :
112 20 : *mrCb = NULL;
113 20 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
114 :
115 20 : hccp_info("cannot find mrcb for addr@0x%lx !", addr);
116 :
117 20 : return -ENODEV;
118 : }
119 :
120 18 : STATIC void *RsNotifyMrListAdd(struct RsQpCb *qpCb, const char *buf)
121 : {
122 : int ret;
123 : struct RsMrCb *notifyMrCb;
124 :
125 18 : notifyMrCb = calloc(1, sizeof(struct RsMrCb));
126 18 : CHK_PRT_RETURN(notifyMrCb == NULL, hccp_err("notify_mr_cb calloc failed"), NULL);
127 16 : ret = memcpy_s(¬ifyMrCb->mrInfo, sizeof(struct RsMrInfo),
128 16 : &((const struct RsQpInfo *)buf)->notifyMr, sizeof(struct RsMrInfo));
129 16 : if (ret) {
130 1 : hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u",
131 : ret, sizeof(struct RsMrInfo), sizeof(struct RsMrInfo));
132 1 : free(notifyMrCb);
133 1 : notifyMrCb = NULL;
134 1 : return NULL;
135 : }
136 :
137 15 : hccp_info("qpn is %d, rdevIndex:%u, chipId %u, recv notify va is 0x%llx, notify size is %llu",
138 : qpCb->qpInfoLo.qpn, qpCb->rdevCb->rdevIndex, qpCb->rdevCb->rsCb->chipId,
139 : notifyMrCb->mrInfo.addr, notifyMrCb->mrInfo.len);
140 :
141 15 : RsListAddTail(¬ifyMrCb->list, &qpCb->remMrList);
142 :
143 15 : return notifyMrCb;
144 : }
145 :
146 21 : STATIC int RsQpStateModify(struct RsQpCb *qpCb)
147 : {
148 21 : struct ibv_qp_init_attr initAttr = { 0 };
149 21 : struct ibv_qp_attr attr = { 0 };
150 : enum ibv_qp_state state;
151 : int ret;
152 :
153 : // see ib_modify_qp_is_ok for status modify, only support modify qp from INIT to RTR
154 21 : ret = RsIbvQueryQp(qpCb->ibQp, &attr, IBV_QP_STATE, &initAttr);
155 21 : if (ret != 0) {
156 1 : hccp_warn("rs_ibv_query_qp qpn:%d unsuccessful, ret:%d", qpCb->qpInfoLo.qpn, ret);
157 1 : state = IBV_QPS_UNKNOWN;
158 : } else {
159 20 : state = attr.qp_state;
160 : }
161 :
162 : // disallow modify qp from IBV_QPS_RTS to IBV_QPS_RTS
163 21 : if (state == IBV_QPS_RTS) {
164 1 : hccp_err("qpn:%d disallow modify from %d", qpCb->qpInfoLo.qpn, state);
165 1 : return -EINVAL;
166 : }
167 :
168 20 : hccp_info("qpn:%d state:%d start modify", qpCb->qpInfoLo.qpn, state);
169 :
170 : // modify qp from others to RESET
171 20 : if (state != IBV_QPS_RESET && state != IBV_QPS_INIT && state != IBV_QPS_RTR) {
172 1 : ret = RsDrvQpStateModifytoReset(qpCb);
173 1 : CHK_PRT_RETURN(ret, hccp_err("qpn:%d modify %d to reset failed, ret:%d", qpCb->qpInfoLo.qpn, state, ret),
174 : ret);
175 0 : state = IBV_QPS_RESET;
176 : }
177 :
178 : // modify qp from RESET to INIT
179 19 : if (state == IBV_QPS_RESET) {
180 19 : ret = RsDrvQpStateModifytoInit(qpCb, &attr);
181 19 : CHK_PRT_RETURN(ret, hccp_err("qpn:%d modify %d to init failed, ret %d", qpCb->qpInfoLo.qpn, state, ret),
182 : ret);
183 18 : state = IBV_QPS_INIT;
184 : }
185 :
186 : // modify qp from INIT to RTR
187 18 : if (state == IBV_QPS_INIT) {
188 18 : ret = RsDrvQpStateModifytoRtr(qpCb, &attr);
189 18 : CHK_PRT_RETURN(ret, hccp_err("qpn:%d modify %d to rtr failed, ret %d", qpCb->qpInfoLo.qpn, state, ret), ret);
190 16 : state = IBV_QPS_RTR;
191 : }
192 :
193 : // modify qp from RTR to RTS
194 16 : if (state == IBV_QPS_RTR) {
195 16 : ret = RsDrvQpStateModifytoRts(qpCb, &attr);
196 16 : CHK_PRT_RETURN(ret, hccp_err("qpn:%d modify %d to rts failed, ret %d", qpCb->qpInfoLo.qpn, state, ret), ret);
197 : }
198 :
199 16 : hccp_info("local qpn[%d] remote qpn[%d] modify succ", qpCb->qpInfoLo.qpn, qpCb->qpInfoRem.qpn);
200 :
201 16 : return 0;
202 : }
203 :
204 17 : STATIC int RsEpollRecvQpHandle(struct RsQpCb *qpCb, const char *bufTmp)
205 : {
206 : int ret;
207 17 : float timeCost = 0.0;
208 :
209 17 : ret = memcpy_s(&qpCb->qpInfoRem, sizeof(struct RsQpInfo),
210 : bufTmp, sizeof(struct RsQpInfo));
211 17 : CHK_PRT_RETURN(ret, hccp_err("memcpy_s failed[%d], dest size:%d, src size:%d", ret, sizeof(struct RsQpInfo),
212 : sizeof(struct RsQpInfo)), -ENOMEM);
213 :
214 : /* modify qp state to RTR/RTS */
215 17 : ret = RsQpStateModify(qpCb);
216 17 : CHK_PRT_RETURN(ret, hccp_err("rs_qp_state_modify local qpn[%d] remote qpn[%d] failed ret[%d]",
217 : qpCb->qpInfoLo.qpn, qpCb->qpInfoRem.qpn, ret), ret);
218 :
219 16 : RsGetCurTime(&qpCb->endTime);
220 16 : HccpTimeInterval(&qpCb->endTime, &qpCb->startTime, &timeCost);
221 16 : if (timeCost > RS_EXPECT_TIME_MAX) {
222 2 : hccp_warn("local qpn[%d] remote qpn [%d] connect success cost[%f] more than[%f]ms!", qpCb->qpInfoLo.qpn,
223 : qpCb->qpInfoRem.qpn, timeCost, RS_EXPECT_TIME_MAX);
224 : } else {
225 14 : hccp_info("local qpn[%d] remote qpn [%d] connect success! cost [%f] ms", qpCb->qpInfoLo.qpn,
226 : qpCb->qpInfoRem.qpn, timeCost);
227 : }
228 :
229 16 : hccp_info("qp [%d] state has been migrate to RTS!, qpCb state is %d", qpCb->qpInfoLo.qpn, qpCb->state);
230 :
231 16 : return 0;
232 : }
233 :
234 14 : STATIC void *RsEpollRecvMrHandle(struct RsQpCb *qpCb, const char *bufTmp)
235 : {
236 : int ret;
237 : struct RsMrCb *mrCb;
238 :
239 14 : mrCb = calloc(1, sizeof(struct RsMrCb));
240 14 : CHK_PRT_RETURN(mrCb == NULL, hccp_err("mr_cb calloc failed"), NULL);
241 13 : ret = memcpy_s(&mrCb->mrInfo, sizeof(struct RsMrInfo), bufTmp, sizeof(struct RsMrInfo));
242 13 : if (ret) {
243 0 : hccp_err("memcpy_s failed[%d], dest size:%u, src size:%u", ret, sizeof(struct RsMrInfo),
244 : sizeof(struct RsMrInfo));
245 0 : free(mrCb);
246 0 : mrCb = NULL;
247 0 : return NULL;
248 : }
249 :
250 13 : RsListAddTail(&mrCb->list, &qpCb->remMrList);
251 :
252 13 : hccp_info("recv mr addr is 0x%llx", mrCb->mrInfo.addr);
253 13 : hccp_info("recv mr len is %llu", mrCb->mrInfo.len);
254 :
255 13 : return mrCb;
256 : }
257 :
258 17 : STATIC int RsCmdQpInfoHandle(struct RsQpCb *qpCb, unsigned int totalSize,
259 : const char *bufTmp, unsigned int curSize, bool *flag)
260 : {
261 : int ret;
262 17 : CHK_PRT_RETURN((totalSize - curSize) < sizeof(struct RsQpInfo), hccp_info("qp_info remain size"
263 : "[%u] < size [%u], wait for next recv", totalSize - curSize, sizeof(struct RsQpInfo)), -EINVAL);
264 :
265 17 : ret = RsEpollRecvQpHandle(qpCb, bufTmp);
266 17 : CHK_PRT_RETURN(ret, hccp_err("rs_epoll_recv_qp_handle failed! ret[%d]", ret), ret);
267 :
268 16 : RsNotifyMrListAdd(qpCb, bufTmp);
269 16 : hccp_info("rs_notify_mr_list_add");
270 :
271 16 : *flag = true;
272 16 : hccp_info("qp_info cur_size(%u) len(%u) !", curSize, sizeof(struct RsQpInfo));
273 :
274 16 : return 0;
275 : }
276 :
277 14 : STATIC int RsCmdMrInfoHandle(struct RsQpCb *qpCb, unsigned int totalSize, const char *bufTmp,
278 : unsigned int curSize, bool *flag)
279 : {
280 14 : CHK_PRT_RETURN((totalSize - curSize) < sizeof(struct RsMrInfo), hccp_info("mr_info remain size"
281 : "[%u] < size [%u], wait for next recv", totalSize - curSize, sizeof(struct RsMrInfo)), -EINVAL);
282 :
283 14 : (void)RsEpollRecvMrHandle(qpCb, bufTmp);
284 :
285 14 : *flag = true;
286 :
287 14 : hccp_info("mr_info cur_size(%u) len(%u) !", curSize, sizeof(struct RsMrInfo));
288 :
289 14 : return 0;
290 : }
291 :
292 14 : STATIC int RsCmdLenInfoHandle(struct RsQpCb *qpCb, unsigned int totalSize, const char *bufTmp,
293 : unsigned int curSize, bool *flag)
294 : {
295 14 : CHK_PRT_RETURN((totalSize - curSize) < sizeof(struct RsQpLenInfo), hccp_info("len_info remain size"
296 : "[%u] < size [%u], wait for next recv", totalSize - curSize, sizeof(struct RsQpLenInfo)), -EINVAL);
297 :
298 14 : qpCb->expectLen = *((const uint32_t*)(bufTmp + sizeof(uint32_t)));
299 :
300 14 : *flag = true;
301 :
302 14 : return 0;
303 : }
304 :
305 15 : STATIC void RsEpollRecvHandleRemain(struct RsQpCb *qpCb, unsigned int totalSize,
306 : unsigned int curSize, bool flag, const char *bufTmp)
307 : {
308 15 : int ret = 0;
309 :
310 15 : qpCb->remainSize = totalSize - curSize;
311 15 : if ((qpCb->remainSize > 0) && (flag == true)) {
312 1 : ret = memcpy_s(qpCb->qpMrBuf, RS_BUF_SIZE, bufTmp, qpCb->remainSize);
313 1 : if (ret) {
314 1 : hccp_err("memcpy_s failed, ret:%d, remainSize:%u", ret, qpCb->remainSize);
315 1 : return;
316 : }
317 : }
318 :
319 14 : return;
320 : }
321 :
322 18 : STATIC void RsEpollRecvHandle(struct RsQpCb *qpCb, char *buf, int size)
323 : {
324 18 : unsigned int totalSize = qpCb->remainSize + (unsigned int)size;
325 18 : char *bufTmp = (char *)qpCb->qpMrBuf;
326 18 : unsigned int curSize = 0;
327 18 : bool flag = false;
328 : uint32_t cmd;
329 : int ret;
330 :
331 18 : hccp_info("Message for qp:%d, qpCb->remainSize:%u, size:%d", qpCb->qpInfoLo.qpn, qpCb->remainSize, size);
332 18 : ret = memcpy_s(qpCb->qpMrBuf + qpCb->remainSize, RS_BUF_SIZE - qpCb->remainSize, buf, size);
333 18 : if (ret) {
334 2 : hccp_err("memcpy_s failed, ret:%d, remainSize:%u, size:%d", ret, qpCb->remainSize, size);
335 4 : return;
336 : }
337 :
338 : do {
339 47 : cmd = *((uint32_t *)bufTmp);
340 47 : switch (cmd) {
341 17 : case RS_CMD_QP_INFO:
342 17 : ret = RsCmdQpInfoHandle(qpCb, totalSize, bufTmp, curSize, &flag);
343 17 : if (ret) {
344 1 : goto out;
345 : }
346 :
347 16 : curSize += sizeof(struct RsQpInfo);
348 16 : bufTmp = qpCb->qpMrBuf + curSize;
349 16 : break;
350 14 : case RS_CMD_MR_INFO:
351 14 : ret = RsCmdMrInfoHandle(qpCb, totalSize, bufTmp, curSize, &flag);
352 14 : if (ret) {
353 0 : goto out;
354 : }
355 :
356 14 : curSize += sizeof(struct RsMrInfo);
357 14 : bufTmp = qpCb->qpMrBuf + curSize;
358 14 : break;
359 14 : case RS_CMD_LEN_INFO:
360 14 : ret = RsCmdLenInfoHandle(qpCb, totalSize, bufTmp, curSize, &flag);
361 14 : if (ret) {
362 0 : goto out;
363 : }
364 14 : curSize += sizeof(struct RsQpLenInfo);
365 14 : bufTmp = qpCb->qpMrBuf + curSize;
366 14 : break;
367 2 : default:
368 2 : hccp_warn("qp %d, unknown cmd(0x%x)!", qpCb->qpInfoLo.qpn, cmd);
369 2 : RsBufPrint(buf, size);
370 2 : return;
371 : }
372 44 : } while (curSize < totalSize);
373 :
374 13 : out:
375 14 : RsEpollRecvHandleRemain(qpCb, totalSize, curSize, flag, bufTmp);
376 : }
377 :
378 27 : STATIC void RsQpMrRecvHandle(int fd, struct RsQpCb *qpCb)
379 : {
380 : char buf[RS_BUF_SIZE];
381 : int size;
382 : int ret;
383 :
384 27 : RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
385 :
386 27 : size = RsSocketRecv(fd, buf, RS_BUF_SIZE - qpCb->remainSize);
387 27 : hccp_dbg("fd %d qpn %d read size = %d, qpCb->remainSize:%u", fd, qpCb->qpInfoLo.qpn, size, qpCb->remainSize);
388 :
389 27 : if (size > 0) {
390 13 : qpCb->recvLen += (uint32_t)size;
391 13 : RsEpollRecvHandle(qpCb, buf, size);
392 14 : } else if (size == 0) {
393 0 : hccp_dbg("fd %d read size = %d, remote fd has been closed, fd cannot use !", fd, size);
394 : #ifdef CA_CONFIG_LLT
395 0 : qpCb->state = RS_QP_STATUS_REM_FD_CLOSE;
396 : #endif
397 : } else {
398 14 : ret = errno;
399 14 : hccp_dbg("no data available, errno:%d", ret);
400 : }
401 27 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
402 :
403 27 : return;
404 : }
405 :
406 0 : STATIC int RsHandleQpMrEpollEvent(struct RsRdevCb *rdevCb, int fd)
407 : {
408 : struct RsQpCb *qpCb;
409 0 : struct RsQpCb *qpCb2 = NULL;
410 :
411 : /* QP event, QP info exchange */
412 0 : RS_LIST_GET_HEAD_ENTRY(qpCb, qpCb2, &rdevCb->qpList, list, struct RsQpCb);
413 0 : for (; (&qpCb->list) != &rdevCb->qpList;
414 0 : qpCb = qpCb2, qpCb2 = list_entry(qpCb2->list.next, struct RsQpCb, list)) {
415 0 : if (qpCb->channel == NULL) {
416 0 : continue;
417 : }
418 0 : if (qpCb->srqContext != NULL && qpCb->srqContext->channel->fd == fd) {
419 0 : hccp_dbg("fd %d poll cq!", fd);
420 0 : RsDrvPollSrqCqHandle(qpCb);
421 0 : return 0;
422 : }
423 0 : if (fd == qpCb->channel->fd) {
424 0 : hccp_dbg("fd %d poll cq!", fd);
425 0 : RsDrvPollCqHandle(qpCb);
426 0 : return 0;
427 : }
428 : }
429 0 : return -ENODEV;
430 : }
431 :
432 0 : int RsEpollEventQpMrInHandle(struct rs_cb *rsCb, int fd)
433 : {
434 : int ret;
435 0 : struct RsRdevCb *rdevCbTmp = NULL;
436 0 : struct RsRdevCb *rdevCbTmp2 = NULL;
437 :
438 0 : if (rsCb->protocol != PROTOCOL_RDMA) {
439 0 : return -ENODEV;
440 : }
441 :
442 0 : RS_LIST_GET_HEAD_ENTRY(rdevCbTmp, rdevCbTmp2, &rsCb->rdevList, list, struct RsRdevCb);
443 0 : for (; (&rdevCbTmp->list) != &rsCb->rdevList;
444 0 : rdevCbTmp = rdevCbTmp2, rdevCbTmp2 = list_entry(rdevCbTmp2->list.next, struct RsRdevCb, list)) {
445 0 : RS_PTHREAD_MUTEX_LOCK(&rdevCbTmp->rdevMutex);
446 0 : ret = RsHandleQpMrEpollEvent(rdevCbTmp, fd);
447 0 : RS_PTHREAD_MUTEX_ULOCK(&rdevCbTmp->rdevMutex);
448 0 : if (ret == 0) {
449 0 : return 0;
450 : }
451 : }
452 0 : return -ENODEV;
453 : }
454 :
455 28 : STATIC int RsMrInfoSync(struct RsMrCb *mrCb)
456 : {
457 : int ret;
458 :
459 28 : hccp_info("mr state:%d, addr:0x%lx", mrCb->state, mrCb->mrInfo.addr);
460 :
461 28 : CHK_PRT_RETURN(mrCb->state & RS_MR_STATE_SYNCED, hccp_warn("mr synced ! mr_cb->flag[%d] & [%d] != 0",
462 : mrCb->state, RS_MR_STATE_SYNCED), 0);
463 :
464 : /*
465 : * no socket available for MR_INFO exchange if allowed
466 : * need exchange when socket available
467 : */
468 27 : CHK_PRT_RETURN(mrCb->qpCb->connInfo == NULL, hccp_warn("no conn available !"), 0);
469 :
470 27 : CHK_PRT_RETURN(mrCb->qpCb->state == RS_QP_STATUS_REM_FD_CLOSE, hccp_warn("remote qp fd closed,"
471 : "cann not use it anymore! status[%d](RS_QP_STATUS_REM_FD_CLOSE)", mrCb->qpCb->state), -EFAULT);
472 :
473 27 : CHK_PRT_RETURN(mrCb->qpCb->connInfo->connfd == RS_FD_INVALID, hccp_warn("rm info sync failed! fd not ready!"
474 : "connfd[%d](RS_FD_INVALID)", mrCb->qpCb->connInfo->connfd), -ENETUNREACH);
475 :
476 26 : mrCb->mrInfo.cmd = (unsigned int)RS_CMD_MR_INFO;
477 26 : ret = RsSocketSend(mrCb->qpCb->connInfo->connfd, &mrCb->mrInfo,
478 : sizeof(struct RsMrInfo));
479 26 : CHK_PRT_RETURN(ret != sizeof(struct RsMrInfo), hccp_err("mr_info send %d/%ld incomplete",
480 : ret, sizeof(struct RsMrInfo)), -EAGAIN);
481 :
482 25 : mrCb->qpCb->sendLen += (uint32_t)ret;
483 25 : mrCb->state |= RS_MR_STATE_SYNCED;
484 25 : hccp_info("after send mr state:%d, addr:0x%lx", mrCb->state, mrCb->mrInfo.addr);
485 :
486 25 : return 0;
487 : }
488 :
489 5 : STATIC int RsMrPrepareRoceSign(unsigned int phyId, struct RsRdevCb *devCb, struct roce_process_sign *roceSign)
490 : {
491 5 : unsigned int tmpPhyId = phyId;
492 : unsigned int chipId;
493 : int ret;
494 :
495 : // reg mr with backup phyId
496 5 : if (devCb->backupInfo.backupFlag) {
497 0 : tmpPhyId = devCb->backupInfo.rdevInfo.phyId;
498 0 : ret = DlDrvGetLocalDevIdByHostDevId(tmpPhyId, &chipId);
499 : } else {
500 5 : ret = rsGetLocalDevIDByHostDevID(tmpPhyId, &chipId);
501 : }
502 5 : CHK_PRT_RETURN(ret != 0, hccp_err("get chipId failed, ret %d, phyid[%u] backupFlag[%d]",
503 : ret, tmpPhyId, devCb->backupInfo.backupFlag), -EACCES);
504 5 : roceSign->tgid = devCb->rsCb->pRsSign.tgid;
505 5 : roceSign->devid = chipId;
506 5 : roceSign->vfid = 0;
507 5 : ret = strcpy_s(roceSign->sign, PROCESS_RS_SIGN_LENGTH, devCb->rsCb->pRsSign.sign);
508 5 : CHK_PRT_RETURN(ret != 0, hccp_err("Invalid pid sign, ret(%d)", ret), -ESAFEFUNC);
509 5 : return 0;
510 : }
511 :
512 8 : STATIC int RsMrPreReg(unsigned int phyId, struct RsQpCb *qpCb, struct RsMrCb *mrCb, struct RdmaMrRegInfo *mrRegInfo)
513 : {
514 8 : unsigned long long len = mrRegInfo->len;
515 8 : struct roce_process_sign roceSign = {0};
516 8 : int access = mrRegInfo->access;
517 8 : char *addr = mrRegInfo->addr;
518 : int ret;
519 :
520 8 : if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE || qpCb->rdevCb->rsCb->hccpMode == NETWORK_ONLINE ||
521 7 : qpCb->isExp == RS_NOT_EXP) {
522 3 : mrCb->ibMr = RsDrvMrReg(qpCb->ibPd, addr, len, access);
523 3 : CHK_PRT_RETURN(mrCb->ibMr == NULL, hccp_err("rs_drv_mr_reg addr is NULL len[%lld] failed ",
524 : len), -EACCES);
525 : } else {
526 5 : ret = RsMrPrepareRoceSign(phyId, qpCb->rdevCb, &roceSign);
527 5 : CHK_PRT_RETURN(ret != 0, hccp_err("RsMrPrepareRoceSign failed, ret(%d)", ret), ret);
528 5 : mrCb->ibMr = RsDrvExpMrReg(qpCb->ibPd, addr, len, access, roceSign);
529 5 : CHK_PRT_RETURN(mrCb->ibMr == NULL, hccp_err("rs_drv_exp_mr_reg addr is NULL len[%lld] failed ",
530 : len), -EACCES);
531 : }
532 :
533 8 : mrCb->mrInfo.cmd = (unsigned int)RS_CMD_MR_INFO;
534 8 : mrCb->mrInfo.addr = (uintptr_t)addr;
535 8 : mrCb->mrInfo.len = len;
536 8 : mrCb->mrInfo.rkey = mrCb->ibMr->rkey;
537 :
538 8 : RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
539 8 : RsListAddTail(&mrCb->list, &qpCb->mrList);
540 8 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
541 :
542 8 : qpCb->mrNum++;
543 8 : return 0;
544 : }
545 :
546 40 : STATIC int RsCallocMr(int num, struct RsMrCb **mrCb)
547 : {
548 40 : CHK_PRT_RETURN(num <= 0, hccp_err("invalid num for mr calloc"), -EINVAL);
549 :
550 39 : *mrCb = calloc(num, sizeof(struct RsMrCb));
551 39 : CHK_PRT_RETURN((*mrCb) == NULL, hccp_err("calloc mr_cb failed"), -ENOMEM);
552 39 : return 0;
553 : }
554 :
555 53 : STATIC int RsCallocQpcb(int num, struct RsQpCb **qpCb)
556 : {
557 53 : if (num <= 0) {
558 1 : return -EINVAL;
559 : }
560 :
561 52 : *qpCb = calloc(num, sizeof(struct RsQpCb));
562 52 : if ((*qpCb) == NULL) {
563 1 : return -ENOMEM;
564 : }
565 :
566 51 : return 0;
567 : }
568 :
569 10 : RS_ATTRI_VISI_DEF int RsMrReg(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
570 : struct RdmaMrRegInfo *mrRegInfo)
571 : {
572 : int ret;
573 10 : struct RsQpCb *qpCb = NULL;
574 10 : struct RsMrCb *mrCb = NULL;
575 :
576 10 : CHK_PRT_RETURN(mrRegInfo == NULL || mrRegInfo->addr == NULL || mrRegInfo->len == 0 ||
577 : phyId >= RS_MAX_DEV_NUM, hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM),
578 : -EINVAL);
579 :
580 9 : hccp_info("qpn[%u], len[0x%llx], access[%d]",
581 : qpn, mrRegInfo->len, mrRegInfo->access);
582 :
583 9 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
584 9 : CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb qpn[%d] ret[%d] failed ", qpn, ret), ret);
585 :
586 8 : CHK_PRT_RETURN(qpCb->mrNum >= RS_MR_NUM_MAX, hccp_err("Exceeded the maximum MR limit %d",
587 : qpCb->mrNum), -EINVAL);
588 :
589 8 : ret = RsGetMrcb(qpCb, (uintptr_t)mrRegInfo->addr, &mrCb, &qpCb->mrList);
590 8 : if (ret == 0) {
591 0 : hccp_warn("mr already registered");
592 0 : goto found;
593 : }
594 :
595 8 : ret = RsCallocMr(1, &mrCb);
596 8 : CHK_PRT_RETURN(ret, hccp_err("calloc mr failed"), ret);
597 :
598 8 : mrCb->qpCb = qpCb;
599 :
600 8 : ret = RsMrPreReg(phyId, qpCb, mrCb, mrRegInfo);
601 8 : if (ret) {
602 0 : hccp_err("pre reg mr failed, qpn %u, ret %d", qpn, ret);
603 0 : goto reg_err;
604 : }
605 :
606 8 : found:
607 8 : mrRegInfo->lkey = mrCb->ibMr->lkey;
608 8 : mrRegInfo->rkey = mrCb->ibMr->rkey;
609 :
610 8 : hccp_info("rs_mr_reg succ, state:%u", mrCb->state);
611 8 : return 0;
612 :
613 0 : reg_err:
614 0 : free(mrCb);
615 0 : mrCb = NULL;
616 :
617 0 : return ret;
618 : }
619 :
620 10 : RS_ATTRI_VISI_DEF int RsMrDereg(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, char *addr)
621 : {
622 : int ret;
623 10 : struct RsQpCb *qpCb = NULL;
624 10 : struct RsMrCb *mrCb = NULL;
625 :
626 10 : hccp_dbg("start rs_mr_dereg");
627 10 : RS_CHECK_POINTER_NULL_RETURN_INT(addr);
628 9 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM),
629 : -EINVAL);
630 :
631 9 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
632 9 : CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb failed ret[%d]", ret), ret);
633 :
634 7 : CHK_PRT_RETURN(RsGetMrcb(qpCb, (uintptr_t)addr, &mrCb, &qpCb->mrList), hccp_err("rs_get_mrcb failed "\
635 : "g_rs_send_wr_num[%u]", gRsSendWrNum), -EFAULT);
636 :
637 6 : ret = RsDrvMrDereg(mrCb->ibMr);
638 6 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_mr_dereg failed ret[%d] ", ret), -EACCES);
639 :
640 6 : RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
641 6 : RsListDel(&mrCb->list);
642 6 : free(mrCb);
643 6 : mrCb = NULL;
644 6 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
645 6 : qpCb->mrNum--;
646 :
647 6 : hccp_dbg("qpn[%u] succ", qpn);
648 :
649 6 : return 0;
650 : }
651 :
652 2 : STATIC int RsRegisterUbSegment(int directFlag, uint64_t addr, uint64_t len)
653 : {
654 2 : struct DVattribute attr = {0};
655 2 : int ret = 0;
656 :
657 2 : if (directFlag != DIRECT_FLAG_UB) {
658 2 : return 0;
659 : }
660 :
661 0 : ret = DlDrvMemGetAttribute(addr, &attr);
662 0 : CHK_PRT_RETURN(ret != 0, hccp_err("DlDrvMemGetAttribute failed, ret:%d", ret), ret);
663 :
664 0 : if (attr.memType != DV_MEM_LOCK_DEV) { // not support host memory
665 0 : return ret;
666 : }
667 :
668 0 : ret = DlHalMemRegUbSegment(attr.devId, addr, len);
669 0 : CHK_PRT_RETURN(ret != 0, hccp_err("DlHalMemRegUbSegment failed, ret:%d devId:%u len:%u",
670 : ret, attr.devId, len), ret);
671 :
672 0 : return ret;
673 : }
674 :
675 2 : STATIC int RsUnRegisterUbSegment(int directFlag, uint64_t addr)
676 : {
677 2 : struct DVattribute attr = {0};
678 2 : int ret = 0;
679 :
680 2 : if (directFlag != DIRECT_FLAG_UB) {
681 2 : return 0;
682 : }
683 :
684 0 : ret = DlDrvMemGetAttribute(addr, &attr);
685 0 : CHK_PRT_RETURN(ret != 0, hccp_err("DrvMemGetAttribute failed, ret:%d", ret), ret);
686 :
687 0 : if (attr.memType != DV_MEM_LOCK_DEV) { // not support host memory
688 0 : return ret;
689 : }
690 :
691 0 : ret = DlHalMemUnRegUbSegment(attr.devId, addr);
692 0 : if (ret != 0) {
693 0 : hccp_err("DlHalMemUnRegUbSegment failed, ret:%d devId:%u", ret, attr.devId);
694 : }
695 :
696 0 : return ret;
697 : }
698 :
699 3 : RS_ATTRI_VISI_DEF int RsRegisterMr(unsigned int phyId, unsigned int rdevIndex, struct RdmaMrRegInfo *mrRegInfo,
700 : void **mrHandle)
701 : {
702 3 : RS_CHECK_POINTER_NULL_RETURN_INT(mrHandle);
703 :
704 : int ret;
705 : unsigned int chipId;
706 3 : struct RsRdevCb *rdevCb = NULL;
707 3 : struct ibv_mr *rsMrHandle = NULL;
708 :
709 3 : CHK_PRT_RETURN(mrRegInfo == NULL || mrRegInfo->addr == NULL || mrRegInfo->len == 0 ||
710 : phyId >= RS_MAX_DEV_NUM, hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId,
711 : RS_MAX_DEV_NUM), -EINVAL);
712 :
713 2 : hccp_info("[rs_register_mr] len[0x%llx], access[%d]", mrRegInfo->len, mrRegInfo->access);
714 :
715 2 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
716 2 : CHK_PRT_RETURN(ret, hccp_err("rs_register_mr rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret %d",
717 : phyId, ret), ret);
718 :
719 2 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
720 2 : CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d",
721 : chipId, ret), ret);
722 :
723 2 : ret = RsRegisterUbSegment(rdevCb->directFlag, (uint64_t)(uintptr_t)mrRegInfo->addr, mrRegInfo->len);
724 2 : if (ret != 0) {
725 0 : hccp_err("RsRegisterUbSegment failed, ret[%d] vendor_id[0x%x] part_id[0x%x] directFlag[%u] "
726 : "addr[0x%llx] len[0x%llx]", ret, rdevCb->deviceAttr.vendor_id, rdevCb->deviceAttr.vendor_part_id,
727 : rdevCb->directFlag, (uint64_t)(uintptr_t)mrRegInfo->addr, mrRegInfo->len);
728 0 : goto mem_reg_err;
729 : }
730 :
731 2 : *mrHandle = (void *)RsDrvMrReg(rdevCb->ibPd, mrRegInfo->addr, mrRegInfo->len, mrRegInfo->access);
732 2 : if (*mrHandle == NULL) {
733 1 : hccp_warn("rs_drv_mr_reg addr is NULL len[0x%llx] access[%d] unsuccessful errno[%d]", mrRegInfo->len,
734 : mrRegInfo->access, errno);
735 1 : goto mr_reg_err;
736 : }
737 :
738 1 : rsMrHandle = (struct ibv_mr *)*mrHandle;
739 1 : mrRegInfo->lkey = rsMrHandle->lkey;
740 1 : mrRegInfo->rkey = rsMrHandle->rkey;
741 :
742 1 : hccp_info("rs_register_mr succ");
743 1 : return ret;
744 1 : mr_reg_err:
745 1 : (void)RsUnRegisterUbSegment(rdevCb->directFlag, (uint64_t)(uintptr_t)mrRegInfo->addr);
746 1 : mem_reg_err:
747 1 : mrRegInfo->lkey = 0;
748 :
749 1 : return ret;
750 : }
751 :
752 2 : STATIC int RsInitTypicalMrCb(unsigned int phyId, struct RdmaMrRegInfo *mrRegInfo, struct RsRdevCb *devCb,
753 : struct RsMrCb *mrCb)
754 : {
755 2 : unsigned long long len = mrRegInfo->len;
756 2 : struct roce_process_sign roceSign = {0};
757 2 : char *addr = (char *)mrRegInfo->addr;
758 2 : int access = mrRegInfo->access;
759 : int ret;
760 :
761 2 : if (devCb->rsCb->hccpMode == NETWORK_PEER_ONLINE || devCb->rsCb->hccpMode == NETWORK_ONLINE) {
762 2 : mrCb->ibMr = RsDrvMrReg(devCb->ibPd, addr, len, access);
763 2 : CHK_PRT_RETURN(mrCb->ibMr == NULL, hccp_err("rs_drv_mr_reg addr is NULL len[%lld] failed", len), -EACCES);
764 : } else {
765 0 : ret = RsMrPrepareRoceSign(phyId, devCb, &roceSign);
766 0 : CHK_PRT_RETURN(ret != 0, hccp_err("RsMrPrepareRoceSign failed, ret(%d)", ret), ret);
767 0 : mrCb->ibMr = RsDrvExpMrReg(devCb->ibPd, addr, len, access, roceSign);
768 0 : CHK_PRT_RETURN(mrCb->ibMr == NULL, hccp_err("rs_drv_exp_mr_reg addr is NULL len[%lld] failed", len), -EACCES);
769 : }
770 :
771 2 : mrCb->mrInfo.addr = (uintptr_t)addr;
772 2 : mrCb->mrInfo.len = len;
773 2 : mrCb->mrInfo.rkey = mrCb->ibMr->rkey;
774 :
775 2 : RS_PTHREAD_MUTEX_LOCK(&devCb->rdevMutex);
776 2 : RsListAddTail(&mrCb->list, &devCb->typicalMrList);
777 2 : RS_PTHREAD_MUTEX_ULOCK(&devCb->rdevMutex);
778 :
779 2 : return 0;
780 : }
781 :
782 1 : RS_ATTRI_VISI_DEF int RsTypicalRegisterMrV1(unsigned int phyId, unsigned int rdevIndex,
783 : struct RdmaMrRegInfo *mrRegInfo, void **mrHandle)
784 : {
785 1 : RS_CHECK_POINTER_NULL_RETURN_INT(mrHandle);
786 :
787 1 : struct RsMrCb *typicalMrCb = NULL;
788 1 : struct RsRdevCb *rdevCb = NULL;
789 : unsigned int chipId;
790 : int ret;
791 :
792 1 : CHK_PRT_RETURN(mrRegInfo == NULL || mrRegInfo->addr == NULL || mrRegInfo->len == 0 ||
793 : phyId >= RS_MAX_DEV_NUM, hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId,
794 : RS_MAX_DEV_NUM), -EINVAL);
795 :
796 1 : hccp_info("[rs_typical_register_mr] len[0x%llx], access[%d]",
797 : mrRegInfo->len, mrRegInfo->access);
798 :
799 1 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
800 1 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_typical_register_mr rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret %d",
801 : phyId, ret), ret);
802 :
803 1 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
804 1 : CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d",
805 : chipId, ret), ret);
806 :
807 1 : ret = RsQueryMrCb(rdevCb, (uint64_t)(uintptr_t)mrRegInfo->addr, &typicalMrCb, &rdevCb->typicalMrList);
808 1 : if (ret == 0) {
809 0 : hccp_warn("typical mr already registered");
810 0 : goto found;
811 : }
812 :
813 1 : typicalMrCb = calloc(1, sizeof(struct RsMrCb));
814 1 : CHK_PRT_RETURN(typicalMrCb == NULL, hccp_err("calloc typical_mr_cb failed"), -ENOMEM);
815 1 : typicalMrCb->devCb = rdevCb;
816 :
817 1 : ret = RsInitTypicalMrCb(phyId, mrRegInfo, rdevCb, typicalMrCb);
818 1 : if (ret != 0) {
819 0 : hccp_err("rs_init_typical_mr_cb failed, devIndex[%u], ret[%d]", rdevIndex, ret);
820 0 : goto reg_err;
821 : }
822 :
823 1 : found:
824 1 : *mrHandle = typicalMrCb->ibMr;
825 1 : mrRegInfo->lkey = typicalMrCb->ibMr->lkey;
826 1 : mrRegInfo->rkey = typicalMrCb->ibMr->rkey;
827 1 : hccp_info("rs_typical_register_mr succ, state:%d", typicalMrCb->state);
828 1 : return 0;
829 :
830 0 : reg_err:
831 0 : free(typicalMrCb);
832 0 : typicalMrCb = NULL;
833 0 : return ret;
834 : }
835 :
836 1 : RS_ATTRI_VISI_DEF int RsTypicalRegisterMr(unsigned int phyId, unsigned int rdevIndex,
837 : struct RdmaMrRegInfo *mrRegInfo, void **mrHandle)
838 : {
839 1 : RS_CHECK_POINTER_NULL_RETURN_INT(mrHandle);
840 :
841 1 : struct RsMrCb *typicalMrCb = NULL;
842 1 : struct RsRdevCb *rdevCb = NULL;
843 : unsigned int chipId;
844 : int ret;
845 :
846 1 : CHK_PRT_RETURN(mrRegInfo == NULL || mrRegInfo->addr == NULL || mrRegInfo->len == 0 ||
847 : phyId >= RS_MAX_DEV_NUM, hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId,
848 : RS_MAX_DEV_NUM), -EINVAL);
849 :
850 1 : hccp_info("start register len[0x%llx], access[%d]", mrRegInfo->len, mrRegInfo->access);
851 :
852 1 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
853 1 : CHK_PRT_RETURN(ret != 0, hccp_err("rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret %d", phyId, ret), ret);
854 :
855 1 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
856 1 : CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d",
857 : chipId, ret), ret);
858 :
859 1 : typicalMrCb = calloc(1, sizeof(struct RsMrCb));
860 1 : CHK_PRT_RETURN(typicalMrCb == NULL, hccp_err("calloc typical_mr_cb failed"), -ENOMEM);
861 1 : typicalMrCb->devCb = rdevCb;
862 :
863 1 : ret = RsInitTypicalMrCb(phyId, mrRegInfo, rdevCb, typicalMrCb);
864 1 : if (ret != 0) {
865 0 : hccp_err("rs_init_typical_mr_cb failed, devIndex[%u], ret[%d]", rdevIndex, ret);
866 0 : goto reg_err;
867 : }
868 :
869 : // resv len as 1 to save addr for later unreg to query
870 1 : typicalMrCb->mrInfo.addr = (uint64_t)(uintptr_t)typicalMrCb->ibMr;
871 1 : typicalMrCb->mrInfo.len = 1U;
872 1 : *mrHandle = typicalMrCb->ibMr;
873 1 : mrRegInfo->lkey = typicalMrCb->ibMr->lkey;
874 1 : mrRegInfo->rkey = typicalMrCb->ibMr->rkey;
875 1 : hccp_info("register succ, state:%d", typicalMrCb->state);
876 1 : return 0;
877 :
878 0 : reg_err:
879 0 : free(typicalMrCb);
880 0 : typicalMrCb = NULL;
881 0 : return ret;
882 : }
883 :
884 4 : RS_ATTRI_VISI_DEF int RsRemapMr(unsigned int phyId, unsigned int rdevIndex, struct MemRemapInfo memList[],
885 : unsigned int memNum)
886 : {
887 4 : struct RsRdevCb *devCb = NULL;
888 4 : struct RsMrCb *mrCurr = NULL;
889 4 : struct RsMrCb *mrNext = NULL;
890 4 : unsigned long long addr = 0;
891 4 : bool isMemMatched = false;
892 : unsigned int chipId;
893 : unsigned int i;
894 : int ret;
895 :
896 4 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= %d, is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
897 :
898 4 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
899 4 : CHK_PRT_RETURN(ret, hccp_err("rsGetLocalDevIDByHostDevID failed, phyId:%u invalid, ret:%d", phyId, ret), ret);
900 :
901 4 : ret = RsRdev2rdevCb(chipId, rdevIndex, &devCb);
902 4 : CHK_PRT_RETURN(devCb == NULL, hccp_err("rs_rdev2rdev_cb failed, chipId:%u, ret:%d", chipId, ret), -ENODEV);
903 :
904 6 : for (i = 0; i < memNum; i++) {
905 4 : isMemMatched = false;
906 4 : addr = (uint64_t)(uintptr_t)memList[i].addr;
907 4 : RS_PTHREAD_MUTEX_LOCK(&devCb->rdevMutex);
908 4 : RS_LIST_GET_HEAD_ENTRY(mrCurr, mrNext, &devCb->typicalMrList, list, struct RsMrCb);
909 7 : for (; (&mrCurr->list) != &devCb->typicalMrList;
910 3 : mrCurr = mrNext, mrNext = list_entry(mrNext->list.next, struct RsMrCb, list)) {
911 : // mem is out range of mr, continue to find next matching mr
912 3 : if ((addr < (uint64_t)(uintptr_t)mrCurr->ibMr->addr) ||
913 3 : (memList[i].size > mrCurr->ibMr->length) ||
914 2 : (addr + memList[i].size < addr) ||
915 2 : (addr + memList[i].size > (uint64_t)(uintptr_t)mrCurr->ibMr->addr + mrCurr->ibMr->length)) {
916 1 : continue;
917 : }
918 :
919 : // each mr remap each corresponding mem
920 2 : ret = RsRoceRemapMr(mrCurr->ibMr, (struct hns_roce_mr_remap_info *)(void *)&memList[i], 1);
921 2 : if (ret != 0) {
922 0 : hccp_err("remap %u-th mem failed, ret:%d addr:0x%llx size:0x%llx", i, ret, addr, memList[i].size);
923 0 : RS_PTHREAD_MUTEX_ULOCK(&devCb->rdevMutex);
924 0 : return ret;
925 : }
926 2 : isMemMatched = true;
927 : }
928 4 : RS_PTHREAD_MUTEX_ULOCK(&devCb->rdevMutex);
929 :
930 4 : if (!isMemMatched) {
931 2 : hccp_err("find %u-th mem failed, addr:0x%llx size:0x%llx", i, addr, memList[i].size);
932 2 : return -ENODEV;
933 : }
934 2 : hccp_dbg("remap %u-th mem success, addr:0x%llx size:0x%llx", i, addr, memList[i].size);
935 : }
936 :
937 2 : return 0;
938 : }
939 :
940 2 : RS_ATTRI_VISI_DEF int RsTypicalDeregisterMr(unsigned int phyId, unsigned int devIndex, unsigned long long addr)
941 : {
942 2 : struct RsMrCb *typicalMrCb = NULL;
943 2 : struct RsRdevCb *devCb = NULL;
944 : unsigned int chipId;
945 : int ret;
946 :
947 2 : hccp_info("typical mr unreg start, addr[%llu]", addr);
948 2 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= %d, is invalid", phyId, RS_MAX_DEV_NUM),
949 : -EINVAL);
950 :
951 2 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
952 2 : CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
953 :
954 2 : ret = RsRdev2rdevCb(chipId, devIndex, &devCb);
955 2 : CHK_PRT_RETURN(ret != 0 || devCb == NULL, hccp_err("rs_rdev2rdev_cb get dev_cb failed for chip_id[%u], ret[%d]",
956 : chipId, ret), -ENODEV);
957 :
958 2 : ret = RsQueryMrCb(devCb, addr, &typicalMrCb, &devCb->typicalMrList);
959 2 : CHK_PRT_RETURN(ret, hccp_err("rs_query_mr_cb failed ret[%d]", ret), ret);
960 :
961 2 : ret = RsDrvMrDereg(typicalMrCb->ibMr);
962 2 : CHK_PRT_RETURN(ret, hccp_err("rs_drv_mr_dereg failed ret[%d]", ret), -EACCES);
963 :
964 2 : RS_PTHREAD_MUTEX_LOCK(&devCb->rdevMutex);
965 2 : RsListDel(&typicalMrCb->list);
966 2 : free(typicalMrCb);
967 2 : typicalMrCb = NULL;
968 2 : RS_PTHREAD_MUTEX_ULOCK(&devCb->rdevMutex);
969 :
970 2 : hccp_info("devIndex[%u] succ", devIndex);
971 :
972 2 : return 0;
973 : }
974 :
975 2 : RS_ATTRI_VISI_DEF int RsDeregisterMr(unsigned int phyId, unsigned int rdevIndex, void *mrHandle)
976 : {
977 2 : RS_CHECK_POINTER_NULL_RETURN_INT(mrHandle);
978 :
979 1 : struct ibv_mr *rsMrHandle = (struct ibv_mr *)mrHandle;
980 1 : uint64_t addr = (uint64_t)(uintptr_t)rsMrHandle->addr;
981 1 : struct RsRdevCb *devCb = NULL;
982 : unsigned int chipId;
983 1 : int ret = 0;
984 :
985 1 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
986 1 : CHK_PRT_RETURN(ret != 0, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
987 :
988 1 : ret = RsRdev2rdevCb(chipId, rdevIndex, &devCb);
989 1 : CHK_PRT_RETURN(ret != 0 || devCb == NULL, hccp_err("rs_rdev2rdev_cb get dev_cb failed for chip_id[%u], ret[%d]",
990 : chipId, ret), -ENODEV);
991 :
992 1 : ret = RsDrvMrDereg(rsMrHandle);
993 1 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_drv_mr_dereg failed ret[%d]", ret), -EACCES);
994 :
995 1 : ret = RsUnRegisterUbSegment(devCb->directFlag, addr);
996 1 : CHK_PRT_RETURN(ret != 0, hccp_err("RsUnRegisterUbSegment failed ret[%d], vendor_id[0x%x] part_id[0x%x]"
997 : " directFlag[%u]", ret, devCb->deviceAttr.vendor_id, devCb->deviceAttr.vendor_part_id,
998 : devCb->directFlag), ret);
999 :
1000 1 : hccp_info("rs_deregister_mr succ");
1001 1 : return 0;
1002 : }
1003 :
1004 7 : RS_ATTRI_VISI_DEF int RsSendWr(unsigned int phyId, unsigned int rdevIndex, uint32_t qpn, struct SendWr *wr,
1005 : struct SendWrRsp *wrRsp)
1006 : {
1007 : int ret;
1008 7 : struct RsQpCb *qpCb = NULL;
1009 7 : struct RsMrCb *mrCb = NULL;
1010 7 : struct RsMrCb *remMrCb = NULL;
1011 :
1012 7 : RS_CHECK_POINTER_NULL_RETURN_INT(wr);
1013 7 : RS_CHECK_POINTER_NULL_RETURN_INT(wr->bufList);
1014 7 : RS_CHECK_POINTER_NULL_RETURN_INT(wrRsp);
1015 :
1016 7 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid",
1017 : phyId, RS_MAX_DEV_NUM), -EINVAL);
1018 :
1019 7 : CHK_PRT_RETURN(wr->bufNum > MAX_SGE_NUM || wr->bufNum == 0, hccp_err("invalid buf_num[%u]!",
1020 : wr->bufNum), -EINVAL);
1021 :
1022 6 : CHK_PRT_RETURN(wr->bufList->len > RS_SGLIST_LEN_MAX || wr->bufList->len == 0, hccp_err("sg list"
1023 : "len is more than 2G, len[%u]", wr->bufList->len), -EINVAL);
1024 :
1025 5 : if (RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb)) {
1026 1 : return -EACCES;
1027 : }
1028 :
1029 4 : qpCb->sendWrNum++;
1030 :
1031 4 : hccp_info("qpn %d, bufList[0].addr is 0x%llx", qpn, wr->bufList[0].addr);
1032 4 : if (RsGetMrcb(qpCb, wr->bufList[0].addr, &mrCb, &qpCb->mrList)) {
1033 1 : hccp_err("qpn %d, bufList[0].addr[0x%llx] len[0x%x] is invalid.", qpn, wr->bufList[0].addr,
1034 : wr->bufList[0].len);
1035 1 : return -EFAULT;
1036 : }
1037 :
1038 : // send op no need to check & get remote mr
1039 3 : if (wr->op != RA_WR_SEND && wr->op != RA_WR_SEND_WITH_IMM) {
1040 3 : hccp_info("remote wr dst addr is 0x%llx", wr->dstAddr);
1041 3 : if (RsGetMrcb(qpCb, wr->dstAddr, &remMrCb, &qpCb->remMrList)) {
1042 1 : hccp_err("qpn %d, remote wr dst addr[0x%llx] len[0x%x] is invalid.", qpn, wr->dstAddr,
1043 : wr->bufList[0].len);
1044 1 : return -ENOENT;
1045 : }
1046 : }
1047 :
1048 2 : ret = RsDrvSendExp(qpCb, mrCb, remMrCb, wr, wrRsp);
1049 2 : if (ret) {
1050 0 : hccp_err("send exp failed qpn %u, ret %d", qpn, ret);
1051 : }
1052 2 : gRsSendWrNum++;
1053 2 : return ret;
1054 : }
1055 :
1056 5 : STATIC void BuildUpWrWithKey(struct WrInfo *wr, struct ibv_sge *list, struct ibv_send_wr *ibWr)
1057 : {
1058 5 : list->addr = (uintptr_t)wr->memList.addr;
1059 5 : list->length = wr->memList.len;
1060 5 : list->lkey = wr->memList.lkey;
1061 :
1062 5 : ibWr->sg_list = list;
1063 5 : ibWr->opcode = wr->op;
1064 5 : ibWr->send_flags = (unsigned int)wr->sendFlags;
1065 5 : ibWr->imm_data = htobe32(wr->immData);
1066 :
1067 5 : ibWr->num_sge = 1; /* only support one sge */
1068 5 : ibWr->wr_id = wr->wrId;
1069 5 : if (wr->op != IBV_WR_SEND && wr->op != IBV_WR_SEND_WITH_IMM) {
1070 5 : ibWr->wr.rdma.rkey = wr->rkey;
1071 5 : ibWr->wr.rdma.remote_addr = wr->dstAddr;
1072 : }
1073 5 : }
1074 :
1075 0 : STATIC void RsSendBuildUpWr(struct RsMrCb *mrCb, struct WrInfo *wr, struct ibv_sge *list,
1076 : struct ibv_send_wr *ibWr)
1077 : {
1078 0 : list->addr = (uintptr_t)wr->memList.addr;
1079 0 : list->lkey = mrCb->ibMr->lkey;
1080 0 : list->length = wr->memList.len;
1081 :
1082 0 : ibWr->sg_list = list;
1083 0 : ibWr->opcode = wr->op;
1084 0 : ibWr->imm_data = htobe32(wr->immData);
1085 0 : ibWr->send_flags = (unsigned int)wr->sendFlags;
1086 :
1087 0 : ibWr->num_sge = 1; /* only support one sge */
1088 0 : ibWr->wr_id = wr->wrId;
1089 0 : }
1090 :
1091 2 : STATIC void RsWirteAndReadBuildUpWr(struct RsMrCb *mrCb, struct RsMrCb *remMrCb,
1092 : struct WrInfo *wr, struct ibv_sge *list, struct ibv_send_wr *ibWr)
1093 : {
1094 2 : list->addr = (uintptr_t)wr->memList.addr;
1095 2 : list->length = wr->memList.len;
1096 2 : list->lkey = mrCb->ibMr->lkey;
1097 :
1098 2 : ibWr->sg_list = list;
1099 2 : ibWr->opcode = wr->op;
1100 2 : ibWr->send_flags = (unsigned int)wr->sendFlags;
1101 2 : ibWr->imm_data = htobe32(wr->immData);
1102 :
1103 2 : ibWr->num_sge = 1; /* only support one sge */
1104 2 : ibWr->wr_id = wr->wrId;
1105 2 : ibWr->wr.rdma.rkey = remMrCb->mrInfo.rkey;
1106 2 : ibWr->wr.rdma.remote_addr = wr->dstAddr;
1107 2 : }
1108 :
1109 13 : STATIC int RsBuildUpWrList(struct WrInfo *wrList, struct RsQpCb *qpCb, struct ibv_sge *list,
1110 : struct ibv_send_wr *ibWr, unsigned int i)
1111 : {
1112 13 : struct RsMrCb *mrCb = NULL;
1113 13 : struct RsMrCb *remMrCb = NULL;
1114 13 : CHK_PRT_RETURN(wrList[i].memList.len > RS_SGLIST_LEN_MAX, hccp_err("sg list len is more than 2G, len[%u]",
1115 : wrList[i].memList.len), -EINVAL);
1116 :
1117 12 : hccp_dbg("qpn %d, bufList[0].addr is 0x%llx", qpCb->ibQp->qp_num, wrList[i].memList.addr);
1118 12 : if (RsGetMrcb(qpCb, wrList[i].memList.addr, &mrCb, &qpCb->mrList)) {
1119 2 : hccp_err("qpn %d, bufList[0].addr[0x%llx] len[0x%x] is invalid.", qpCb->ibQp->qp_num,
1120 : wrList[i].memList.addr, wrList[i].memList.len);
1121 2 : return -EFAULT;
1122 : }
1123 :
1124 : // send op no need to check & get remote mr
1125 10 : if (wrList[i].op != IBV_WR_SEND && wrList[i].op != IBV_WR_SEND_WITH_IMM) {
1126 10 : hccp_dbg("remote wr dst addr is 0x%llx", wrList[i].dstAddr);
1127 10 : if (RsGetMrcb(qpCb, wrList[i].dstAddr, &remMrCb, &qpCb->remMrList)) {
1128 8 : hccp_err("qpn %d, remote wr dst addr[0x%llx] len[0x%x] is invalid.", qpCb->ibQp->qp_num,
1129 : wrList[i].dstAddr, wrList[i].memList.len);
1130 8 : return -ENOENT;
1131 : }
1132 2 : RsWirteAndReadBuildUpWr(mrCb, remMrCb, &wrList[i], &list[i], &ibWr[i]);
1133 : } else {
1134 0 : RsSendBuildUpWr(mrCb, &wrList[i], &list[i], &ibWr[i]);
1135 : }
1136 :
1137 2 : return 0;
1138 : }
1139 :
1140 6 : STATIC int RsBuildUpWrListWithKey(struct WrInfo *wrList, struct ibv_sge *list,
1141 : struct ibv_send_wr *ibWr, unsigned int i)
1142 : {
1143 6 : CHK_PRT_RETURN(wrList[i].memList.len > RS_SGLIST_LEN_MAX, hccp_err("sg list len is more than 2G, len[%u]",
1144 : wrList[i].memList.len), -EINVAL);
1145 :
1146 5 : BuildUpWrWithKey(&wrList[i], &list[i], &ibWr[i]);
1147 5 : return 0;
1148 : }
1149 :
1150 8 : STATIC int RsSendNormalWrlist(struct RsQpCb *qpCb, struct WrInfo *wrList,
1151 : unsigned int sendNum, unsigned int *completeNum, unsigned int keyFlag)
1152 : {
1153 : int ret;
1154 : unsigned int i, j;
1155 :
1156 8 : struct ibv_send_wr *badWr = NULL;
1157 8 : CHK_PRT_RETURN(sendNum > MAX_WR_NUM || sendNum == 0, hccp_err("send num[%u] is invalid!", sendNum), -EINVAL);
1158 8 : struct ibv_send_wr *ibWr = (struct ibv_send_wr *)calloc(sendNum, sizeof(struct ibv_send_wr));
1159 8 : CHK_PRT_RETURN(ibWr == NULL, hccp_err("calloc ib_wr failed!"), -ENOSPC);
1160 :
1161 8 : struct ibv_sge *list = (struct ibv_sge *)calloc(sendNum, sizeof(struct ibv_sge));
1162 8 : if (list == NULL) {
1163 0 : hccp_err("calloc list failed!");
1164 0 : ret = -ENOSPC;
1165 0 : goto alloc_fail;
1166 : }
1167 :
1168 10 : for (i = 0; i < sendNum; i++) {
1169 8 : ret = (keyFlag == 0) ? RsBuildUpWrList(wrList, qpCb, list, ibWr, i) :
1170 2 : RsBuildUpWrListWithKey(wrList, list, ibWr, i);
1171 8 : if (ret) {
1172 6 : goto input_err;
1173 : }
1174 2 : j = i + 1;
1175 2 : ibWr[i].next = (i < sendNum - 1) ? &ibWr[j] : NULL;
1176 : }
1177 :
1178 2 : ret = RsIbvPostSend(qpCb->ibQp, &ibWr[0], &badWr);
1179 2 : if (ret == 0) {
1180 2 : *completeNum = sendNum;
1181 0 : } else if (ret == -ENOMEM) {
1182 0 : *completeNum = (unsigned int)((void *)badWr - (void *)ibWr) / sizeof(struct ibv_send_wr);
1183 0 : hccp_dbg("post send wqe overflow, completeNum[%d]", *completeNum);
1184 : } else {
1185 0 : hccp_err("ibv_post_send failed, ret[%d]", ret);
1186 0 : *completeNum = 0;
1187 : }
1188 2 : qpCb->sendWrNum = qpCb->sendWrNum + (*completeNum);
1189 :
1190 8 : input_err:
1191 8 : free(list);
1192 8 : list = NULL;
1193 8 : alloc_fail:
1194 8 : free(ibWr);
1195 8 : ibWr = NULL;
1196 8 : return (ret == -ENOMEM) ? 0 : ret;
1197 : }
1198 :
1199 11 : STATIC int RsSendExpWrlist(struct RsQpCb *qpCb, struct WrInfo *wrList, unsigned int sendNum,
1200 : struct SendWrRsp *wrRsp, unsigned int *completeNum, unsigned int keyFlag)
1201 : {
1202 11 : struct ibv_post_send_ext_attr extAttr = {0};
1203 11 : struct ibv_post_send_ext_resp extRsp = {0};
1204 11 : struct ibv_send_wr *badWr = NULL;
1205 11 : struct wr_exp_rsp expRsp = {0};
1206 11 : struct ibv_send_wr ibWr = {0};
1207 11 : struct ibv_sge list = {0};
1208 : unsigned int i;
1209 11 : int ret = 0;
1210 :
1211 14 : for (i = 0; i < sendNum; i++) {
1212 : // reuse code: only need to build up one wr once a time
1213 11 : ret = (keyFlag == 0) ? RsBuildUpWrList(&wrList[i], qpCb, &list, &ibWr, 0) :
1214 4 : RsBuildUpWrListWithKey(&wrList[i], &list, &ibWr, 0);
1215 11 : if (ret != 0) {
1216 6 : hccp_err("qpn:%u key_flag:%u build_up_wr i:%u failed, ret:%d", qpCb->ibQp->qp_num, keyFlag, i, ret);
1217 6 : break;
1218 : }
1219 :
1220 5 : if (wrList[i].op == RA_WR_RDMA_WRITE_WITH_NOTIFY ||
1221 5 : wrList[i].op == RA_WR_RDMA_REDUCE_WRITE ||
1222 5 : wrList[i].op == RA_WR_RDMA_REDUCE_WRITE_WITH_NOTIFY) {
1223 1 : ibWr.imm_data = htobe32((wrList[i].aux.notifyOffset & WRITE_NOTIFY_OFFSET_MASK) |
1224 : WRITE_NOTIFY_VALUE_RECORD);
1225 1 : extAttr.reduce_op = wrList[i].aux.reduceType;
1226 1 : extAttr.reduce_type = wrList[i].aux.dataType;
1227 1 : ret = RsIbvExtPostSend(qpCb->ibQp, &ibWr, &badWr, &extAttr, &extRsp);
1228 1 : expRsp.wqe_index = extRsp.wqe_index;
1229 1 : expRsp.db_info = extRsp.db_info;
1230 1 : hccp_dbg("rs_ibv_ext_post_send, op = [%x], immData = [0x%lx], reduce_op = [%d],reduceType = [%d]",
1231 : ibWr.opcode, ibWr.imm_data, extAttr.reduce_op, extAttr.reduce_type);
1232 : } else {
1233 4 : ret = RsIbvExpPostSend(qpCb->ibQp, &ibWr, &badWr, &expRsp);
1234 4 : hccp_dbg("rs_ibv_exp_post_send, op = [%x], remoteAddr = [0x%llx], size = [%d]",
1235 : ibWr.opcode, ibWr.wr.rdma.remote_addr, ibWr.sg_list->length);
1236 : }
1237 :
1238 5 : if (ret != 0) {
1239 2 : if (ret == -ENOMEM) {
1240 1 : hccp_warn("qpn:%u rs_ibv_exp_post_send i:%u unsuccessful, ret %d", qpCb->ibQp->qp_num, i, ret);
1241 : } else {
1242 1 : hccp_err("qpn:%u rs_ibv_exp_post_send i:%u failed, ret %d", qpCb->ibQp->qp_num, i, ret);
1243 : }
1244 2 : break;
1245 : }
1246 :
1247 3 : qpCb->sendWrNum++;
1248 :
1249 3 : if (qpCb->qpMode == RA_RS_GDR_TMPL_QP_MODE) {
1250 1 : wrRsp[i].wqeTmp.sqIndex = (unsigned int)qpCb->sqIndex;
1251 1 : wrRsp[i].wqeTmp.wqeIndex = expRsp.wqe_index;
1252 2 : } else if (qpCb->qpMode == RA_RS_OP_QP_MODE ||
1253 2 : qpCb->qpMode == RA_RS_GDR_ASYN_QP_MODE) {
1254 2 : wrRsp[i].db.dbIndex = (unsigned int)qpCb->dbIndex;
1255 2 : wrRsp[i].db.dbInfo = expRsp.db_info;
1256 : }
1257 : }
1258 :
1259 11 : hccp_dbg("complete_num[%d], ret[%d]", i, ret);
1260 11 : *completeNum = i;
1261 11 : return (ret == -ENOMEM) ? 0 : ret;
1262 : }
1263 :
1264 15 : RS_ATTRI_VISI_DEF int RsSendWrlist(struct RsWrlistBaseInfo baseInfo, struct WrInfo *wrList,
1265 : unsigned int sendNum, struct SendWrRsp *wrRsp, unsigned int *completeNum)
1266 : {
1267 : int ret;
1268 : unsigned int phyId, rdevIndex, qpn;
1269 15 : struct RsQpCb *qpCb = NULL;
1270 :
1271 15 : RS_CHECK_POINTER_NULL_RETURN_INT(wrList);
1272 15 : RS_CHECK_POINTER_NULL_RETURN_INT(wrRsp);
1273 15 : CHK_PRT_RETURN(sendNum > MAX_WR_NUM || sendNum == 0 || baseInfo.phyId >= RS_MAX_DEV_NUM,
1274 : hccp_err("send_num[%u] or phyId:%u >= [%d], is invalid", sendNum, baseInfo.phyId, RS_MAX_DEV_NUM),
1275 : -EINVAL);
1276 :
1277 14 : phyId = baseInfo.phyId;
1278 14 : rdevIndex = baseInfo.rdevIndex;
1279 14 : qpn = baseInfo.qpn;
1280 :
1281 14 : CHK_PRT_RETURN(RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb), hccp_err("rs_qpn2qpcb failed, physical id[%u]",
1282 : phyId), -EACCES);
1283 :
1284 : // only allow normal qp to call this func when ai_op_support not set
1285 13 : if (qpCb->qpMode == RA_RS_NOR_QP_MODE && qpCb->aiOpSupport == 0) {
1286 6 : ret = RsSendNormalWrlist(qpCb, wrList, sendNum, completeNum, baseInfo.keyFlag);
1287 : } else {
1288 7 : ret = RsSendExpWrlist(qpCb, wrList, sendNum, wrRsp, completeNum, baseInfo.keyFlag);
1289 : }
1290 13 : return ret;
1291 : }
1292 :
1293 0 : RS_ATTRI_VISI_DEF int RsRecvWrlist(struct RsWrlistBaseInfo baseInfo, struct RecvWrlistData *wr,
1294 : unsigned int recvNum, unsigned int *completeNum)
1295 : {
1296 0 : struct RsQpCb *qpCb = NULL;
1297 :
1298 0 : RS_CHECK_POINTER_NULL_RETURN_INT(wr);
1299 0 : CHK_PRT_RETURN(recvNum > MAX_WR_NUM || recvNum == 0 || baseInfo.phyId >= RS_MAX_DEV_NUM,
1300 : hccp_err("recv_num[%u] or phyId:%u >= [%d], is invalid", recvNum, baseInfo.phyId, RS_MAX_DEV_NUM),
1301 : -EINVAL);
1302 :
1303 0 : CHK_PRT_RETURN(RsQpn2qpcb(baseInfo.phyId, baseInfo.rdevIndex, baseInfo.qpn, &qpCb),
1304 : hccp_err("rs_qpn2qpcb failed, physical id[%u]", baseInfo.phyId), -EACCES);
1305 :
1306 0 : return RsDrvPostRecv(qpCb, wr, recvNum, completeNum);
1307 : }
1308 :
1309 0 : RS_ATTRI_VISI_DEF int RsSetHostPid(uint32_t phyId, pid_t hostPid, const char *pidSign)
1310 : {
1311 : int ret;
1312 : unsigned int chipId;
1313 0 : struct rs_cb *rsCb = NULL;
1314 :
1315 0 : RS_CHECK_POINTER_NULL_RETURN_INT(pidSign);
1316 0 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs_set_host_pid rs set param error ! phyId:%u",
1317 : phyId), -EINVAL);
1318 :
1319 0 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
1320 0 : CHK_PRT_RETURN(ret, hccp_err("rs_set_host_pid rsGetLocalDevIDByHostDevID phyId invalid, ret %d", ret), ret);
1321 :
1322 0 : hccp_info("phyId[%u] host_pid[%d]", chipId, hostPid);
1323 :
1324 0 : ret = RsDev2rscb(chipId, &rsCb, false);
1325 0 : CHK_PRT_RETURN(ret, hccp_err("get rs cb failed, chipId:%u", chipId), ret);
1326 :
1327 0 : rsCb->pRsSign.tgid = hostPid;
1328 0 : ret = strcpy_s(rsCb->pRsSign.sign, PROCESS_RS_SIGN_LENGTH, pidSign);
1329 0 : CHK_PRT_RETURN(ret, hccp_err("copy sign failed, ret %d", ret), -ESAFEFUNC);
1330 :
1331 0 : return 0;
1332 : }
1333 :
1334 6 : RS_ATTRI_VISI_DEF int RsRdevGetPortStatus(unsigned int phyId, unsigned int rdevIndex, enum PortStatus *status)
1335 : {
1336 6 : struct ibv_port_attr portAttr = { 0 };
1337 6 : struct RsRdevCb *rdevCb = NULL;
1338 : unsigned int chipId;
1339 : int ret;
1340 :
1341 6 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid",
1342 : phyId, RS_MAX_DEV_NUM), -EINVAL);
1343 4 : CHK_PRT_RETURN(status == NULL, hccp_err("param err! status is NULL"), -EINVAL);
1344 :
1345 3 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
1346 3 : CHK_PRT_RETURN(ret, hccp_err("rsGetLocalDevIDByHostDevID failed, phyId[%u] invalid, ret %d", phyId, ret), ret);
1347 :
1348 3 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
1349 3 : CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d",
1350 : chipId, ret), ret);
1351 :
1352 2 : ret = RsIbvQueryPort(rdevCb->ibCtx, rdevCb->ibPort, &portAttr);
1353 2 : CHK_PRT_RETURN(ret, hccp_err("ibv_query_port failed ret[%d]", ret), -EOPENSRC);
1354 :
1355 1 : *status = portAttr.state == IBV_PORT_ACTIVE ? PORT_STATUS_ACTIVE : PORT_STATUS_DOWN;
1356 :
1357 1 : hccp_dbg("phyId:%u port_attr.state:%u status:%u", phyId, portAttr.state, *status);
1358 1 : return 0;
1359 : }
1360 :
1361 3 : RS_ATTRI_VISI_DEF int RsGetNotifyMrInfo(unsigned int phyId, unsigned int rdevIndex, struct MrInfoT *info)
1362 : {
1363 3 : struct RsRdevCb *rdevCb = NULL;
1364 3 : struct rs_cb *rsCb = NULL;
1365 : unsigned int chipId;
1366 : int ret;
1367 :
1368 3 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid",
1369 : phyId, RS_MAX_DEV_NUM), -EINVAL);
1370 :
1371 2 : CHK_PRT_RETURN(info == NULL, hccp_err("param err! info is NULL"), -EINVAL);
1372 :
1373 1 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
1374 1 : CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret:%d", phyId, ret), ret);
1375 :
1376 1 : ret = RsDev2rscb(chipId, &rsCb, false);
1377 1 : CHK_PRT_RETURN(ret, hccp_err("get rs_cb failed, ret:%d", ret), -ENODEV);
1378 :
1379 1 : ret = RsGetRdevCb(rsCb, rdevIndex, &rdevCb);
1380 1 : CHK_PRT_RETURN(ret, hccp_err("rs_get_rdev_cb failed!, ret:%d, rdevIndex:%u", ret, rdevIndex), ret);
1381 :
1382 1 : info->addr = (void *)(uintptr_t)rdevCb->notifyVaBase;
1383 1 : info->size = rdevCb->notifySize;
1384 1 : info->access = rdevCb->notifyAccess;
1385 1 : info->lkey = rdevCb->notifyMr->lkey;
1386 :
1387 1 : return 0;
1388 : }
1389 :
1390 4 : RS_ATTRI_VISI_DEF int RsNotifyCfgSet(unsigned int phyId, unsigned long long va, unsigned long long size)
1391 : {
1392 : int ret;
1393 : unsigned int chipId;
1394 4 : struct rs_cb *rsCb = NULL;
1395 :
1396 4 : RS_CHECK_POINTER_NULL_RETURN_INT((void *)(uintptr_t)va);
1397 :
1398 4 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM ||
1399 : (size != MAX_NOTIFY_SIZE_CLOUD && size != NOTIFY_NUM_MAX_V2 && size != NOTIFY_NUM_MAX_V3),
1400 : hccp_err("rs_notify_cfg_set rs set param error ! phyId[%u] size[%llu]", phyId, size), -EINVAL);
1401 :
1402 3 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
1403 3 : CHK_PRT_RETURN(ret, hccp_err("rs_notify_cfg_set phyId invalid, ret %d, phyId:%u", ret, phyId), ret);
1404 :
1405 1 : ret = RsDev2rscb(chipId, &rsCb, false);
1406 1 : CHK_PRT_RETURN(ret, hccp_err("get rs cb failed, chipId:%u", chipId), ret);
1407 :
1408 1 : rsCb->notifyVaBase = va;
1409 1 : rsCb->notifySize = size;
1410 :
1411 1 : return 0;
1412 : }
1413 :
1414 0 : RS_ATTRI_VISI_DEF int RsNotifyCfgGet(unsigned int phyId, unsigned long long *va, unsigned long long *size)
1415 : {
1416 : int ret;
1417 : unsigned int chipId;
1418 0 : struct rs_cb *rsCb = NULL;
1419 :
1420 0 : RS_CHECK_POINTER_NULL_RETURN_INT(va);
1421 0 : RS_CHECK_POINTER_NULL_RETURN_INT(size);
1422 :
1423 0 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs_notify_cfg_get rs set param error ! phyId:%u",
1424 : phyId), -EINVAL);
1425 :
1426 0 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
1427 0 : CHK_PRT_RETURN(ret, hccp_err("rs_notify_cfg_get phyId invalid, ret %d, phyId:%u", ret, phyId), ret);
1428 :
1429 0 : ret = RsDev2rscb(chipId, &rsCb, false);
1430 0 : CHK_PRT_RETURN(ret, hccp_err("get rs cb failed, chipId:%u", chipId), ret);
1431 :
1432 0 : *va = rsCb->notifyVaBase;
1433 0 : *size = rsCb->notifySize;
1434 :
1435 0 : return 0;
1436 : }
1437 :
1438 6 : RS_ATTRI_VISI_DEF int RsSetTsqpDepth(unsigned int phyId, unsigned int rdevIndex, unsigned int tempDepth,
1439 : unsigned int *qpNum)
1440 : {
1441 : #ifdef CUSTOM_INTERFACE
1442 6 : struct RsRdevCb *rdevCb = NULL;
1443 6 : unsigned int sqDepth = 0;
1444 6 : unsigned int chipId = 0;
1445 : int ret;
1446 :
1447 6 : if (!RsIsCustomInterfaceSupported()) {
1448 0 : return 0;
1449 : }
1450 6 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs_set_tsqp_depth param error ! phyId:%d", phyId), -EINVAL);
1451 :
1452 5 : CHK_PRT_RETURN(qpNum == NULL, hccp_err("rs_set_tsqp_depth qp_num is NULL, param error!"), -EINVAL);
1453 :
1454 4 : CHK_PRT_RETURN(tempDepth < RS_MIN_TEMPTH_DEPTH || tempDepth > RS_MAX_TEMPTH_DEPTH, hccp_err("param error!"
1455 : "temp_depth[%u] can not smaller than [%d] or bigerr than [%d]", tempDepth, RS_MIN_TEMPTH_DEPTH,
1456 : RS_MAX_TEMPTH_DEPTH), -EINVAL);
1457 :
1458 3 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
1459 3 : CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
1460 :
1461 2 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
1462 2 : CHK_PRT_RETURN(ret || rdevCb == NULL, hccp_err("rs_set_tsqp_depth rs_rdev2rdev_cb for chip_id[%u]"
1463 : "failed, ret %d", chipId, ret), ret);
1464 :
1465 1 : ret = RsRoceSetTsqpDepth(rdevCb->devName, rdevIndex, tempDepth, qpNum, &sqDepth);
1466 1 : CHK_PRT_RETURN(ret, hccp_err("rs_roce_set_tsqp_depth failed, ret %d, devName[%s]", ret, rdevCb->devName), ret);
1467 :
1468 0 : rdevCb->txDepth = sqDepth;
1469 0 : rdevCb->rxDepth = sqDepth;
1470 0 : rdevCb->qpMaxNum = *qpNum;
1471 : #endif
1472 0 : return 0;
1473 : }
1474 :
1475 5 : RS_ATTRI_VISI_DEF int RsGetTsqpDepth(unsigned int phyId, unsigned int rdevIndex, unsigned int *tempDepth,
1476 : unsigned int *qpNum)
1477 : {
1478 : #ifdef CUSTOM_INTERFACE
1479 5 : struct RsRdevCb *rdevCb = NULL;
1480 5 : unsigned int sqDepth = 0;
1481 5 : unsigned int chipId = 0;
1482 : int ret;
1483 :
1484 5 : if (!RsIsCustomInterfaceSupported()) {
1485 0 : return 0;
1486 : }
1487 5 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("param error ! phyId:%d", phyId), -EINVAL);
1488 :
1489 4 : CHK_PRT_RETURN(tempDepth == NULL || qpNum == NULL, hccp_err("temp_depth or qp_num is NULL,"
1490 : "param error!"), -EINVAL);
1491 :
1492 3 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
1493 3 : CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
1494 :
1495 2 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
1496 2 : CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_get_tsqp_depth rs_rdev2rdev_cb for chip_id[%u]"
1497 : "failed, ret %d", chipId, ret), ret);
1498 :
1499 1 : ret = RsRoceGetTsqpDepth(rdevCb->devName, rdevIndex, tempDepth, qpNum, &sqDepth);
1500 1 : CHK_PRT_RETURN(ret, hccp_err("rs_roce_get_tsqp_depth failed, ret %d, devName[%s]", ret, rdevCb->devName), ret);
1501 : #endif
1502 0 : return 0;
1503 : }
1504 :
1505 44 : STATIC void RsSetQpDepthAttr(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb, struct RsQpNorm *qpNorm)
1506 : {
1507 44 : if (qpCb->qpMode == RA_RS_GDR_TMPL_QP_MODE) {
1508 40 : qpCb->txDepth = rdevCb->txDepth;
1509 40 : qpCb->rxDepth = rdevCb->rxDepth;
1510 : } else {
1511 4 : if (rdevCb->rsCb->hccpMode == NETWORK_OFFLINE) {
1512 2 : qpCb->txDepth = RS_QP_TX_DEPTH_OFFLINE;
1513 2 : qpCb->rxDepth = RS_QP_RX_DEPTH_OFFLINE;
1514 : } else {
1515 2 : qpCb->txDepth = RS_QP_TX_DEPTH_ONLINE;
1516 2 : qpCb->rxDepth = RS_QP_RX_DEPTH_ONLINE;
1517 : }
1518 : }
1519 :
1520 44 : if (qpNorm->isExp != 0 && qpNorm->qpMode != RA_RS_NOR_QP_MODE) {
1521 42 : if (rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
1522 2 : qpCb->txDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH_PEER_ONLINE : qpCb->txDepth;
1523 2 : qpCb->rxDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH_PEER_ONLINE : qpCb->rxDepth;
1524 : } else {
1525 40 : qpCb->txDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE && qpCb->qpMode != RA_RS_GDR_ASYN_QP_MODE)
1526 : ? RS_QP_32K_DEPTH
1527 40 : : qpCb->txDepth;
1528 : }
1529 42 : qpCb->sendSgeNum = 1;
1530 42 : qpCb->recvSgeNum = 1;
1531 : } else {
1532 2 : if (rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
1533 0 : qpCb->txDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH_PEER_ONLINE : qpCb->txDepth;
1534 0 : qpCb->rxDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH_PEER_ONLINE : qpCb->rxDepth;
1535 : } else {
1536 2 : qpCb->txDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH : qpCb->txDepth;
1537 2 : qpCb->rxDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH : qpCb->rxDepth;
1538 : }
1539 2 : qpCb->sendSgeNum = RS_QP_ATTR_MAX_SEND_SGE;
1540 2 : qpCb->recvSgeNum = 1;
1541 : }
1542 44 : }
1543 :
1544 44 : STATIC int RsQpcbInit(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb, struct RsQpNorm *qpNorm)
1545 : {
1546 : #define RS_DRV_CQ_DEPTH 16384
1547 : #define RS_DRV_CQ_128_DEPTH 128
1548 : #define RS_DRV_CQ_8K_DEPTH 8192
1549 : #define RS_DRV_CQ_32K_DEPTH 32768
1550 44 : int qpMode = qpNorm->qpMode;
1551 : int ret;
1552 :
1553 44 : qpCb->rdevCb = rdevCb;
1554 44 : RS_INIT_LIST_HEAD(&qpCb->mrList);
1555 44 : RS_INIT_LIST_HEAD(&qpCb->remMrList);
1556 :
1557 44 : qpCb->qpMode = qpMode;
1558 44 : qpCb->eqNum = 0;
1559 44 : qpCb->numRecvCqEvents = 0;
1560 44 : qpCb->numSendCqEvents = 0;
1561 44 : qpCb->state = RS_QP_STATUS_DISCONNECT;
1562 44 : qpCb->ibPd = rdevCb->ibPd;
1563 :
1564 : // cq attr
1565 44 : if (qpNorm->isExt == 1) {
1566 : // update TEMP & ASYN mode cq depth from 32K to 8K due to memory issue
1567 2 : qpCb->sendCqDepth = (qpMode != RA_RS_GDR_TMPL_QP_MODE && qpMode != RA_RS_GDR_ASYN_QP_MODE)
1568 4 : ? RS_DRV_CQ_32K_DEPTH : RS_DRV_CQ_8K_DEPTH;
1569 2 : qpCb->recvCqDepth = RS_DRV_CQ_128_DEPTH;
1570 : } else {
1571 42 : qpCb->sendCqDepth = RS_DRV_CQ_DEPTH;
1572 42 : qpCb->recvCqDepth = RS_DRV_CQ_DEPTH;
1573 : }
1574 :
1575 : // qp attr
1576 44 : RsSetQpDepthAttr(rdevCb, qpCb, qpNorm);
1577 :
1578 44 : qpCb->memAlign = qpNorm->memAlign;
1579 :
1580 44 : qpCb->channel = RsIbvCreateCompChannel(rdevCb->ibCtx);
1581 44 : CHK_PRT_RETURN(qpCb->channel == NULL, hccp_err("ibv_create_comp_channel failed! errno(%d)", errno), -EINVAL);
1582 43 : qpCb->qosAttr.tc = (RS_ROCE_DSCP_33 & RS_DSCP_MASK) << RS_DSCP_OFF;
1583 43 : qpCb->qosAttr.sl = RS_ROCE_4_SL;
1584 43 : qpCb->timeout = RS_QP_ATTR_TIMEOUT;
1585 43 : qpCb->retryCnt = RS_QP_ATTR_RETRY_CNT;
1586 :
1587 43 : ret = RsEpollCtl(rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_ADD, qpCb->channel->fd, EPOLLIN | EPOLLRDHUP);
1588 : #ifndef CA_CONFIG_LLT
1589 : if (ret) {
1590 : RsIbvDestroyCompChannel(qpCb->channel);
1591 : hccp_err("add channel fd failed ret %d", ret);
1592 : return ret;
1593 : }
1594 : #endif
1595 43 : return 0;
1596 : }
1597 :
1598 47 : STATIC int RsQpcbDeinit(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb)
1599 : {
1600 : int ret;
1601 :
1602 47 : if (qpCb == NULL || qpCb->channel == NULL) {
1603 0 : hccp_err("qp_cb or qp_cb->channel is NULL!");
1604 0 : return -EINVAL;
1605 : }
1606 :
1607 47 : ret = RsEpollCtl(rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_DEL, qpCb->channel->fd, EPOLLIN | EPOLLRDHUP);
1608 : #ifndef CA_CONFIG_LLT
1609 : if (ret) {
1610 : hccp_err("del channel fd failed ret %d", ret);
1611 : }
1612 : #endif
1613 :
1614 47 : if (qpCb->channel != NULL) {
1615 47 : RsIbvDestroyCompChannel(qpCb->channel);
1616 47 : qpCb->channel = NULL;
1617 : }
1618 : #ifndef CA_CONFIG_LLT
1619 : return ret;
1620 : #else
1621 47 : return 0;
1622 : #endif
1623 : }
1624 :
1625 31 : STATIC int RsQpNotifyMr(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb, uint32_t *qpn)
1626 : {
1627 : int ret;
1628 31 : struct RsMrCb *notifyMrNode = NULL;
1629 :
1630 31 : ret = RsCallocMr(1, ¬ifyMrNode);
1631 31 : CHK_PRT_RETURN(ret, hccp_err("notify_mr_cb malloc failed"), ret);
1632 :
1633 31 : RS_PTHREAD_MUTEX_LOCK(&rdevCb->rdevMutex);
1634 31 : RsListAddTail(&qpCb->list, &rdevCb->qpList);
1635 31 : RS_PTHREAD_MUTEX_ULOCK(&rdevCb->rdevMutex);
1636 :
1637 31 : if (rdevCb->notifyType != NO_USE) {
1638 31 : notifyMrNode->qpCb = qpCb;
1639 31 : notifyMrNode->ibMr = rdevCb->notifyMr;
1640 31 : notifyMrNode->mrInfo.addr = rdevCb->notifyVaBase;
1641 31 : notifyMrNode->mrInfo.len = rdevCb->notifySize;
1642 31 : notifyMrNode->mrInfo.rkey = notifyMrNode->ibMr->rkey;
1643 : } else {
1644 0 : notifyMrNode->qpCb = qpCb;
1645 0 : notifyMrNode->ibMr = NULL;
1646 : }
1647 :
1648 31 : RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
1649 31 : RsListAddTail(¬ifyMrNode->list, &qpCb->mrList);
1650 31 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
1651 31 : rdevCb->qpCnt++;
1652 31 : *qpn = qpCb->ibQp->qp_num;
1653 :
1654 31 : hccp_info("rs qp %d create OK!", *qpn);
1655 :
1656 31 : return 0;
1657 : }
1658 :
1659 52 : STATIC int RsQpQueryInfo(unsigned int phyId, unsigned int rdevIndex, struct RsRdevCb **rdevCb, int qpMode)
1660 : {
1661 : int ret;
1662 : unsigned int chipId;
1663 52 : struct rs_cb *rsCb = NULL;
1664 :
1665 52 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs_qp_query_info rs set param error! phyId:%u",
1666 : phyId), -EINVAL);
1667 :
1668 52 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
1669 52 : CHK_PRT_RETURN(ret, hccp_err("rs_qp_query_info phyId[%u] invalid, ret:%d", phyId, ret), ret);
1670 :
1671 51 : ret = RsDev2rscb(chipId, &rsCb, false);
1672 51 : CHK_PRT_RETURN(ret, hccp_err("rs_qp_query_info get rs_cb failed, ret:%d", ret), -ENODEV);
1673 :
1674 51 : ret = RsGetRdevCb(rsCb, rdevIndex, rdevCb);
1675 51 : CHK_PRT_RETURN(ret, hccp_err("rs_get_rdev_cb failed! ret:%d, rdevIndex:%u", ret, rdevIndex), ret);
1676 :
1677 51 : if (qpMode == RA_RS_GDR_TMPL_QP_MODE) {
1678 45 : CHK_PRT_RETURN((*rdevCb)->qpCnt >= (*rdevCb)->qpMaxNum, hccp_err("Exceeded the maximum QP limit(%u)",
1679 : (*rdevCb)->qpMaxNum), -EINVAL);
1680 : } else {
1681 6 : CHK_PRT_RETURN((*rdevCb)->qpCnt >= RS_QP_NUM_MAX, hccp_err("Exceeded the maximum QP limit(%u)",
1682 : (*rdevCb)->qpCnt), -EINVAL);
1683 : }
1684 :
1685 49 : return 0;
1686 : }
1687 :
1688 49 : STATIC int RsInitMemPool(struct RsQpCb *qpCb)
1689 : {
1690 49 : struct roce_mem_cq_qp_attr memAttr = {0};
1691 : int ret;
1692 :
1693 49 : if ((qpCb->qpMode != RA_RS_OP_QP_MODE && qpCb->qpMode != RA_RS_OP_QP_MODE_EXT) ||
1694 4 : qpCb->memAlign != LITE_ALIGN_2MB) {
1695 48 : return 0;
1696 : }
1697 :
1698 : // init mem_pool and store mem_data in mem_resp
1699 1 : memAttr.mem_align = qpCb->memAlign;
1700 1 : memAttr.send_qp_depth = qpCb->txDepth;
1701 1 : memAttr.send_cq_depth = (unsigned int)qpCb->sendCqDepth;
1702 1 : memAttr.send_sge_num = qpCb->sendSgeNum;
1703 1 : memAttr.recv_qp_depth = qpCb->rxDepth;
1704 1 : memAttr.recv_cq_depth = (unsigned int)qpCb->recvCqDepth;
1705 1 : memAttr.recv_sge_num = qpCb->recvSgeNum;
1706 1 : memAttr.use_resv_mem = qpCb->useResvMem;
1707 1 : memAttr.resv_mem_pool_id = qpCb->resvMemPoolId;
1708 1 : memAttr.ctx = qpCb->rdevCb->ibCtx;
1709 :
1710 1 : ret = RsRoceInitMemPool(&memAttr, &qpCb->memResp.memData, qpCb->rdevCb->rsCb->chipId);
1711 1 : if (ret != 0) {
1712 1 : hccp_err("rs_roce_init_mem_pool failed, ret=%d, chipId=%u", ret, qpCb->rdevCb->rsCb->chipId);
1713 : }
1714 1 : return ret;
1715 : }
1716 :
1717 49 : STATIC void RsDeinitMemPool(struct RsQpCb *qpCb)
1718 : {
1719 49 : if ((qpCb->qpMode != RA_RS_OP_QP_MODE && qpCb->qpMode != RA_RS_OP_QP_MODE_EXT) ||
1720 4 : qpCb->memAlign != LITE_ALIGN_2MB) {
1721 48 : return;
1722 : }
1723 :
1724 1 : (void)RsRoceDeinitMemPool(qpCb->memResp.memData.mem_idx);
1725 : }
1726 :
1727 45 : STATIC int RsAllocQpcb(struct RsRdevCb *rdevCb, struct RsQpCb **qpCb, struct RsQpNorm *qpNorm)
1728 : {
1729 : int ret;
1730 :
1731 45 : ret = RsCallocQpcb(1, qpCb);
1732 45 : CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d errno:%d", ret, errno), -ENOMEM);
1733 :
1734 44 : ret = pthread_mutex_init(&(*qpCb)->qpMutex, NULL);
1735 44 : if (ret) {
1736 0 : hccp_err("pthread_mutex_init failed, ret %d", ret);
1737 0 : goto qp_mutex_init_err;
1738 : }
1739 :
1740 44 : ret = pthread_mutex_init(&(*qpCb)->cqeErrInfo.mutex, NULL);
1741 44 : if (ret) {
1742 0 : hccp_err("pthread_mutex_init failed, ret %d", ret);
1743 0 : goto cqe_mutex_init_err;
1744 : }
1745 :
1746 44 : ret = RsQpcbInit(rdevCb, *qpCb, qpNorm);
1747 44 : if (ret) {
1748 1 : hccp_err("create qp tx rx failed ret %d", ret);
1749 1 : goto rs_qpcb_init_err;
1750 : }
1751 :
1752 43 : ret = RsInitMemPool(*qpCb);
1753 43 : if (ret) {
1754 0 : hccp_err("init mem pool failed ret %d", ret);
1755 0 : goto rs_init_mem_err;
1756 : }
1757 :
1758 43 : ret = RsDrvCreateCq(*qpCb, qpNorm->isExt);
1759 43 : if (ret) {
1760 1 : hccp_err("create cq failed ret %d", ret);
1761 1 : goto create_cq_err;
1762 : }
1763 :
1764 42 : return 0;
1765 :
1766 1 : create_cq_err:
1767 1 : RsDeinitMemPool(*qpCb);
1768 :
1769 1 : rs_init_mem_err:
1770 1 : RsQpcbDeinit(rdevCb, *qpCb);
1771 :
1772 2 : rs_qpcb_init_err:
1773 2 : pthread_mutex_destroy(&(*qpCb)->cqeErrInfo.mutex);
1774 :
1775 2 : cqe_mutex_init_err:
1776 2 : pthread_mutex_destroy(&(*qpCb)->qpMutex);
1777 :
1778 2 : qp_mutex_init_err:
1779 2 : free(*qpCb);
1780 2 : *qpCb = NULL;
1781 :
1782 2 : return ret;
1783 : }
1784 :
1785 15 : STATIC void RsFreeQpcb(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb)
1786 : {
1787 15 : RsDrvDestroyCq(qpCb);
1788 15 : RsDeinitMemPool(qpCb);
1789 15 : (void)RsQpcbDeinit(rdevCb, qpCb);
1790 15 : pthread_mutex_destroy(&qpCb->cqeErrInfo.mutex);
1791 15 : pthread_mutex_destroy(&qpCb->qpMutex);
1792 15 : free(qpCb);
1793 15 : qpCb = NULL;
1794 15 : }
1795 :
1796 47 : RS_ATTRI_VISI_DEF int RsQpCreate(unsigned int phyId, unsigned int rdevIndex, struct RsQpNorm qpNorm,
1797 : struct RsQpResp *qpResp)
1798 : {
1799 47 : struct RsRdevCb *rdevCb = NULL;
1800 47 : struct RsQpCb *qpCb = NULL;
1801 : int ret;
1802 :
1803 47 : RS_QP_PARA_CHECK(phyId);
1804 46 : CHK_PRT_RETURN(qpResp == NULL, hccp_err("qp_resp is NULL!"), -EINVAL);
1805 :
1806 46 : ret = RsQpQueryInfo(phyId, rdevIndex, &rdevCb, qpNorm.qpMode);
1807 46 : CHK_PRT_RETURN(ret, hccp_err("query qp info failed:%d", ret), ret);
1808 :
1809 45 : ret = RsAllocQpcb(rdevCb, &qpCb, &qpNorm);
1810 45 : CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d", ret), ret);
1811 :
1812 42 : ret = RsDrvQpCreate(qpCb, &qpNorm);
1813 42 : if (ret) {
1814 14 : hccp_err("create drv qp create failed:%d", ret);
1815 14 : goto create_qp_err;
1816 : }
1817 :
1818 28 : ret = ibv_req_notify_cq(qpCb->ibSendCq, 0);
1819 28 : if (ret) {
1820 1 : hccp_err("Couldn't request send CQ notification, ret:%d", ret);
1821 1 : ret = -EOPENSRC;
1822 1 : goto ret_noritfy_cq;
1823 : }
1824 :
1825 27 : ret = ibv_req_notify_cq(qpCb->ibRecvCq, 0);
1826 27 : if (ret) {
1827 0 : hccp_err("Couldn't request recv CQ notification, ret:%d", ret);
1828 0 : ret = -EOPENSRC;
1829 0 : goto ret_noritfy_cq;
1830 : }
1831 :
1832 27 : ret = RsQpNotifyMr(rdevCb, qpCb, &qpResp->qpn); // alloc mr
1833 27 : if (ret) {
1834 0 : hccp_err("store qp notify mr failed:%d", ret);
1835 0 : goto ret_noritfy_cq;
1836 : }
1837 :
1838 27 : if (qpNorm.isExp) {
1839 25 : qpCb->isExp = RS_IS_EXP;
1840 : } else {
1841 2 : qpCb->isExp = RS_NOT_EXP;
1842 : }
1843 :
1844 27 : qpResp->qpn = (unsigned int)qpCb->qpInfoLo.qpn;
1845 27 : qpResp->gidIdx = (unsigned int)qpCb->qpInfoLo.gidIdx;
1846 27 : qpResp->psn = (unsigned int)qpCb->qpInfoLo.psn;
1847 27 : qpResp->gid = qpCb->qpInfoLo.gid;
1848 :
1849 27 : return 0;
1850 :
1851 1 : ret_noritfy_cq:
1852 1 : RsDrvQpDestroy(qpCb);
1853 :
1854 15 : create_qp_err:
1855 15 : RsFreeQpcb(rdevCb, qpCb);
1856 15 : return ret;
1857 : }
1858 :
1859 4 : STATIC int RsQpcbInitWithAttrs(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb,
1860 : struct RsQpNormWithAttrs *qpNorm)
1861 : {
1862 : int ret;
1863 :
1864 4 : qpCb->rdevCb = rdevCb;
1865 4 : RS_INIT_LIST_HEAD(&qpCb->mrList);
1866 4 : RS_INIT_LIST_HEAD(&qpCb->remMrList);
1867 :
1868 4 : qpCb->qpMode = qpNorm->extAttrs.qpMode;
1869 4 : qpCb->numRecvCqEvents = 0;
1870 4 : qpCb->numSendCqEvents = 0;
1871 4 : qpCb->state = RS_QP_STATUS_DISCONNECT;
1872 4 : qpCb->ibPd = rdevCb->ibPd;
1873 :
1874 4 : qpCb->txDepth = qpNorm->extAttrs.qpAttr.cap.max_send_wr;
1875 4 : qpCb->rxDepth = qpNorm->extAttrs.qpAttr.cap.max_send_wr;
1876 4 : qpCb->sendSgeNum = qpNorm->extAttrs.qpAttr.cap.max_send_sge;
1877 4 : qpCb->recvSgeNum = qpNorm->extAttrs.qpAttr.cap.max_recv_sge;
1878 4 : qpCb->sendCqDepth = qpNorm->extAttrs.cqAttr.sendCqDepth;
1879 4 : qpCb->recvCqDepth = qpNorm->extAttrs.cqAttr.recvCqDepth;
1880 4 : qpCb->memAlign = qpNorm->extAttrs.memAlign;
1881 :
1882 4 : qpCb->channel = RsIbvCreateCompChannel(rdevCb->ibCtx);
1883 4 : CHK_PRT_RETURN(qpCb->channel == NULL, hccp_err("ibv_create_comp_channel failed! errno(%d)", errno), -EINVAL);
1884 4 : qpCb->qosAttr.tc = (RS_ROCE_DSCP_33 & RS_DSCP_MASK) << RS_DSCP_OFF;
1885 4 : qpCb->qosAttr.sl = RS_ROCE_4_SL;
1886 4 : qpCb->timeout = RS_QP_ATTR_TIMEOUT;
1887 4 : qpCb->retryCnt = RS_QP_ATTR_RETRY_CNT;
1888 :
1889 4 : qpCb->udpSport = qpNorm->extAttrs.udpSport;
1890 :
1891 4 : qpCb->aiOpSupport = qpNorm->aiOpSupport;
1892 4 : qpCb->grpId = rdevCb->rsCb->grpId;
1893 4 : qpCb->cqCstmFlag = qpNorm->extAttrs.dataPlaneFlag.bs.cqCstm;
1894 4 : qpCb->useResvMem = qpNorm->extAttrs.cstmFlag.bs.useResvMem;
1895 4 : qpCb->resvMemPoolId = qpNorm->extAttrs.resvMemPoolId;
1896 :
1897 4 : ret = RsEpollCtl(rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_ADD, qpCb->channel->fd, EPOLLIN | EPOLLRDHUP);
1898 : #ifndef CA_CONFIG_LLT
1899 : if (ret) {
1900 : RsIbvDestroyCompChannel(qpCb->channel);
1901 : hccp_err("add channel fd failed ret %d", ret);
1902 : return ret;
1903 : }
1904 : #endif
1905 4 : return 0;
1906 : }
1907 :
1908 4 : STATIC int RsAllocQpcbWithAttrs(struct RsRdevCb *rdevCb, struct RsQpCb **qpCb,
1909 : struct RsQpNormWithAttrs *qpNorm)
1910 : {
1911 : int ret;
1912 :
1913 4 : ret = RsCallocQpcb(1, qpCb);
1914 4 : CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d errno:%d", ret, errno), -ENOMEM);
1915 :
1916 4 : ret = pthread_mutex_init(&(*qpCb)->qpMutex, NULL);
1917 4 : if (ret) {
1918 0 : hccp_err("pthread_mutex_init failed, ret %d", ret);
1919 0 : goto qp_mutex_init_err;
1920 : }
1921 :
1922 4 : ret = pthread_mutex_init(&(*qpCb)->cqeErrInfo.mutex, NULL);
1923 4 : if (ret) {
1924 0 : hccp_err("pthread_mutex_init failed, ret %d", ret);
1925 0 : goto cqe_mutex_init_err;
1926 : }
1927 :
1928 4 : ret = RsQpcbInitWithAttrs(rdevCb, *qpCb, qpNorm);
1929 4 : if (ret) {
1930 0 : hccp_err("create qp tx rx failed ret %d", ret);
1931 0 : goto rs_qpcb_init_err;
1932 : }
1933 :
1934 4 : ret = RsInitMemPool(*qpCb);
1935 4 : if (ret) {
1936 0 : hccp_err("init mem pool failed ret %d", ret);
1937 0 : goto rs_init_mem_err;
1938 : }
1939 :
1940 4 : ret = RsDrvCreateCqWithAttrs(*qpCb, qpNorm->isExt, &qpNorm->extAttrs.cqAttr);
1941 4 : if (ret) {
1942 0 : hccp_err("create cq failed ret %d", ret);
1943 0 : goto create_cq_err;
1944 : }
1945 :
1946 4 : return 0;
1947 :
1948 0 : create_cq_err:
1949 0 : RsDeinitMemPool(*qpCb);
1950 :
1951 0 : rs_init_mem_err:
1952 0 : RsQpcbDeinit(rdevCb, *qpCb);
1953 :
1954 0 : rs_qpcb_init_err:
1955 0 : pthread_mutex_destroy(&(*qpCb)->cqeErrInfo.mutex);
1956 :
1957 0 : cqe_mutex_init_err:
1958 0 : pthread_mutex_destroy(&(*qpCb)->qpMutex);
1959 :
1960 0 : qp_mutex_init_err:
1961 0 : free(*qpCb);
1962 0 : *qpCb = NULL;
1963 :
1964 0 : return ret;
1965 : }
1966 :
1967 9 : STATIC int RsQpCheckQpNorm(struct RsQpNormWithAttrs *qpNorm, int *qpMode)
1968 : {
1969 9 : CHK_PRT_RETURN(qpNorm == NULL, hccp_err("qp_norm is NULL!"), -EINVAL);
1970 8 : CHK_PRT_RETURN(qpNorm->extAttrs.version != QP_CREATE_WITH_ATTR_VERSION,
1971 : hccp_err("attr version[%d] mismatch, expect [%d]", qpNorm->extAttrs.version, QP_CREATE_WITH_ATTR_VERSION),
1972 : -EINVAL);
1973 :
1974 7 : *qpMode = qpNorm->extAttrs.qpMode;
1975 7 : if (*qpMode < 0 || *qpMode >= RA_RS_ERR_QP_MODE) {
1976 1 : hccp_err("qp_mode[%d] must greater or equal to 0 and less than %d", *qpMode, RA_RS_ERR_QP_MODE);
1977 1 : return -EINVAL;
1978 : }
1979 :
1980 6 : if (*qpMode == RA_RS_OP_QP_MODE_EXT) {
1981 1 : *qpMode = RA_RS_OP_QP_MODE;
1982 : }
1983 :
1984 6 : qpNorm->extAttrs.qpMode = *qpMode;
1985 6 : return 0;
1986 : }
1987 :
1988 : #ifdef CUSTOM_INTERFACE
1989 8 : STATIC void RsQpPrepareCqDataPlaneInfo(struct ibv_cq *ibCq, struct AiDataPlaneCq *dataPlaneCq)
1990 : {
1991 8 : struct hns_roce_cq_data_plane_info cqInfo = {0};
1992 :
1993 8 : (void)RsRoceGetCqDataPlaneInfo(ibCq, &cqInfo);
1994 8 : dataPlaneCq->cqn = cqInfo.cqn;
1995 8 : dataPlaneCq->bufAddr = cqInfo.buf_addr;
1996 8 : dataPlaneCq->cqeSize = cqInfo.cqe_size;
1997 8 : dataPlaneCq->depth = cqInfo.depth;
1998 8 : dataPlaneCq->headAddr = cqInfo.head_addr;
1999 8 : dataPlaneCq->tailAddr = cqInfo.tail_addr;
2000 8 : dataPlaneCq->swdbAddr = cqInfo.swdb_addr;
2001 8 : dataPlaneCq->dbReg = cqInfo.db_reg;
2002 8 : hccp_info("cqn:%u buf_addr:0x%llx cqe_size:%u depth:%u head_addr:0x%llx tail_addr:0x%llx swdb_addr:0x%llx",
2003 : dataPlaneCq->cqn, dataPlaneCq->bufAddr, dataPlaneCq->cqeSize, dataPlaneCq->depth,
2004 : dataPlaneCq->headAddr, dataPlaneCq->tailAddr, dataPlaneCq->swdbAddr);
2005 8 : }
2006 :
2007 8 : STATIC void RsQpPrepareWqDataPlaneInfo(struct hns_roce_wq_data_plane_info *wqInfo,
2008 : struct AiDataPlaneWq *dataPlaneWq)
2009 : {
2010 8 : dataPlaneWq->wqn = wqInfo->wqn;
2011 8 : dataPlaneWq->bufAddr = wqInfo->buf_addr;
2012 8 : dataPlaneWq->wqebbSize = wqInfo->wqebb_size;
2013 8 : dataPlaneWq->depth = wqInfo->depth;
2014 8 : dataPlaneWq->headAddr = wqInfo->head_addr;
2015 8 : dataPlaneWq->tailAddr = wqInfo->tail_addr;
2016 8 : dataPlaneWq->swdbAddr = wqInfo->swdb_addr;
2017 8 : dataPlaneWq->dbReg = wqInfo->db_reg;
2018 8 : hccp_info("wqn:%u buf_addr:0x%llx wqebb_size:%u depth:%u head_addr:%u tail_addr:%u swdb_addr:0x%llx",
2019 : dataPlaneWq->wqn, dataPlaneWq->bufAddr, dataPlaneWq->wqebbSize, dataPlaneWq->depth,
2020 : dataPlaneWq->headAddr, dataPlaneWq->tailAddr, dataPlaneWq->swdbAddr);
2021 8 : }
2022 :
2023 4 : STATIC void RsQpPrepareQpDataPlaneInfo(struct ibv_qp *ibQp, struct AiDataPlaneWq *dataPlaneSq,
2024 : struct AiDataPlaneWq *dataPlaneRq)
2025 : {
2026 4 : struct hns_roce_qp_data_plane_info qpInfo = {0};
2027 :
2028 4 : (void)RsRoceGetQpDataPlaneInfo(ibQp, &qpInfo);
2029 4 : RsQpPrepareWqDataPlaneInfo(&qpInfo.sq, dataPlaneSq);
2030 4 : RsQpPrepareWqDataPlaneInfo(&qpInfo.rq, dataPlaneRq);
2031 4 : }
2032 :
2033 4 : STATIC void RsQpPrepareDataPlaneInfo(struct RsQpNormWithAttrs *qpNorm, struct RsQpCb *qpCb,
2034 : struct RsQpRespWithAttrs *qpResp)
2035 : {
2036 : // skip to prepare cq data plane info
2037 4 : if (qpNorm->extAttrs.dataPlaneFlag.bs.cqCstm != 0) {
2038 4 : qpResp->aiScqAddr = (unsigned long long)(uintptr_t)qpCb->ibSendCq;
2039 4 : qpResp->aiRcqAddr = (unsigned long long)(uintptr_t)qpCb->ibRecvCq;
2040 4 : RsQpPrepareCqDataPlaneInfo(qpCb->ibSendCq, &qpResp->dataPlaneInfo.scq);
2041 4 : RsQpPrepareCqDataPlaneInfo(qpCb->ibRecvCq, &qpResp->dataPlaneInfo.rcq);
2042 : }
2043 :
2044 : // skip to prepare qp data plane info
2045 4 : if (qpNorm->aiOpSupport != 0) {
2046 4 : RsQpPrepareQpDataPlaneInfo(qpCb->ibQp, &qpResp->dataPlaneInfo.sq, &qpResp->dataPlaneInfo.rq);
2047 : }
2048 4 : }
2049 : #endif
2050 :
2051 4 : STATIC void RsQpPrepareQpResp(struct RsQpNormWithAttrs *qpNorm, struct RsQpCb *qpCb,
2052 : struct RsQpRespWithAttrs *qpResp)
2053 : {
2054 4 : if (qpNorm->isExp != 0) {
2055 4 : qpCb->isExp = RS_IS_EXP;
2056 : } else {
2057 0 : qpCb->isExp = RS_NOT_EXP;
2058 : }
2059 :
2060 4 : qpResp->aiQpAddr = (unsigned long long)(uintptr_t)qpCb->ibQp;
2061 4 : qpResp->sqIndex = (unsigned int)qpCb->sqIndex;
2062 4 : qpResp->dbIndex = (unsigned int)qpCb->dbIndex;
2063 4 : qpResp->gidIdx = (unsigned int)qpCb->qpInfoLo.gidIdx;
2064 4 : qpResp->psn = (unsigned int)qpCb->qpInfoLo.psn;
2065 :
2066 : #ifdef CUSTOM_INTERFACE
2067 4 : if (RsIsCustomInterfaceSupported()) {
2068 4 : RsQpPrepareDataPlaneInfo(qpNorm, qpCb, qpResp);
2069 : }
2070 : #endif
2071 :
2072 4 : return;
2073 : }
2074 :
2075 12 : RS_ATTRI_VISI_DEF int RsQpCreateWithAttrs(unsigned int phyId, unsigned int rdevIndex,
2076 : struct RsQpNormWithAttrs *qpNorm, struct RsQpRespWithAttrs *qpResp)
2077 : {
2078 12 : struct RsRdevCb *rdevCb = NULL;
2079 12 : struct RsQpCb *qpCb = NULL;
2080 : int qpMode;
2081 : int ret;
2082 :
2083 12 : RS_QP_PARA_CHECK(phyId);
2084 10 : CHK_PRT_RETURN(qpResp == NULL, hccp_err("qp_resp is NULL!"), -EINVAL);
2085 :
2086 9 : ret = RsQpCheckQpNorm(qpNorm, &qpMode);
2087 9 : CHK_PRT_RETURN(ret != 0, hccp_err("check qp mode failed, ret:%d", ret), ret);
2088 :
2089 6 : ret = RsQpQueryInfo(phyId, rdevIndex, &rdevCb, qpMode);
2090 6 : CHK_PRT_RETURN(ret, hccp_err("query qp info failed:%d", ret), ret);
2091 :
2092 4 : ret = RsAllocQpcbWithAttrs(rdevCb, &qpCb, qpNorm);
2093 4 : CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d", ret), ret);
2094 :
2095 4 : ret = RsDrvQpCreateWithAttrs(qpCb, qpNorm);
2096 4 : if (ret) {
2097 0 : hccp_err("create drv qp create failed:%d", ret);
2098 0 : goto create_qp_err;
2099 : }
2100 :
2101 4 : ret = ibv_req_notify_cq(qpCb->ibSendCq, 0);
2102 4 : if (ret) {
2103 0 : hccp_err("Couldn't request send CQ notification, ret:%d", ret);
2104 0 : ret = -EOPENSRC;
2105 0 : goto ret_noritfy_cq;
2106 : }
2107 :
2108 4 : ret = ibv_req_notify_cq(qpCb->ibRecvCq, 0);
2109 4 : if (ret) {
2110 0 : hccp_err("Couldn't request recv CQ notification, ret:%d", ret);
2111 0 : ret = -EOPENSRC;
2112 0 : goto ret_noritfy_cq;
2113 : }
2114 :
2115 4 : ret = RsQpNotifyMr(rdevCb, qpCb, &qpResp->qpn); // alloc mr
2116 4 : if (ret) {
2117 0 : hccp_err("store qp notify mr failed:%d", ret);
2118 0 : goto ret_noritfy_cq;
2119 : }
2120 :
2121 4 : RsQpPrepareQpResp(qpNorm, qpCb, qpResp);
2122 :
2123 4 : return 0;
2124 :
2125 0 : ret_noritfy_cq:
2126 0 : RsDrvQpDestroy(qpCb);
2127 :
2128 0 : create_qp_err:
2129 0 : RsFreeQpcb(rdevCb, qpCb);
2130 0 : return ret;
2131 : }
2132 :
2133 34 : void RsMrRelease(struct RsQpCb *qpCb)
2134 : {
2135 34 : struct RsMrCb *mrTmp2 = NULL;
2136 34 : struct RsMrCb *mrTmp = NULL;
2137 :
2138 34 : RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
2139 34 : RS_LIST_GET_HEAD_ENTRY(mrTmp, mrTmp2, &qpCb->mrList, list, struct RsMrCb);
2140 67 : for (; (&mrTmp->list) != &qpCb->mrList;
2141 33 : mrTmp = mrTmp2, mrTmp2 = list_entry(mrTmp2->list.next, struct RsMrCb, list)) {
2142 33 : if (mrTmp->ibMr != qpCb->rdevCb->notifyMr) {
2143 2 : (void)RsDrvMrDereg(mrTmp->ibMr);
2144 : }
2145 33 : RsListDel(&mrTmp->list);
2146 33 : free(mrTmp);
2147 33 : mrTmp = NULL;
2148 : }
2149 :
2150 34 : RS_LIST_GET_HEAD_ENTRY(mrTmp, mrTmp2, &qpCb->remMrList, list, struct RsMrCb);
2151 65 : for (; (&mrTmp->list) != &qpCb->remMrList;
2152 31 : mrTmp = mrTmp2, mrTmp2 = list_entry(mrTmp2->list.next, struct RsMrCb, list)) {
2153 31 : RsListDel(&mrTmp->list);
2154 31 : free(mrTmp);
2155 31 : mrTmp = NULL;
2156 : }
2157 34 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
2158 34 : }
2159 :
2160 33 : STATIC void RsQpRelease(struct RsQpCb *qpCb)
2161 : {
2162 33 : RS_PTHREAD_MUTEX_LOCK(&qpCb->rdevCb->rdevMutex);
2163 33 : RsListDel(&qpCb->list);
2164 33 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->rdevCb->rdevMutex);
2165 33 : RsIbvAckCqEvents(qpCb->ibSendCq, qpCb->numSendCqEvents);
2166 33 : RsIbvAckCqEvents(qpCb->ibRecvCq, qpCb->numRecvCqEvents);
2167 :
2168 : // dereg mr
2169 33 : RsMrRelease(qpCb);
2170 33 : }
2171 :
2172 33 : RS_ATTRI_VISI_DEF int RsQpDestroy(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn)
2173 : {
2174 33 : struct RsQpCb *qpCb = NULL;
2175 : int ret;
2176 :
2177 33 : RS_QP_PARA_CHECK(phyId);
2178 33 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
2179 33 : CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed! qpn %u, ret %d", qpn, ret), ret);
2180 :
2181 31 : RsQpRelease(qpCb);
2182 :
2183 : // destroy qp
2184 31 : RsDrvQpDestroy(qpCb);
2185 31 : RsDrvDestroyCq(qpCb);
2186 31 : RsDeinitMemPool(qpCb);
2187 :
2188 31 : qpCb->rdevCb->qpCnt--;
2189 31 : ret = RsQpcbDeinit(qpCb->rdevCb, qpCb);
2190 31 : if (ret) {
2191 0 : hccp_err("rs_qpcb_deinit failed! ret[%d]", ret);
2192 : }
2193 :
2194 31 : pthread_mutex_destroy(&qpCb->cqeErrInfo.mutex);
2195 31 : pthread_mutex_destroy(&qpCb->qpMutex);
2196 31 : hccp_info("qp %d destroy qp, send wr[%u].", qpn, qpCb->sendWrNum);
2197 :
2198 31 : free(qpCb);
2199 31 : qpCb = NULL;
2200 31 : return ret;
2201 : }
2202 :
2203 0 : RS_ATTRI_VISI_DEF int RsQpDestroyWithoutCQ(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn)
2204 : {
2205 0 : struct RsQpCb *qpCb = NULL;
2206 : int ret;
2207 :
2208 0 : RS_QP_PARA_CHECK(phyId);
2209 0 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
2210 0 : CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed! qpn %u, ret %d", qpn, ret), ret);
2211 :
2212 0 : RsQpRelease(qpCb);
2213 :
2214 : // destroy qp
2215 0 : RsDrvQpDestroy(qpCb);
2216 0 : RsDeinitMemPool(qpCb);
2217 :
2218 0 : qpCb->rdevCb->qpCnt--;
2219 0 : ret = RsQpcbDeinit(qpCb->rdevCb, qpCb);
2220 0 : if (ret) {
2221 0 : hccp_err("rs_qpcb_deinit failed! ret[%d]", ret);
2222 : }
2223 :
2224 0 : pthread_mutex_destroy(&qpCb->cqeErrInfo.mutex);
2225 0 : pthread_mutex_destroy(&qpCb->qpMutex);
2226 0 : hccp_info("qp %d destroy qp without cq, send wr[%u].", qpn, qpCb->sendWrNum);
2227 :
2228 0 : free(qpCb);
2229 0 : qpCb = NULL;
2230 0 : return ret;
2231 : }
2232 :
2233 27 : static void RsQpConnectAsyncMr(const struct RsQpCb *qpCb)
2234 : {
2235 : int ret;
2236 27 : struct RsMrCb *mrCb = NULL;
2237 27 : struct RsMrCb *mrCb2 = NULL;
2238 :
2239 27 : RS_LIST_GET_HEAD_ENTRY(mrCb, mrCb2, &qpCb->mrList, list, struct RsMrCb);
2240 53 : for (; (&mrCb->list) != &qpCb->mrList;
2241 26 : mrCb = mrCb2, mrCb2 = list_entry(mrCb2->list.next, struct RsMrCb, list)) {
2242 26 : ret = RsMrInfoSync(mrCb);
2243 26 : if (ret) {
2244 0 : hccp_warn("rs_mr_info_sync unsuccessful, ret:%d", ret);
2245 : }
2246 : }
2247 27 : }
2248 :
2249 27 : STATIC void RsQpConnectAsyncQpcbSet(int fd, struct RsQpCb *qpCb)
2250 : {
2251 : int ret;
2252 27 : ret = RsSocketSend(fd, &qpCb->qpInfoLo, sizeof(struct RsQpInfo));
2253 27 : if (ret == sizeof(struct RsQpInfo)) {
2254 27 : qpCb->sendLen += (uint32_t)ret;
2255 27 : qpCb->state = RS_QP_STATUS_CONNECTING;
2256 : } else {
2257 0 : qpCb->state = RS_QP_STATUS_TIMEOUT;
2258 : }
2259 27 : }
2260 :
2261 27 : STATIC void RsQpConnectAsyncLength(int fd, struct RsQpCb *qpCb)
2262 : {
2263 : int ret;
2264 : struct RsQpLenInfo msg;
2265 :
2266 27 : msg.cmd = RS_CMD_LEN_INFO;
2267 27 : msg.len = qpCb->sendLen;
2268 :
2269 27 : ret = RsSocketSend(fd, &msg, sizeof(struct RsQpLenInfo));
2270 27 : if (ret != sizeof(struct RsQpLenInfo)) {
2271 0 : qpCb->state = RS_QP_STATUS_TIMEOUT;
2272 : }
2273 27 : }
2274 :
2275 32 : static int RsQpConnectAsyncInitPara(struct RsQpConnPara qpConnPara, int fd,
2276 : struct RsQpCb **qpCb, struct RsConnInfo **conn)
2277 : {
2278 : int ret;
2279 :
2280 32 : CHK_PRT_RETURN(qpConnPara.phyId >= RS_MAX_DEV_NUM, hccp_err("param error ! phyId:%u",
2281 : qpConnPara.phyId), -EINVAL);
2282 :
2283 32 : CHK_PRT_RETURN(fd < 0, hccp_err("param error ! fd:%d must bigger than 0", fd), -EINVAL);
2284 :
2285 30 : ret = RsQpn2qpcb(qpConnPara.phyId, qpConnPara.rdevIndex, qpConnPara.qpn, qpCb);
2286 30 : CHK_PRT_RETURN(ret, hccp_err("get qpcb failed, qpn %u, ret %d", qpConnPara.qpn, ret), ret);
2287 :
2288 28 : ret = RsFd2conn(fd, conn);
2289 28 : CHK_PRT_RETURN(ret, hccp_err("get conn failed, fd %d, ret %d", fd, ret), ret);
2290 :
2291 28 : RsGetCurTime(&((*qpCb)->startTime));
2292 28 : (*qpCb)->sendLen = 0;
2293 28 : (*qpCb)->recvLen = 0;
2294 28 : (*qpCb)->expectLen = 0;
2295 28 : (*qpCb)->connInfo = *conn;
2296 :
2297 28 : return 0;
2298 : }
2299 :
2300 2 : STATIC int RsTypicalQpStateModifytoRtr(struct RsQpCb *qpCb, struct TypicalQp *localQpInfo,
2301 : struct TypicalQp *remoteQpInfo)
2302 : {
2303 2 : struct ibv_port_attr portAttr = { 0 };
2304 2 : union ibv_gid remoteInfoGid = { 0 };
2305 2 : struct ibv_qp_attr attr = { 0 };
2306 : int ret;
2307 :
2308 2 : attr.qp_state = IBV_QPS_RTR;
2309 2 : attr.dest_qp_num = remoteQpInfo->qpn;
2310 2 : attr.rq_psn = remoteQpInfo->psn;
2311 2 : attr.min_rnr_timer = RS_QP_ATTR_MIN_RNR_TIMER;
2312 2 : (attr.ah_attr).is_global = 0;
2313 2 : (attr.ah_attr).sl = localQpInfo->sl;
2314 2 : (attr.ah_attr).src_path_bits = 0;
2315 2 : (attr.ah_attr).port_num = qpCb->rdevCb->ibPort;
2316 :
2317 2 : attr.path_mtu = RsDrvSetMtu(qpCb);
2318 2 : CHK_PRT_RETURN(attr.path_mtu < IBV_MTU_1024, hccp_err("qpn[%u] failed to set mtu, mtu[%d] < [%d]",
2319 : localQpInfo->qpn, attr.path_mtu, IBV_MTU_1024), -EPERM);
2320 2 : if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
2321 2 : attr.max_dest_rd_atomic = RS_MAX_RD_ATOMIC_NUM_PEER_ONLINE;
2322 : } else {
2323 0 : attr.max_dest_rd_atomic = RS_MAX_RD_ATOMIC_NUM;
2324 : }
2325 2 : (attr.ah_attr).grh.traffic_class = localQpInfo->tc;
2326 : // get gid_idx dynamically to avoid gid_idx changed issue: refresh gid_idx when it changed
2327 2 : ret = RsDrvGetGidIndex(qpCb->rdevCb, &portAttr, &qpCb->qpInfoLo.gidIdx);
2328 2 : if (ret == 0 && localQpInfo->gidIdx != (uint32_t)qpCb->qpInfoLo.gidIdx) {
2329 0 : hccp_warn("qpn[%u] qp_mode[%d] refresh gid_idx[%u] to [%d]", localQpInfo->qpn, qpCb->qpMode,
2330 : localQpInfo->gidIdx, qpCb->qpInfoLo.gidIdx);
2331 0 : localQpInfo->gidIdx = (uint32_t)qpCb->qpInfoLo.gidIdx;
2332 : }
2333 :
2334 2 : (void)memcpy_s(remoteInfoGid.raw, HCCP_GID_RAW_LEN, remoteQpInfo->gid, HCCP_GID_RAW_LEN);
2335 2 : if (remoteInfoGid.global.interface_id) {
2336 2 : attr.ah_attr.is_global = 1;
2337 2 : attr.ah_attr.grh.hop_limit = 1;
2338 2 : attr.ah_attr.grh.dgid = remoteInfoGid;
2339 2 : attr.ah_attr.grh.sgid_index = localQpInfo->gidIdx;
2340 : }
2341 :
2342 2 : ret = RsIbvModifyQp(qpCb->ibQp, &attr,
2343 : IBV_QP_STATE | IBV_QP_AV |
2344 : IBV_QP_PATH_MTU | IBV_QP_DEST_QPN |
2345 : IBV_QP_RQ_PSN | IBV_QP_MAX_DEST_RD_ATOMIC |
2346 : IBV_QP_MIN_RNR_TIMER);
2347 2 : CHK_PRT_RETURN(ret, hccp_err("[modifyto_rtr]local_qpn[%u] remote_qpn[%u] ibv_modify_qp failed ret[%d], errno[%d]",
2348 : localQpInfo->qpn, remoteQpInfo->qpn, ret, errno), -EOPENSRC);
2349 2 : hccp_info("qp qos attr: qpn[%u] tc[%u] sl[%u]", localQpInfo->qpn, localQpInfo->tc, localQpInfo->sl);
2350 2 : return 0;
2351 : }
2352 :
2353 2 : STATIC int RsTypicalQpStateModifytoRts(struct RsQpCb *qpCb, struct TypicalQp *localQpInfo)
2354 : {
2355 2 : struct ibv_qp_attr attr = {0};
2356 : int ret;
2357 :
2358 2 : attr.qp_state = IBV_QPS_RTS;
2359 2 : attr.timeout = (uint8_t)localQpInfo->retryTime;
2360 2 : attr.retry_cnt = (uint8_t)localQpInfo->retryCnt;
2361 2 : attr.rnr_retry = RS_QP_ATTR_RNR_RETRY;
2362 2 : attr.sq_psn = localQpInfo->psn;
2363 2 : if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
2364 2 : attr.max_rd_atomic = RS_MAX_RD_ATOMIC_NUM_PEER_ONLINE;
2365 : } else {
2366 0 : attr.max_rd_atomic = RS_MAX_RD_ATOMIC_NUM;
2367 : }
2368 :
2369 2 : ret = RsIbvModifyQp(qpCb->ibQp, &attr,
2370 : IBV_QP_STATE | IBV_QP_TIMEOUT |
2371 : IBV_QP_RETRY_CNT | IBV_QP_RNR_RETRY |
2372 : IBV_QP_SQ_PSN | IBV_QP_MAX_QP_RD_ATOMIC);
2373 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[modifyto_rts]local_qpn[%u] ibv_modify_qp failed ret[%d], errno[%d]",
2374 : localQpInfo->qpn, ret, errno), -EOPENSRC);
2375 :
2376 2 : hccp_info("qp rdma attr: qpn[%u] timeout[%u] retrycnt[%u]", localQpInfo->qpn, localQpInfo->retryTime,
2377 : localQpInfo->retryCnt);
2378 2 : return 0;
2379 : }
2380 :
2381 2 : STATIC void RsTypicalQpModifyInfoRelated(struct RsQpCb *qpCb, struct TypicalQp *localQpInfo,
2382 : struct TypicalQp *remoteQpInfo)
2383 : {
2384 2 : qpCb->state = RS_QP_STATUS_CONNECTED;
2385 : // local qp info related: no need to relate qpn, psn, gid_idx, gid
2386 2 : qpCb->qosAttr.tc = (unsigned char)localQpInfo->tc;
2387 2 : qpCb->qosAttr.sl = (unsigned char)localQpInfo->sl;
2388 2 : qpCb->retryCnt = localQpInfo->retryCnt;
2389 2 : qpCb->timeout = localQpInfo->retryTime;
2390 : // remote qp info related
2391 2 : qpCb->qpInfoRem.qpn = (int)remoteQpInfo->qpn;
2392 2 : qpCb->qpInfoRem.psn = (int)remoteQpInfo->psn;
2393 2 : qpCb->qpInfoRem.gidIdx = (int)remoteQpInfo->gidIdx;
2394 2 : (void)memcpy_s(qpCb->qpInfoRem.gid.raw, HCCP_GID_RAW_LEN, remoteQpInfo->gid, HCCP_GID_RAW_LEN);
2395 2 : }
2396 :
2397 2 : STATIC int RsTypicalQueryQpAttr(struct RsQpCb *qpCb, struct TypicalQpAttr *qpAttr)
2398 : {
2399 2 : unsigned int qpAttrMask = HNS_ROCE_AI_QPC_UDPSPN;
2400 2 : struct hns_roce_qpc_attr_val qpAttrVal = {0};
2401 2 : struct ibv_qp_init_attr initAttr = {0};
2402 2 : struct ibv_qp_attr ibvQpAttr = {0};
2403 2 : int ret = 0;
2404 :
2405 : (void)qpAttrMask;
2406 : (void)qpAttrVal;
2407 : #ifdef CUSTOM_INTERFACE
2408 2 : if (RsIsCustomInterfaceSupported()) {
2409 2 : ret = RsRoceQueryQpc(qpCb->ibQp, &qpAttrVal, qpAttrMask);
2410 2 : if (ret != 0) {
2411 2 : hccp_warn("qpn:%d query qpc unsuccessful, ret %d", qpCb->qpInfoLo.qpn, ret);
2412 : } else {
2413 0 : qpCb->udpSport = qpAttrVal.udp_sport;
2414 : }
2415 : }
2416 : #endif
2417 :
2418 2 : ret = RsIbvQueryQp(qpCb->ibQp, &ibvQpAttr, IBV_QP_PATH_MTU, &initAttr);
2419 2 : CHK_PRT_RETURN(ret, hccp_err("RsIbvQueryQp failed, ret:%d errno:%d", ret, errno), -EOPENSRC);
2420 :
2421 2 : qpAttr->udpSport = qpCb->udpSport;
2422 2 : qpAttr->pathMtu = (int)ibvQpAttr.path_mtu;
2423 2 : return 0;
2424 : }
2425 :
2426 2 : RS_ATTRI_VISI_DEF int RsTypicalQpModify(unsigned int phyId, unsigned int rdevIndex,
2427 : struct TypicalQp localQpInfo, struct TypicalQp remoteQpInfo, struct TypicalQpAttr *qpAttr)
2428 : {
2429 2 : struct ibv_qp_init_attr initAttr = { 0 };
2430 2 : struct ibv_qp_attr attr = { 0 };
2431 2 : struct RsQpCb *qpCb = NULL;
2432 : int ret;
2433 :
2434 2 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("[modify]phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM),
2435 : -EINVAL);
2436 :
2437 2 : CHK_PRT_RETURN(RsQpn2qpcb(phyId, rdevIndex, localQpInfo.qpn, &qpCb),
2438 : hccp_err("[modify]rs_qpn2qpcb qpn:%u failed, phyId[%u]", localQpInfo.qpn, phyId), -EACCES);
2439 :
2440 2 : CHK_PRT_RETURN(qpCb->state == RS_QP_STATUS_CONNECTED,
2441 : hccp_info("local_qpn:%u remote_qpn:%u already been connected, no need to modify again",
2442 : localQpInfo.qpn, remoteQpInfo.qpn), 0);
2443 :
2444 : // see ib_modify_qp_is_ok for status modify, only support modify qp from INIT to RTR
2445 2 : ret = RsIbvQueryQp(qpCb->ibQp, &attr, IBV_QP_STATE, &initAttr);
2446 2 : CHK_PRT_RETURN(ret != 0 || attr.qp_state != IBV_QPS_INIT, hccp_err("query qpn:%u failed, ret:%d or state:%d != %d",
2447 : localQpInfo.qpn, ret, attr.qp_state, IBV_QPS_INIT), -EOPENSRC);
2448 :
2449 2 : ret = RsTypicalQpStateModifytoRtr(qpCb, &localQpInfo, &remoteQpInfo);
2450 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[modify]local_qpn:%u remote_qpn:%u modify to rtr failed, ret %d",
2451 : localQpInfo.qpn, remoteQpInfo.qpn, ret), ret);
2452 :
2453 2 : ret = RsTypicalQpStateModifytoRts(qpCb, &localQpInfo);
2454 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[modify]local_qpn:%u remote_qpn:%u modify to rts failed, ret %d",
2455 : localQpInfo.qpn, remoteQpInfo.qpn, ret), ret);
2456 :
2457 2 : ret = RsTypicalQueryQpAttr(qpCb, qpAttr);
2458 2 : CHK_PRT_RETURN(ret != 0, hccp_err("RsTypicalQueryQpAttr failed, ret %d local_qpn:%u", ret, localQpInfo.qpn), ret);
2459 :
2460 2 : RsTypicalQpModifyInfoRelated(qpCb, &localQpInfo, &remoteQpInfo);
2461 :
2462 2 : hccp_info("local_qpn:%u remote_qpn:%u modify succ, udpSport:%u",
2463 : localQpInfo.qpn, remoteQpInfo.qpn, qpCb->udpSport);
2464 :
2465 2 : return 0;
2466 : }
2467 :
2468 2 : STATIC int RsQpStateBatchModifytoPause(struct RsQpCb *qpCb)
2469 : {
2470 : int ret;
2471 :
2472 2 : ret = RsDrvQpStateModifytoReset(qpCb);
2473 2 : CHK_PRT_RETURN(ret, hccp_err("qp modify to reset failed, ret %d", ret), ret);
2474 :
2475 2 : hccp_info("local qpn[%d] remote qpn[%d] modify to pause succ", qpCb->qpInfoLo.qpn, qpCb->qpInfoRem.qpn);
2476 2 : return 0;
2477 : }
2478 :
2479 2 : STATIC int RsQpStateBatchModifytoConnected(struct RsQpCb *qpCb)
2480 : {
2481 : struct ibv_qp_attr attr;
2482 : int ret;
2483 :
2484 2 : ret = memset_s(&attr, sizeof(struct ibv_qp_attr), 0, sizeof(struct ibv_qp_attr));
2485 2 : CHK_PRT_RETURN(ret, hccp_err("memset_s attr failed ret %d", ret), -ESAFEFUNC);
2486 :
2487 2 : ret = RsDrvQpStateModifytoInit(qpCb, &attr);
2488 2 : CHK_PRT_RETURN(ret, hccp_err("qp modify to init failed, ret %d", ret), ret);
2489 2 : ret = RsDrvQpStateModifytoRtr(qpCb, &attr);
2490 2 : CHK_PRT_RETURN(ret, hccp_err("qp modify to rtr failed, ret %d", ret), ret);
2491 2 : ret = RsDrvQpStateModifytoRts(qpCb, &attr);
2492 2 : CHK_PRT_RETURN(ret, hccp_err("qp modify to rts failed, ret %d", ret), ret);
2493 :
2494 2 : hccp_info("local qpn[%d] remote qpn[%d] modify to rts succ", qpCb->qpInfoLo.qpn, qpCb->qpInfoRem.qpn);
2495 2 : return 0;
2496 : }
2497 :
2498 3 : RS_ATTRI_VISI_DEF int RsQpBatchModify(unsigned int phyId, unsigned int rdevIndex,
2499 : int status, int qpn[], int qpnNum)
2500 : {
2501 3 : struct RsQpCb *qpCb = NULL;
2502 : int ret;
2503 : int i;
2504 :
2505 3 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("[modify]phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM),
2506 : -EINVAL);
2507 :
2508 7 : for (i = 0; i < qpnNum; i++) {
2509 5 : CHK_PRT_RETURN(RsQpn2qpcb(phyId, rdevIndex, (uint32_t)qpn[i], &qpCb),
2510 : hccp_err("[modify]rs_qpn2qpcb failed, phyId[%u]", phyId), -EACCES);
2511 :
2512 : /*
2513 : * see ib_modify_qp_is_ok for status modify
2514 : * only support modify qp from STATUS_PAUSE(RESET) to STATUS_CONNECTED(INIT)
2515 : */
2516 5 : if (status == RS_QP_STATUS_CONNECTED && qpCb->state == RS_QP_STATUS_PAUSE) {
2517 2 : ret = RsQpStateBatchModifytoConnected(qpCb);
2518 2 : CHK_PRT_RETURN(ret, hccp_err("modify_qp qpn[%d]:%d to connected failed, ret[%d] phyId[%u]",
2519 : i, qpn[i], ret, phyId), ret);
2520 3 : } else if (status == RS_QP_STATUS_PAUSE) {
2521 2 : ret = RsQpStateBatchModifytoPause(qpCb);
2522 2 : CHK_PRT_RETURN(ret, hccp_err("modify_qp qpn[%d]:%d to pause failed, ret[%d] phyId[%u]",
2523 : i, qpn[i], ret, phyId), ret);
2524 : } else {
2525 1 : hccp_err("modify_qp qpn[%d]:%d failed, not support to modify status[%d] to status[%d], phyId[%u]",
2526 : i, qpn[i], qpCb->state, status, phyId);
2527 1 : return -EINVAL;
2528 : }
2529 :
2530 4 : qpCb->state = status;
2531 : }
2532 :
2533 2 : return 0;
2534 : }
2535 :
2536 2 : RS_ATTRI_VISI_DEF int RsSetQpLbValue(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, int lbValue)
2537 : {
2538 2 : struct RsQpCb *qpCb = NULL;
2539 2 : int ret = 0;
2540 :
2541 2 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
2542 2 : CHK_PRT_RETURN(ret != 0, hccp_err("RsQpn2qpcb failed ret:%d", ret), ret);
2543 :
2544 1 : return RsRoceSetQpLbValue(qpCb->ibQp, lbValue);
2545 : }
2546 :
2547 3 : RS_ATTRI_VISI_DEF int RsGetQpLbValue(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, int *lbValue)
2548 : {
2549 3 : struct RsQpCb *qpCb = NULL;
2550 3 : int ret = 0;
2551 :
2552 3 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
2553 3 : CHK_PRT_RETURN(ret != 0, hccp_err("RsQpn2qpcb failed ret:%d", ret), ret);
2554 :
2555 2 : return RsRoceGetQpLbValue(qpCb->ibQp, lbValue);
2556 : }
2557 :
2558 32 : RS_ATTRI_VISI_DEF int RsQpConnectAsync(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, int fd)
2559 : {
2560 : int ret;
2561 32 : struct RsQpCb *qpCb = NULL;
2562 32 : struct RsConnInfo *conn = NULL;
2563 : struct RsQpConnPara qpConnPara;
2564 32 : hccp_info("qp:%d, fd:%d", qpn, fd);
2565 :
2566 32 : qpConnPara.phyId = phyId;
2567 32 : qpConnPara.rdevIndex = rdevIndex;
2568 32 : qpConnPara.qpn = qpn;
2569 32 : ret = RsQpConnectAsyncInitPara(qpConnPara, fd, &qpCb, &conn);
2570 32 : CHK_PRT_RETURN(ret, hccp_err("rs_qp_connect_async_init_para failed, qpn %u, ret %d", qpn, ret), ret);
2571 :
2572 28 : RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
2573 :
2574 28 : if (qpCb->state == RS_QP_STATUS_REM_FD_CLOSE) {
2575 0 : hccp_warn("remote qp fd close, can not use it anymore!");
2576 0 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
2577 0 : return -EFAULT;
2578 : }
2579 :
2580 28 : if ((qpCb->state == RS_QP_STATUS_CONNECTED) || (qpCb->state == RS_QP_STATUS_CONNECTING)) {
2581 1 : hccp_warn("qp %d has already sync! state[%d]", qpCb->qpInfoLo.qpn, qpCb->state);
2582 1 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
2583 1 : return -EEXIST;
2584 : }
2585 :
2586 27 : RsQpConnectAsyncQpcbSet(fd, qpCb);
2587 :
2588 27 : hccp_info("after socket fd %d send QP %u, chipId %u, state:%d!",
2589 : fd, qpn, qpCb->rdevCb->rsCb->chipId, qpCb->state);
2590 :
2591 27 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
2592 :
2593 27 : RsQpMrRecvHandle(fd, qpCb);
2594 :
2595 27 : RsQpConnectAsyncMr(qpCb);
2596 :
2597 27 : RsQpConnectAsyncLength(fd, qpCb);
2598 :
2599 27 : hccp_info("QP %d async done, state:%d!", qpn, qpCb->state);
2600 :
2601 27 : return 0;
2602 : }
2603 :
2604 1 : RS_ATTRI_VISI_DEF int RsGetQpStatus(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
2605 : struct RsQpStatusInfo *qpInfo)
2606 : {
2607 1 : unsigned int qpAttrMask = HNS_ROCE_AI_QPC_UDPSPN;
2608 1 : struct hns_roce_qpc_attr_val qpAttrVal = { 0 };
2609 1 : struct RsQpCb *qpCb = NULL;
2610 : int ret;
2611 :
2612 : (void)qpAttrMask;
2613 : (void)qpAttrVal;
2614 1 : CHK_PRT_RETURN(qpInfo == NULL, hccp_err("param error, qpInfo is NULL"), -EINVAL);
2615 :
2616 1 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid",
2617 : phyId, RS_MAX_DEV_NUM), -EINVAL);
2618 :
2619 1 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
2620 1 : CHK_PRT_RETURN(ret, hccp_err("get qp cb failed, qpn:%u, ret %d", qpn, ret), ret);
2621 :
2622 : // qp state is CONNECTED, no need to handle
2623 1 : if (qpCb->state == RS_QP_STATUS_CONNECTED) {
2624 1 : goto update_qp_cb;
2625 : }
2626 :
2627 : // modify state to CONNECTED
2628 0 : if (qpCb->expectLen == qpCb->recvLen - sizeof(struct RsQpLenInfo)) {
2629 0 : qpCb->state = RS_QP_STATUS_CONNECTED;
2630 : } else {
2631 0 : RsQpMrRecvHandle(qpCb->connInfo->connfd, qpCb);
2632 0 : goto out;
2633 : }
2634 :
2635 1 : update_qp_cb:
2636 : #ifdef CUSTOM_INTERFACE
2637 1 : if (RsIsCustomInterfaceSupported()) {
2638 1 : ret = RsRoceQueryQpc(qpCb->ibQp, &qpAttrVal, qpAttrMask);
2639 1 : if (ret != 0) {
2640 1 : hccp_warn("qpn:%d query qpc unsuccessful, ret %d", qpCb->qpInfoLo.qpn, ret);
2641 : } else {
2642 0 : qpCb->udpSport = qpAttrVal.udp_sport;
2643 : }
2644 : }
2645 : #endif
2646 0 : out:
2647 1 : hccp_dbg("qp:%u, state:%d, udpSport:%u", qpn, qpCb->state, qpCb->udpSport);
2648 1 : qpInfo->status = qpCb->state;
2649 1 : qpInfo->udpSport = qpCb->udpSport;
2650 :
2651 1 : return 0;
2652 : }
2653 :
2654 3 : RS_ATTRI_VISI_DEF int RsGetQpContext(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, void** qp,
2655 : void** sendCq, void** recvCq)
2656 : {
2657 : int ret;
2658 3 : struct RsQpCb *qpCb = NULL;
2659 :
2660 3 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM),
2661 : -EINVAL);
2662 :
2663 2 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
2664 2 : CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb failed ret[%d]", ret), ret);
2665 :
2666 1 : *qp = qpCb->ibQp;
2667 1 : *sendCq = qpCb->ibSendCq;
2668 1 : *recvCq = qpCb->ibRecvCq;
2669 :
2670 1 : hccp_dbg("qpn[%u] succ", qpn);
2671 :
2672 1 : return 0;
2673 : }
2674 :
2675 26 : int RsQueryRdevCb(unsigned int phyId, unsigned int rdevIndex, struct RsRdevCb **rdevCb)
2676 : {
2677 : int ret;
2678 : unsigned int chipId;
2679 26 : struct rs_cb *rsCb = NULL;
2680 :
2681 26 : RS_QP_PARA_CHECK(phyId);
2682 :
2683 24 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
2684 24 : CHK_PRT_RETURN(ret, hccp_err("rs_query_rdev_cb phyId[%u] invalid, ret:%d", phyId, ret), ret);
2685 :
2686 23 : ret = RsDev2rscb(chipId, &rsCb, false);
2687 23 : CHK_PRT_RETURN(ret, hccp_err("rs_query_rdev_cb get rs_cb failed, ret:%d", ret), -ENODEV);
2688 :
2689 23 : ret = RsGetRdevCb(rsCb, rdevIndex, rdevCb);
2690 23 : CHK_PRT_RETURN(ret, hccp_err("rs_get_rdev_cb failed! ret:%d, rdevIndex:%u", ret, rdevIndex), ret);
2691 :
2692 23 : return 0;
2693 : }
2694 :
2695 3 : RS_ATTRI_VISI_DEF int RsGetLbMax(unsigned int phyId, unsigned int rdevIndex, int *lbMax)
2696 : {
2697 3 : struct RsRdevCb *rdevCb = NULL;
2698 3 : int ret = 0;
2699 :
2700 3 : ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
2701 3 : CHK_PRT_RETURN(ret != 0, hccp_err("RsQueryRdevCb phyId:%u rdev_index:%u ret:%d", phyId, rdevIndex, ret), ret);
2702 :
2703 2 : return RsRoceGetQpNum(rdevCb->ibCtx, lbMax);
2704 : }
2705 :
2706 3 : STATIC int RsBuildUpQpcb(struct RsCqContext *cqContext, struct ibv_qp_init_attr *qpInitAttr,
2707 : struct RsQpCb **qpCb)
2708 : {
2709 : int ret;
2710 :
2711 3 : ret = RsCallocQpcb(1, qpCb);
2712 3 : CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d errno:%d", ret, errno), -ENOMEM);
2713 :
2714 3 : ret = pthread_mutex_init(&(*qpCb)->qpMutex, NULL);
2715 3 : if (ret) {
2716 0 : hccp_err("pthread_mutex_init failed, ret %d", ret);
2717 0 : goto pthread_mutex_init_err;
2718 : }
2719 :
2720 3 : (*qpCb)->rdevCb = cqContext->rdevCb;
2721 3 : RS_INIT_LIST_HEAD(&(*qpCb)->mrList);
2722 3 : RS_INIT_LIST_HEAD(&(*qpCb)->remMrList);
2723 :
2724 3 : (*qpCb)->eqNum = cqContext->eqNum;
2725 3 : (*qpCb)->channel = cqContext->channel;
2726 3 : (*qpCb)->ibSendCq = cqContext->ibSendCq;
2727 3 : (*qpCb)->ibRecvCq = cqContext->ibRecvCq;
2728 3 : (*qpCb)->sendEvent = cqContext->sendEvent;
2729 3 : (*qpCb)->recvEvent = cqContext->recvEvent;
2730 3 : (*qpCb)->numRecvCqEvents = 0;
2731 3 : (*qpCb)->numSendCqEvents = 0;
2732 3 : (*qpCb)->srqContext = cqContext->srqContext;
2733 3 : (*qpCb)->state = RS_QP_STATUS_DISCONNECT;
2734 3 : (*qpCb)->ibPd = cqContext->rdevCb->ibPd;
2735 3 : (*qpCb)->txDepth = qpInitAttr->cap.max_send_wr;
2736 3 : (*qpCb)->rxDepth = qpInitAttr->cap.max_recv_wr;
2737 3 : (*qpCb)->qosAttr.tc = (RS_ROCE_DSCP_33 & RS_DSCP_MASK) << RS_DSCP_OFF;
2738 3 : (*qpCb)->qosAttr.sl = RS_ROCE_4_SL;
2739 3 : (*qpCb)->timeout = RS_QP_ATTR_TIMEOUT;
2740 3 : (*qpCb)->retryCnt = RS_QP_ATTR_RETRY_CNT;
2741 :
2742 3 : return 0;
2743 :
2744 0 : pthread_mutex_init_err:
2745 0 : free(*qpCb);
2746 0 : (*qpCb) = NULL;
2747 0 : return ret;
2748 : }
2749 :
2750 6 : RS_ATTRI_VISI_DEF int RsCreateCqEvent(struct RsCqContext *cqContext, struct CqAttr *attr)
2751 : {
2752 : int ret;
2753 6 : cqContext->channel = RsIbvCreateCompChannel(cqContext->rdevCb->ibCtx);
2754 :
2755 6 : if (cqContext->channel == NULL) {
2756 1 : hccp_err("ibv_create_comp_channel failed, ret %d, errno(%d)", -EINVAL, errno);
2757 1 : return -EINVAL;
2758 : }
2759 :
2760 5 : hccp_info("comp channel fd[%d].", cqContext->channel->fd);
2761 5 : ret = RsEpollCtl(cqContext->rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_ADD,
2762 5 : cqContext->channel->fd, EPOLLIN | EPOLLRDHUP);
2763 : #ifndef CA_CONFIG_LLT
2764 : if (ret) {
2765 : hccp_err("add channel fd failed ret %d", ret);
2766 : goto rs_cq_epoll_ctl_err;
2767 : }
2768 : #endif
2769 :
2770 5 : ret = RsDrvCreateCqEvent(cqContext, attr);
2771 5 : if (ret) {
2772 0 : hccp_err("create drv cq event failed:%d", ret);
2773 0 : goto rs_cq_create_err;
2774 : }
2775 :
2776 5 : return ret;
2777 0 : rs_cq_create_err:
2778 0 : ret = RsEpollCtl(cqContext->rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_DEL, cqContext->channel->fd,
2779 : EPOLLIN | EPOLLRDHUP);
2780 : #ifndef CA_CONFIG_LLT
2781 : if (ret) {
2782 : hccp_err("del channel fd failed ret %d", ret);
2783 : }
2784 : #endif
2785 0 : rs_cq_epoll_ctl_err:
2786 0 : if (cqContext->channel != NULL) {
2787 0 : RsIbvDestroyCompChannel(cqContext->channel);
2788 0 : cqContext->channel = NULL;
2789 : }
2790 0 : return ret;
2791 : }
2792 :
2793 5 : RS_ATTRI_VISI_DEF int RsCqCreate(unsigned int phyId, unsigned int rdevIndex, struct CqAttr *attr)
2794 : {
2795 : int ret;
2796 5 : struct RsRdevCb *rdevCb = NULL;
2797 5 : struct RsCqContext *cqContext = NULL;
2798 :
2799 5 : ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
2800 5 : if (ret) {
2801 0 : hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u], ret %d", phyId, rdevIndex, ret);
2802 0 : return ret;
2803 : }
2804 :
2805 5 : cqContext = calloc(1, sizeof(struct RsCqContext));
2806 5 : if (cqContext == NULL) {
2807 0 : return -ENOMEM;
2808 : }
2809 5 : cqContext->rdevCb = rdevCb;
2810 5 : cqContext->eqNum = 0;
2811 5 : if (attr->sendChannel == NULL && attr->recvChannel == NULL) {
2812 3 : if (*attr->ibSendCq == NULL && *attr->ibRecvCq != NULL) {
2813 : // 只创建sq cq
2814 1 : cqContext->cqCreateMode = RS_SQ_CQ_CREATE;
2815 1 : cqContext->ibRecvCq = *attr->ibRecvCq;
2816 1 : cqContext->srqContext = attr->srqContext;
2817 : } else {
2818 : // 创建sq&rq cq
2819 2 : cqContext->cqCreateMode = RS_NORMAL_CQ_CREATE;
2820 : }
2821 3 : ret = RsCreateCqEvent(cqContext, attr);
2822 3 : if (ret) {
2823 0 : hccp_err("create cq event failed:%d", ret);
2824 0 : goto rs_cq_create_err;
2825 : }
2826 2 : } else if (attr->sendChannel != NULL && attr->recvChannel != NULL) {
2827 : // 使用输入comp channel创建sq&rq
2828 1 : ret = RsDrvCreateCqWithChannel(cqContext, attr);
2829 1 : if (ret) {
2830 0 : hccp_err("create drv cq with channel failed:%d", ret);
2831 0 : goto rs_cq_create_err;
2832 : }
2833 : } else {
2834 1 : hccp_err("rs create cq failed, sendChannel or recvChannel is NULL.");
2835 1 : ret = -EPERM;
2836 1 : goto rs_cq_create_err;
2837 : }
2838 :
2839 4 : *attr->qpContext = cqContext;
2840 4 : return 0;
2841 :
2842 1 : rs_cq_create_err:
2843 1 : free(cqContext);
2844 1 : cqContext = NULL;
2845 :
2846 1 : return ret;
2847 : }
2848 :
2849 0 : RS_ATTRI_VISI_DEF int RsTypicalCqCreate(unsigned int phyId, unsigned int rdevIndex, unsigned int cqDepth,
2850 : unsigned int *cqn)
2851 : {
2852 : struct RsTypicalCqEntry *entry;
2853 : struct RsTypicalCqEntry *tmp;
2854 : int ret;
2855 0 : struct RsRdevCb *rdevCb = NULL;
2856 0 : struct ibv_cq *ibCq = NULL;
2857 : struct rdma_lite_device_cq_attr deviceCqAttr;
2858 :
2859 0 : ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
2860 0 : if (ret) {
2861 0 : hccp_err("rs_query_rdev_cb phyId[%u] rdevIndex[%u], ret %d", phyId, rdevIndex, ret);
2862 0 : return ret;
2863 : }
2864 :
2865 0 : ret = RsDrvTypicalCqCreate(rdevCb, cqDepth, cqn, &ibCq, &deviceCqAttr);
2866 0 : if (ret) {
2867 0 : hccp_err("rs_drv_typical_cq_create failed, cqDepth[%u] ret[%d]", cqDepth, ret);
2868 0 : return ret;
2869 : }
2870 :
2871 0 : pthread_mutex_lock(&gRsTypicalCqMutex);
2872 0 : if (gRsTypicalCqList.next == NULL) {
2873 0 : RS_INIT_LIST_HEAD(&gRsTypicalCqList);
2874 : }
2875 :
2876 0 : RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
2877 0 : for (; &tmp->list != &gRsTypicalCqList;
2878 0 : tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
2879 0 : if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == *cqn) {
2880 0 : tmp->ibCq = ibCq;
2881 0 : tmp->deviceCqAttr = deviceCqAttr;
2882 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2883 0 : hccp_info("RsTypicalCqCreate updated: phyId[%u] rdevIndex[%u] cqn[%u] cqDepth[%u]",
2884 : phyId, rdevIndex, *cqn, cqDepth);
2885 0 : return 0;
2886 : }
2887 : }
2888 :
2889 0 : entry = calloc(1, sizeof(struct RsTypicalCqEntry));
2890 0 : if (entry == NULL) {
2891 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2892 0 : hccp_err("RsTypicalCqCreate calloc failed, cqn[%u]", *cqn);
2893 0 : return -ENOMEM;
2894 : }
2895 0 : entry->phyId = phyId;
2896 0 : entry->rdevIndex = rdevIndex;
2897 0 : entry->cqn = *cqn;
2898 0 : entry->ibCq = ibCq;
2899 0 : entry->deviceCqAttr = deviceCqAttr;
2900 0 : RsListAddTail(&entry->list, &gRsTypicalCqList);
2901 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2902 :
2903 0 : hccp_info("RsTypicalCqCreate success: phyId[%u] rdevIndex[%u] cqn[%u] cqDepth[%u]",
2904 : phyId, rdevIndex, *cqn, cqDepth);
2905 :
2906 0 : return 0;
2907 : }
2908 :
2909 0 : RS_ATTRI_VISI_DEF int RsTypicalCqDestroy(unsigned int phyId, unsigned int rdevIndex, unsigned int cqn)
2910 : {
2911 : struct RsTypicalCqEntry *entry;
2912 : struct RsTypicalCqEntry *tmp;
2913 : int ret;
2914 :
2915 0 : pthread_mutex_lock(&gRsTypicalCqMutex);
2916 0 : if (gRsTypicalCqList.next == NULL) {
2917 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2918 0 : hccp_err("rs_typical_cq_destroy: cqn[%u] not found phyId[%u] rdevIndex[%u]", cqn, phyId, rdevIndex);
2919 0 : return -EINVAL;
2920 : }
2921 :
2922 0 : RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
2923 0 : for (; &tmp->list != &gRsTypicalCqList;
2924 0 : tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
2925 0 : if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == cqn) {
2926 0 : RsListDel(&tmp->list);
2927 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2928 :
2929 0 : if (tmp->ibCq != NULL) {
2930 0 : ret = RsIbvDestroyCq(tmp->ibCq);
2931 0 : if (ret) {
2932 0 : hccp_err("rs_ibv_destroy_cq failed cqn[%u] ret[%d]", cqn, ret);
2933 0 : free(tmp);
2934 0 : return ret;
2935 : }
2936 : }
2937 0 : free(tmp);
2938 0 : hccp_info("RsTypicalCqDestroy success: phyId[%u] rdevIndex[%u] cqn[%u]",
2939 : phyId, rdevIndex, cqn);
2940 0 : return 0;
2941 : }
2942 : }
2943 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2944 :
2945 0 : hccp_err("rs_typical_cq_destroy: cqn[%u] not found phyId[%u] rdevIndex[%u]", cqn, phyId, rdevIndex);
2946 0 : return -EINVAL;
2947 : }
2948 :
2949 0 : RS_ATTRI_VISI_DEF int RsGetLiteCqAttr(unsigned int phyId, unsigned int rdevIndex, unsigned int cqn,
2950 : struct rdma_lite_device_cq_attr *deviceCqAttr)
2951 : {
2952 : struct RsTypicalCqEntry *entry;
2953 : struct RsTypicalCqEntry *tmp;
2954 : int ret;
2955 :
2956 0 : RS_CHECK_POINTER_NULL_RETURN_INT(deviceCqAttr);
2957 :
2958 0 : pthread_mutex_lock(&gRsTypicalCqMutex);
2959 0 : if (gRsTypicalCqList.next == NULL) {
2960 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2961 0 : hccp_err("rs_get_lite_cq_attr: cqn[%u] not found phyId[%u] rdevIndex[%u]", cqn, phyId, rdevIndex);
2962 0 : return -EINVAL;
2963 : }
2964 :
2965 0 : RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
2966 0 : for (; &tmp->list != &gRsTypicalCqList;
2967 0 : tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
2968 0 : if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == cqn) {
2969 0 : ret = memcpy_s(deviceCqAttr, sizeof(*deviceCqAttr),
2970 0 : &tmp->deviceCqAttr, sizeof(tmp->deviceCqAttr));
2971 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2972 0 : if (ret) {
2973 0 : hccp_err("memcpy_s failed, ret:%d", ret);
2974 0 : return ret;
2975 : }
2976 0 : hccp_info("RsGetLiteCqAttr success: cqn[%u] depth[%u]", cqn, deviceCqAttr->depth);
2977 0 : return 0;
2978 : }
2979 : }
2980 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
2981 :
2982 0 : hccp_err("rs_get_lite_cq_attr: cqn[%u] not found phyId[%u] rdevIndex[%u]", cqn, phyId, rdevIndex);
2983 0 : return -EINVAL;
2984 : }
2985 :
2986 0 : RS_ATTRI_VISI_DEF int RsQpCreateWithCQWithAttrs(unsigned int phyId, unsigned int rdevIndex,
2987 : unsigned int sendCqn, unsigned int recvCqn,
2988 : struct RsQpNormWithAttrs *qpNorm, struct RsQpRespWithAttrs *qpResp)
2989 : {
2990 : struct RsTypicalCqEntry *entry;
2991 : struct RsTypicalCqEntry *tmp;
2992 0 : struct RsRdevCb *rdevCb = NULL;
2993 0 : struct RsQpCb *qpCb = NULL;
2994 0 : struct ibv_cq *sendIbCq = NULL;
2995 0 : struct ibv_cq *recvIbCq = NULL;
2996 : struct rdma_lite_device_cq_attr sendDeviceCqAttr;
2997 : struct rdma_lite_device_cq_attr recvDeviceCqAttr;
2998 : int qpMode;
2999 : int ret;
3000 0 : bool sendFound = false;
3001 0 : bool recvFound = false;
3002 :
3003 0 : RS_QP_PARA_CHECK(phyId);
3004 0 : CHK_PRT_RETURN(qpResp == NULL, hccp_err("qp_resp is NULL!"), -EINVAL);
3005 :
3006 0 : ret = RsQpCheckQpNorm(qpNorm, &qpMode);
3007 0 : CHK_PRT_RETURN(ret != 0, hccp_err("check qp mode failed, ret:%d", ret), ret);
3008 :
3009 0 : ret = RsQpQueryInfo(phyId, rdevIndex, &rdevCb, qpMode);
3010 0 : CHK_PRT_RETURN(ret, hccp_err("query qp info failed:%d", ret), ret);
3011 :
3012 0 : pthread_mutex_lock(&gRsTypicalCqMutex);
3013 0 : if (gRsTypicalCqList.next != NULL) {
3014 0 : RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
3015 0 : for (; &tmp->list != &gRsTypicalCqList;
3016 0 : tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
3017 0 : if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == sendCqn) {
3018 0 : sendIbCq = tmp->ibCq;
3019 0 : sendDeviceCqAttr = tmp->deviceCqAttr;
3020 0 : sendFound = true;
3021 0 : break;
3022 : }
3023 : }
3024 : }
3025 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
3026 0 : CHK_PRT_RETURN(!sendFound,
3027 : hccp_err("send cq not found: sendCqn[%u] phyId[%u] rdevIndex[%u]", sendCqn, phyId, rdevIndex),
3028 : -EINVAL);
3029 :
3030 0 : pthread_mutex_lock(&gRsTypicalCqMutex);
3031 0 : if (gRsTypicalCqList.next != NULL) {
3032 0 : RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
3033 0 : for (; &tmp->list != &gRsTypicalCqList;
3034 0 : tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
3035 0 : if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == recvCqn) {
3036 0 : recvIbCq = tmp->ibCq;
3037 0 : recvDeviceCqAttr = tmp->deviceCqAttr;
3038 0 : recvFound = true;
3039 0 : break;
3040 : }
3041 : }
3042 : }
3043 0 : pthread_mutex_unlock(&gRsTypicalCqMutex);
3044 0 : CHK_PRT_RETURN(!recvFound,
3045 : hccp_err("recv cq not found: recvCqn[%u] phyId[%u] rdevIndex[%u]", recvCqn, phyId, rdevIndex),
3046 : -EINVAL);
3047 :
3048 0 : ret = RsCallocQpcb(1, &qpCb);
3049 0 : CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d errno:%d", ret, errno), -ENOMEM);
3050 :
3051 0 : ret = pthread_mutex_init(&qpCb->qpMutex, NULL);
3052 0 : if (ret) {
3053 0 : hccp_err("pthread_mutex_init failed, ret %d", ret);
3054 0 : goto qp_mutex_init_err;
3055 : }
3056 :
3057 0 : ret = pthread_mutex_init(&qpCb->cqeErrInfo.mutex, NULL);
3058 0 : if (ret) {
3059 0 : hccp_err("pthread_mutex_init failed, ret %d", ret);
3060 0 : goto cqe_mutex_init_err;
3061 : }
3062 :
3063 0 : ret = RsQpcbInitWithAttrs(rdevCb, qpCb, qpNorm);
3064 0 : if (ret) {
3065 0 : hccp_err("create qp tx rx failed ret %d", ret);
3066 0 : goto rs_qpcb_init_err;
3067 : }
3068 :
3069 0 : ret = RsInitMemPool(qpCb);
3070 0 : if (ret) {
3071 0 : hccp_err("init mem pool failed ret %d", ret);
3072 0 : goto rs_init_mem_err;
3073 : }
3074 :
3075 : // Assign pre-existing CQs (instead of RsDrvCreateCqWithAttrs)
3076 0 : qpCb->ibSendCq = sendIbCq;
3077 0 : qpCb->ibRecvCq = recvIbCq;
3078 0 : qpCb->qpResp.sendCqData = sendDeviceCqAttr;
3079 0 : qpCb->qpResp.recvCqData = recvDeviceCqAttr;
3080 0 : qpCb->sendCqDepth = sendDeviceCqAttr.depth;
3081 0 : qpCb->recvCqDepth = recvDeviceCqAttr.depth;
3082 :
3083 0 : ret = RsDrvQpCreateWithAttrs(qpCb, qpNorm);
3084 0 : if (ret) {
3085 0 : hccp_err("Create drv qp create failed:%d", ret);
3086 0 : goto create_qp_err;
3087 : }
3088 :
3089 0 : ret = ibv_req_notify_cq(qpCb->ibSendCq, 0);
3090 0 : if (ret) {
3091 0 : hccp_err("Can't request send CQ notification, ret:%d", ret);
3092 0 : ret = -EOPENSRC;
3093 0 : goto ret_noritfy_cq;
3094 : }
3095 :
3096 0 : ret = ibv_req_notify_cq(qpCb->ibRecvCq, 0);
3097 0 : if (ret) {
3098 0 : hccp_err("Can't request recv CQ notification, ret:%d", ret);
3099 0 : ret = -EOPENSRC;
3100 0 : goto ret_noritfy_cq;
3101 : }
3102 :
3103 0 : ret = RsQpNotifyMr(rdevCb, qpCb, &qpResp->qpn);
3104 0 : if (ret) {
3105 0 : hccp_err("Store qp notify mr failed:%d", ret);
3106 0 : goto ret_noritfy_cq;
3107 : }
3108 :
3109 0 : RsQpPrepareQpResp(qpNorm, qpCb, qpResp);
3110 :
3111 0 : return 0;
3112 :
3113 0 : ret_noritfy_cq:
3114 0 : RsDrvQpDestroy(qpCb);
3115 :
3116 0 : create_qp_err:
3117 : // Do NOT call RsDrvDestroyCq — CQs are not owned by this QP
3118 0 : RsDeinitMemPool(qpCb);
3119 0 : (void)RsQpcbDeinit(rdevCb, qpCb);
3120 :
3121 0 : rs_init_mem_err:
3122 0 : rs_qpcb_init_err:
3123 0 : pthread_mutex_destroy(&qpCb->cqeErrInfo.mutex);
3124 :
3125 0 : cqe_mutex_init_err:
3126 0 : pthread_mutex_destroy(&qpCb->qpMutex);
3127 :
3128 0 : qp_mutex_init_err:
3129 0 : free(qpCb);
3130 0 : qpCb = NULL;
3131 :
3132 0 : return ret;
3133 : }
3134 :
3135 7 : RS_ATTRI_VISI_DEF int RsCqDestroy(unsigned int phyId, unsigned int rdevIndex, struct CqAttr *attr)
3136 : {
3137 : int ret;
3138 7 : struct RsRdevCb *rdevCb = NULL;
3139 7 : struct RsCqContext *cqContext = NULL;
3140 :
3141 7 : ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
3142 7 : CHK_PRT_RETURN(ret, hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u], ret %d", phyId, rdevIndex, ret), ret);
3143 :
3144 7 : cqContext = *attr->qpContext;
3145 :
3146 7 : ret = RsDrvDestroyCqEvent(cqContext);
3147 7 : if (ret) {
3148 0 : hccp_err("rs_drv_destroy_cq_event failed ret %d", ret);
3149 : }
3150 :
3151 7 : if (cqContext->channel != NULL) {
3152 5 : ret = RsEpollCtl(rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_DEL, cqContext->channel->fd,
3153 : EPOLLIN | EPOLLRDHUP);
3154 : #ifndef CA_CONFIG_LLT
3155 : if (ret) {
3156 : hccp_err("del channel fd failed ret %d", ret);
3157 : }
3158 : #endif
3159 5 : RsIbvDestroyCompChannel(cqContext->channel);
3160 5 : cqContext->channel = NULL;
3161 : }
3162 :
3163 7 : free(cqContext);
3164 7 : cqContext = NULL;
3165 :
3166 7 : return ret;
3167 : }
3168 :
3169 4 : RS_ATTRI_VISI_DEF int RsNormalQpCreate(unsigned int phyId, unsigned int rdevIndex,
3170 : struct ibv_qp_init_attr *qpInitAttr, struct RsQpResp *qpResp, void **qp)
3171 : {
3172 4 : struct RsCqContext *cqContext = NULL;
3173 4 : struct RsRdevCb *rdevCb = NULL;
3174 4 : struct RsQpCb *qpCb = NULL;
3175 : int ret;
3176 :
3177 4 : CHK_PRT_RETURN(qpResp == NULL, hccp_err("qp_resp is NULL!"), -EINVAL);
3178 4 : ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
3179 4 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u], ret %d",
3180 : phyId, rdevIndex, ret), ret);
3181 :
3182 4 : CHK_PRT_RETURN(qpInitAttr == NULL, hccp_err("qp_init_attr is NULL!"), -EINVAL);
3183 :
3184 4 : cqContext = qpInitAttr->qp_context;
3185 4 : CHK_PRT_RETURN(cqContext == NULL, hccp_err("cq_context is NULL!"), -EINVAL);
3186 3 : CHK_PRT_RETURN(rdevCb != cqContext->rdevCb, hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u],"
3187 : "rdevCb is invalid.", phyId, rdevIndex), -EINVAL);
3188 :
3189 3 : ret = RsBuildUpQpcb(cqContext, qpInitAttr, &qpCb);
3190 3 : CHK_PRT_RETURN(ret, hccp_err("rs_build_up_qpcb failed, ret:%d", ret), ret);
3191 :
3192 3 : ret = RsDrvNormalQpCreate(qpCb, qpInitAttr);
3193 3 : if (ret) {
3194 1 : hccp_err("create drv qp create failed:%d", ret);
3195 1 : goto create_qp_err;
3196 : }
3197 :
3198 2 : RS_PTHREAD_MUTEX_LOCK(&rdevCb->rdevMutex);
3199 2 : RsListAddTail(&qpCb->list, &rdevCb->qpList);
3200 2 : RS_PTHREAD_MUTEX_ULOCK(&rdevCb->rdevMutex);
3201 2 : rdevCb->qpCnt++;
3202 2 : *qp = qpCb->ibQp;
3203 2 : qpResp->qpn = (unsigned int)qpCb->qpInfoLo.qpn;
3204 2 : qpResp->gidIdx = (unsigned int)qpCb->qpInfoLo.gidIdx;
3205 2 : qpResp->psn = (unsigned int)qpCb->qpInfoLo.psn;
3206 2 : qpResp->gid = qpCb->qpInfoLo.gid;
3207 :
3208 2 : hccp_info("qp %d create qp.", qpResp->qpn);
3209 :
3210 2 : return 0;
3211 :
3212 1 : create_qp_err:
3213 1 : pthread_mutex_destroy(&qpCb->qpMutex);
3214 1 : free(qpCb);
3215 1 : qpCb = NULL;
3216 1 : return ret;
3217 : }
3218 :
3219 2 : RS_ATTRI_VISI_DEF int RsNormalQpDestroy(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn)
3220 : {
3221 2 : struct RsQpCb *qpCb = NULL;
3222 : int ret;
3223 :
3224 2 : RS_QP_PARA_CHECK(phyId);
3225 2 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
3226 2 : CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
3227 :
3228 2 : RsQpRelease(qpCb);
3229 :
3230 : // destroy qp
3231 2 : RsDrvQpDestroy(qpCb);
3232 :
3233 2 : qpCb->rdevCb->qpCnt--;
3234 :
3235 2 : pthread_mutex_destroy(&qpCb->qpMutex);
3236 2 : hccp_info("qp %d destroy qp, send wr[%u].", qpn, qpCb->sendWrNum);
3237 :
3238 2 : free(qpCb);
3239 2 : qpCb = NULL;
3240 2 : return ret;
3241 : }
3242 :
3243 4 : RS_ATTRI_VISI_DEF int RsCreateCompChannel(unsigned int phyId, unsigned int rdevIndex, void** compChannel)
3244 : {
3245 : int ret;
3246 : unsigned int chipId;
3247 :
3248 4 : struct RsRdevCb *rdevCb = NULL;
3249 :
3250 4 : CHK_PRT_RETURN(compChannel == NULL || phyId >= RS_MAX_DEV_NUM,
3251 : hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
3252 :
3253 4 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
3254 4 : CHK_PRT_RETURN(ret,
3255 : hccp_err("rs_create_comp_channel rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret %d", phyId, ret), ret);
3256 :
3257 3 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
3258 3 : CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d",
3259 : chipId, ret), ret);
3260 :
3261 2 : *compChannel = (void *)RsIbvCreateCompChannel(rdevCb->ibCtx);
3262 2 : if (*compChannel == NULL) {
3263 1 : hccp_err("rs_ibv_create_comp_channel failed, errno(%d)", errno);
3264 1 : return -EOPENSRC;
3265 : }
3266 1 : hccp_info("create comp channel success!");
3267 1 : return 0;
3268 : }
3269 :
3270 2 : RS_ATTRI_VISI_DEF int RsDestroyCompChannel(void* compChannel)
3271 : {
3272 : int ret;
3273 2 : struct ibv_comp_channel *rsCompChannel = (struct ibv_comp_channel *)compChannel;
3274 :
3275 2 : ret = RsIbvDestroyCompChannel(rsCompChannel);
3276 2 : CHK_PRT_RETURN(ret, hccp_err("rs_destroy_comp_channel failed."), ret);
3277 1 : hccp_info("destroy comp channel success!");
3278 :
3279 1 : return 0;
3280 : }
3281 :
3282 5 : RS_ATTRI_VISI_DEF int RsCreateSrq(unsigned int phyId, unsigned int rdevIndex, struct SrqAttr *attr)
3283 : {
3284 : int ret;
3285 5 : struct RsRdevCb *rdevCb = NULL;
3286 5 : struct RsCqContext *cqContext = NULL;
3287 :
3288 5 : CHK_PRT_RETURN(attr == NULL || attr->context == NULL || attr->ibRecvCq == NULL || attr->ibSrq == NULL ||
3289 : phyId >= RS_MAX_DEV_NUM, hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM),
3290 : -EINVAL);
3291 :
3292 5 : ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
3293 5 : CHK_PRT_RETURN(ret, hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u], ret %d", phyId, rdevIndex, ret), ret);
3294 :
3295 4 : cqContext = calloc(1, sizeof(struct RsCqContext));
3296 4 : if (cqContext == NULL) {
3297 1 : return -ENOMEM;
3298 : }
3299 :
3300 3 : cqContext->rdevCb = rdevCb;
3301 3 : cqContext->eqNum = 0;
3302 3 : cqContext->cqCreateMode = RS_SRQ_CQ_CREATE;
3303 3 : *attr->context = cqContext;
3304 :
3305 3 : struct CqAttr cqAttr = {0};
3306 3 : cqAttr.recvCqDepth = attr->cqDepth;
3307 3 : cqAttr.recvCqEventId = attr->srqEventId;
3308 3 : cqAttr.ibRecvCq = attr->ibRecvCq;
3309 : // 创建srq cq
3310 3 : ret = RsCreateCqEvent(cqContext, &cqAttr);
3311 3 : if (ret) {
3312 1 : hccp_err("rs_create_cq_event create cq failed! ret:%d", ret);
3313 1 : goto create_cq_event_err;
3314 : }
3315 2 : cqContext->ibSrqCq = *attr->ibRecvCq;
3316 :
3317 2 : struct ibv_srq_init_attr srqInitAttr = {
3318 : .attr = {
3319 2 : .max_wr = attr->srqDepth,
3320 2 : .max_sge = attr->maxSge
3321 : }
3322 : };
3323 2 : hccp_info("max_wr [%u], max_sge[%u]", srqInitAttr.attr.max_wr, srqInitAttr.attr.max_sge);
3324 :
3325 : // 创建srq
3326 2 : *attr->ibSrq = RsIbvCreateSrq(rdevCb->ibPd, &srqInitAttr);
3327 2 : if (*attr->ibSrq == NULL) {
3328 1 : hccp_err("rs_ibv_create_srq failed.");
3329 1 : ret = -EOPENSRC;
3330 1 : goto create_srq_err;
3331 : }
3332 1 : hccp_info("create srq success!");
3333 :
3334 1 : return 0;
3335 1 : create_cq_event_err:
3336 2 : create_srq_err:
3337 2 : cqAttr.qpContext = attr->context;
3338 2 : RsCqDestroy(phyId, rdevIndex, &cqAttr);
3339 :
3340 2 : return ret;
3341 : }
3342 :
3343 1 : RS_ATTRI_VISI_DEF int RsDestroySrq(unsigned int phyId, unsigned int rdevIndex, struct SrqAttr *attr)
3344 : {
3345 : int ret;
3346 :
3347 1 : CHK_PRT_RETURN(*attr->context == NULL || *attr->ibSrq == NULL|| phyId >= RS_MAX_DEV_NUM,
3348 : hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
3349 :
3350 1 : struct CqAttr cqAttr = {0};
3351 1 : struct RsCqContext *cqContext = *attr->context;
3352 1 : cqAttr.qpContext = attr->context;
3353 1 : RsIbvAckCqEvents(cqContext->ibSrqCq, cqContext->numRecvCqEvents);
3354 :
3355 : // 销毁srq cq
3356 1 : ret = RsCqDestroy(phyId, rdevIndex, &cqAttr);
3357 1 : CHK_PRT_RETURN(ret, hccp_err("rs_cq_destroy destroy cq failed! ret:%d", ret), ret);
3358 :
3359 1 : ret = RsIbvDestroySrq(*attr->ibSrq);
3360 1 : CHK_PRT_RETURN(ret, hccp_err("rs_ibv_destroy_srq failed."), ret);
3361 :
3362 1 : return 0;
3363 : }
3364 :
3365 2 : RS_ATTRI_VISI_DEF int RsGetLiteSupport(unsigned int phyId, unsigned int rdevIndex, int *supportLite)
3366 : {
3367 : int ret;
3368 : unsigned int chipId;
3369 2 : struct RsRdevCb *rdevCb = NULL;
3370 :
3371 2 : RS_CHECK_POINTER_NULL_RETURN_INT(supportLite);
3372 :
3373 2 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs set param error ! phyId:%u", phyId), -EINVAL);
3374 2 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
3375 2 : CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
3376 :
3377 2 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
3378 2 : CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d",
3379 : chipId, ret), ret);
3380 :
3381 2 : rdevCb->supportLite = 1;
3382 2 : *supportLite = rdevCb->supportLite;
3383 :
3384 2 : return 0;
3385 : }
3386 :
3387 2 : RS_ATTRI_VISI_DEF int RsGetLiteRdevCap(
3388 : unsigned int phyId, unsigned int rdevIndex, struct LiteRdevCapResp *resp)
3389 : {
3390 : int ret;
3391 : unsigned int chipId;
3392 2 : struct RsRdevCb *rdevCb = NULL;
3393 :
3394 2 : RS_CHECK_POINTER_NULL_RETURN_INT(resp);
3395 :
3396 2 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs set param error ! phyId:%u", phyId), -EINVAL);
3397 2 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
3398 2 : CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
3399 :
3400 2 : ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
3401 2 : CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d",
3402 : chipId, ret), ret);
3403 :
3404 2 : ret = RsIbvExpQueryDevice(rdevCb->ibCtx, &resp->cap);
3405 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_ibv_exp_query_device for phyId[%u] failed, ret %d", phyId, ret), ret);
3406 :
3407 2 : ret = memcpy_s(resp, sizeof(struct dev_cap_info), (void *)&resp->cap, sizeof(resp->cap));
3408 2 : if (ret) {
3409 0 : hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u",
3410 : ret,
3411 : (unsigned int)sizeof(resp->cap),
3412 : (unsigned int)sizeof(struct dev_cap_info));
3413 0 : return ret;
3414 : }
3415 :
3416 2 : return 0;
3417 : }
3418 :
3419 2 : RS_ATTRI_VISI_DEF int RsGetLiteQpCqAttr(
3420 : unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, struct LiteQpCqAttrResp *resp)
3421 : {
3422 : int ret;
3423 2 : struct RsQpCb *qpCb = NULL;
3424 :
3425 2 : RS_CHECK_POINTER_NULL_RETURN_INT(resp);
3426 :
3427 2 : RS_QP_PARA_CHECK(phyId);
3428 2 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
3429 2 : CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
3430 :
3431 2 : ret = memcpy_s(resp, sizeof(struct LiteQpCqAttrResp), (void *)&qpCb->qpResp, sizeof(qpCb->qpResp));
3432 2 : if (ret) {
3433 0 : hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u",
3434 : ret,
3435 : (unsigned int)sizeof(qpCb->qpResp),
3436 : (unsigned int)sizeof(struct LiteQpCqAttrResp));
3437 0 : return ret;
3438 : }
3439 :
3440 2 : return 0;
3441 : }
3442 :
3443 0 : RS_ATTRI_VISI_DEF int RsGetLiteQpAttr(
3444 : unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, struct LiteQpAttrResp *resp)
3445 : {
3446 : int ret;
3447 0 : struct RsQpCb *qpCb = NULL;
3448 :
3449 0 : RS_CHECK_POINTER_NULL_RETURN_INT(resp);
3450 :
3451 0 : RS_QP_PARA_CHECK(phyId);
3452 0 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
3453 0 : CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
3454 :
3455 0 : ret = memcpy_s(resp, sizeof(struct LiteQpAttrResp), (void *)&qpCb->qpResp.qpData, sizeof(qpCb->qpResp.qpData));
3456 0 : if (ret) {
3457 0 : hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u",
3458 : ret,
3459 : (unsigned int)sizeof(qpCb->qpResp.qpData),
3460 : (unsigned int)sizeof(struct LiteQpAttrResp));
3461 0 : return ret;
3462 : }
3463 :
3464 0 : return 0;
3465 : }
3466 :
3467 2 : RS_ATTRI_VISI_DEF int RsGetLiteMemAttr(
3468 : unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, struct LiteMemAttrResp *resp)
3469 : {
3470 : int ret;
3471 2 : struct RsQpCb *qpCb = NULL;
3472 :
3473 2 : RS_CHECK_POINTER_NULL_RETURN_INT(resp);
3474 :
3475 2 : RS_QP_PARA_CHECK(phyId);
3476 2 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
3477 2 : CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
3478 :
3479 2 : ret = memcpy_s(resp, sizeof(struct LiteMemAttrResp), (void *)&qpCb->memResp, sizeof(qpCb->memResp));
3480 2 : if (ret) {
3481 0 : hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u",
3482 : ret,
3483 : (unsigned int)sizeof(qpCb->memResp),
3484 : (unsigned int)sizeof(struct LiteMemAttrResp));
3485 0 : return ret;
3486 : }
3487 :
3488 2 : return 0;
3489 : }
3490 :
3491 4 : STATIC void RsGetMrInfo(
3492 : struct RsQpCb *qpCb, struct LiteMrInfo *mr, uint32_t maxMrNum, struct RsListHead *mrList)
3493 : {
3494 4 : struct RsMrCb *mrTmp = NULL;
3495 4 : struct RsMrCb *mrTmp2 = NULL;
3496 4 : uint32_t i = 0;
3497 :
3498 4 : RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
3499 4 : RS_LIST_GET_HEAD_ENTRY(mrTmp, mrTmp2, mrList, list, struct RsMrCb);
3500 6 : for (; (&mrTmp->list) != mrList;
3501 2 : mrTmp = mrTmp2, mrTmp2 = list_entry(mrTmp2->list.next, struct RsMrCb, list)) {
3502 2 : if (i < maxMrNum) {
3503 2 : mr[i].key = mrTmp->mrInfo.rkey;
3504 2 : mr[i].addr = mrTmp->mrInfo.addr;
3505 2 : mr[i].len = mrTmp->mrInfo.len;
3506 2 : i++;
3507 : } else {
3508 0 : break;
3509 : }
3510 : }
3511 :
3512 4 : RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
3513 4 : }
3514 :
3515 2 : RS_ATTRI_VISI_DEF int RsGetLiteConnectedInfo(
3516 : unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, struct LiteConnectedInfoResp *resp)
3517 : {
3518 : int ret;
3519 2 : struct RsQpCb *qpCb = NULL;
3520 :
3521 2 : RS_CHECK_POINTER_NULL_RETURN_INT(resp);
3522 2 : RS_QP_PARA_CHECK(phyId);
3523 2 : ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
3524 2 : CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
3525 :
3526 2 : resp->state = (unsigned int)qpCb->state;
3527 2 : if (resp->state == RS_QP_STATUS_CONNECTED) {
3528 2 : RsGetMrInfo(qpCb, &resp->localMr[0], RA_MR_MAX_NUM, &qpCb->mrList);
3529 2 : RsGetMrInfo(qpCb, &resp->remMr[0], RA_MR_MAX_NUM, &qpCb->remMrList);
3530 2 : resp->qosAttr.sl = qpCb->qosAttr.sl;
3531 2 : resp->qosAttr.tc = qpCb->qosAttr.tc;
3532 : }
3533 :
3534 2 : return 0;
3535 : }
|