LCOV - code coverage report
Current view: top level - base_comm/resources/hccp/rdma_agent/hdc/async - ra_hdc_async.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 18.5 % 410 76
Test Date: 2026-08-04 10:52:23 Functions: 37.9 % 29 11

            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 <sys/prctl.h>
      13              : #include "securec.h"
      14              : #include "user_log.h"
      15              : #include "dl_hal_function.h"
      16              : #include "ra.h"
      17              : #include "ra_async.h"
      18              : #include "ra_rs_comm.h"
      19              : #include "ra_rs_err.h"
      20              : #include "ra_hdc.h"
      21              : #include "ra_hdc_socket.h"
      22              : #include "ra_hdc_async_socket.h"
      23              : #include "ra_hdc_ctx.h"
      24              : #include "ra_hdc_async_ctx.h"
      25              : #include "ra_hdc_async.h"
      26              : 
      27              : struct HdcAsyncInfo gRaHdcAsync[RA_MAX_PHY_ID_NUM] = { 0 };
      28              : 
      29              : struct RaAsyncOpHandle gRaAsyncOpHandle[] = {
      30              :     {RA_RS_GET_EID_BY_IP, RDMA_OP, RaHdcAsyncHandleGetEidByIp, sizeof(union OpGetEidByIpData)},
      31              :     {RA_RS_GET_IP_BY_EID, RDMA_OP, RaHdcAsyncHandleGetIpByEid, sizeof(union OpGetIpByEidData)},
      32              :     {RA_RS_LMEM_REG, RDMA_OP, RaHdcAsyncHandleLmemRegister, sizeof(union OpLmemRegInfoData)},
      33              :     {RA_RS_LMEM_UNREG, RDMA_OP, NULL, sizeof(union OpLmemUnregInfoData)},
      34              :     {RA_RS_CTX_QP_CREATE, RDMA_OP, RaHdcAsyncHandleQpCreate, sizeof(union OpCtxQpCreateData)},
      35              :     {RA_RS_CTX_QP_DESTROY, RDMA_OP, NULL, sizeof(union OpCtxQpDestroyData)},
      36              :     {RA_RS_CTX_QP_IMPORT, RDMA_OP, RaHdcAsyncHandleQpImport, sizeof(union OpCtxQpImportData)},
      37              :     {RA_RS_CTX_QP_UNIMPORT, RDMA_OP, NULL, sizeof(union OpCtxQpUnimportData)},
      38              :     {RA_RS_GET_TP_INFO_LIST, RDMA_OP, RaHdcAsyncHandleTpInfoList, sizeof(union OpGetTpInfoListData)},
      39              :     {RA_RS_GET_TP_ATTR, RDMA_OP, RaHdcAsyncHandleGetTpAttr, sizeof(union OpGetTpAttrData)},
      40              :     {RA_RS_SET_TP_ATTR, RDMA_OP, NULL, sizeof(union OpSetTpAttrData)},
      41              :     {RA_RS_CTX_QP_DESTROY_BATCH, RDMA_OP, RaHdcAsyncHandleQpDestroyBatch,
      42              :         sizeof(union OpCtxQpDestroyBatchData)},
      43              :     {RA_RS_SOCKET_SEND, SOCKET_OP, RaHdcAsyncHandleSocketSend, sizeof(union OpSocketSendData)},
      44              :     {RA_RS_SOCKET_RECV, SOCKET_OP, RaHdcAsyncHandleSocketRecv, sizeof(union OpSocketRecvData)},
      45              :     {RA_RS_SOCKET_LISTEN_START, SOCKET_OP, RaHdcAsyncHandleSocketListenStart,
      46              :         sizeof(union OpSocketListenData)},
      47              :     {RA_RS_SOCKET_LISTEN_STOP, SOCKET_OP, NULL, sizeof(union OpSocketListenData)},
      48              :     {RA_RS_SOCKET_CONN, SOCKET_OP, NULL, sizeof(union OpSocketConnectData)},
      49              :     {RA_RS_SOCKET_CLOSE, SOCKET_OP, RaHdcAsyncHandleSocketBatchClose, sizeof(union OpSocketCloseData)},
      50              :     {RA_RS_HDC_SESSION_CLOSE, OTHERS, NULL, sizeof(union OpHdcCloseData)},
      51              : };
      52              : 
      53            1 : STATIC struct RaAsyncOpHandle *RaHdcIsAsyncOp(unsigned int opcode)
      54              : {
      55            1 :     int num = sizeof(gRaAsyncOpHandle) / sizeof(gRaAsyncOpHandle[0]);
      56              :     int i;
      57              : 
      58           20 :     for (i = 0; i < num; i++) {
      59           19 :         if (gRaAsyncOpHandle[i].opcode == (enum OpType)opcode) {
      60            0 :             return &gRaAsyncOpHandle[i];
      61              :         }
      62              :     }
      63            1 :     return NULL;
      64              : }
      65              : 
      66            0 : STATIC void HdcAsyncHandlePrivData(struct RaRequestHandle *reqHandle)
      67              : {
      68            0 :     if (reqHandle->opHandle->privDataHandle == NULL) {
      69            0 :         return;
      70              :     }
      71              : 
      72            0 :     reqHandle->opHandle->privDataHandle(reqHandle);
      73              : }
      74              : 
      75            0 : STATIC void HdcAsyncSetRequest(struct RaRequestHandle *reqHandle, unsigned int reqId,
      76              :     struct RaAsyncOpHandle *opHandle, unsigned int phyId, unsigned int dataSize)
      77              : {
      78            0 :     reqHandle->reqId = reqId;
      79            0 :     reqHandle->opHandle = opHandle;
      80            0 :     reqHandle->phyId = phyId;
      81            0 :     reqHandle->dataSize = dataSize;
      82            0 : }
      83              : 
      84            0 : STATIC int HdcAsyncGetRequest(struct HdcAsyncInfo *asyncInfo, unsigned int reqId,
      85              :     struct RaRequestHandle **reqHandle)
      86              : {
      87            0 :     struct RaRequestHandle *reqTmp2 = NULL;
      88            0 :     struct RaRequestHandle *reqTmp = NULL;
      89              : 
      90              :     // no need to use lock: req_id always exist in current req_list(the data is always sent before it is received)
      91            0 :     RA_LIST_GET_HEAD_ENTRY(reqTmp, reqTmp2, &asyncInfo->reqList, list, struct RaRequestHandle);
      92            0 :     for (; (&reqTmp->list) != &asyncInfo->reqList;
      93            0 :         reqTmp = reqTmp2, reqTmp2 = list_entry(reqTmp2->list.next, struct RaRequestHandle, list)) {
      94            0 :         if (reqTmp->reqId == reqId) {
      95            0 :             *reqHandle = reqTmp;
      96            0 :             return 0;
      97              :         }
      98              :     }
      99            0 :     *reqHandle = NULL;
     100            0 :     return -ENODEV;
     101              : }
     102              : 
     103            0 : STATIC void HdcAsyncSetReqDone(struct RaRequestHandle *reqHandle, unsigned int phyId, int ret)
     104              : {
     105            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].rspMutex);
     106            0 :     RaListAddTail(&reqHandle->list, &gRaHdcAsync[phyId].rspList);
     107            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].rspMutex);
     108            0 :     reqHandle->opRet = (ret != 0) ? ret : reqHandle->opRet;
     109            0 :     reqHandle->isDone = true;
     110            0 : }
     111              : 
     112            1 : STATIC void RaHwAsyncSetConnectStatus(unsigned int phyId, unsigned int connectStatus)
     113              : {
     114            1 :     gRaHdcAsync[phyId].connectStatus = connectStatus;
     115            1 : }
     116              : 
     117            0 : STATIC bool HdcAsyncIsMsgValid(unsigned int phyId, struct MsgHead *recvMsgHead, unsigned int recvLen,
     118              :     struct RaRequestHandle **reqHandle)
     119              : {
     120            0 :     struct RaRequestHandle *reqHandleTmp = NULL;
     121              :     int ret;
     122              : 
     123              :     // check recv_len and get req_handle
     124            0 :     CHK_PRT_RETURN(recvLen < sizeof(struct MsgHead),
     125              :         hccp_run_warn("[async][ra_hdc_recv]recv_len[%u] < [%lu] is invalid", recvLen, sizeof(struct MsgHead)), false);
     126            0 :     ret = HdcAsyncGetRequest(&gRaHdcAsync[phyId], recvMsgHead->asyncReqId, &reqHandleTmp);
     127            0 :     CHK_PRT_RETURN(reqHandleTmp == NULL, hccp_run_warn("[async][ra_hdc_recv]req_id[%u] invalid, ret[%d], opcode[%u]",
     128              :         recvMsgHead->asyncReqId, ret, recvMsgHead->opcode), false);
     129              : 
     130              :     // del req_handle from req_list
     131            0 :     RaListDel(&reqHandleTmp->list);
     132              : 
     133              :     // opcode RA_RS_HDC_SESSION_CLOSE
     134            0 :     if (recvMsgHead->opcode == RA_RS_HDC_SESSION_CLOSE) {
     135            0 :         RaHwAsyncSetConnectStatus(phyId, HDC_UNCONNECTED);
     136            0 :         hccp_dbg("opcode[%u] req_id[%u] phyId[%u]", recvMsgHead->opcode, reqHandleTmp->reqId, phyId);
     137            0 :         reqHandleTmp->isDone = true;
     138            0 :         return false;
     139              :     }
     140              : 
     141              :     // need to check op_data size and recv data size
     142            0 :     if ((reqHandleTmp->dataSize != recvMsgHead->msgDataLen) ||
     143            0 :         (recvMsgHead->msgDataLen + (unsigned int)sizeof(struct MsgHead)) != recvLen) {
     144            0 :         hccp_run_warn("[async][ra_hdc_recv]opcode[%u] data_size[%u] msg_data_len[%u] mismatch or recv_len[%u] mismatch",
     145              :             recvMsgHead->opcode, reqHandleTmp->dataSize, recvMsgHead->msgDataLen, recvLen);
     146            0 :         HdcAsyncSetReqDone(reqHandleTmp, phyId, -EINVAL);
     147            0 :         return false;
     148              :     }
     149              : 
     150            0 :     *reqHandle = reqHandleTmp;
     151            0 :     return true;
     152              : }
     153              : 
     154            0 : STATIC int HdcAsyncAddResponse(unsigned int phyId, void *recvBuf, unsigned int recvLen)
     155              : {
     156            0 :     struct RaRequestHandle *reqHandleTmp = NULL;
     157            0 :     struct MsgHead *recvMsgHead = NULL;
     158            0 :     int ret = 0;
     159              : 
     160            0 :     recvMsgHead = (struct MsgHead *)recvBuf;
     161              :     // check recv msg: req_id, opcode, msg_data_len and get req_handle
     162            0 :     if (!HdcAsyncIsMsgValid(phyId, recvMsgHead, recvLen, &reqHandleTmp)) {
     163            0 :         return -EINVAL;
     164              :     }
     165              : 
     166              :     //  handle recv msg
     167            0 :     reqHandleTmp->recvBuf = (void *)calloc(recvMsgHead->msgDataLen, sizeof(char));
     168            0 :     if (reqHandleTmp->recvBuf == NULL) {
     169            0 :         hccp_err("[async][ra_hdc_recv]calloc recv_buf failed, msgDataLen[%u] reqId[%u] opcode[%u]",
     170              :             recvMsgHead->msgDataLen, recvMsgHead->asyncReqId, recvMsgHead->opcode);
     171            0 :         ret = -ENOMEM;
     172            0 :         goto out;
     173              :     }
     174            0 :     (void)memcpy_s(reqHandleTmp->recvBuf, recvMsgHead->msgDataLen, recvBuf + sizeof(struct MsgHead),
     175            0 :         recvMsgHead->msgDataLen);
     176            0 :     reqHandleTmp->recvLen = recvMsgHead->msgDataLen;
     177            0 :     reqHandleTmp->opRet = recvMsgHead->ret;
     178            0 :     HdcAsyncHandlePrivData(reqHandleTmp);
     179              : 
     180            0 : out:
     181            0 :     HdcAsyncSetReqDone(reqHandleTmp, phyId, ret);
     182            0 :     return ret;
     183              : }
     184              : 
     185            1 : static void HdcAsyncDelReqHandle(struct RaRequestHandle *reqHandle, pthread_mutex_t *mutex)
     186              : {
     187            1 :     RA_PTHREAD_MUTEX_LOCK(mutex);
     188            1 :     RaListDel(&reqHandle->list);
     189            1 :     RA_PTHREAD_MUTEX_UNLOCK(mutex);
     190            1 :     if (reqHandle->recvBuf != NULL && reqHandle->recvLen != 0) {
     191            1 :         free(reqHandle->recvBuf);
     192            1 :         reqHandle->recvBuf = NULL;
     193            1 :         reqHandle->recvLen = 0;
     194              :     }
     195              :     // async api return failed, free corresponding handle
     196            1 :     if (reqHandle->opRet != 0 && reqHandle->privHandle != NULL) {
     197            0 :         free(reqHandle->privHandle);
     198            0 :         reqHandle->privHandle = NULL;
     199              :     }
     200            1 :     free(reqHandle);
     201            1 :     reqHandle = NULL;
     202            1 :     return;
     203              : }
     204              : 
     205            1 : void HdcAsyncDelResponse(struct RaRequestHandle *reqHandle)
     206              : {
     207            1 :     HdcAsyncDelReqHandle(reqHandle, &gRaHdcAsync[reqHandle->phyId].rspMutex);
     208            1 : }
     209              : 
     210            1 : int RaHdcSendMsgAsync(unsigned int opcode, unsigned int phyId, char *data, unsigned int dataSize,
     211              :     struct RaRequestHandle *reqHandle)
     212              : {
     213            1 :     struct RaAsyncOpHandle *opHandleTmp = NULL;
     214            1 :     unsigned int asyncReqId = 0;
     215            1 :     void *sendBuf = NULL;
     216              :     unsigned int sendLen;
     217              :     pid_t hostTgid;
     218              :     int ret;
     219              : 
     220            1 :     if (gRaHdcAsync[phyId].restoreFlag != 0) {
     221            0 :         return 0;
     222              :     }
     223              : 
     224            1 :     CHK_PRT_RETURN(RaHdcIsBroken(gRaHdcAsync[phyId].lastRecvStatus),
     225              :         hccp_err("[async][ra_hdc_send]HDC broken, phyId(%u)", phyId), gRaHdcAsync[phyId].lastRecvStatus);
     226            1 :     opHandleTmp = RaHdcIsAsyncOp(opcode);
     227            1 :     CHK_PRT_RETURN(opHandleTmp == NULL, hccp_err("[async][ra_hdc_send]opcode[%u] invalid", opcode), -EINVAL);
     228              : 
     229            0 :     hostTgid = gRaHdcAsync[phyId].hostTgid;
     230            0 :     sendLen = (unsigned int)sizeof(struct MsgHead) + dataSize;
     231            0 :     sendBuf = (void *)calloc(sendLen, sizeof(char));
     232            0 :     CHK_PRT_RETURN(sendBuf == NULL, hccp_err("[async][ra_hdc_send]calloc send_buf failed. phyId(%u) opcode(%u)",
     233              :         phyId, opcode), -ENOMEM);
     234              : 
     235            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].reqMutex);
     236            0 :     asyncReqId = gRaHdcAsync[phyId].reqId;
     237            0 :     gRaHdcAsync[phyId].reqId++;
     238            0 :     HdcAsyncSetRequest(reqHandle, asyncReqId, opHandleTmp, phyId, dataSize);
     239              :     // make sure request has been added to req_list
     240            0 :     RaListAddTail(&reqHandle->list, &gRaHdcAsync[phyId].reqList);
     241            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].reqMutex);
     242              : 
     243            0 :     MsgHeadBuildUp(sendBuf, opcode, asyncReqId, dataSize, hostTgid);
     244            0 :     ret = memcpy_s(sendBuf + sizeof(struct MsgHead), sendLen - sizeof(struct MsgHead), data, dataSize);
     245            0 :     if (ret != 0) {
     246            0 :         hccp_err("[async][ra_hdc_send]memcpy_s failed, ret(%d) phyId(%u) opcode(%u)", ret, phyId, opcode);
     247            0 :         ret = -ESAFEFUNC;
     248            0 :         goto out;
     249              :     }
     250              : 
     251            0 :     ret = HdcAsyncSendPkt(&gRaHdcAsync[phyId], phyId, sendBuf, sendLen);
     252            0 :     if (ret != 0) {
     253            0 :         hccp_err("[async][ra_hdc_send]hdc_async_send_pkt opcode(%u) failed ret(%d) phyId(%u)", opcode, ret, phyId);
     254            0 :         goto out;
     255              :     }
     256              : 
     257            0 :     free(sendBuf);
     258            0 :     sendBuf = NULL;
     259            0 :     return 0;
     260              : 
     261            0 : out:
     262            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].reqMutex);
     263            0 :     RaListDel(&reqHandle->list);
     264            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].reqMutex);
     265            0 :     free(sendBuf);
     266            0 :     sendBuf = NULL;
     267            0 :     return ret;
     268              : }
     269              : 
     270            0 : STATIC int RaHdcAsyncSessionConnect(struct RaInitConfig *cfg)
     271              : {
     272            0 :     union OpAsyncHdcConnectData asyncData = {0};
     273            0 :     unsigned int interfaceVersion = 0;
     274              :     int ret;
     275              : 
     276            0 :     ret = RaHdcGetInterfaceVersion(cfg->phyId, RA_RS_ASYNC_HDC_SESSION_CONNECT, &interfaceVersion);
     277              :     // compatibility issue: ignore return value and set base version queue size to MAX_POOL_QUEUE_SIZE_V1
     278            0 :     if (ret != 0 || interfaceVersion <= RA_RS_OPCODE_BASE_VERSION) {
     279            0 :         asyncData.txData.queueSize = MAX_POOL_QUEUE_SIZE_V1;
     280              :     } else {
     281            0 :         asyncData.txData.queueSize = MAX_POOL_QUEUE_SIZE;
     282              :     }
     283            0 :     asyncData.txData.phyId = cfg->phyId;
     284            0 :     asyncData.txData.threadNum = RA_POOL_THREAD_NUM;
     285            0 :     ret = RaHdcProcessMsg(RA_RS_ASYNC_HDC_SESSION_CONNECT, cfg->phyId, (char *)&asyncData,
     286              :         sizeof(union OpAsyncHdcConnectData));
     287            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra_hdc_async]ra hdc message process failed ret[%d] phyId[%u]",
     288              :         ret, cfg->phyId), ret);
     289            0 :     return ret;
     290              : }
     291              : 
     292            0 : STATIC int RaHdcAsyncSessionClose(unsigned int phyId)
     293              : {
     294            0 :     union OpAsyncHdcCloseData asyncData = {0};
     295            0 :     struct RaRequestHandle *reqHandle = NULL;
     296            0 :     union OpHdcCloseData opData = {0};
     297            0 :     int timeout = RA_THREAD_TRY_TIME;
     298              :     int ret;
     299              : 
     300            0 :     if (gRaHdcAsync[phyId].restoreFlag != 0) {
     301            0 :         return 0;
     302              :     }
     303              : 
     304              :     // close async session
     305            0 :     opData.txData.phyId = phyId;
     306            0 :     reqHandle = (struct RaRequestHandle *)calloc(1, sizeof(struct RaRequestHandle));
     307            0 :     CHK_PRT_RETURN(reqHandle == NULL,
     308              :         hccp_err("[deinit][ra_hdc_async]calloc req_handle failed, phyId[%u]", phyId), -ENOMEM);
     309            0 :     ret = RaHdcSendMsgAsync(RA_RS_HDC_SESSION_CLOSE, phyId, (char *)&opData, sizeof(union OpHdcCloseData),
     310              :         reqHandle);
     311            0 :     if (ret != 0) {
     312            0 :         hccp_err("[deinit][ra_hdc_async]hdc async send message failed ret[%d] phyId[%u]", ret, phyId);
     313            0 :         free(reqHandle);
     314            0 :         reqHandle = NULL;
     315            0 :         return ret;
     316              :     }
     317              : 
     318              :     // wait request done until time out: RA_THREAD_TRY_TIME * RA_THREAD_SLEEP_TIME us
     319            0 :     while (!reqHandle->isDone && timeout > 0) {
     320            0 :         usleep(RA_THREAD_SLEEP_TIME);
     321            0 :         timeout--;
     322              :     }
     323            0 :     if (timeout <= 0) {
     324            0 :         hccp_warn("[deinit][ra_hdc_async]hdc async session close timeout:%d phyId[%u]", timeout, phyId);
     325              :     }
     326            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].reqMutex);    
     327            0 :     HdcAsyncDelResponse(reqHandle);     
     328            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].reqMutex);
     329              : 
     330              :     // destroy async recv thread and work thread pool
     331            0 :     ret = RaHdcProcessMsg(RA_RS_ASYNC_HDC_SESSION_CLOSE, phyId, (char *)&asyncData,
     332              :         sizeof(union OpAsyncHdcCloseData));
     333            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra_hdc_async]ra hdc message process failed ret[%d] phyId[%u]",
     334              :         ret, phyId), ret);
     335            0 :     return ret;
     336              : }
     337              : 
     338            0 : STATIC void RaHwAsyncHdcServerInit(void *arg)
     339              : {
     340            0 :     struct RaInitConfig cfg = {0};
     341              :     int ret;
     342              : 
     343            0 :     if (arg == NULL) {
     344            0 :         hccp_err("[init][ra_hdc_async]arg is NULL");
     345            0 :         return;
     346              :     }
     347              : 
     348            0 :     cfg = *(struct RaInitConfig *)arg;
     349            0 :     ret = pthread_detach(pthread_self());
     350            0 :     if (ret != 0) {
     351            0 :         hccp_err("[init][ra_hdc_async]pthread detach failed ret %d", ret);
     352            0 :         return;
     353              :     }
     354              : 
     355            0 :     (void)prctl(PR_SET_NAME, (uintptr_t)"hccp_async_server", 0, 0, 0);
     356              : 
     357              :     // trigger server to connect session
     358            0 :     ret = RaHdcAsyncSessionConnect(&cfg);
     359            0 :     if (ret != 0) {
     360            0 :         hccp_err("[init][ra_hdc_async]ra_hdc_async_session_connect failed ret[%d] phyId[%u]", ret, cfg.phyId);
     361            0 :         return;
     362              :     }
     363            0 :     return;
     364              : }
     365              : 
     366            0 : STATIC void RaHwAsyncHdcClientInit(void *arg)
     367              : {
     368            0 :     struct RaInitConfig cfg = {0};
     369            0 :     unsigned int logicId = 0;
     370            0 :     unsigned int phyId = 0;
     371              :     int ret;
     372              : 
     373            0 :     if (arg == NULL) {
     374            0 :         hccp_err("[init][ra_hdc_async]arg is NULL");
     375            0 :         return;
     376              :     }
     377              : 
     378            0 :     cfg = *(struct RaInitConfig *)arg;
     379            0 :     ret = pthread_detach(pthread_self());
     380            0 :     if (ret != 0) {
     381            0 :         hccp_err("[init][ra_hdc_async]pthread detach failed ret %d", ret);
     382            0 :         return;
     383              :     }
     384              : 
     385            0 :     (void)prctl(PR_SET_NAME, (uintptr_t)"hccp_async_client", 0, 0, 0);
     386              : 
     387            0 :     phyId = cfg.phyId;
     388            0 :     ret = DlDrvDeviceGetIndexByPhyId(phyId, &logicId);
     389            0 :     if (ret != 0) {
     390            0 :         hccp_err("get logic id failed(%d), phyId(%u)", ret, phyId);
     391            0 :         return;
     392              :     }
     393              : 
     394            0 :     ret = RaHdcInitSession(0, (int)logicId, phyId, cfg.hdcType, &gRaHdcAsync[phyId].session);
     395            0 :     if (ret != 0) {
     396            0 :         hccp_err("hdc session_connect failed ret(%d) phyId(%u)", ret, phyId);
     397            0 :         return;
     398              :     }
     399              : 
     400            0 :     ret = RaHdcSetSessionReference(&gRaHdcAsync[phyId].session);
     401            0 :     if (ret != 0) {
     402            0 :         goto set_ref_err;
     403              :     }
     404              : 
     405            0 :     RaHwAsyncSetConnectStatus(phyId, HDC_CONNECTED);
     406            0 :     return;
     407              : 
     408            0 : set_ref_err:
     409            0 :     RaHdcDeinitSession(&gRaHdcAsync[phyId].session);
     410            0 :     return;
     411              : }
     412              : 
     413            0 : STATIC void RaHwAsyncSetThreadStatus(unsigned int phyId, unsigned int threadStatus)
     414              : {
     415            0 :     gRaHdcAsync[phyId].threadStatus = threadStatus;
     416            0 : }
     417              : 
     418            1 : STATIC void RaHwAsyncDelList(struct RaListHead *head, pthread_mutex_t *mutex)
     419              : {
     420            1 :     struct RaRequestHandle *reqNext = NULL;
     421            1 :     struct RaRequestHandle *reqCur = NULL;
     422              : 
     423            1 :     RA_LIST_GET_HEAD_ENTRY(reqCur, reqNext, head, list, struct RaRequestHandle);
     424            1 :     for (; (&reqCur->list) != head;
     425            0 :         reqCur = reqNext, reqNext = list_entry(reqNext->list.next, struct RaRequestHandle, list)) {
     426            0 :         HdcAsyncDelReqHandle(reqCur, mutex);
     427              :     }
     428            1 : }
     429              : 
     430            0 : STATIC void RaHwAsyncHdcClientDeinit(unsigned int phyId)
     431              : {
     432            0 :     int tryAgain = HDC_TRY_TIME;
     433              : 
     434              :     // destroy thread
     435            0 :     RaHwAsyncSetThreadStatus(phyId, THREAD_DESTROYING);
     436            0 :     while ((gRaHdcAsync[phyId].threadStatus != THREAD_HALT) && (tryAgain != 0)) {
     437            0 :         usleep(HDC_USLEEP_TIME);
     438            0 :         tryAgain--;
     439              :     }
     440            0 :     if (tryAgain <= 0) {
     441            0 :         hccp_warn("hdc async message thread quit timeout");
     442              :     }
     443              : 
     444              :     // close session
     445            0 :     RaHwAsyncSetConnectStatus(phyId, HDC_UNCONNECTED);
     446            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].sendMutex);
     447            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].recvMutex);
     448            0 :     RaHdcDeinitSession(&gRaHdcAsync[phyId].snapshotSession);
     449            0 :     RaHdcDeinitSession(&gRaHdcAsync[phyId].session);
     450            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     451            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].sendMutex);
     452              : 
     453            0 :     RaHwAsyncDelList(&gRaHdcAsync[phyId].reqList, &gRaHdcAsync[phyId].reqMutex);
     454            0 :     RaHwAsyncDelList(&gRaHdcAsync[phyId].rspList, &gRaHdcAsync[phyId].rspMutex);
     455            0 : }
     456              : 
     457            0 : STATIC int RaHdcAsyncMutexInit(unsigned int phyId)
     458              : {
     459            0 :     int ret = 0;
     460              : 
     461            0 :     ret = pthread_mutex_init(&gRaHdcAsync[phyId].sendMutex, NULL);
     462            0 :     if (ret != 0) {
     463            0 :         hccp_err("[init][ra_hdc_async]pthread_mutex_init send_mutex failed ret(%d) phyId(%u)", ret, phyId);
     464            0 :         return -ESYSFUNC;
     465              :     }
     466            0 :     ret = pthread_mutex_init(&gRaHdcAsync[phyId].recvMutex, NULL);
     467            0 :     if (ret != 0) {
     468            0 :         hccp_err("[init][ra_hdc_async]pthread_mutex_init recv_mutex failed ret(%d) phyId(%u)", ret, phyId);
     469            0 :         ret = -ESYSFUNC;
     470            0 :         goto recv_mutex_fail;
     471              :     }
     472            0 :     ret = pthread_mutex_init(&gRaHdcAsync[phyId].reqMutex, NULL);
     473            0 :     if (ret != 0) {
     474            0 :         hccp_err("[init][ra_hdc_async]pthread_mutex_init req_mutex failed ret(%d) phyId(%u)", ret, phyId);
     475            0 :         ret = -ESYSFUNC;
     476            0 :         goto req_mutex_fail;
     477              :     }
     478            0 :     ret = pthread_mutex_init(&gRaHdcAsync[phyId].rspMutex, NULL);
     479            0 :     if (ret != 0) {
     480            0 :         hccp_err("[init][ra_hdc_async]pthread_mutex_init rsp_mutex failed ret(%d) phyId(%u)", ret, phyId);
     481            0 :         ret = -ESYSFUNC;
     482            0 :         goto rsp_mutex_fail;
     483              :     }
     484              : 
     485            0 :     return 0;
     486              : 
     487            0 : rsp_mutex_fail:
     488            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].reqMutex);
     489            0 : req_mutex_fail:
     490            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].recvMutex);
     491            0 : recv_mutex_fail:
     492            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].sendMutex);
     493            0 :     return ret;
     494              : }
     495              : 
     496            0 : STATIC void RaHdcAsyncMutexDeinit(unsigned int phyId)
     497              : {
     498            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].rspMutex);
     499            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].reqMutex);
     500            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].recvMutex);
     501            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].sendMutex);
     502            0 : }
     503              : 
     504            1 : STATIC int RaHdcAsyncInitSession(struct RaInitConfig *cfg)
     505              : {
     506            1 :     unsigned int phyId = cfg->phyId;
     507            1 :     int timeout = RA_THREAD_TRY_TIME;
     508              :     pthread_t serverTidp;
     509              :     pthread_t clientTidp;
     510            1 :     int ret = 0;
     511              : 
     512            1 :     CHK_PRT_RETURN(gRaHdcAsync[phyId].session != NULL, hccp_warn("hdc async session for phyId[%u] already existed",
     513              :         phyId), -EEXIST);
     514              : 
     515              :     // server will be blocked, use a thread to trigger server to accept
     516            1 :     ret = pthread_create(&serverTidp, NULL, (void *)RaHwAsyncHdcServerInit, cfg);
     517            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("Create async_hdc_server_init pthread failed, ret(%d)", ret), -ESYSFUNC);
     518              : 
     519              :     // client will be blocked, use a thread to trigger client to connect
     520            1 :     ret = pthread_create(&clientTidp, NULL, (void *)RaHwAsyncHdcClientInit, cfg);
     521            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("Create async_hdc_client_init pthread failed, ret(%d)", ret), -ESYSFUNC);
     522              : 
     523              :     // will block until time out: RA_CONNECT_TRY_TIME * RA_THREAD_SLEEP_TIME us
     524            1 :     timeout = RA_CONNECT_TRY_TIME;
     525            1 :     while (gRaHdcAsync[phyId].connectStatus != HDC_CONNECTED && timeout > 0) {
     526            0 :         usleep(RA_THREAD_SLEEP_TIME);
     527            0 :         timeout--;
     528              :     }
     529            1 :     if (gRaHdcAsync[phyId].connectStatus == HDC_UNCONNECTED || timeout <= 0) {
     530            0 :         hccp_err("HDC async connect timeout, connectStatus %d, timeout %d, total_timeout %d(us)",
     531              :             gRaHdcAsync[phyId].connectStatus, timeout, RA_CONNECT_TRY_TIME * RA_THREAD_SLEEP_TIME);
     532            0 :         return -ETIMEDOUT;
     533              :     }
     534              : 
     535            1 :     gRaHdcAsync[phyId].hostTgid = DlDrvDeviceGetBareTgid();
     536            1 :     ret = RaHdcAsyncMutexInit(phyId);
     537            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("ra_hdc_async_mutex_init failed, ret(%d), phyId(%u)", ret, phyId), ret);
     538              : 
     539            0 :     RA_INIT_LIST_HEAD(&gRaHdcAsync[phyId].reqList);
     540            0 :     RA_INIT_LIST_HEAD(&gRaHdcAsync[phyId].rspList);
     541            0 :     return 0;
     542              : }
     543              : 
     544            2 : STATIC void HdcAsyncHandleRecvBroken(struct HdcAsyncInfo *asyncInfo)
     545              : {
     546            2 :     struct RaRequestHandle *reqNext = NULL;
     547            2 :     struct RaRequestHandle *reqCurr = NULL;
     548              : 
     549            2 :     if (!RaHdcIsBroken(asyncInfo->lastRecvStatus)) {
     550            0 :         return;
     551              :     }
     552              : 
     553            2 :     RA_PTHREAD_MUTEX_LOCK(&asyncInfo->reqMutex);
     554            2 :     RA_LIST_GET_HEAD_ENTRY(reqCurr, reqNext, &asyncInfo->reqList, list, struct RaRequestHandle);
     555            3 :     for (; (&reqCurr->list) != &asyncInfo->reqList;
     556            1 :         reqCurr = reqNext, reqNext = list_entry(reqNext->list.next, struct RaRequestHandle, list)) {
     557            1 :         RaListDel(&reqCurr->list);
     558            1 :         HdcAsyncSetReqDone(reqCurr, reqCurr->phyId, asyncInfo->lastRecvStatus);
     559              :     }
     560            2 :     RA_PTHREAD_MUTEX_UNLOCK(&asyncInfo->reqMutex);
     561              : }
     562              : 
     563            0 : STATIC void *RaHdcRecvMsgAsync(void *arg)
     564              : {
     565            0 :     unsigned int phyId = *(unsigned int *)arg;
     566            0 :     unsigned int recvLen = MAX_HDC_MSG_DATA;
     567            0 :     void *recvBuf = NULL;
     568              :     int ret;
     569              : 
     570              :     // free memory after using arg
     571            0 :     free(arg);
     572            0 :     arg = NULL;
     573              : 
     574            0 :     ret = pthread_detach(pthread_self());
     575            0 :     CHK_PRT_RETURN(ret, hccp_err("pthread detach failed ret %d, phyId %u", ret, phyId), NULL);
     576              : 
     577            0 :     (void)prctl(PR_SET_NAME, (uintptr_t)"hccp_ra_async", 0, 0, 0);
     578              : 
     579            0 :     hccp_info("[async][ra_hdc_recv]thread[%d] phyId[%u] enter", getpid(), phyId);
     580            0 :     RaHwAsyncSetThreadStatus(phyId, THREAD_RUNNING);
     581            0 :     recvBuf = (void *)calloc(recvLen, sizeof(char));
     582            0 :     CHK_PRT_RETURN(recvBuf == NULL, hccp_err("[async][ra_hdc_recv]calloc recv_buf failed. phyId(%u)", phyId), NULL);
     583              : 
     584              :     while (1) {
     585            0 :         if (gRaHdcAsync[phyId].threadStatus == THREAD_DESTROYING) {
     586            0 :             break;
     587              :         }
     588            0 :         RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].recvMutex);
     589            0 :         if (gRaHdcAsync[phyId].connectStatus != HDC_CONNECTED) {
     590            0 :             RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     591            0 :             usleep(THREAD_SLEEP_TIME);
     592            0 :             continue;
     593              :         }
     594              : 
     595            0 :         if (RaListEmpty(&gRaHdcAsync[phyId].reqList)) {
     596            0 :             RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     597            0 :             usleep(THREAD_SLEEP_TIME);
     598            0 :             continue;
     599              :         }
     600              : 
     601            0 :         recvLen = MAX_HDC_MSG_DATA;
     602            0 :         ret = HdcAsyncRecvPkt(&gRaHdcAsync[phyId], phyId, recvBuf, &recvLen);
     603            0 :         if (ret != 0) {
     604            0 :             RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     605            0 :             HdcAsyncHandleRecvBroken(&gRaHdcAsync[phyId]);
     606            0 :             continue;
     607              :         }
     608            0 :         RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     609              : 
     610            0 :         RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].reqMutex);
     611            0 :         (void)HdcAsyncAddResponse(phyId, recvBuf, recvLen);
     612            0 :         RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].reqMutex);
     613              :     }
     614              : 
     615            0 :     hccp_info("[async][ra_hdc_recv]thread[%d] phyId[%u] is out", getpid(), phyId);
     616            0 :     RaHwAsyncSetThreadStatus(phyId, THREAD_HALT);
     617            0 :     free(recvBuf);
     618            0 :     recvBuf = NULL;
     619            0 :     return NULL;
     620              : }
     621              : 
     622            0 : STATIC int RaHdcAsyncInitRecvThread(unsigned int phyId)
     623              : {
     624            0 :     unsigned int *phyIdTmp = NULL;
     625            0 :     int ret = 0;
     626              : 
     627            0 :     phyIdTmp = (unsigned int *)calloc(1, sizeof(unsigned int));
     628            0 :     CHK_PRT_RETURN(phyIdTmp == NULL, hccp_err("calloc phy_id_tmp failed, errno(%d)", errno), -ENOMEM);
     629            0 :     *phyIdTmp = phyId;
     630              : 
     631              :     // create a thread to recv msg from server
     632            0 :     ret = pthread_create(&gRaHdcAsync[phyId].tid, NULL, RaHdcRecvMsgAsync, (void *)phyIdTmp);
     633            0 :     if (ret != 0) {
     634            0 :         hccp_err("Create ra_hdc_recv_msg_async pthread failed, ret(%d)", ret);
     635            0 :         goto err;
     636              :     }
     637              : 
     638            0 :     return 0;
     639              : 
     640            0 : err:
     641            0 :     free(phyIdTmp);
     642            0 :     phyIdTmp = NULL;
     643            0 :     return ret;
     644              : }
     645              : 
     646            1 : int RaHdcInitAsync(struct RaInitConfig *cfg)
     647              : {
     648            1 :     unsigned int interfaceVersion = 0;
     649            1 :     int ret = 0;
     650              : 
     651            1 :     CHK_PRT_RETURN(!cfg->enableHdcAsync, hccp_info("[init][ra_hdc_async]no need to init async hdc session"), 0);
     652              : 
     653            0 :     ret = RaHdcGetInterfaceVersion(cfg->phyId, RA_RS_ASYNC_HDC_SESSION_CONNECT, &interfaceVersion);
     654              :     // normal case: driver not support to or no need to init async hdc session
     655            0 :     CHK_PRT_RETURN(ret != 0 || interfaceVersion < RA_RS_OPCODE_BASE_VERSION,
     656              :         hccp_run_warn("[init][ra_hdc_async]not support to init async hdc session, ret(%d), interfaceVersion(%u)",
     657              :         ret, interfaceVersion), 0);
     658              : 
     659            0 :     ret = RaHdcAsyncInitSession(cfg);
     660            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra_hdc_async]ra_hdc_async_init_session failed, ret(%d) phyId(%u)",
     661              :         ret, cfg->phyId), ret);
     662              : 
     663            0 :     ret = RaHdcAsyncInitRecvThread(cfg->phyId);
     664            0 :     if (ret != 0) {
     665            0 :         hccp_err("[init][ra_hdc_async]ra_hdc_async_init_recv_thread failed, ret(%d) phyId(%u)", ret, cfg->phyId);
     666            0 :         goto err;
     667              :     }
     668              : 
     669            0 :     return 0;
     670              : 
     671            0 : err:
     672            0 :     RaHdcAsyncMutexDeinit(cfg->phyId);
     673            0 :     return -ESRCH;
     674              : }
     675              : 
     676            2 : int RaHdcDeinitAsync(unsigned int phyId)
     677              : {
     678              :     int ret;
     679              : 
     680            2 :     hccp_run_info("hdc deinit async start! phyId[%u] restore_flag[%u]", phyId, gRaHdcAsync[phyId].restoreFlag);
     681              : 
     682            2 :     CHK_PRT_RETURN(gRaHdcAsync[phyId].session == NULL && gRaHdcAsync[phyId].restoreFlag == 0,
     683              :         hccp_warn("hdc async session for phyId[%u] is NULL", phyId), -ENODEV);
     684              : 
     685              :     // close server session
     686            0 :     ret = RaHdcAsyncSessionClose(phyId);
     687            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra_hdc_async]ra_hdc_async_session_close failed ret[%d] phyId[%u]",
     688              :         ret, phyId), ret);
     689              : 
     690              :     // close client session & deinit client resources
     691            0 :     RaHwAsyncHdcClientDeinit(phyId);
     692              : 
     693            0 :     RaHdcAsyncMutexDeinit(phyId);
     694              : 
     695            0 :     (void)memset_s(&gRaHdcAsync[phyId], sizeof(gRaHdcAsync[phyId]), 0, sizeof(gRaHdcAsync[phyId]));
     696              : 
     697            0 :     return 0;
     698              : }
     699              : 
     700            0 : int RaHdcAsyncSaveSnapshot(unsigned int phyId, enum SaveSnapshotAction action)
     701              : {
     702            0 :     int ret = 0;
     703              : 
     704            0 :     if (gRaHdcAsync[phyId].threadStatus == THREAD_HALT) {
     705            0 :         return 0;
     706              :     }
     707              : 
     708              : #ifndef HNS_ROCE_LLT
     709              :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].sendMutex);
     710              :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].recvMutex);
     711              :     if (action == SAVE_SNAPSHOT_ACTION_PRE_PROCESSING && gRaHdcAsync[phyId].session != NULL) {
     712              :         RaHwAsyncSetConnectStatus(phyId, HDC_UNCONNECTED);
     713              :         gRaHdcAsync[phyId].snapshotSession = gRaHdcAsync[phyId].session;
     714              :         gRaHdcAsync[phyId].session = NULL;
     715              :     } else if (action == SAVE_SNAPSHOT_ACTION_POST_PROCESSING && gRaHdcAsync[phyId].session == NULL) {
     716              :         RaHwAsyncSetConnectStatus(phyId, HDC_CONNECTED);
     717              :         gRaHdcAsync[phyId].session = gRaHdcAsync[phyId].snapshotSession;
     718              :         gRaHdcAsync[phyId].snapshotSession = NULL;
     719              :     } else {
     720              :         hccp_err("duplicate or incorrect order calls are not allowed, phyId[%u] action[%d]", phyId, action);
     721              :         ret = -EPERM;
     722              :     }
     723              :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     724              :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].sendMutex);
     725              : #endif
     726            0 :     return ret;
     727              : }
     728              : 
     729            0 : int RaHdcAsyncRestoreSnapshot(unsigned int phyId)
     730              : {
     731            0 :     int ret = 0;
     732              : 
     733            0 :     if (gRaHdcAsync[phyId].threadStatus == THREAD_HALT) {
     734            0 :         return 0;
     735              :     }
     736              : 
     737              : #ifndef HNS_ROCE_LLT
     738              :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].sendMutex);
     739              :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].recvMutex);
     740              :     if (gRaHdcAsync[phyId].connectStatus != HDC_UNCONNECTED) {
     741              :         hccp_err("incorrect order calls are not allowed, phyId[%u] connectStatus[%u]", phyId,
     742              :             gRaHdcAsync[phyId].connectStatus);
     743              :         ret = -EPERM;
     744              :     } else {
     745              :         gRaHdcAsync[phyId].restoreFlag = 1;
     746              :     }
     747              :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     748              :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].sendMutex);
     749              : #endif
     750            0 :     return ret;
     751              : }
     752              : 
     753            2 : void RaHdcDeinitAsyncAll(void)
     754              : {
     755            2 :     unsigned int phyId = 0;
     756              : 
     757          130 :     for (phyId = 0; phyId < RA_MAX_PHY_ID_NUM; phyId++) {
     758          128 :         if (gRaHdcAsync[phyId].session == NULL || gRaHdcAsync[phyId].threadStatus != THREAD_RUNNING) {
     759          128 :             continue;
     760              :         }
     761              : 
     762            0 :         (void)RaHdcDeinitAsync(phyId);
     763              :     }
     764            2 : }
        

Generated by: LCOV version 2.0-1