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 : #include <stdlib.h>
12 : #include <string.h>
13 : #include <arpa/inet.h>
14 : #include <unistd.h>
15 : #include <errno.h>
16 : #include <sys/time.h>
17 : #include <sys/prctl.h>
18 : #include <pthread.h>
19 : #include "user_log.h"
20 : #include "ra_hdc.h"
21 : #include "securec.h"
22 : #include "ra.h"
23 : #include "ra_rdma_lite.h"
24 : #include "dl_hal_function.h"
25 : #include "ra_rs_comm.h"
26 : #include "ra_rs_err.h"
27 : #include "ra_hdc_lite.h"
28 :
29 : struct RaCqeErrInfo gRaCqeErr[RA_MAX_PHY_ID_NUM];
30 :
31 0 : void RaHdcLiteStoreTypicalCq(struct RaRdmaHandle *rdmaHandle, unsigned int cqn, struct rdma_lite_cq *liteCq,
32 : struct rdma_lite_device_cq_attr *deviceCqAttr)
33 : {
34 : struct TypicalLiteCqEntry *entry;
35 : struct TypicalLiteCqEntry *tmp;
36 0 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
37 :
38 0 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->typicalLiteCqMutex);
39 :
40 0 : RA_LIST_GET_HEAD_ENTRY(tmp, entry, &rdmaHandle->typicalLiteCqList, list, struct TypicalLiteCqEntry);
41 0 : for (; &tmp->list != &rdmaHandle->typicalLiteCqList;
42 0 : tmp = entry, entry = list_entry(entry->list.next, struct TypicalLiteCqEntry, list)) {
43 0 : if (tmp->cqn == cqn) {
44 0 : tmp->liteCq = liteCq;
45 0 : tmp->deviceCqAttr = *deviceCqAttr;
46 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
47 0 : hccp_info("[store][ra_hdc_lite]updated typical lite cq, phyId[%u] cqn[%u]", phyId, cqn);
48 0 : return;
49 : }
50 : }
51 :
52 0 : entry = calloc(1, sizeof(struct TypicalLiteCqEntry));
53 0 : if (entry == NULL) {
54 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
55 0 : hccp_err("[store][ra_hdc_lite]calloc typical lite cq entry failed, cqn[%u]", cqn);
56 0 : return;
57 : }
58 0 : entry->phyId = phyId;
59 0 : entry->cqn = cqn;
60 0 : entry->liteCq = liteCq;
61 0 : entry->deviceCqAttr = *deviceCqAttr;
62 0 : RaListAddTail(&entry->list, &rdmaHandle->typicalLiteCqList);
63 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
64 0 : hccp_info("[store][ra_hdc_lite]stored typical lite cq, phyId[%u] cqn[%u]", phyId, cqn);
65 : }
66 :
67 0 : struct rdma_lite_cq *RaHdcLiteFindTypicalCq(struct RaRdmaHandle *rdmaHandle, unsigned int cqn)
68 : {
69 : struct TypicalLiteCqEntry *entry;
70 : struct TypicalLiteCqEntry *tmp;
71 0 : struct rdma_lite_cq *liteCq = NULL;
72 0 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
73 :
74 0 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->typicalLiteCqMutex);
75 0 : if (RaListEmpty(&rdmaHandle->typicalLiteCqList)) {
76 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
77 0 : hccp_err("[find][ra_hdc_lite]typical lite cq list is empty, phyId[%u] cqn[%u]", phyId, cqn);
78 0 : return NULL;
79 : }
80 :
81 0 : RA_LIST_GET_HEAD_ENTRY(tmp, entry, &rdmaHandle->typicalLiteCqList, list, struct TypicalLiteCqEntry);
82 0 : for (; &tmp->list != &rdmaHandle->typicalLiteCqList;
83 0 : tmp = entry, entry = list_entry(entry->list.next, struct TypicalLiteCqEntry, list)) {
84 0 : if (tmp->cqn == cqn) {
85 0 : liteCq = tmp->liteCq;
86 0 : break;
87 : }
88 : }
89 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
90 :
91 0 : if (liteCq != NULL) {
92 0 : hccp_info("[find][ra_hdc_lite]found typical lite cq, phyId[%u] cqn[%u]", phyId, cqn);
93 : } else {
94 0 : hccp_err("[find][ra_hdc_lite]typical lite cq not found, phyId[%u] cqn[%u]", phyId, cqn);
95 : }
96 0 : return liteCq;
97 : }
98 :
99 0 : int RaHdcLiteFindTypicalCqAttr(struct RaRdmaHandle *rdmaHandle, unsigned int cqn,
100 : struct rdma_lite_device_cq_attr **deviceCqAttr)
101 : {
102 : struct TypicalLiteCqEntry *entry;
103 : struct TypicalLiteCqEntry *tmp;
104 0 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
105 0 : int ret = -EINVAL;
106 :
107 0 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->typicalLiteCqMutex);
108 0 : if (RaListEmpty(&rdmaHandle->typicalLiteCqList)) {
109 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
110 0 : hccp_err("[find][ra_hdc_lite]typical lite cq list is empty, phyId[%u] cqn[%u]", phyId, cqn);
111 0 : return -EINVAL;
112 : }
113 :
114 0 : RA_LIST_GET_HEAD_ENTRY(tmp, entry, &rdmaHandle->typicalLiteCqList, list, struct TypicalLiteCqEntry);
115 0 : for (; &tmp->list != &rdmaHandle->typicalLiteCqList;
116 0 : tmp = entry, entry = list_entry(entry->list.next, struct TypicalLiteCqEntry, list)) {
117 0 : if (tmp->cqn == cqn) {
118 0 : *deviceCqAttr = &tmp->deviceCqAttr;
119 0 : ret = 0;
120 0 : break;
121 : }
122 : }
123 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
124 :
125 0 : if (ret != 0) {
126 0 : hccp_err("[find][ra_hdc_lite]typical lite cq attr not found, phyId[%u] cqn[%u]", phyId, cqn);
127 : }
128 0 : return ret;
129 : }
130 :
131 0 : void RaHdcLiteRemoveTypicalCq(struct RaRdmaHandle *rdmaHandle, unsigned int cqn)
132 : {
133 0 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
134 : struct TypicalLiteCqEntry *entry;
135 : struct TypicalLiteCqEntry *tmp;
136 :
137 0 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->typicalLiteCqMutex);
138 0 : if (RaListEmpty(&rdmaHandle->typicalLiteCqList)) {
139 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
140 0 : return;
141 : }
142 :
143 0 : RA_LIST_GET_HEAD_ENTRY(tmp, entry, &rdmaHandle->typicalLiteCqList, list, struct TypicalLiteCqEntry);
144 0 : for (; &tmp->list != &rdmaHandle->typicalLiteCqList;
145 0 : tmp = entry, entry = list_entry(entry->list.next, struct TypicalLiteCqEntry, list)) {
146 0 : if (tmp->cqn == cqn) {
147 0 : RaListDel(&tmp->list);
148 0 : free(tmp);
149 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
150 0 : hccp_info("[remove][ra_hdc_lite]removed typical lite cq, phyId[%u] cqn[%u]", phyId, cqn);
151 0 : return;
152 : }
153 : }
154 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->typicalLiteCqMutex);
155 0 : hccp_warn("[remove][ra_hdc_lite]typical lite cq not found for removal, phyId[%u] cqn[%u]", phyId, cqn);
156 : }
157 :
158 : STATIC void *RaHdcLitePthread(void *arg);
159 :
160 2 : STATIC int RaHdcGetDrvLiteSupport(unsigned int phyId, bool enabled910aLite, unsigned int *support)
161 : {
162 : int ret;
163 2 : size_t outLen = 0;
164 : unsigned int logicId;
165 2 : int64_t deviceInfo = 0;
166 2 : struct supportFeaturePara inPara = { 0 };
167 2 : struct supportFeaturePara outPara = { 0 };
168 :
169 2 : ret = DlDrvDeviceGetIndexByPhyId(phyId, &logicId);
170 2 : CHK_PRT_RETURN(ret, hccp_err("[init][ra_hdc_lite]dl_drv_device_get_index_by_phy_id failed, ret(%d), phyId(%u)",
171 : ret, phyId), ret);
172 :
173 : // enabled_910a_lite not explicitly set to true, disabled lite if chip_type is 910A due to memory limits
174 2 : if (!enabled910aLite) {
175 1 : ret = DlHalGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &deviceInfo);
176 1 : CHK_PRT_RETURN(ret, hccp_err("[init][ra_hdc_lite]dl_hal_get_device_info failed, ret(%d), phyId(%u)",
177 : ret, phyId), ret);
178 1 : if (DlHalPlatGetChip((uint64_t)deviceInfo) == CHIP_TYPE_910A) { // Memory Limits
179 1 : *support = 0;
180 1 : hccp_info("[init][ra_hdc_lite]device_info:0x%llx not support, phyId(%u)", deviceInfo, phyId);
181 1 : return 0;
182 : }
183 : }
184 :
185 1 : inPara.support_feature = CTRL_SUPPORT_DEV_MEM_REGISTER_MASK | CTRL_SUPPORT_PCIE_BAR_HUGE_MEM_MASK;
186 1 : inPara.devid = logicId;
187 1 : ret = DlHalMemCtl(CTRL_TYPE_SUPPORT_FEATURE, &inPara, sizeof(struct supportFeaturePara), &outPara, &outLen);
188 1 : if ((ret != 0) || (((outPara.support_feature & CTRL_SUPPORT_DEV_MEM_REGISTER_MASK) == 0) &&
189 1 : ((outPara.support_feature & CTRL_SUPPORT_PCIE_BAR_HUGE_MEM_MASK) == 0))) {
190 1 : *support = 0;
191 1 : return 0;
192 : }
193 :
194 0 : if ((outPara.support_feature & CTRL_SUPPORT_DEV_MEM_REGISTER_MASK) != 0) {
195 0 : *support = LITE_SUPPORT_DEV_MEM_REGISTER;
196 : }
197 0 : if ((outPara.support_feature & CTRL_SUPPORT_PCIE_BAR_HUGE_MEM_MASK) != 0) {
198 0 : *support |= LITE_SUPPORT_PCIE_BAR_HUGE_MEM;
199 : }
200 :
201 0 : return 0;
202 : }
203 :
204 5 : STATIC void RaHdcGetOpcodeLiteSupport(unsigned int phyId, unsigned int supportFeature, int *support)
205 : {
206 : int ret;
207 5 : unsigned int interfaceVersion = 0;
208 :
209 5 : ret = RaHdcGetInterfaceVersion(phyId, RA_RS_GET_LITE_SUPPORT, &interfaceVersion);
210 : // get version failed or opcode interface_version is 0: opcode not support lite
211 5 : if (ret != 0 || interfaceVersion == 0) {
212 1 : hccp_info("[init][ra_hdc_lite]get opcode not support, ret[%d] != 0 or interfaceVersion is 0", ret);
213 1 : *support = LITE_NOT_SUPPORT;
214 1 : return;
215 : }
216 :
217 : // at least driver&host support lite 4KB page_size align
218 4 : if ((supportFeature & LITE_SUPPORT_DEV_MEM_REGISTER) != 0) {
219 2 : *support = LITE_ALIGN_4KB;
220 2 : return;
221 : }
222 :
223 : // driver&host support lite 2MB page_size align
224 2 : if ((interfaceVersion == LITE_VERSION_V2) && ((supportFeature & LITE_SUPPORT_PCIE_BAR_HUGE_MEM) != 0)) {
225 1 : *support = LITE_ALIGN_2MB;
226 1 : return;
227 : }
228 :
229 : // none of 4KB page_size align & 2MB page_size align lite support
230 1 : hccp_info("[init][ra_hdc_lite]get opcode not support, interfaceVersion[%u] supportFeature[0x%x]",
231 : interfaceVersion, supportFeature);
232 1 : *support = LITE_NOT_SUPPORT;
233 1 : return;
234 : }
235 :
236 8 : STATIC int RaHdcGetRdmaLiteSupport(struct RaRdmaHandle *rdmaHandle, unsigned int supportFeature, int *support)
237 : {
238 8 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
239 8 : unsigned int rdevIndex = rdmaHandle->rdevIndex;
240 : union OpLiteSupportData liteSupportData;
241 8 : int supportLite = 0;
242 : int ret;
243 :
244 : // get opcode support lite with support_feature
245 8 : RaHdcGetOpcodeLiteSupport(phyId, supportFeature, &supportLite);
246 8 : if (supportLite == LITE_NOT_SUPPORT) {
247 0 : *support = LITE_NOT_SUPPORT;
248 0 : return 0;
249 : }
250 :
251 : // no need to support lite if enabled_2mb_lite not enabled
252 8 : if (supportLite == LITE_ALIGN_2MB && !rdmaHandle->enabled2mbLite) {
253 0 : hccp_run_info("[init][ra_hdc_lite]rdma_handle->enabled_2mb_lite=%d, no need to support LITE_ALIGN_2MB",
254 : rdmaHandle->enabled2mbLite);
255 0 : *support = LITE_NOT_SUPPORT;
256 0 : return 0;
257 : }
258 :
259 : // RA_RS_GET_LITE_SUPPORT will set rdev_cb->support_lite = 1
260 8 : (void)memset_s(&liteSupportData, sizeof(liteSupportData), 0, sizeof(liteSupportData));
261 8 : liteSupportData.txData.phyId = phyId;
262 8 : liteSupportData.txData.rdevIndex = rdevIndex;
263 8 : ret = RaHdcProcessMsg(RA_RS_GET_LITE_SUPPORT, phyId, (char *)&liteSupportData,
264 : sizeof(union OpLiteSupportData));
265 8 : if (ret != 0) {
266 1 : if (ret == -EPROTONOSUPPORT) {
267 1 : *support = LITE_NOT_SUPPORT;
268 1 : ret = 0;
269 : } else {
270 0 : hccp_err("[init][ra_hdc_lite]ra hdc message process failed ret(%d) phyId(%u)", ret, phyId);
271 : }
272 1 : return ret;
273 : }
274 :
275 7 : *support = supportLite;
276 7 : return 0;
277 : }
278 :
279 8 : STATIC int RaHdcGetLiteSupport(struct RaRdmaHandle *rdmaHandle, unsigned int phyId)
280 : {
281 : int ret;
282 8 : unsigned int supportFeature = 0;
283 :
284 : #ifndef HNS_ROCE_LLT
285 : ret = RaHdcGetDrvLiteSupport(phyId, rdmaHandle->enabled910aLite, &supportFeature);
286 : CHK_PRT_RETURN(ret, hccp_err("[init][ra_hdc_lite]ra_hdc_get_drv_lite_support failed, ret(%d), phyId(%u)",
287 : ret, phyId), ret);
288 : #else
289 8 : supportFeature = 1;
290 : #endif
291 8 : if (supportFeature != 0) {
292 8 : ret = RaHdcGetRdmaLiteSupport(rdmaHandle, supportFeature, &rdmaHandle->supportLite);
293 8 : CHK_PRT_RETURN(ret, hccp_err("[init][ra_hdc_lite]ra_hdc_get_rdma_lite_support failed, ret(%d), phyId(%u)",
294 : ret, phyId), ret);
295 :
296 8 : if (rdmaHandle->supportLite) {
297 7 : hccp_run_info("[init][ra_hdc_lite]support_feature:0x%x, supportLite:%u", supportFeature,
298 : rdmaHandle->supportLite);
299 7 : ret = RaHdcRdmaLiteApiInit();
300 7 : CHK_PRT_RETURN(ret, hccp_err("[init][ra_hdc_lite]ra_hdc_rdma_lite_api_init failed, ret(%d), phyId(%u)",
301 : ret, phyId), ret);
302 : }
303 : }
304 :
305 8 : return 0;
306 : }
307 :
308 7 : STATIC int RaSensorNodeRegister(unsigned int phyId, struct RaRdmaHandle *rdmaHandle)
309 : {
310 7 : struct halSensorNodeCfg cfg = { 0 };
311 7 : unsigned int interfaceVersion = 0;
312 : int ret;
313 :
314 7 : ret = RaHdcGetInterfaceVersion(phyId, RA_RS_RDEV_INIT, &interfaceVersion);
315 7 : if ((ret != 0) || (interfaceVersion <= RA_RS_OPCODE_BASE_VERSION)) {
316 : /* unknown or old version, not support sensor */
317 6 : rdmaHandle->sensorHandle = 0;
318 6 : hccp_warn("[init][ra_hdc_lite]not support sensor, ret:%d, phyId:%u, interfaceVersion:%u",
319 : ret, phyId, interfaceVersion);
320 6 : return 0;
321 : }
322 :
323 1 : rdmaHandle->sensorUpdateCnt = 0;
324 1 : ret = sprintf_s(cfg.name, sizeof(cfg.name), "roce_ra_%d", getpid());
325 1 : CHK_PRT_RETURN(ret <= 0, hccp_err("[init][ra_hdc_lite]sprintf_s name err, ret:%d, phyId:%u",
326 : ret, phyId), -ESAFEFUNC);
327 :
328 1 : cfg.NodeType = HAL_DMS_DEV_TYPE_HCCP;
329 1 : cfg.SensorType = RDMA_CQE_ERR_SENSOR_TYPE;
330 1 : cfg.AssertEventMask = RDMA_CQE_ERR_RETRY_TIMEOUT_EVENT_MASK;
331 1 : cfg.DeassertEventMask = RDMA_CQE_ERR_RETRY_TIMEOUT_EVENT_TYPE_MASK;
332 1 : ret = DlHalSensorNodeRegister(rdmaHandle->logicDevid, &cfg, &rdmaHandle->sensorHandle);
333 1 : CHK_PRT_RETURN(ret, hccp_err("[init][ra_hdc_lite]dl_hal_sensor_node_register failed, ret(%d)", ret), ret);
334 :
335 1 : return 0;
336 : }
337 :
338 11 : STATIC int RaHdcLiteGetRdevCap(struct RaRdmaHandle *rdmaHandle, unsigned int phyId, unsigned int rdevIndex,
339 : union OpLiteRdevCapData *liteRdevCapData)
340 : {
341 : #define PAGE_ALIGN_2MB (2 * 1024 * 1024)
342 : int ret;
343 :
344 11 : liteRdevCapData->txData.phyId = phyId;
345 11 : liteRdevCapData->txData.rdevIndex = rdevIndex;
346 11 : ret = RaHdcProcessMsg(RA_RS_GET_LITE_RDEV_CAP, phyId, (char *)liteRdevCapData,
347 : sizeof(union OpLiteRdevCapData));
348 11 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra_hdc_lite_ctx]hdc get lite rdev cap failed, ret(%d), phyId(%u)",
349 : ret, phyId), ret);
350 :
351 : // should change page_size to 2MB
352 11 : if (rdmaHandle->supportLite == LITE_ALIGN_2MB) {
353 0 : liteRdevCapData->rxData.resp.cap.page_size = PAGE_ALIGN_2MB;
354 : }
355 11 : return 0;
356 : }
357 :
358 8 : STATIC int RaHdcLiteMutexInit(struct RaRdmaHandle *rdmaHandle, unsigned int phyId)
359 : {
360 : int ret;
361 :
362 8 : ret = pthread_mutex_init(&rdmaHandle->rdevMutex, NULL);
363 8 : if (ret != 0) {
364 2 : hccp_err("[init][ra_hdc_lite_ctx]pthread_mutex_init rdev_mutex failed ret(%d) phyId(%u)", ret, phyId);
365 2 : return -ESYSFUNC;
366 : }
367 :
368 6 : ret = pthread_mutex_init(&rdmaHandle->cqeErrCntMutex, NULL);
369 6 : if (ret != 0) {
370 0 : (void)pthread_mutex_destroy(&rdmaHandle->rdevMutex);
371 0 : hccp_err("[init][ra_hdc_lite_ctx]pthread_mutex_init cqe_err_cnt_mutex failed ret(%d) phyId(%u)", ret, phyId);
372 0 : return -ESYSFUNC;
373 : }
374 :
375 6 : ret = pthread_mutex_init(&rdmaHandle->typicalLiteCqMutex, NULL);
376 6 : if (ret != 0) {
377 0 : (void)pthread_mutex_destroy(&rdmaHandle->cqeErrCntMutex);
378 0 : (void)pthread_mutex_destroy(&rdmaHandle->rdevMutex);
379 0 : hccp_err("[init][ra_hdc_lite_ctx]pthread_mutex_init typical_lite_cq_mutex failed ret(%d) phyId(%u)",
380 : ret, phyId);
381 0 : return -ESYSFUNC;
382 : }
383 :
384 6 : return 0;
385 : }
386 :
387 5 : STATIC void RaHdcLiteMutexDeinit(struct RaRdmaHandle *rdmaHandle)
388 : {
389 5 : (void)pthread_mutex_destroy(&rdmaHandle->typicalLiteCqMutex);
390 5 : (void)pthread_mutex_destroy(&rdmaHandle->cqeErrCntMutex);
391 5 : (void)pthread_mutex_destroy(&rdmaHandle->rdevMutex);
392 5 : }
393 :
394 12 : STATIC int RaHdcLiteCtxInit(struct RaRdmaHandle *rdmaHandle, unsigned int phyId, unsigned int rdevIndex)
395 : {
396 12 : union OpLiteRdevCapData liteRdevCapData = { 0 };
397 12 : int ret = 0;
398 :
399 12 : if (rdmaHandle->supportLite == 0) {
400 1 : return 0;
401 : }
402 :
403 : // register sensor node
404 11 : ret = DlDrvDeviceGetIndexByPhyId(phyId, &rdmaHandle->logicDevid);
405 11 : CHK_PRT_RETURN(ret, hccp_err("[init][ra_hdc_lite_ctx]dl_drv_device_get_index_by_phy_id failed, ret(%d) phyId(%u)",
406 : ret, phyId), ret);
407 11 : ret = RaSensorNodeRegister(phyId, rdmaHandle);
408 11 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra_hdc_lite_ctx]ra_sensor_node_register failed, ret(%d) phyId(%u)",
409 : ret, phyId), ret);
410 :
411 : // alloc ctx
412 11 : ret = RaHdcLiteGetRdevCap(rdmaHandle, phyId, rdevIndex, &liteRdevCapData);
413 11 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra_hdc_lite_ctx]ra_hdc_lite_get_rdev_cap failed, ret(%d) phyId(%u)",
414 : ret, phyId), ret);
415 11 : rdmaHandle->liteCtx = RaRdmaLiteAllocCtx(phyId, &liteRdevCapData.rxData.resp.cap);
416 11 : if (rdmaHandle->liteCtx == NULL) {
417 2 : hccp_err("[init][ra_hdc_lite_ctx]ra_rdma_lite_alloc_ctx errno(%d) phyId(%u)", errno, phyId);
418 2 : ret = -EFAULT;
419 2 : goto unreg_sensor;
420 : }
421 :
422 9 : RA_INIT_LIST_HEAD(&rdmaHandle->qpList);
423 9 : RA_INIT_LIST_HEAD(&rdmaHandle->typicalLiteCqList);
424 :
425 9 : ret = RaHdcLiteMutexInit(rdmaHandle, phyId);
426 9 : if (ret != 0) {
427 1 : goto free_ctx;
428 : }
429 :
430 8 : if (rdmaHandle->disabledLiteThread) {
431 2 : hccp_run_info("lite thread disabled");
432 2 : return 0;
433 : }
434 :
435 6 : rdmaHandle->threadStatus = LITE_THREAD_STATUS_RUNNING;
436 6 : ret = pthread_create(&rdmaHandle->tid, NULL, RaHdcLitePthread, (void *)rdmaHandle);
437 6 : if (ret != 0) {
438 2 : hccp_err("[init][ra_hdc_lite_ctx]pthread_create failed, ret:%d, phyId:%u errno:%d", ret, phyId, errno);
439 2 : rdmaHandle->threadStatus = LITE_THREAD_STATUS_DESTROY;
440 2 : ret = -ESYSFUNC;
441 2 : goto mutex_deinit;
442 : }
443 :
444 4 : return 0;
445 :
446 2 : mutex_deinit:
447 2 : RaHdcLiteMutexDeinit(rdmaHandle);
448 3 : free_ctx:
449 3 : RaRdmaLiteFreeCtx(rdmaHandle->liteCtx);
450 5 : unreg_sensor:
451 5 : (void)DlHalSensorNodeUnregister(rdmaHandle->logicDevid, rdmaHandle->sensorHandle);
452 5 : return ret;
453 : }
454 :
455 9 : int RaHdcLiteInit(struct RaRdmaHandle *rdmaHandle, unsigned int phyId, unsigned int rdevIndex)
456 : {
457 : int ret;
458 :
459 9 : ret = RaHdcGetLiteSupport(rdmaHandle, phyId);
460 9 : if (ret != 0) {
461 1 : hccp_err("[init][ra_hdc_rdev]ra_hdc_get_lite_support failed ret(%d) phyId(%u)", ret, phyId);
462 1 : return ret;
463 : }
464 :
465 8 : ret = RaHdcLiteCtxInit(rdmaHandle, phyId, rdevIndex);
466 8 : if (ret != 0) {
467 3 : hccp_err("[init][ra_hdc_rdev]ra_hdc_lite_ctx_init failed ret(%d) phyId(%u)", ret, phyId);
468 3 : goto free_lite_api;
469 : }
470 :
471 5 : return 0;
472 :
473 3 : free_lite_api:
474 3 : RaHdcRdmaLiteApiDeinit();
475 3 : return ret;
476 : }
477 :
478 10 : void RaHdcLiteDeinit(struct RaRdmaHandle *rdmaHandle)
479 : {
480 : #define FINISH_RUNNING 2
481 : #define THREAD_STATUS_CHANGE_TIMEOUT 100
482 : int i;
483 :
484 10 : if (rdmaHandle->supportLite) {
485 4 : if (rdmaHandle->disabledLiteThread) {
486 1 : goto disabled_thread_out;
487 : }
488 :
489 3 : rdmaHandle->threadStatus = LITE_THREAD_STATUS_DESTROY;
490 : // wait thread change to finish running status(2), wait 100 times(total cost: 1s) until timeout
491 6 : for (i = 0; i < THREAD_STATUS_CHANGE_TIMEOUT && rdmaHandle->threadStatus != FINISH_RUNNING; i++) {
492 3 : usleep(RA_LITE_POLL_CQE_PERIOD_TIME);
493 : }
494 : // thread not in finish running status(2), report timeout
495 3 : if (rdmaHandle->threadStatus != FINISH_RUNNING) {
496 0 : hccp_run_info("hdc wait thread tid:%lu finish running timeout, thread status:%d",
497 : rdmaHandle->tid, rdmaHandle->threadStatus);
498 : }
499 :
500 3 : disabled_thread_out:
501 4 : if (!RaListEmpty(&rdmaHandle->typicalLiteCqList)) {
502 : struct TypicalLiteCqEntry *entry;
503 : struct TypicalLiteCqEntry *tmp;
504 0 : RA_LIST_GET_HEAD_ENTRY(tmp, entry, &rdmaHandle->typicalLiteCqList,
505 : list, struct TypicalLiteCqEntry);
506 0 : while (&tmp->list != &rdmaHandle->typicalLiteCqList) {
507 0 : entry = list_entry(tmp->list.next, struct TypicalLiteCqEntry, list);
508 0 : RaListDel(&tmp->list);
509 0 : free(tmp);
510 0 : tmp = entry;
511 : }
512 : }
513 4 : RaHdcLiteMutexDeinit(rdmaHandle);
514 4 : RaRdmaLiteFreeCtx(rdmaHandle->liteCtx);
515 4 : RaHdcRdmaLiteApiDeinit();
516 4 : (void)DlHalSensorNodeUnregister(rdmaHandle->logicDevid, rdmaHandle->sensorHandle);
517 : }
518 10 : }
519 :
520 0 : int RaHdcLiteGetCqAttr(struct RaRdmaHandle *rdmaHandle, unsigned int cqn,
521 : struct rdma_lite_device_cq_attr *deviceCqAttr)
522 : {
523 0 : union OpGetLiteCqAttrData getLiteCqAttrData = {0};
524 0 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
525 : int ret;
526 :
527 0 : getLiteCqAttrData.txData.phyId = phyId;
528 0 : getLiteCqAttrData.txData.rdevIndex = rdmaHandle->rdevIndex;
529 0 : getLiteCqAttrData.txData.cqn = cqn;
530 :
531 0 : ret = RaHdcProcessMsg(RA_RS_GET_LITE_CQ_ATTR, phyId, (char *)&getLiteCqAttrData,
532 : sizeof(union OpGetLiteCqAttrData));
533 0 : if (ret) {
534 0 : hccp_err("[create][ra_hdc_lite_get_cq_attr]ra hdc message process failed ret(%d) phyId(%u)", ret, phyId);
535 0 : return ret;
536 : }
537 :
538 0 : *deviceCqAttr = getLiteCqAttrData.rxData.deviceCqAttr;
539 0 : hccp_info("[create][ra_hdc_lite_get_cq_attr]get lite cq attr success, cqn[%u] depth[%u]",
540 : cqn, deviceCqAttr->depth);
541 0 : return 0;
542 : }
543 :
544 0 : int RaHdcLiteCqCreate(struct RaRdmaHandle *rdmaHandle, unsigned int cqDepth,
545 : union OpTypicalCqCreateData *cqData, struct rdma_lite_cq **liteCq)
546 : {
547 0 : struct rdma_lite_cq_attr liteCqAttr = {0};
548 0 : struct rdma_lite_device_cq_attr deviceCqAttr = {0};
549 : int ret;
550 :
551 0 : if (rdmaHandle->supportLite == 0) {
552 0 : hccp_warn("[RaHdcLiteCqCreate]rdmaHandle->supportLite = 0");
553 0 : return 0;
554 : }
555 :
556 0 : ret = RaHdcLiteGetCqAttr(rdmaHandle, cqData->rxData.cqn, &deviceCqAttr);
557 0 : if (ret) {
558 0 : hccp_err("[create][ra_hdc_lite_cq]get lite cq attr failed, cqn[%u] ret[%d]",
559 : cqData->rxData.cqn, ret);
560 0 : return ret;
561 : }
562 :
563 0 : liteCqAttr.device_cq_attr = deviceCqAttr;
564 0 : liteCqAttr.mem_idx = 0;
565 :
566 0 : if (rdmaHandle->supportLite == LITE_ALIGN_2MB) {
567 0 : liteCqAttr.mem_idx = 0;
568 : }
569 :
570 0 : *liteCq = RaRdmaLiteCreateCq(rdmaHandle->liteCtx, &liteCqAttr);
571 0 : if (*liteCq == NULL) {
572 0 : hccp_err("[create][ra_hdc_lite_cq]create lite cq failed, errno(%d) cqDepth(%u)",
573 : errno, cqDepth);
574 0 : return -EFAULT;
575 : }
576 :
577 0 : RaHdcLiteStoreTypicalCq(rdmaHandle, cqData->rxData.cqn, *liteCq, &deviceCqAttr);
578 :
579 0 : hccp_info("[create][ra_hdc_lite_cq]lite cq created successfully, cqDepth(%u), liteCq[%p]", cqDepth, *liteCq);
580 :
581 0 : return 0;
582 : }
583 :
584 3 : STATIC void RaHdcLiteQpAttrInit(struct RaQpHandle *qpHdc, struct rdma_lite_qp_attr *liteQpAttr,
585 : struct rdma_lite_qp_cap *cap)
586 : {
587 3 : liteQpAttr->send_cq = qpHdc->sendLiteCq;
588 3 : liteQpAttr->recv_cq = qpHdc->recvLiteCq;
589 3 : liteQpAttr->qp_mode = qpHdc->qpMode;
590 3 : liteQpAttr->qp_type = RDMA_LITE_QPT_RC;
591 3 : liteQpAttr->cap.max_inline_data = cap->max_inline_data;
592 3 : liteQpAttr->cap.max_send_sge = cap->max_send_sge;
593 3 : liteQpAttr->cap.max_recv_sge = cap->max_recv_sge;
594 3 : liteQpAttr->cap.max_send_wr = cap->max_send_wr;
595 3 : liteQpAttr->cap.max_recv_wr = cap->max_recv_wr;
596 3 : }
597 :
598 3 : STATIC int RaHdcLiteInitMemPool(struct RaRdmaHandle *rdmaHandle, struct RaQpHandle *qpHdc,
599 : struct rdma_lite_cq_attr *liteSendCqAttr, struct rdma_lite_cq_attr *liteRecvCqAttr,
600 : struct rdma_lite_qp_attr *liteQpAttr)
601 : {
602 3 : union OpLiteMemAttrData liteMemAttrData = { 0 };
603 3 : unsigned int phyId = qpHdc->phyId;
604 : int ret;
605 :
606 3 : if (rdmaHandle->supportLite != LITE_ALIGN_2MB) {
607 3 : return 0;
608 : }
609 :
610 0 : liteMemAttrData.txData.phyId = phyId;
611 0 : liteMemAttrData.txData.rdevIndex = rdmaHandle->rdevIndex;
612 0 : liteMemAttrData.txData.qpn = qpHdc->qpn;
613 0 : ret = RaHdcProcessMsg(RA_RS_GET_LITE_MEM_ATTR, phyId, (char *)&liteMemAttrData,
614 : sizeof(union OpLiteMemAttrData));
615 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp]ra hdc message process failed ret(%d) phyId(%u)",
616 : ret, phyId), ret);
617 :
618 0 : ret = RaRdmaLiteInitMemPool(rdmaHandle->liteCtx,
619 : (struct rdma_lite_mem_attr *)&liteMemAttrData.rxData.resp.memData);
620 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp]ra_rdma_lite_init_mem_pool failed ret(%d) phyId(%u)",
621 : ret, phyId), ret);
622 :
623 0 : qpHdc->memIdx = liteMemAttrData.rxData.resp.memData.mem_idx;
624 0 : liteSendCqAttr->mem_idx = qpHdc->memIdx;
625 0 : liteRecvCqAttr->mem_idx = qpHdc->memIdx;
626 0 : liteQpAttr->mem_idx = qpHdc->memIdx;
627 0 : return 0;
628 : }
629 :
630 0 : STATIC void RaHdcLiteDeinitMemPool(struct RaRdmaHandle *rdmaHandle, struct RaQpHandle *qpHdc)
631 : {
632 0 : unsigned int phyId = qpHdc->phyId;
633 : int ret;
634 :
635 0 : if (rdmaHandle->supportLite != LITE_ALIGN_2MB) {
636 0 : return;
637 : }
638 :
639 0 : ret = RaRdmaLiteDeinitMemPool(rdmaHandle->liteCtx, qpHdc->memIdx);
640 0 : if (ret != 0) {
641 0 : hccp_err("[create][ra_hdc_lite_qp]ra_rdma_lite_deinit_mem_pool failed ret(%d) phyId(%u)", ret, phyId);
642 : }
643 0 : return;
644 : }
645 :
646 3 : STATIC int RaHdcLiteGetCqQpAttr(struct RaQpHandle *qpHdc, struct rdma_lite_cq_attr *liteSendCqAttr,
647 : struct rdma_lite_cq_attr *liteRecvCqAttr, struct rdma_lite_qp_attr *liteQpAttr)
648 : {
649 3 : union OpLiteQpCqAttrData liteQpCqAttrData = { 0 };
650 3 : unsigned int phyId = qpHdc->phyId;
651 : int ret;
652 :
653 3 : liteQpCqAttrData.txData.phyId = phyId;
654 3 : liteQpCqAttrData.txData.rdevIndex = qpHdc->rdevIndex;
655 3 : liteQpCqAttrData.txData.qpn = qpHdc->qpn;
656 3 : ret = RaHdcProcessMsg(RA_RS_GET_LITE_QP_CQ_ATTR, phyId, (char *)&liteQpCqAttrData,
657 : sizeof(union OpLiteQpCqAttrData));
658 3 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp]ra hdc message process failed ret(%d) phyId(%u)",
659 : ret, phyId), ret);
660 :
661 3 : qpHdc->dbIndex = liteQpCqAttrData.rxData.resp.qpData.qp_info;
662 3 : liteSendCqAttr->device_cq_attr = liteQpCqAttrData.rxData.resp.sendCqData;
663 3 : liteRecvCqAttr->device_cq_attr = liteQpCqAttrData.rxData.resp.recvCqData;
664 3 : ret = memcpy_s((void *)&(liteQpAttr->device_qp_attr), sizeof(liteQpAttr->device_qp_attr),
665 : (void *)&liteQpCqAttrData.rxData.resp.qpData, sizeof(liteQpCqAttrData.rxData.resp.qpData));
666 3 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp]memcpy_s failed ret(%d) phyId(%u)",
667 : ret, phyId), ret);
668 :
669 3 : return 0;
670 : }
671 :
672 0 : int RaHdcLiteGetQpAttr(struct RaQpHandle *qpHdc, struct rdma_lite_qp_attr *liteQpAttr)
673 : {
674 0 : union OpLiteQpAttrData liteQpAttrData = { 0 };
675 0 : unsigned int phyId = qpHdc->phyId;
676 : int ret;
677 :
678 0 : liteQpAttrData.txData.phyId = phyId;
679 0 : liteQpAttrData.txData.rdevIndex = qpHdc->rdevIndex;
680 0 : liteQpAttrData.txData.qpn = qpHdc->qpn;
681 0 : ret = RaHdcProcessMsg(RA_RS_GET_LITE_QP_ATTR, phyId, (char *)&liteQpAttrData,
682 : sizeof(union OpLiteQpAttrData));
683 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp]ra hdc message process failed ret(%d) phyId(%u)",
684 : ret, phyId), ret);
685 :
686 0 : qpHdc->dbIndex = liteQpAttrData.rxData.resp.qpData.qp_info;
687 0 : ret = memcpy_s((void *)&(liteQpAttr->device_qp_attr), sizeof(liteQpAttr->device_qp_attr),
688 : (void *)&liteQpAttrData.rxData.resp.qpData, sizeof(liteQpAttrData.rxData.resp.qpData));
689 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp]memcpy_s failed ret(%d) phyId(%u)",
690 : ret, phyId), ret);
691 :
692 0 : return 0;
693 : }
694 :
695 9 : int RaHdcLiteQpCreate(struct RaRdmaHandle *rdmaHandle, struct RaQpHandle *qpHdc,
696 : struct rdma_lite_qp_cap *cap)
697 : {
698 9 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
699 9 : struct rdma_lite_cq_attr liteSendCqAttr = { 0 };
700 9 : struct rdma_lite_cq_attr liteRecvCqAttr = { 0 };
701 9 : struct rdma_lite_qp_attr liteQpAttr = { 0 };
702 : int ret;
703 :
704 : // not support rdma lite or not op mode qp
705 9 : if (rdmaHandle->supportLite == 0 || (qpHdc->qpMode != RA_RS_OP_QP_MODE && qpHdc->qpMode != RA_RS_OP_QP_MODE_EXT)) {
706 6 : return 0;
707 : }
708 :
709 3 : ret = RaHdcLiteGetCqQpAttr(qpHdc, &liteSendCqAttr, &liteRecvCqAttr, &liteQpAttr);
710 3 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp]ra_hdc_lite_get_cq_qp_attr failed ret(%d) phyId(%u)",
711 : ret, phyId), ret);
712 :
713 3 : ret = RaHdcLiteInitMemPool(rdmaHandle, qpHdc, &liteSendCqAttr, &liteRecvCqAttr, &liteQpAttr);
714 3 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp]ra_hdc_lite_init_mem_pool failed ret(%d) phyId(%u)",
715 : ret, phyId), -EFAULT);
716 :
717 3 : qpHdc->sendLiteCq = RaRdmaLiteCreateCq(rdmaHandle->liteCtx, &liteSendCqAttr);
718 3 : if (qpHdc->sendLiteCq == NULL) {
719 0 : hccp_err("[create][ra_hdc_lite_qp]create send_lite_cq failed, errno(%d) phyId(%u)", errno, phyId);
720 0 : ret = -EFAULT;
721 0 : goto free_mem_pool;
722 : }
723 :
724 3 : qpHdc->recvLiteCq = RaRdmaLiteCreateCq(rdmaHandle->liteCtx, &liteRecvCqAttr);
725 3 : if (qpHdc->recvLiteCq == NULL) {
726 0 : hccp_err("[create][ra_hdc_lite_qp]create recv_lite_cq failed, errno(%d) phyId(%u)", errno, phyId);
727 0 : ret = -EFAULT;
728 0 : goto free_send_lite_cq;
729 : }
730 :
731 3 : RaHdcLiteQpAttrInit(qpHdc, &liteQpAttr, cap);
732 3 : qpHdc->liteQp = RaRdmaLiteCreateQp(rdmaHandle->liteCtx, &liteQpAttr);
733 3 : if (qpHdc->liteQp == NULL) {
734 0 : hccp_err("[create][ra_hdc_lite_qp]ra_rdma_lite_create_qp failed, errno(%d) phyId(%u)", errno, phyId);
735 0 : ret = -EFAULT;
736 0 : goto free_recv_lite_cq;
737 : }
738 :
739 3 : ret = pthread_mutex_init(&qpHdc->qpMutex, NULL);
740 3 : if (ret != 0) {
741 0 : hccp_err("[create][ra_hdc_lite_qp]pthread_mutex_init failed ret(%d) phyId(%u)", ret, phyId);
742 0 : goto free_lite_qp;
743 : }
744 :
745 3 : ret = pthread_mutex_init(&qpHdc->cqeErrInfo.mutex, NULL);
746 3 : if (ret != 0) {
747 0 : hccp_err("[create][ra_hdc_lite_qp]pthread_mutex_init failed ret(%d) phyId(%u)", ret, phyId);
748 0 : (void)pthread_mutex_destroy(&qpHdc->qpMutex);
749 0 : goto free_lite_qp;
750 : }
751 :
752 3 : qpHdc->liteWc = calloc(MAX_POLL_CQE_NUM, sizeof(struct rdma_lite_wc));
753 3 : if (qpHdc->liteWc == NULL) {
754 0 : ret = -ENOMEM;
755 0 : (void)pthread_mutex_destroy(&qpHdc->qpMutex);
756 0 : (void)pthread_mutex_destroy(&qpHdc->cqeErrInfo.mutex);
757 0 : hccp_err("[create][ra_hdc_lite_qp]lite_wc calloc failed phyId(%u)", phyId);
758 0 : goto free_lite_qp;
759 : }
760 :
761 3 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->rdevMutex);
762 3 : RaListAddTail(&qpHdc->list, &rdmaHandle->qpList);
763 3 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->rdevMutex);
764 :
765 3 : qpHdc->supportLite = rdmaHandle->supportLite;
766 :
767 3 : return 0;
768 :
769 0 : free_lite_qp:
770 0 : (void)RaRdmaLiteDestroyQp(qpHdc->liteQp);
771 0 : free_recv_lite_cq:
772 0 : (void)RaRdmaLiteDestroyCq(qpHdc->recvLiteCq);
773 0 : free_send_lite_cq:
774 0 : (void)RaRdmaLiteDestroyCq(qpHdc->sendLiteCq);
775 0 : free_mem_pool:
776 0 : RaHdcLiteDeinitMemPool(rdmaHandle, qpHdc);
777 0 : return ret;
778 : }
779 :
780 12 : void RaHdcLiteQpDestroy(struct RaQpHandle *qpHdc)
781 : {
782 12 : if ((qpHdc->supportLite != LITE_NOT_SUPPORT) &&
783 3 : (qpHdc->qpMode == RA_RS_OP_QP_MODE || qpHdc->qpMode == RA_RS_OP_QP_MODE_EXT)) {
784 3 : RA_PTHREAD_MUTEX_LOCK(&qpHdc->rdmaHandle->rdevMutex);
785 3 : RaListDel(&qpHdc->list);
786 3 : RA_PTHREAD_MUTEX_UNLOCK(&qpHdc->rdmaHandle->rdevMutex);
787 :
788 3 : free(qpHdc->liteWc);
789 3 : qpHdc->liteWc = NULL;
790 3 : (void)pthread_mutex_destroy(&qpHdc->qpMutex);
791 3 : (void)pthread_mutex_destroy(&qpHdc->cqeErrInfo.mutex);
792 3 : (void)RaRdmaLiteDestroyQp(qpHdc->liteQp);
793 3 : qpHdc->liteQp = NULL;
794 3 : (void)RaRdmaLiteDestroyCq(qpHdc->sendLiteCq);
795 3 : qpHdc->sendLiteCq = NULL;
796 3 : (void)RaRdmaLiteDestroyCq(qpHdc->recvLiteCq);
797 3 : qpHdc->recvLiteCq = NULL;
798 3 : if (qpHdc->supportLite == LITE_ALIGN_2MB) {
799 0 : (void)RaRdmaLiteDeinitMemPool(qpHdc->rdmaHandle->liteCtx, qpHdc->memIdx);
800 : }
801 : }
802 12 : }
803 :
804 0 : void RaHdcLiteQpDestroyWithoutCQ(struct RaQpHandle *verbsQpHdc)
805 : {
806 0 : if ((verbsQpHdc->supportLite != LITE_NOT_SUPPORT) &&
807 0 : (verbsQpHdc->qpMode == RA_RS_OP_QP_MODE || verbsQpHdc->qpMode == RA_RS_OP_QP_MODE_EXT)) {
808 0 : RA_PTHREAD_MUTEX_LOCK(&verbsQpHdc->rdmaHandle->rdevMutex);
809 0 : RaListDel(&verbsQpHdc->list);
810 0 : RA_PTHREAD_MUTEX_UNLOCK(&verbsQpHdc->rdmaHandle->rdevMutex);
811 :
812 0 : free(verbsQpHdc->liteWc);
813 0 : verbsQpHdc->liteWc = NULL;
814 0 : (void)pthread_mutex_destroy(&verbsQpHdc->qpMutex);
815 0 : (void)pthread_mutex_destroy(&verbsQpHdc->cqeErrInfo.mutex);
816 0 : (void)RaRdmaLiteDestroyQp(verbsQpHdc->liteQp);
817 0 : verbsQpHdc->liteQp = NULL;
818 0 : if (verbsQpHdc->supportLite == LITE_ALIGN_2MB) {
819 0 : (void)RaRdmaLiteDeinitMemPool(verbsQpHdc->rdmaHandle->liteCtx, verbsQpHdc->memIdx);
820 : }
821 : }
822 0 : }
823 :
824 0 : int RaHdcLiteQpCreateWithCQ(struct RaRdmaHandle *rdmaHandle, struct RaQpHandle *qpHdc,
825 : struct rdma_lite_qp_cap *cap, struct rdma_lite_cq *sendLiteCq, struct rdma_lite_cq *recvLiteCq,
826 : unsigned int sendCqn, unsigned int recvCqn)
827 : {
828 0 : struct rdma_lite_device_cq_attr *storedSendCqAttr = NULL;
829 0 : struct rdma_lite_device_cq_attr *storedRecvCqAttr = NULL;
830 0 : struct rdma_lite_cq_attr liteSendCqAttr = { 0 };
831 0 : struct rdma_lite_cq_attr liteRecvCqAttr = { 0 };
832 0 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
833 0 : struct rdma_lite_qp_attr liteQpAttr = { 0 };
834 : int ret;
835 :
836 0 : if (rdmaHandle->supportLite == 0 || (qpHdc->qpMode != RA_RS_OP_QP_MODE && qpHdc->qpMode != RA_RS_OP_QP_MODE_EXT)) {
837 0 : return 0;
838 : }
839 :
840 0 : hccp_info("[QP_PATH][ra_hdc_lite_qp_with_cq]RaHdcLiteQpCreateWithCQ NEW path, phyId[%u] sendCqn[%u] recvCqn[%u]",
841 : phyId, sendCqn, recvCqn);
842 :
843 0 : ret = RaHdcLiteGetQpAttr(qpHdc, &liteQpAttr);
844 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp_with_cq]get qp attr failed ret(%d) phyId(%u)",
845 : ret, phyId), ret);
846 :
847 0 : ret = RaHdcLiteFindTypicalCqAttr(rdmaHandle, sendCqn, &storedSendCqAttr);
848 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp_with_cq]find send cq attr failed phyId(%u) cqn(%u)",
849 : phyId, sendCqn), ret);
850 0 : ret = RaHdcLiteFindTypicalCqAttr(rdmaHandle, recvCqn, &storedRecvCqAttr);
851 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp_with_cq]find recv cq attr failed phyId(%u) cqn(%u)",
852 : phyId, recvCqn), ret);
853 0 : liteSendCqAttr.device_cq_attr = *storedSendCqAttr;
854 0 : liteRecvCqAttr.device_cq_attr = *storedRecvCqAttr;
855 :
856 0 : ret = RaHdcLiteInitMemPool(rdmaHandle, qpHdc, &liteSendCqAttr, &liteRecvCqAttr, &liteQpAttr);
857 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[create][ra_hdc_lite_qp_with_cq]ra_hdc_lite_init_mem_pool failed ret(%d) phyId(%u)",
858 : ret, phyId), -EFAULT);
859 :
860 0 : qpHdc->sendLiteCq = sendLiteCq;
861 0 : qpHdc->recvLiteCq = recvLiteCq;
862 :
863 0 : RaHdcLiteQpAttrInit(qpHdc, &liteQpAttr, cap);
864 0 : qpHdc->liteQp = RaRdmaLiteCreateQp(rdmaHandle->liteCtx, &liteQpAttr);
865 0 : if (qpHdc->liteQp == NULL) {
866 0 : hccp_err("[create][ra_hdc_lite_qp_with_cq]ra_rdma_lite_create_qp failed, errno(%d) phyId(%u)", errno, phyId);
867 0 : ret = -EFAULT;
868 0 : goto free_mem_pool;
869 : }
870 :
871 0 : ret = pthread_mutex_init(&qpHdc->qpMutex, NULL);
872 0 : if (ret != 0) {
873 0 : hccp_err("[create][ra_hdc_lite_qp_with_cq]pthread_mutex_init failed ret(%d) phyId(%u)", ret, phyId);
874 0 : goto free_lite_qp;
875 : }
876 :
877 0 : ret = pthread_mutex_init(&qpHdc->cqeErrInfo.mutex, NULL);
878 0 : if (ret != 0) {
879 0 : hccp_err("[create][ra_hdc_lite_qp_with_cq]pthread_mutex_init failed ret(%d) phyId(%u)", ret, phyId);
880 0 : (void)pthread_mutex_destroy(&qpHdc->qpMutex);
881 0 : goto free_lite_qp;
882 : }
883 :
884 0 : qpHdc->liteWc = calloc(MAX_POLL_CQE_NUM, sizeof(struct rdma_lite_wc));
885 0 : if (qpHdc->liteWc == NULL) {
886 0 : ret = -ENOMEM;
887 0 : (void)pthread_mutex_destroy(&qpHdc->qpMutex);
888 0 : (void)pthread_mutex_destroy(&qpHdc->cqeErrInfo.mutex);
889 0 : hccp_err("[create][ra_hdc_lite_qp_with_cq]lite_wc calloc failed phyId(%u)", phyId);
890 0 : goto free_lite_qp;
891 : }
892 :
893 0 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->rdevMutex);
894 0 : RaListAddTail(&qpHdc->list, &rdmaHandle->qpList);
895 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->rdevMutex);
896 :
897 0 : qpHdc->supportLite = rdmaHandle->supportLite;
898 :
899 0 : return 0;
900 :
901 0 : free_lite_qp:
902 0 : (void)RaRdmaLiteDestroyQp(qpHdc->liteQp);
903 0 : free_mem_pool:
904 0 : RaHdcLiteDeinitMemPool(rdmaHandle, qpHdc);
905 0 : return ret;
906 : }
907 :
908 2 : int RaHdcLiteGetConnectedInfo(struct RaQpHandle *qpHdc)
909 : {
910 : int ret;
911 2 : union OpLiteConnectedInfoData liteConnectedInfoData = { {0} };
912 :
913 2 : if ((qpHdc->supportLite != LITE_NOT_SUPPORT) &&
914 0 : (qpHdc->qpMode == RA_RS_OP_QP_MODE || qpHdc->qpMode == RA_RS_OP_QP_MODE_EXT)) {
915 0 : liteConnectedInfoData.txData.phyId = qpHdc->phyId;
916 0 : liteConnectedInfoData.txData.rdevIndex = qpHdc->rdevIndex;
917 0 : liteConnectedInfoData.txData.qpn = qpHdc->qpn;
918 0 : ret = RaHdcProcessMsg(RA_RS_GET_LITE_CONNECTED_INFO, qpHdc->phyId, (char *)&liteConnectedInfoData,
919 : sizeof(union OpLiteConnectedInfoData));
920 0 : CHK_PRT_RETURN(ret, hccp_err("[get][ra_hdc_lite_connect]ra hdc message process failed ret(%d) phyId(%u)",
921 : ret, qpHdc->phyId), ret);
922 :
923 0 : ret = memcpy_s((void *)&qpHdc->localMr[0],
924 : sizeof(qpHdc->localMr),
925 : (void *)&liteConnectedInfoData.rxData.resp.localMr[0],
926 : sizeof(liteConnectedInfoData.rxData.resp.localMr));
927 0 : CHK_PRT_RETURN(ret, hccp_err("[recv][ra_hdc_lite_connect]memcpy_s local_mr failed, ret(%d) phyId(%u)",
928 : ret, qpHdc->phyId), -ESAFEFUNC);
929 :
930 0 : ret = memcpy_s((void *)&qpHdc->remMr[0],
931 : sizeof(qpHdc->remMr),
932 : (void *)&liteConnectedInfoData.rxData.resp.remMr[0],
933 : sizeof(liteConnectedInfoData.rxData.resp.remMr));
934 0 : CHK_PRT_RETURN(ret, hccp_err("[recv][ra_hdc_lite_connect]memcpy_s rem_mr failed, ret(%d) phyId(%u)",
935 : ret, qpHdc->phyId), -ESAFEFUNC);
936 :
937 0 : ret = RaRdmaLiteSetQpSl(qpHdc->liteQp, liteConnectedInfoData.rxData.resp.qosAttr.sl);
938 0 : CHK_PRT_RETURN(ret, hccp_err("[get][ra_hdc_lite_connect]ra_rdma_lite_set_qp_sl failed ret(%d) phyId(%u)",
939 : ret, qpHdc->phyId), ret);
940 : }
941 :
942 2 : return 0;
943 : }
944 :
945 0 : void RaHdcLiteGetCqeErrInfo(unsigned int phyId, struct CqeErrInfo *info)
946 : {
947 0 : struct RaCqeErrInfo *errInfo = &gRaCqeErr[phyId];
948 0 : struct CqeErrInfo *tempInfo = &errInfo->info;
949 :
950 0 : RA_PTHREAD_MUTEX_LOCK(&errInfo->mutex);
951 0 : info->qpn = tempInfo->qpn;
952 0 : info->status = tempInfo->status;
953 0 : info->time = tempInfo->time;
954 0 : (void)memset_s(&errInfo->info, sizeof(struct CqeErrInfo), 0, sizeof(struct CqeErrInfo));
955 0 : RA_PTHREAD_MUTEX_UNLOCK(&errInfo->mutex);
956 0 : }
957 :
958 0 : int RaHdcLiteGetCqeErrInfoList(struct RaRdmaHandle *rdmaHandle, struct CqeErrInfo *infoList,
959 : unsigned int *num)
960 : {
961 0 : struct RaQpHandle *qpHdcTmp1 = NULL;
962 0 : struct RaQpHandle *qpHdcTmp = NULL;
963 0 : unsigned int cqeErrIdx = 0;
964 0 : unsigned int numTmp = 0;
965 :
966 : // not support lite
967 0 : if (rdmaHandle->supportLite == 0) {
968 0 : *num = 0;
969 0 : return 0;
970 : }
971 :
972 : // no cqe err or no qp
973 0 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->cqeErrCntMutex);
974 0 : if (rdmaHandle->cqeErrCnt == 0) {
975 0 : *num = 0;
976 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->cqeErrCntMutex);
977 0 : return 0;
978 : }
979 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->cqeErrCntMutex);
980 :
981 0 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->rdevMutex);
982 0 : if (RaListEmpty(&rdmaHandle->qpList)) {
983 0 : *num = 0;
984 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->rdevMutex);
985 0 : return 0;
986 : }
987 :
988 : // get & clear cqe err info from qp
989 0 : numTmp = *num;
990 0 : RA_LIST_GET_HEAD_ENTRY(qpHdcTmp, qpHdcTmp1, &rdmaHandle->qpList, list, struct RaQpHandle);
991 0 : for (; (&qpHdcTmp->list) != &rdmaHandle->qpList;
992 0 : qpHdcTmp = qpHdcTmp1, qpHdcTmp1 = list_entry(qpHdcTmp1->list.next, struct RaQpHandle, list)) {
993 0 : RA_PTHREAD_MUTEX_LOCK(&qpHdcTmp->cqeErrInfo.mutex);
994 0 : if (qpHdcTmp->cqeErrInfo.info.status == 0) {
995 0 : RA_PTHREAD_MUTEX_UNLOCK(&qpHdcTmp->cqeErrInfo.mutex);
996 0 : continue;
997 : }
998 0 : infoList[cqeErrIdx].status = qpHdcTmp->cqeErrInfo.info.status;
999 0 : infoList[cqeErrIdx].qpn = qpHdcTmp->cqeErrInfo.info.qpn;
1000 0 : infoList[cqeErrIdx].time = qpHdcTmp->cqeErrInfo.info.time;
1001 0 : qpHdcTmp->cqeErrInfo.info.status = 0;
1002 0 : RA_PTHREAD_MUTEX_UNLOCK(&qpHdcTmp->cqeErrInfo.mutex);
1003 :
1004 0 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->cqeErrCntMutex);
1005 0 : rdmaHandle->cqeErrCnt--;
1006 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->cqeErrCntMutex);
1007 0 : cqeErrIdx++;
1008 0 : if (cqeErrIdx >= numTmp) {
1009 0 : break;
1010 : }
1011 : }
1012 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->rdevMutex);
1013 :
1014 0 : *num = cqeErrIdx;
1015 0 : return 0;
1016 : }
1017 :
1018 0 : STATIC void RaHdcLiteSaveCqeErrInfo(struct RaQpHandle *qpHdc, unsigned int status)
1019 : {
1020 0 : unsigned int phyId = qpHdc->phyId;
1021 0 : struct RaCqeErrInfo *errInfo = &gRaCqeErr[phyId];
1022 0 : struct CqeErrInfo *tempInfo = &errInfo->info;
1023 :
1024 0 : RA_PTHREAD_MUTEX_LOCK(&errInfo->mutex);
1025 0 : if (tempInfo->status != 0) {
1026 0 : hccp_run_info("over status=[0x%x], drop qpn[0x%x] err cqe status[0x%x]",
1027 : tempInfo->status, qpHdc->qpn, status);
1028 0 : RA_PTHREAD_MUTEX_UNLOCK(&errInfo->mutex);
1029 0 : return;
1030 : }
1031 0 : tempInfo->status = status;
1032 0 : tempInfo->qpn = qpHdc->qpn;
1033 0 : (void)gettimeofday(&tempInfo->time, NULL);
1034 0 : RA_PTHREAD_MUTEX_UNLOCK(&errInfo->mutex);
1035 : }
1036 :
1037 0 : STATIC void RaHdcLiteSaveQpCqeErrInfo(struct RaQpHandle *qpHdc, unsigned int status)
1038 : {
1039 0 : RA_PTHREAD_MUTEX_LOCK(&qpHdc->cqeErrInfo.mutex);
1040 0 : if (qpHdc->cqeErrInfo.info.status != 0) {
1041 0 : RA_PTHREAD_MUTEX_UNLOCK(&qpHdc->cqeErrInfo.mutex);
1042 0 : return;
1043 : }
1044 0 : qpHdc->cqeErrInfo.info.status = status;
1045 0 : qpHdc->cqeErrInfo.info.qpn = (uint32_t)qpHdc->qpn;
1046 0 : (void)gettimeofday(&qpHdc->cqeErrInfo.info.time, NULL);
1047 0 : RA_PTHREAD_MUTEX_UNLOCK(&qpHdc->cqeErrInfo.mutex);
1048 :
1049 0 : RA_PTHREAD_MUTEX_LOCK(&qpHdc->rdmaHandle->cqeErrCntMutex);
1050 0 : qpHdc->rdmaHandle->cqeErrCnt++;
1051 0 : RA_PTHREAD_MUTEX_UNLOCK(&qpHdc->rdmaHandle->cqeErrCntMutex);
1052 0 : return;
1053 : }
1054 :
1055 27 : int RaHdcLiteInitCqeErrInfo(unsigned int phyId)
1056 : {
1057 : int ret;
1058 27 : struct RaCqeErrInfo *errInfo = &gRaCqeErr[phyId];
1059 :
1060 27 : ret = pthread_mutex_init(&errInfo->mutex, NULL);
1061 27 : CHK_PRT_RETURN(ret, hccp_err("cqe err mutex_init failed ret %d!, normal ret 0", ret), -ESYSFUNC);
1062 :
1063 27 : (void)memset_s(&errInfo->info, sizeof(struct CqeErrInfo), 0, sizeof(struct CqeErrInfo));
1064 :
1065 27 : return 0;
1066 : }
1067 :
1068 28 : void RaHdcLiteDeinitCqeErrInfo(unsigned int phyId)
1069 : {
1070 28 : struct RaCqeErrInfo *errInfo = &gRaCqeErr[phyId];
1071 :
1072 28 : (void)pthread_mutex_destroy(&errInfo->mutex);
1073 28 : }
1074 :
1075 0 : STATIC void RaRetryTimeoutExceptionCheck(struct RaRdmaHandle *rdmaHandle, struct rdma_lite_wc *wc)
1076 : {
1077 0 : int ret = 0;
1078 :
1079 0 : if (rdmaHandle->sensorHandle == 0) {
1080 0 : return;
1081 : }
1082 :
1083 0 : if (wc->status != RDMA_LITE_WC_RETRY_EXC_ERR) {
1084 0 : return;
1085 : }
1086 :
1087 : /* The notification alarm framework does not filter alarms. In this example, only one notification
1088 : alarm is reported by a single process, which does not need to be accurate. Therefore, no lock is used. */
1089 0 : if (rdmaHandle->sensorUpdateCnt == 0) {
1090 0 : ret = DlHalSensorNodeUpdateState(rdmaHandle->logicDevid, rdmaHandle->sensorHandle,
1091 : RDMA_CQE_ERR_RETRY_TIMEOUT_EVENT_TYPE, GENERAL_EVENT_TYPE_ONE_TIME);
1092 0 : if (ret == 0) {
1093 0 : rdmaHandle->sensorUpdateCnt++;
1094 : }
1095 : }
1096 :
1097 0 : hccp_warn("update sensor state logic_devid(%u), qpn(%u), sensorUpdateCnt(%d), ret(%d)\n",
1098 : rdmaHandle->logicDevid, wc->qp_num, rdmaHandle->sensorUpdateCnt, ret);
1099 : }
1100 :
1101 1 : STATIC void RaHdcLitePeriodPollCqe(struct RaRdmaHandle *rdmaHandle)
1102 : {
1103 : int i;
1104 1 : int ret = 0;
1105 : struct rdma_lite_wc *liteWc;
1106 : unsigned int sentWr, pollCqe;
1107 1 : struct RaQpHandle *qpHdcTmp = NULL;
1108 1 : struct RaQpHandle *qpHdcTmp1 = NULL;
1109 :
1110 1 : RA_LIST_GET_HEAD_ENTRY(qpHdcTmp, qpHdcTmp1, &rdmaHandle->qpList, list, struct RaQpHandle);
1111 1 : for (; (&qpHdcTmp->list) != &rdmaHandle->qpList;
1112 0 : qpHdcTmp = qpHdcTmp1, qpHdcTmp1 = list_entry(qpHdcTmp1->list.next, struct RaQpHandle, list)) {
1113 0 : sentWr = qpHdcTmp->sendWrNum;
1114 0 : pollCqe = sentWr - qpHdcTmp->pollCqeNum;
1115 :
1116 0 : if (pollCqe == 0) {
1117 0 : continue;
1118 : }
1119 :
1120 0 : liteWc = calloc(pollCqe, sizeof(struct rdma_lite_wc));
1121 0 : if (liteWc == NULL) {
1122 0 : hccp_err("[create][ra_hdc_period_poll]lite_wc calloc failed phyId(%u)", qpHdcTmp->phyId);
1123 0 : break;
1124 : }
1125 :
1126 0 : ret = RaRdmaLitePollCq(qpHdcTmp->sendLiteCq, pollCqe, liteWc);
1127 0 : if (ret < 0) {
1128 0 : hccp_err("ra_rdma_lite_poll_cq failed ret %d", ret);
1129 0 : goto poll_cq_err;
1130 : }
1131 :
1132 0 : for (i = 0; i < ret; i++) {
1133 0 : if (liteWc[i].status != RDMA_LITE_WC_SUCCESS && liteWc[i].status != RDMA_LITE_WC_WR_FLUSH_ERR) {
1134 0 : hccp_err(
1135 : "[create][ra_hdc_period_poll]failed CQE status[%u], wr[%llu]", liteWc[i].status, liteWc[i].wr_id);
1136 0 : RaHdcLiteSaveCqeErrInfo(qpHdcTmp, liteWc[i].status);
1137 0 : RaHdcLiteSaveQpCqeErrInfo(qpHdcTmp, liteWc[i].status);
1138 0 : RaRetryTimeoutExceptionCheck(rdmaHandle, &liteWc[i]);
1139 0 : qpHdcTmp->liteQpState = LITE_QP_STATE_ERR;
1140 : }
1141 : }
1142 :
1143 0 : qpHdcTmp->pollCqeNum += (unsigned int)ret;
1144 :
1145 0 : poll_cq_err:
1146 0 : free(liteWc);
1147 0 : liteWc = NULL;
1148 : }
1149 1 : }
1150 :
1151 3 : STATIC void *RaHdcLitePthread(void *arg)
1152 : {
1153 3 : struct RaRdmaHandle *rdmaHandle = (struct RaRdmaHandle *)arg;
1154 3 : unsigned int phyId = rdmaHandle->rdevInfo.phyId;
1155 :
1156 3 : hccp_run_info("lite thread begin! thread_id:%lu, pid:%d, ppid:%d, phyId:%u",
1157 : pthread_self(), getpid(), getppid(), phyId);
1158 3 : CHK_PRT_RETURN(pthread_detach(pthread_self()), hccp_err("pthread_detach failed! thread_id:%lu, errno:%d, phyId:%u",
1159 : pthread_self(), errno, phyId), NULL);
1160 :
1161 3 : (void)prctl(PR_SET_NAME, (uintptr_t)"hccp_hdc_lite", 0, 0, 0);
1162 :
1163 : while (1) {
1164 4 : if (rdmaHandle->threadStatus == LITE_THREAD_STATUS_DESTROY) {
1165 3 : break;
1166 : }
1167 1 : RA_PTHREAD_MUTEX_LOCK(&rdmaHandle->rdevMutex);
1168 1 : if (rdmaHandle->threadStatus == LITE_THREAD_STATUS_SUSPEND) {
1169 0 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->rdevMutex);
1170 0 : usleep(THREAD_SLEEP_TIME);
1171 0 : continue;
1172 : }
1173 1 : RaHdcLitePeriodPollCqe(rdmaHandle);
1174 1 : RA_PTHREAD_MUTEX_UNLOCK(&rdmaHandle->rdevMutex);
1175 1 : usleep(RA_LITE_POLL_CQE_PERIOD_TIME);
1176 : }
1177 :
1178 : // thread quit, change status to finish running status(2)
1179 3 : rdmaHandle->threadStatus = LITE_THREAD_STATUS_FINISH_RUNNING;
1180 3 : hccp_run_info("lite QUIT thread_id:%lu, pid:%d, phyId:%u", pthread_self(), getpid(), phyId);
1181 :
1182 3 : return NULL;
1183 : }
1184 :
1185 1 : int RaHdcLitePollCq(struct RaQpHandle *qpHdc, bool isSendCq, unsigned int numEntries,
1186 : struct rdma_lite_wc_v2 *liteWc)
1187 : {
1188 1 : int ret = 0;
1189 1 : struct rdma_lite_cq *cq = isSendCq ? qpHdc->liteQp->send_cq : qpHdc->liteQp->recv_cq;
1190 1 : unsigned int *pollCqeNum = isSendCq ? &qpHdc->pollCqeNum : &qpHdc->pollRecvCqeNum;
1191 1 : unsigned int wrNum = isSendCq ? qpHdc->sendWrNum : qpHdc->recvWrNum;
1192 : int i;
1193 :
1194 : // no need to poll
1195 1 : if ((wrNum - *pollCqeNum) == 0) {
1196 0 : return 0;
1197 : }
1198 :
1199 1 : ret = RaRdmaLitePollCqV2(cq, (int)numEntries, liteWc);
1200 1 : CHK_PRT_RETURN(ret < 0, hccp_err("ra_rdma_lite_poll_cq_v2 failed, ret %d", ret), ret);
1201 1 : CHK_PRT_RETURN(ret > (int)numEntries,
1202 : hccp_err("ra_rdma_lite_poll_cq_v2 failed, expect maximum numEntries:%u but got %d", numEntries, ret), -EIO);
1203 :
1204 1 : for (i = 0; i < ret; i++) {
1205 0 : RaRetryTimeoutExceptionCheck(qpHdc->rdmaHandle, &liteWc[i].wc);
1206 : }
1207 :
1208 1 : *pollCqeNum += (unsigned int)ret;
1209 1 : return ret;
1210 : }
1211 :
1212 0 : STATIC int RaHdcLitePostSend(struct RaQpHandle *qpHdc, struct LiteMrInfo *localMr,
1213 : struct LiteMrInfo *remMr, struct LiteSendWr *wr, struct SendWrRsp *wrRsp, u64 wrId)
1214 : {
1215 : int i;
1216 : int ret;
1217 : struct rdma_lite_sge list[RA_SGLIST_MAX];
1218 0 : struct rdma_lite_send_wr liteWr = {
1219 : .sg_list = list,
1220 0 : .opcode = wr->wr.op,
1221 0 : .send_flags = wr->wr.sendFlag,
1222 : };
1223 0 : struct rdma_lite_send_wr *badWr = NULL;
1224 0 : struct rdma_lite_post_send_resp resp = { 0 };
1225 0 : struct rdma_lite_post_send_attr attr = { 0 };
1226 :
1227 0 : for (i = 0; i < wr->wr.bufNum && i < RA_SGLIST_MAX; i++) {
1228 0 : list[i].addr = (uintptr_t)wr->wr.bufList[i].addr;
1229 0 : list[i].length = wr->wr.bufList[i].len;
1230 0 : list[i].lkey = localMr->key;
1231 : }
1232 :
1233 0 : if (liteWr.opcode == RDMA_LITE_WR_WRITE_WITH_NOTIFY ||
1234 0 : liteWr.opcode == RDMA_LITE_WR_REDUCE_WRITE ||
1235 0 : liteWr.opcode == RDMA_LITE_WR_REDUCE_WRITE_NOTIFY) {
1236 0 : liteWr.imm_data = htobe32((wr->aux.notifyOffset & WRITE_NOTIFY_OFFSET_MASK) |
1237 : WRITE_NOTIFY_VALUE_RECORD);
1238 0 : attr.reduce_op = wr->aux.reduceType;
1239 0 : attr.reduce_type = wr->aux.dataType;
1240 : }
1241 :
1242 0 : if (liteWr.opcode == RDMA_LITE_WR_RDMA_WRITE_WITH_IMM ||
1243 0 : liteWr.opcode == RDMA_LITE_WR_SEND_WITH_IMM ||
1244 0 : liteWr.opcode == RDMA_LITE_WR_ATOMIC_WRITE) {
1245 0 : liteWr.imm_data = htobe32(wr->ext.immData);
1246 : }
1247 :
1248 0 : liteWr.num_sge = i;
1249 0 : liteWr.wr_id = wrId;
1250 : // send op has no rem_mr, no need to assign
1251 0 : if (wr->wr.op != RA_WR_SEND && wr->wr.op != RA_WR_SEND_WITH_IMM) {
1252 0 : liteWr.rkey = remMr->key;
1253 0 : liteWr.remote_addr = wr->wr.dstAddr;
1254 : }
1255 :
1256 0 : ret = RaRdmaLitePostSend(qpHdc->liteQp, &liteWr, &badWr, &attr, &resp);
1257 0 : if (ret) {
1258 0 : return ret;
1259 : }
1260 :
1261 0 : wrRsp->db.dbIndex = (unsigned int)qpHdc->dbIndex;
1262 0 : wrRsp->db.dbInfo = resp.db.lite_db_info;
1263 :
1264 0 : return 0;
1265 : }
1266 :
1267 0 : static int RaHdcLiteGetMr(struct RaQpHandle *qpHdc, unsigned long long addr, struct LiteMrInfo **mr,
1268 : struct LiteMrInfo *srcMr, unsigned int mrNum)
1269 : {
1270 : unsigned int i;
1271 :
1272 0 : RA_PTHREAD_MUTEX_LOCK(&qpHdc->qpMutex);
1273 :
1274 0 : for (i = 0; i < mrNum; i++) {
1275 0 : if ((srcMr[i].addr <= addr) && (addr < srcMr[i].addr + srcMr[i].len)) {
1276 0 : *mr = &srcMr[i];
1277 0 : RA_PTHREAD_MUTEX_UNLOCK(&qpHdc->qpMutex);
1278 0 : return 0;
1279 : }
1280 : }
1281 :
1282 0 : RA_PTHREAD_MUTEX_UNLOCK(&qpHdc->qpMutex);
1283 :
1284 0 : return -EINVAL;
1285 : }
1286 :
1287 2 : STATIC int RaHdcLiteHandleBp(struct RaQpHandle *qpHdc)
1288 : {
1289 : u32 sendWr;
1290 :
1291 2 : if (qpHdc->sendWrNum >= qpHdc->pollCqeNum) {
1292 2 : sendWr = qpHdc->sendWrNum - qpHdc->pollCqeNum;
1293 : } else {
1294 0 : sendWr = qpHdc->sendWrNum + (0xFFFFFFFF - qpHdc->pollCqeNum);
1295 : }
1296 :
1297 : /*
1298 : * Due to driver limitations, the software pointer updates before the hardware pointer.
1299 : * The software must reserve sq_depth(2^x - 2) to prevent the backpressure mechanism from failing.
1300 : */
1301 2 : if (sendWr < (qpHdc->sqDepth - 2U)) {
1302 2 : if (qpHdc->bpCnt != 0) {
1303 0 : hccp_run_info("qpn:%u send_wr_num:%u poll_cqe_num:%u send_wr:%u sq_depth:%u "
1304 : "bp_cnt:%u, back pressure relieved",
1305 : qpHdc->qpn, qpHdc->sendWrNum, qpHdc->pollCqeNum, sendWr, qpHdc->sqDepth,
1306 : qpHdc->bpCnt);
1307 0 : qpHdc->bpCnt = 0;
1308 : }
1309 2 : return 0;
1310 : }
1311 :
1312 : // first time back pressure occurred
1313 0 : if (qpHdc->bpCnt == 0) {
1314 0 : hccp_run_warn("qpn:%u send_wr_num:%u poll_cqe_num:%u send_wr:%u sq_depth:%u, back pressure occurred",
1315 : qpHdc->qpn, qpHdc->sendWrNum, qpHdc->pollCqeNum, sendWr, qpHdc->sqDepth);
1316 : } else {
1317 0 : hccp_warn("qpn:%u send_wr_num:%u poll_cqe_num:%u send_wr:%u sq_depth:%u, back pressure continues bpCnt:%u",
1318 : qpHdc->qpn, qpHdc->sendWrNum, qpHdc->pollCqeNum, sendWr, qpHdc->sqDepth, qpHdc->bpCnt);
1319 : }
1320 :
1321 0 : qpHdc->bpCnt++;
1322 0 : return -ENOMEM;
1323 : }
1324 :
1325 2 : int RaHdcLiteTypicalSendWr(struct RaQpHandle *qpHdc, struct LiteSendWr *wr, struct SendWrRsp *opRsp,
1326 : unsigned long long wrId)
1327 : {
1328 2 : struct rdma_lite_post_send_resp resp = { 0 };
1329 2 : struct rdma_lite_post_send_attr attr = { 0 };
1330 : struct rdma_lite_sge list[RA_SGLIST_MAX];
1331 2 : struct rdma_lite_send_wr liteWr = {
1332 : .sg_list = list,
1333 2 : .opcode = wr->wr.op,
1334 2 : .send_flags = wr->wr.sendFlag,
1335 : };
1336 2 : struct rdma_lite_send_wr *badWr = NULL;
1337 : int ret;
1338 : int i;
1339 :
1340 2 : CHK_PRT_RETURN(qpHdc->liteQpState == LITE_QP_STATE_ERR, hccp_err("invalid liteQpState:%u qpn:%u phyId:%u",
1341 : qpHdc->liteQpState, qpHdc->qpn, qpHdc->phyId), -EINVAL);
1342 :
1343 2 : ret = RaHdcLiteHandleBp(qpHdc);
1344 2 : if (ret != 0) {
1345 0 : return ret;
1346 : }
1347 :
1348 3 : for (i = 0; i < wr->wr.bufNum && i < RA_SGLIST_MAX; i++) {
1349 1 : list[i].addr = (uintptr_t)wr->wr.bufList[i].addr;
1350 1 : list[i].length = wr->wr.bufList[i].len;
1351 1 : list[i].lkey = wr->wr.bufList[i].lkey;
1352 : }
1353 :
1354 2 : liteWr.num_sge = i;
1355 2 : liteWr.wr_id = wrId;
1356 2 : liteWr.rkey = wr->wr.rkey;
1357 2 : liteWr.remote_addr = wr->wr.dstAddr;
1358 2 : if (liteWr.opcode == RDMA_LITE_WR_WRITE_WITH_NOTIFY ||
1359 2 : liteWr.opcode == RDMA_LITE_WR_REDUCE_WRITE ||
1360 2 : liteWr.opcode == RDMA_LITE_WR_REDUCE_WRITE_NOTIFY) {
1361 0 : liteWr.imm_data = htobe32((wr->aux.notifyOffset & WRITE_NOTIFY_OFFSET_MASK) |
1362 : WRITE_NOTIFY_VALUE_RECORD);
1363 0 : attr.reduce_op = wr->aux.reduceType;
1364 0 : attr.reduce_type = wr->aux.dataType;
1365 : }
1366 2 : liteWr.imm_data = htobe32(wr->ext.immData);
1367 :
1368 2 : ret = RaRdmaLitePostSend(qpHdc->liteQp, &liteWr, &badWr, &attr, &resp);
1369 2 : if (ret) {
1370 0 : if (ret == -ENOMEM) {
1371 0 : hccp_warn("[send][ra_hdc_wr]ra hdc post send unsuccessful, ret(%d) phyId(%u)", ret, qpHdc->phyId);
1372 : } else {
1373 0 : hccp_err("[send][ra_hdc_wr]ra hdc post send failed ret(%d) phyId(%u)", ret, qpHdc->phyId);
1374 : }
1375 :
1376 0 : return ret;
1377 : }
1378 :
1379 2 : opRsp->db.dbIndex = (unsigned int)qpHdc->dbIndex;
1380 2 : opRsp->db.dbInfo = resp.db.lite_db_info;
1381 :
1382 : // user specify wr send_signal flag or user specify qp sq_sig_all flag
1383 2 : if ((((uint32_t)wr->wr.sendFlag & RA_SEND_SIGNALED) != 0) || (qpHdc->sqSigAll != 0)) {
1384 0 : qpHdc->sendWrNum++;
1385 : }
1386 :
1387 2 : return 0;
1388 : }
1389 :
1390 0 : int RaHdcLiteSendWr(struct RaQpHandle *qpHdc, struct LiteSendWr *wr, struct SendWrRsp *opRsp,
1391 : unsigned long long wrId)
1392 : {
1393 0 : struct LiteMrInfo *localMr = NULL;
1394 0 : struct LiteMrInfo *remMr = NULL;
1395 : int ret;
1396 :
1397 0 : ret = RaHdcLiteGetMr(qpHdc, wr->wr.bufList[0].addr, &localMr, qpHdc->localMr, RA_MR_MAX_NUM);
1398 0 : CHK_PRT_RETURN(ret, hccp_err("[send][ra_hdc_wr]ra hdc get local_mr failed ret(%d) phyId(%u)",
1399 : ret, qpHdc->phyId), ret);
1400 :
1401 : // send op no need to check & get remote mr
1402 0 : if (wr->wr.op != RA_WR_SEND && wr->wr.op != RA_WR_SEND_WITH_IMM) {
1403 0 : ret = RaHdcLiteGetMr(qpHdc, wr->wr.dstAddr, &remMr, qpHdc->remMr, RA_MR_MAX_NUM);
1404 0 : CHK_PRT_RETURN(ret, hccp_err("[send][ra_hdc_wr]ra hdc get rem_mr failed ret(%d) phyId(%u)",
1405 : ret, qpHdc->phyId), ret);
1406 : }
1407 :
1408 0 : CHK_PRT_RETURN(qpHdc->liteQpState == LITE_QP_STATE_ERR, hccp_err("invalid liteQpState:%u qpn:%u phyId:%u",
1409 : qpHdc->liteQpState, qpHdc->qpn, qpHdc->phyId), -EINVAL);
1410 :
1411 0 : ret = RaHdcLiteHandleBp(qpHdc);
1412 0 : if (ret != 0) {
1413 0 : return ret;
1414 : }
1415 :
1416 0 : ret = RaHdcLitePostSend(qpHdc, localMr, remMr, wr, opRsp, wrId);
1417 0 : if (ret) {
1418 0 : if (ret == -ENOMEM) {
1419 0 : hccp_warn("[send][ra_hdc_wr]ra hdc post send unsuccessful, ret(%d) phyId(%u)", ret, qpHdc->phyId);
1420 : } else {
1421 0 : hccp_err("[send][ra_hdc_wr]ra hdc post send failed, ret(%d) phyId(%u)", ret, qpHdc->phyId);
1422 : }
1423 :
1424 0 : return ret;
1425 : }
1426 :
1427 : // user specify wr send_signal flag or user specify qp sq_sig_all flag
1428 0 : if ((((uint32_t)wr->wr.sendFlag & RA_SEND_SIGNALED) != 0) || (qpHdc->sqSigAll != 0)) {
1429 0 : qpHdc->sendWrNum++;
1430 : }
1431 :
1432 0 : return 0;
1433 : }
1434 :
1435 0 : int RaHdcLiteSendWrlist(struct RaQpHandle *qpHdc, struct SendWrlistData wr[], struct SendWrRsp opRsp[],
1436 : struct WrlistSendCompleteNum wrlistNum)
1437 : {
1438 : int ret;
1439 0 : unsigned int i = 0;
1440 0 : struct LiteSendWr normalWr = { 0 };
1441 :
1442 0 : while (i < wrlistNum.sendNum) {
1443 0 : normalWr.wr.bufList = &(wr[i].memList);
1444 0 : normalWr.wr.bufNum = 1;
1445 0 : normalWr.wr.dstAddr = wr[i].dstAddr;
1446 0 : normalWr.wr.op = wr[i].op;
1447 0 : normalWr.wr.sendFlag = wr[i].sendFlags;
1448 0 : ret = RaHdcLiteSendWr(qpHdc, &normalWr, &opRsp[i], HDC_LITE_DEFAULT_WR_ID);
1449 0 : if (ret) {
1450 0 : if (ret == -ENOMEM) {
1451 0 : hccp_warn("[send][ra_hdc_lite_wrlist]ra_hdc_lite_send_wr unsuccessful, ret(%d) phyId(%u) "
1452 : "send_index(%u)", ret, qpHdc->phyId, i);
1453 : } else {
1454 0 : hccp_err("[send][ra_hdc_lite_wrlist]ra_hdc_lite_send_wr failed, ret(%d) phyId(%u) send_index(%u)",
1455 : ret, qpHdc->phyId, i);
1456 : }
1457 :
1458 0 : *(wrlistNum.completeNum) = i;
1459 0 : return ret;
1460 : }
1461 :
1462 0 : i++;
1463 : }
1464 :
1465 0 : *(wrlistNum.completeNum) = i;
1466 :
1467 0 : return 0;
1468 : }
1469 :
1470 0 : int RaHdcLiteSendWrlistExt(struct RaQpHandle *qpHdc, struct SendWrlistDataExt wr[],
1471 : struct SendWrRsp opRsp[], struct WrlistSendCompleteNum wrlistNum)
1472 : {
1473 : int ret;
1474 0 : unsigned int i = 0;
1475 0 : struct LiteSendWr normalWr = { 0 };
1476 :
1477 0 : while (i < wrlistNum.sendNum) {
1478 0 : normalWr.wr.bufList = &(wr[i].memList);
1479 0 : normalWr.wr.bufNum = 1;
1480 0 : normalWr.wr.dstAddr = wr[i].dstAddr;
1481 0 : normalWr.wr.op = wr[i].op;
1482 0 : normalWr.wr.sendFlag = wr[i].sendFlags;
1483 0 : normalWr.aux = wr[i].aux;
1484 0 : normalWr.ext = wr[i].ext;
1485 0 : ret = RaHdcLiteSendWr(qpHdc, &normalWr, &opRsp[i], HDC_LITE_DEFAULT_WR_ID);
1486 0 : if (ret) {
1487 0 : if (ret == -ENOMEM) {
1488 0 : hccp_warn("[send][ra_hdc_lite_send_wrlist_ext]ra_hdc_lite_send_wr unsuccessful, ret(%d) phyId(%u) "
1489 : "send_index(%u)", ret, qpHdc->phyId, i);
1490 : } else {
1491 0 : hccp_err("[send][ra_hdc_lite_send_wrlist_ext]ra_hdc_lite_send_wr failed, ret(%d) phyId(%u) "
1492 : "send_index(%u)", ret, qpHdc->phyId, i);
1493 : }
1494 :
1495 0 : *(wrlistNum.completeNum) = i;
1496 0 : return ret;
1497 : }
1498 :
1499 0 : i++;
1500 : }
1501 :
1502 0 : *(wrlistNum.completeNum) = i;
1503 :
1504 0 : return 0;
1505 : }
1506 :
1507 1 : int RaHdcLiteSendNormalWrlist(struct RaQpHandle *qpHdc, struct WrInfo wr[], struct SendWrRsp opRsp[],
1508 : struct WrlistSendCompleteNum wrlistNum)
1509 : {
1510 1 : struct LiteSendWr normalWr = { 0 };
1511 1 : unsigned int i = 0;
1512 1 : int ret = 0;
1513 :
1514 2 : while (i < wrlistNum.sendNum) {
1515 1 : normalWr.wr.sendFlag = wr[i].sendFlags;
1516 1 : normalWr.wr.rkey = wr[i].rkey;
1517 1 : normalWr.wr.op = wr[i].op;
1518 1 : normalWr.wr.dstAddr = wr[i].dstAddr;
1519 1 : normalWr.wr.bufList = &(wr[i].memList);
1520 1 : normalWr.wr.bufNum = 1;
1521 1 : normalWr.aux = wr[i].aux;
1522 1 : if (wr[i].op == RDMA_LITE_WR_RDMA_WRITE_WITH_IMM || wr[i].op == RDMA_LITE_WR_SEND_WITH_IMM ||
1523 1 : wr[i].op == RDMA_LITE_WR_ATOMIC_WRITE) {
1524 0 : normalWr.ext.immData = wr[i].immData;
1525 : }
1526 1 : ret = RaHdcLiteTypicalSendWr(qpHdc, &normalWr, &opRsp[i], wr[i].wrId);
1527 1 : if (ret != 0) {
1528 0 : if (ret == -ENOMEM) {
1529 0 : hccp_warn("[send][send_wrlist]ra_hdc_lite_send_wr unsuccessful, ret(%d) phyId(%u) send_index(%u)",
1530 : ret, qpHdc->phyId, i);
1531 : } else {
1532 0 : hccp_err("[send][send_wrlist]ra_hdc_lite_send_wr failed, ret(%d) phyId(%u) send_index(%u)",
1533 : ret, qpHdc->phyId, i);
1534 : }
1535 :
1536 0 : break;
1537 : }
1538 :
1539 1 : i++;
1540 : }
1541 :
1542 1 : *(wrlistNum.completeNum) = i;
1543 :
1544 1 : return ret;
1545 : }
1546 :
1547 1 : STATIC void RaHdcLiteBuildRecvWr(struct RecvWrlistData *wr, struct rdma_lite_sge *list,
1548 : struct rdma_lite_recv_wr *liteWr)
1549 : {
1550 1 : list->addr = (uintptr_t)wr->memList.addr;
1551 1 : list->length = wr->memList.len;
1552 1 : list->lkey = wr->memList.lkey;
1553 :
1554 1 : liteWr->sg_list = list;
1555 1 : liteWr->wr_id = wr->wrId;
1556 1 : liteWr->num_sge = 1; /* only support one sge */
1557 1 : }
1558 :
1559 1 : int RaHdcLiteRecvWrlist(struct RaQpHandle *qpHdc, struct RecvWrlistData *wr, unsigned int recvNum,
1560 : unsigned int *completeNum)
1561 : {
1562 1 : struct rdma_lite_recv_wr *liteWr = NULL;
1563 1 : struct rdma_lite_recv_wr *badWr = NULL;
1564 1 : struct rdma_lite_sge *list = NULL;
1565 : unsigned int index;
1566 : unsigned int i;
1567 : int ret;
1568 :
1569 1 : CHK_PRT_RETURN(recvNum == 0, hccp_err("lite recv_num[%u] is invalid!", recvNum), -EINVAL);
1570 :
1571 1 : liteWr = (struct rdma_lite_recv_wr *)calloc(recvNum, sizeof(struct rdma_lite_recv_wr));
1572 1 : CHK_PRT_RETURN(liteWr == NULL, hccp_err("lite calloc lite_wr failed!"), -ENOSPC);
1573 :
1574 1 : list = (struct rdma_lite_sge *)calloc(recvNum, sizeof(struct rdma_lite_sge));
1575 1 : if (list == NULL) {
1576 0 : hccp_err("lite calloc list failed!");
1577 0 : ret = -ENOSPC;
1578 0 : goto alloc_sge_fail;
1579 : }
1580 :
1581 : // build up recv lite wr
1582 2 : for (i = 0; i < recvNum; i++) {
1583 1 : RaHdcLiteBuildRecvWr(&wr[i], &list[i], &liteWr[i]);
1584 1 : index = i + 1;
1585 1 : liteWr[i].next = (i < recvNum - 1) ? &(liteWr[index]) : NULL;
1586 : }
1587 :
1588 1 : ret = RaRdmaLitePostRecv(qpHdc->liteQp, liteWr, &badWr);
1589 1 : if (ret == 0) {
1590 1 : *completeNum = recvNum;
1591 0 : } else if (ret == -ENOMEM) {
1592 0 : *completeNum = (unsigned int)((void *)badWr - (void *)liteWr) / sizeof(struct rdma_lite_recv_wr);
1593 0 : hccp_dbg("ra_rdma_lite_post_recv wqe overflow, completeNum[%d]", *completeNum);
1594 : } else {
1595 0 : *completeNum = 0;
1596 0 : hccp_err("ra_rdma_lite_post_recv failed, ret[%d]", ret);
1597 : }
1598 :
1599 1 : qpHdc->recvWrNum += *completeNum;
1600 :
1601 1 : free(list);
1602 1 : list = NULL;
1603 :
1604 1 : alloc_sge_fail:
1605 1 : free(liteWr);
1606 1 : liteWr = NULL;
1607 1 : return (ret == -ENOMEM) ? 0 : ret;
1608 : }
|