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