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-07-28 12:11:00 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_LMEM_REG, RDMA_OP, RaHdcAsyncHandleLmemRegister, sizeof(union OpLmemRegInfoData)},
      32              :     {RA_RS_LMEM_UNREG, RDMA_OP, NULL, sizeof(union OpLmemUnregInfoData)},
      33              :     {RA_RS_CTX_QP_CREATE, RDMA_OP, RaHdcAsyncHandleQpCreate, sizeof(union OpCtxQpCreateData)},
      34              :     {RA_RS_CTX_QP_DESTROY, RDMA_OP, NULL, sizeof(union OpCtxQpDestroyData)},
      35              :     {RA_RS_CTX_QP_IMPORT, RDMA_OP, RaHdcAsyncHandleQpImport, sizeof(union OpCtxQpImportData)},
      36              :     {RA_RS_CTX_QP_UNIMPORT, RDMA_OP, NULL, sizeof(union OpCtxQpUnimportData)},
      37              :     {RA_RS_GET_TP_INFO_LIST, RDMA_OP, RaHdcAsyncHandleTpInfoList, sizeof(union OpGetTpInfoListData)},
      38              :     {RA_RS_GET_TP_ATTR, RDMA_OP, RaHdcAsyncHandleGetTpAttr, sizeof(union OpGetTpAttrData)},
      39              :     {RA_RS_SET_TP_ATTR, RDMA_OP, NULL, sizeof(union OpSetTpAttrData)},
      40              :     {RA_RS_CTX_QP_DESTROY_BATCH, RDMA_OP, RaHdcAsyncHandleQpDestroyBatch,
      41              :         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,
      45              :         sizeof(union OpSocketListenData)},
      46              :     {RA_RS_SOCKET_LISTEN_STOP, SOCKET_OP, NULL, sizeof(union OpSocketListenData)},
      47              :     {RA_RS_SOCKET_CONN, SOCKET_OP, NULL, sizeof(union OpSocketConnectData)},
      48              :     {RA_RS_SOCKET_CLOSE, SOCKET_OP, RaHdcAsyncHandleSocketBatchClose, sizeof(union OpSocketCloseData)},
      49              :     {RA_RS_HDC_SESSION_CLOSE, OTHERS, NULL, sizeof(union OpHdcCloseData)},
      50              : };
      51              : 
      52            1 : STATIC struct RaAsyncOpHandle *RaHdcIsAsyncOp(unsigned int opcode)
      53              : {
      54            1 :     int num = sizeof(gRaAsyncOpHandle) / sizeof(gRaAsyncOpHandle[0]);
      55              :     int i;
      56              : 
      57           19 :     for (i = 0; i < num; i++) {
      58           18 :         if (gRaAsyncOpHandle[i].opcode == (enum OpType)opcode) {
      59            0 :             return &gRaAsyncOpHandle[i];
      60              :         }
      61              :     }
      62            1 :     return NULL;
      63              : }
      64              : 
      65            0 : STATIC void HdcAsyncHandlePrivData(struct RaRequestHandle *reqHandle)
      66              : {
      67            0 :     if (reqHandle->opHandle->privDataHandle == NULL) {
      68            0 :         return;
      69              :     }
      70              : 
      71            0 :     reqHandle->opHandle->privDataHandle(reqHandle);
      72              : }
      73              : 
      74            0 : STATIC void HdcAsyncSetRequest(struct RaRequestHandle *reqHandle, unsigned int reqId,
      75              :     struct RaAsyncOpHandle *opHandle, unsigned int phyId, unsigned int dataSize)
      76              : {
      77            0 :     reqHandle->reqId = reqId;
      78            0 :     reqHandle->opHandle = opHandle;
      79            0 :     reqHandle->phyId = phyId;
      80            0 :     reqHandle->dataSize = dataSize;
      81            0 : }
      82              : 
      83            0 : STATIC int HdcAsyncGetRequest(struct HdcAsyncInfo *asyncInfo, unsigned int reqId,
      84              :     struct RaRequestHandle **reqHandle)
      85              : {
      86            0 :     struct RaRequestHandle *reqTmp2 = NULL;
      87            0 :     struct RaRequestHandle *reqTmp = NULL;
      88              : 
      89              :     // no need to use lock: req_id always exist in current req_list(the data is always sent before it is received)
      90            0 :     RA_LIST_GET_HEAD_ENTRY(reqTmp, reqTmp2, &asyncInfo->reqList, list, struct RaRequestHandle);
      91            0 :     for (; (&reqTmp->list) != &asyncInfo->reqList;
      92            0 :         reqTmp = reqTmp2, reqTmp2 = list_entry(reqTmp2->list.next, struct RaRequestHandle, list)) {
      93            0 :         if (reqTmp->reqId == reqId) {
      94            0 :             *reqHandle = reqTmp;
      95            0 :             return 0;
      96              :         }
      97              :     }
      98            0 :     *reqHandle = NULL;
      99            0 :     return -ENODEV;
     100              : }
     101              : 
     102            0 : STATIC void HdcAsyncSetReqDone(struct RaRequestHandle *reqHandle, unsigned int phyId, int ret)
     103              : {
     104            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].rspMutex);
     105            0 :     RaListAddTail(&reqHandle->list, &gRaHdcAsync[phyId].rspList);
     106            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].rspMutex);
     107            0 :     reqHandle->opRet = (ret != 0) ? ret : reqHandle->opRet;
     108            0 :     reqHandle->isDone = true;
     109            0 : }
     110              : 
     111            1 : STATIC void RaHwAsyncSetConnectStatus(unsigned int phyId, unsigned int connectStatus)
     112              : {
     113            1 :     gRaHdcAsync[phyId].connectStatus = connectStatus;
     114            1 : }
     115              : 
     116            0 : STATIC bool HdcAsyncIsMsgValid(unsigned int phyId, struct MsgHead *recvMsgHead, unsigned int recvLen,
     117              :     struct RaRequestHandle **reqHandle)
     118              : {
     119            0 :     struct RaRequestHandle *reqHandleTmp = NULL;
     120              :     int ret;
     121              : 
     122              :     // check recv_len and get req_handle
     123            0 :     CHK_PRT_RETURN(recvLen < sizeof(struct MsgHead),
     124              :         hccp_run_warn("[async][ra_hdc_recv]recv_len[%u] < [%lu] is invalid", recvLen, sizeof(struct MsgHead)), false);
     125            0 :     ret = HdcAsyncGetRequest(&gRaHdcAsync[phyId], recvMsgHead->asyncReqId, &reqHandleTmp);
     126            0 :     CHK_PRT_RETURN(reqHandleTmp == NULL, hccp_run_warn("[async][ra_hdc_recv]req_id[%u] invalid, ret[%d], opcode[%u]",
     127              :         recvMsgHead->asyncReqId, ret, recvMsgHead->opcode), 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, hccp_err("[async][ra_hdc_send]calloc send_buf failed. phyId(%u) opcode(%u)",
     232              :         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, hccp_err("[init][ra_hdc_async]ra hdc message process failed ret[%d] phyId[%u]",
     287              :         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,
     307              :         hccp_err("[deinit][ra_hdc_async]calloc req_handle failed, phyId[%u]", phyId), -ENOMEM);
     308            0 :     ret = RaHdcSendMsgAsync(RA_RS_HDC_SESSION_CLOSE, phyId, (char *)&opData, sizeof(union OpHdcCloseData),
     309              :         reqHandle);
     310            0 :     if (ret != 0) {
     311            0 :         hccp_err("[deinit][ra_hdc_async]hdc async send message failed ret[%d] phyId[%u]", ret, phyId);
     312            0 :         free(reqHandle);
     313            0 :         reqHandle = NULL;
     314            0 :         return ret;
     315              :     }
     316              : 
     317              :     // wait request done until time out: RA_THREAD_TRY_TIME * RA_THREAD_SLEEP_TIME us
     318            0 :     while (!reqHandle->isDone && timeout > 0) {
     319            0 :         usleep(RA_THREAD_SLEEP_TIME);
     320            0 :         timeout--;
     321              :     }
     322            0 :     if (timeout <= 0) {
     323            0 :         hccp_warn("[deinit][ra_hdc_async]hdc async session close timeout:%d phyId[%u]", timeout, phyId);
     324              :     }
     325            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].reqMutex);    
     326            0 :     HdcAsyncDelResponse(reqHandle);     
     327            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].reqMutex);
     328              : 
     329              :     // destroy async recv thread and work thread pool
     330            0 :     ret = RaHdcProcessMsg(RA_RS_ASYNC_HDC_SESSION_CLOSE, phyId, (char *)&asyncData,
     331              :         sizeof(union OpAsyncHdcCloseData));
     332            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra_hdc_async]ra hdc message process failed ret[%d] phyId[%u]",
     333              :         ret, phyId), ret);
     334            0 :     return ret;
     335              : }
     336              : 
     337            0 : STATIC void RaHwAsyncHdcServerInit(void *arg)
     338              : {
     339            0 :     struct RaInitConfig cfg = {0};
     340              :     int ret;
     341              : 
     342            0 :     if (arg == NULL) {
     343            0 :         hccp_err("[init][ra_hdc_async]arg is NULL");
     344            0 :         return;
     345              :     }
     346              : 
     347            0 :     cfg = *(struct RaInitConfig *)arg;
     348            0 :     ret = pthread_detach(pthread_self());
     349            0 :     if (ret != 0) {
     350            0 :         hccp_err("[init][ra_hdc_async]pthread detach failed ret %d", ret);
     351            0 :         return;
     352              :     }
     353              : 
     354            0 :     (void)prctl(PR_SET_NAME, (unsigned long)"hccp_async_server");
     355              : 
     356              :     // trigger server to connect session
     357            0 :     ret = RaHdcAsyncSessionConnect(&cfg);
     358            0 :     if (ret != 0) {
     359            0 :         hccp_err("[init][ra_hdc_async]ra_hdc_async_session_connect failed ret[%d] phyId[%u]", ret, cfg.phyId);
     360            0 :         return;
     361              :     }
     362            0 :     return;
     363              : }
     364              : 
     365            0 : STATIC void RaHwAsyncHdcClientInit(void *arg)
     366              : {
     367            0 :     struct RaInitConfig cfg = {0};
     368            0 :     unsigned int logicId = 0;
     369            0 :     unsigned int phyId = 0;
     370              :     int ret;
     371              : 
     372            0 :     if (arg == NULL) {
     373            0 :         hccp_err("[init][ra_hdc_async]arg is NULL");
     374            0 :         return;
     375              :     }
     376              : 
     377            0 :     cfg = *(struct RaInitConfig *)arg;
     378            0 :     ret = pthread_detach(pthread_self());
     379            0 :     if (ret != 0) {
     380            0 :         hccp_err("[init][ra_hdc_async]pthread detach failed ret %d", ret);
     381            0 :         return;
     382              :     }
     383              : 
     384            0 :     (void)prctl(PR_SET_NAME, (unsigned long)"hccp_async_client");
     385              : 
     386            0 :     phyId = cfg.phyId;
     387            0 :     ret = DlDrvDeviceGetIndexByPhyId(phyId, &logicId);
     388            0 :     if (ret != 0) {
     389            0 :         hccp_err("get logic id failed(%d), phyId(%u)", ret, phyId);
     390            0 :         return;
     391              :     }
     392              : 
     393            0 :     ret = RaHdcInitSession(0, (int)logicId, phyId, cfg.hdcType, &gRaHdcAsync[phyId].session);
     394            0 :     if (ret != 0) {
     395            0 :         hccp_err("hdc session_connect failed ret(%d) phyId(%u)", ret, phyId);
     396            0 :         return;
     397              :     }
     398              : 
     399            0 :     ret = RaHdcSetSessionReference(&gRaHdcAsync[phyId].session);
     400            0 :     if (ret != 0) {
     401            0 :         goto set_ref_err;
     402              :     }
     403              : 
     404            0 :     RaHwAsyncSetConnectStatus(phyId, HDC_CONNECTED);
     405            0 :     return;
     406              : 
     407            0 : set_ref_err:
     408            0 :     RaHdcDeinitSession(&gRaHdcAsync[phyId].session);
     409            0 :     return;
     410              : }
     411              : 
     412            0 : STATIC void RaHwAsyncSetThreadStatus(unsigned int phyId, unsigned int threadStatus)
     413              : {
     414            0 :     gRaHdcAsync[phyId].threadStatus = threadStatus;
     415            0 : }
     416              : 
     417            1 : STATIC void RaHwAsyncDelList(struct RaListHead *head, pthread_mutex_t *mutex)
     418              : {
     419            1 :     struct RaRequestHandle *reqNext = NULL;
     420            1 :     struct RaRequestHandle *reqCur = NULL;
     421              : 
     422            1 :     RA_LIST_GET_HEAD_ENTRY(reqCur, reqNext, head, list, struct RaRequestHandle);
     423            1 :     for (; (&reqCur->list) != head;
     424            0 :         reqCur = reqNext, reqNext = list_entry(reqNext->list.next, struct RaRequestHandle, list)) {
     425            0 :         HdcAsyncDelReqHandle(reqCur, mutex);
     426              :     }
     427            1 : }
     428              : 
     429            0 : STATIC void RaHwAsyncHdcClientDeinit(unsigned int phyId)
     430              : {
     431            0 :     int tryAgain = HDC_TRY_TIME;
     432              : 
     433              :     // destroy thread
     434            0 :     RaHwAsyncSetThreadStatus(phyId, THREAD_DESTROYING);
     435            0 :     while ((gRaHdcAsync[phyId].threadStatus != THREAD_HALT) && (tryAgain != 0)) {
     436            0 :         usleep(HDC_USLEEP_TIME);
     437            0 :         tryAgain--;
     438              :     }
     439            0 :     if (tryAgain <= 0) {
     440            0 :         hccp_warn("hdc async message thread quit timeout");
     441              :     }
     442              : 
     443              :     // close session
     444            0 :     RaHwAsyncSetConnectStatus(phyId, HDC_UNCONNECTED);
     445            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].sendMutex);
     446            0 :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].recvMutex);
     447            0 :     RaHdcDeinitSession(&gRaHdcAsync[phyId].snapshotSession);
     448            0 :     RaHdcDeinitSession(&gRaHdcAsync[phyId].session);
     449            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     450            0 :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].sendMutex);
     451              : 
     452            0 :     RaHwAsyncDelList(&gRaHdcAsync[phyId].reqList, &gRaHdcAsync[phyId].reqMutex);
     453            0 :     RaHwAsyncDelList(&gRaHdcAsync[phyId].rspList, &gRaHdcAsync[phyId].rspMutex);
     454            0 : }
     455              : 
     456            0 : STATIC int RaHdcAsyncMutexInit(unsigned int phyId)
     457              : {
     458            0 :     int ret = 0;
     459              : 
     460            0 :     ret = pthread_mutex_init(&gRaHdcAsync[phyId].sendMutex, NULL);
     461            0 :     if (ret != 0) {
     462            0 :         hccp_err("[init][ra_hdc_async]pthread_mutex_init send_mutex failed ret(%d) phyId(%u)", ret, phyId);
     463            0 :         return -ESYSFUNC;
     464              :     }
     465            0 :     ret = pthread_mutex_init(&gRaHdcAsync[phyId].recvMutex, NULL);
     466            0 :     if (ret != 0) {
     467            0 :         hccp_err("[init][ra_hdc_async]pthread_mutex_init recv_mutex failed ret(%d) phyId(%u)", ret, phyId);
     468            0 :         ret = -ESYSFUNC;
     469            0 :         goto recv_mutex_fail;
     470              :     }
     471            0 :     ret = pthread_mutex_init(&gRaHdcAsync[phyId].reqMutex, NULL);
     472            0 :     if (ret != 0) {
     473            0 :         hccp_err("[init][ra_hdc_async]pthread_mutex_init req_mutex failed ret(%d) phyId(%u)", ret, phyId);
     474            0 :         ret = -ESYSFUNC;
     475            0 :         goto req_mutex_fail;
     476              :     }
     477            0 :     ret = pthread_mutex_init(&gRaHdcAsync[phyId].rspMutex, NULL);
     478            0 :     if (ret != 0) {
     479            0 :         hccp_err("[init][ra_hdc_async]pthread_mutex_init rsp_mutex failed ret(%d) phyId(%u)", ret, phyId);
     480            0 :         ret = -ESYSFUNC;
     481            0 :         goto rsp_mutex_fail;
     482              :     }
     483              : 
     484            0 :     return 0;
     485              : 
     486            0 : rsp_mutex_fail:
     487            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].reqMutex);
     488            0 : req_mutex_fail:
     489            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].recvMutex);
     490            0 : recv_mutex_fail:
     491            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].sendMutex);
     492            0 :     return ret;
     493              : }
     494              : 
     495            0 : STATIC void RaHdcAsyncMutexDeinit(unsigned int phyId)
     496              : {
     497            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].rspMutex);
     498            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].reqMutex);
     499            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].recvMutex);
     500            0 :     (void)pthread_mutex_destroy(&gRaHdcAsync[phyId].sendMutex);
     501            0 : }
     502              : 
     503            1 : STATIC int RaHdcAsyncInitSession(struct RaInitConfig *cfg)
     504              : {
     505            1 :     unsigned int phyId = cfg->phyId;
     506            1 :     int timeout = RA_THREAD_TRY_TIME;
     507              :     pthread_t serverTidp;
     508              :     pthread_t clientTidp;
     509            1 :     int ret = 0;
     510              : 
     511            1 :     CHK_PRT_RETURN(gRaHdcAsync[phyId].session != NULL, hccp_warn("hdc async session for phyId[%u] already existed",
     512              :         phyId), -EEXIST);
     513              : 
     514              :     // server will be blocked, use a thread to trigger server to accept
     515            1 :     ret = pthread_create(&serverTidp, NULL, (void *)RaHwAsyncHdcServerInit, cfg);
     516            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("Create async_hdc_server_init pthread failed, ret(%d)", ret), -ESYSFUNC);
     517              : 
     518              :     // client will be blocked, use a thread to trigger client to connect
     519            1 :     ret = pthread_create(&clientTidp, NULL, (void *)RaHwAsyncHdcClientInit, cfg);
     520            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("Create async_hdc_client_init pthread failed, ret(%d)", ret), -ESYSFUNC);
     521              : 
     522              :     // will block until time out: RA_CONNECT_TRY_TIME * RA_THREAD_SLEEP_TIME us
     523            1 :     timeout = RA_CONNECT_TRY_TIME;
     524            1 :     while (gRaHdcAsync[phyId].connectStatus != HDC_CONNECTED && timeout > 0) {
     525            0 :         usleep(RA_THREAD_SLEEP_TIME);
     526            0 :         timeout--;
     527              :     }
     528            1 :     if (gRaHdcAsync[phyId].connectStatus == HDC_UNCONNECTED || timeout <= 0) {
     529            0 :         hccp_err("HDC async connect timeout, connectStatus %d, timeout %d, total_timeout %d(us)",
     530              :             gRaHdcAsync[phyId].connectStatus, timeout, RA_CONNECT_TRY_TIME * RA_THREAD_SLEEP_TIME);
     531            0 :         return -ETIMEDOUT;
     532              :     }
     533              : 
     534            1 :     gRaHdcAsync[phyId].hostTgid = DlDrvDeviceGetBareTgid();
     535            1 :     ret = RaHdcAsyncMutexInit(phyId);
     536            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("ra_hdc_async_mutex_init failed, ret(%d), phyId(%u)", ret, phyId), ret);
     537              : 
     538            0 :     RA_INIT_LIST_HEAD(&gRaHdcAsync[phyId].reqList);
     539            0 :     RA_INIT_LIST_HEAD(&gRaHdcAsync[phyId].rspList);
     540            0 :     return 0;
     541              : }
     542              : 
     543            2 : STATIC void HdcAsyncHandleRecvBroken(struct HdcAsyncInfo *asyncInfo)
     544              : {
     545            2 :     struct RaRequestHandle *reqNext = NULL;
     546            2 :     struct RaRequestHandle *reqCurr = NULL;
     547              : 
     548            2 :     if (!RaHdcIsBroken(asyncInfo->lastRecvStatus)) {
     549            0 :         return;
     550              :     }
     551              : 
     552            2 :     RA_PTHREAD_MUTEX_LOCK(&asyncInfo->reqMutex);
     553            2 :     RA_LIST_GET_HEAD_ENTRY(reqCurr, reqNext, &asyncInfo->reqList, list, struct RaRequestHandle);
     554            3 :     for (; (&reqCurr->list) != &asyncInfo->reqList;
     555            1 :         reqCurr = reqNext, reqNext = list_entry(reqNext->list.next, struct RaRequestHandle, list)) {
     556            1 :         RaListDel(&reqCurr->list);
     557            1 :         HdcAsyncSetReqDone(reqCurr, reqCurr->phyId, asyncInfo->lastRecvStatus);
     558              :     }
     559            2 :     RA_PTHREAD_MUTEX_UNLOCK(&asyncInfo->reqMutex);
     560              : }
     561              : 
     562            0 : STATIC void *RaHdcRecvMsgAsync(void *arg)
     563              : {
     564            0 :     unsigned int phyId = *(unsigned int *)arg;
     565            0 :     unsigned int recvLen = MAX_HDC_MSG_DATA;
     566            0 :     void *recvBuf = NULL;
     567              :     int ret;
     568              : 
     569              :     // free memory after using arg
     570            0 :     free(arg);
     571            0 :     arg = NULL;
     572              : 
     573            0 :     ret = pthread_detach(pthread_self());
     574            0 :     CHK_PRT_RETURN(ret, hccp_err("pthread detach failed ret %d, phyId %u", ret, phyId), NULL);
     575              : 
     576            0 :     (void)prctl(PR_SET_NAME, (unsigned long)"hccp_ra_async");
     577              : 
     578            0 :     hccp_info("[async][ra_hdc_recv]thread[%d] phyId[%u] enter", getpid(), phyId);
     579            0 :     RaHwAsyncSetThreadStatus(phyId, THREAD_RUNNING);
     580            0 :     recvBuf = (void *)calloc(recvLen, sizeof(char));
     581            0 :     CHK_PRT_RETURN(recvBuf == NULL, hccp_err("[async][ra_hdc_recv]calloc recv_buf failed. phyId(%u)", phyId), NULL);
     582              : 
     583              :     while (1) {
     584            0 :         if (gRaHdcAsync[phyId].threadStatus == THREAD_DESTROYING) {
     585            0 :             break;
     586              :         }
     587            0 :         RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].recvMutex);
     588            0 :         if (gRaHdcAsync[phyId].connectStatus != HDC_CONNECTED) {
     589            0 :             RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     590            0 :             usleep(THREAD_SLEEP_TIME);
     591            0 :             continue;
     592              :         }
     593              : 
     594            0 :         if (RaListEmpty(&gRaHdcAsync[phyId].reqList)) {
     595            0 :             RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     596            0 :             usleep(THREAD_SLEEP_TIME);
     597            0 :             continue;
     598              :         }
     599              : 
     600            0 :         recvLen = MAX_HDC_MSG_DATA;
     601            0 :         ret = HdcAsyncRecvPkt(&gRaHdcAsync[phyId], phyId, recvBuf, &recvLen);
     602            0 :         if (ret != 0) {
     603            0 :             RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     604            0 :             HdcAsyncHandleRecvBroken(&gRaHdcAsync[phyId]);
     605            0 :             continue;
     606              :         }
     607            0 :         RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     608              : 
     609            0 :         RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].reqMutex);
     610            0 :         (void)HdcAsyncAddResponse(phyId, recvBuf, recvLen);
     611            0 :         RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].reqMutex);
     612              :     }
     613              : 
     614            0 :     hccp_info("[async][ra_hdc_recv]thread[%d] phyId[%u] is out", getpid(), phyId);
     615            0 :     RaHwAsyncSetThreadStatus(phyId, THREAD_HALT);
     616            0 :     free(recvBuf);
     617            0 :     recvBuf = NULL;
     618            0 :     return NULL;
     619              : }
     620              : 
     621            0 : STATIC int RaHdcAsyncInitRecvThread(unsigned int phyId)
     622              : {
     623            0 :     unsigned int *phyIdTmp = NULL;
     624            0 :     int ret = 0;
     625              : 
     626            0 :     phyIdTmp = (unsigned int *)calloc(1, sizeof(unsigned int));
     627            0 :     CHK_PRT_RETURN(phyIdTmp == NULL, hccp_err("calloc phy_id_tmp failed, errno(%d)", errno), -ENOMEM);
     628            0 :     *phyIdTmp = phyId;
     629              : 
     630              :     // create a thread to recv msg from server
     631            0 :     ret = pthread_create(&gRaHdcAsync[phyId].tid, NULL, RaHdcRecvMsgAsync, (void *)phyIdTmp);
     632            0 :     if (ret != 0) {
     633            0 :         hccp_err("Create ra_hdc_recv_msg_async pthread failed, ret(%d)", ret);
     634            0 :         goto err;
     635              :     }
     636              : 
     637            0 :     return 0;
     638              : 
     639            0 : err:
     640            0 :     free(phyIdTmp);
     641            0 :     phyIdTmp = NULL;
     642            0 :     return ret;
     643              : }
     644              : 
     645            1 : int RaHdcInitAsync(struct RaInitConfig *cfg)
     646              : {
     647            1 :     unsigned int interfaceVersion = 0;
     648            1 :     int ret = 0;
     649              : 
     650            1 :     CHK_PRT_RETURN(!cfg->enableHdcAsync, hccp_info("[init][ra_hdc_async]no need to init async hdc session"), 0);
     651              : 
     652            0 :     ret = RaHdcGetInterfaceVersion(cfg->phyId, RA_RS_ASYNC_HDC_SESSION_CONNECT, &interfaceVersion);
     653              :     // normal case: driver not support to or no need to init async hdc session
     654            0 :     CHK_PRT_RETURN(ret != 0 || interfaceVersion < RA_RS_OPCODE_BASE_VERSION,
     655              :         hccp_run_warn("[init][ra_hdc_async]not support to init async hdc session, ret(%d), interfaceVersion(%u)",
     656              :         ret, interfaceVersion), 0);
     657              : 
     658            0 :     ret = RaHdcAsyncInitSession(cfg);
     659            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra_hdc_async]ra_hdc_async_init_session failed, ret(%d) phyId(%u)",
     660              :         ret, cfg->phyId), ret);
     661              : 
     662            0 :     ret = RaHdcAsyncInitRecvThread(cfg->phyId);
     663            0 :     if (ret != 0) {
     664            0 :         hccp_err("[init][ra_hdc_async]ra_hdc_async_init_recv_thread failed, ret(%d) phyId(%u)", ret, cfg->phyId);
     665            0 :         goto err;
     666              :     }
     667              : 
     668            0 :     return 0;
     669              : 
     670            0 : err:
     671            0 :     RaHdcAsyncMutexDeinit(cfg->phyId);
     672            0 :     return -ESRCH;
     673              : }
     674              : 
     675            2 : int RaHdcDeinitAsync(unsigned int phyId)
     676              : {
     677              :     int ret;
     678              : 
     679            2 :     hccp_run_info("hdc deinit async start! phyId[%u] restore_flag[%u]", phyId, gRaHdcAsync[phyId].restoreFlag);
     680              : 
     681            2 :     CHK_PRT_RETURN(gRaHdcAsync[phyId].session == NULL && gRaHdcAsync[phyId].restoreFlag == 0,
     682              :         hccp_warn("hdc async session for phyId[%u] is NULL", phyId), -ENODEV);
     683              : 
     684              :     // close server session
     685            0 :     ret = RaHdcAsyncSessionClose(phyId);
     686            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra_hdc_async]ra_hdc_async_session_close failed ret[%d] phyId[%u]",
     687              :         ret, phyId), ret);
     688              : 
     689              :     // close client session & deinit client resources
     690            0 :     RaHwAsyncHdcClientDeinit(phyId);
     691              : 
     692            0 :     RaHdcAsyncMutexDeinit(phyId);
     693              : 
     694            0 :     (void)memset_s(&gRaHdcAsync[phyId], sizeof(gRaHdcAsync[phyId]), 0, sizeof(gRaHdcAsync[phyId]));
     695              : 
     696            0 :     return 0;
     697              : }
     698              : 
     699            0 : int RaHdcAsyncSaveSnapshot(unsigned int phyId, enum SaveSnapshotAction action)
     700              : {
     701            0 :     int ret = 0;
     702              : 
     703            0 :     if (gRaHdcAsync[phyId].threadStatus == THREAD_HALT) {
     704            0 :         return 0;
     705              :     }
     706              : 
     707              : #ifndef HNS_ROCE_LLT
     708              :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].sendMutex);
     709              :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].recvMutex);
     710              :     if (action == SAVE_SNAPSHOT_ACTION_PRE_PROCESSING && gRaHdcAsync[phyId].session != NULL) {
     711              :         RaHwAsyncSetConnectStatus(phyId, HDC_UNCONNECTED);
     712              :         gRaHdcAsync[phyId].snapshotSession = gRaHdcAsync[phyId].session;
     713              :         gRaHdcAsync[phyId].session = NULL;
     714              :     } else if (action == SAVE_SNAPSHOT_ACTION_POST_PROCESSING && gRaHdcAsync[phyId].session == NULL) {
     715              :         RaHwAsyncSetConnectStatus(phyId, HDC_CONNECTED);
     716              :         gRaHdcAsync[phyId].session = gRaHdcAsync[phyId].snapshotSession;
     717              :         gRaHdcAsync[phyId].snapshotSession = NULL;
     718              :     } else {
     719              :         hccp_err("duplicate or incorrect order calls are not allowed, phyId[%u] action[%d]", phyId, action);
     720              :         ret = -EPERM;
     721              :     }
     722              :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     723              :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].sendMutex);
     724              : #endif
     725            0 :     return ret;
     726              : }
     727              : 
     728            0 : int RaHdcAsyncRestoreSnapshot(unsigned int phyId)
     729              : {
     730            0 :     int ret = 0;
     731              : 
     732            0 :     if (gRaHdcAsync[phyId].threadStatus == THREAD_HALT) {
     733            0 :         return 0;
     734              :     }
     735              : 
     736              : #ifndef HNS_ROCE_LLT
     737              :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].sendMutex);
     738              :     RA_PTHREAD_MUTEX_LOCK(&gRaHdcAsync[phyId].recvMutex);
     739              :     if (gRaHdcAsync[phyId].connectStatus != HDC_UNCONNECTED) {
     740              :         hccp_err("incorrect order calls are not allowed, phyId[%u] connectStatus[%u]", phyId,
     741              :             gRaHdcAsync[phyId].connectStatus);
     742              :         ret = -EPERM;
     743              :     } else {
     744              :         gRaHdcAsync[phyId].restoreFlag = 1;
     745              :     }
     746              :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].recvMutex);
     747              :     RA_PTHREAD_MUTEX_UNLOCK(&gRaHdcAsync[phyId].sendMutex);
     748              : #endif
     749            0 :     return ret;
     750              : }
     751              : 
     752            2 : void RaHdcDeinitAsyncAll(void)
     753              : {
     754            2 :     unsigned int phyId = 0;
     755              : 
     756          130 :     for (phyId = 0; phyId < RA_MAX_PHY_ID_NUM; phyId++) {
     757          128 :         if (gRaHdcAsync[phyId].session == NULL || gRaHdcAsync[phyId].threadStatus != THREAD_RUNNING) {
     758          128 :             continue;
     759              :         }
     760              : 
     761            0 :         (void)RaHdcDeinitAsync(phyId);
     762              :     }
     763            2 : }
        

Generated by: LCOV version 2.0-1