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

Generated by: LCOV version 2.0-1