LCOV - code coverage report
Current view: top level - base_comm/resources/hccp/rdma_agent/adapter/async - ra_adp_async.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 78.0 % 150 117
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 8 8

            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 <sys/prctl.h>
      12              : #include "securec.h"
      13              : #include "user_log.h"
      14              : #include "ra_hdc_async.h"
      15              : #include "ra_rs_comm.h"
      16              : #include "ra_rs_err.h"
      17              : #include "ra_adp.h"
      18              : #include "ra_adp_pool.h"
      19              : #include "ra_adp_async.h"
      20              : 
      21              : struct RaHdcAsyncInfo gHdcAsync[RA_MAX_PHY_ID_NUM] = {0};
      22              : struct RaHdcInitPara gHdcAsyncInitPara = {0};
      23              : struct RsPthreadInfo gRaAsyncThreadInfo = {0};
      24              : 
      25          119 : int RaHwAsyncInit(unsigned int chipId, pid_t pid)
      26              : {
      27              :     int ret;
      28              : 
      29          119 :     ret = pthread_mutex_init(&gHdcAsyncInitPara.mutex, NULL);
      30          119 :     CHK_PRT_RETURN(ret != 0, hccp_err("g_hdc_async_init_para mutex_init failed ret %d", ret), -ESYSFUNC);
      31              : 
      32          119 :     gHdcAsyncInitPara.chipId = chipId;
      33          119 :     gHdcAsyncInitPara.hostTgid = pid;
      34              : 
      35          119 :     ret = pthread_mutex_init(&gHdcAsync[chipId].sendMutex, NULL);
      36          119 :     if (ret != 0) {
      37            0 :         hccp_err("send_mutex mutex_init failed ret %d", ret);
      38            0 :         pthread_mutex_destroy(&gHdcAsyncInitPara.mutex);
      39            0 :         return -ESYSFUNC;
      40              :     }
      41          119 :     RaHdcInitOpSec(&gHdcAsync[chipId].opSec, BUCKET_DEPTH, true);
      42          119 :     return 0;
      43              : }
      44              : 
      45            1 : STATIC int RaHdcHandleSendPkt(unsigned int chipId, void *recvBuf, unsigned int recvLen)
      46              : {
      47            1 :     unsigned int closeSession = 0;
      48            1 :     void *sendBuf = NULL;
      49            1 :     int sendLen = 0;
      50              :     int ret;
      51              : 
      52            1 :     RsSetCtx(chipId);
      53              : 
      54            1 :     ret = RaHandle(&gHdcAsync[chipId].opSec, recvBuf, recvLen, (char **)&sendBuf, &sendLen, &closeSession);
      55            1 :     if (ret != 0) {
      56            0 :         hccp_err("ra_handle failed, ret:%d", ret);
      57            0 :         goto out;
      58              :     }
      59              : 
      60            1 :     ret = RaHdcAsyncSendPkt(&gHdcAsync[chipId], chipId, sendBuf, sendLen);
      61            1 :     if (ret != 0) {
      62            1 :         hccp_err("send_pkt failed, ret:%d", ret);
      63            1 :         goto err;
      64              :     }
      65              : 
      66            0 : err:
      67            1 :     free(sendBuf);
      68            1 :     sendBuf = NULL;
      69            1 : out:
      70            1 :     return ret;
      71              : }
      72              : 
      73            1 : STATIC void RaAsyncHandlePkt(unsigned int chipId, void *recvBuf, unsigned int recvLen)
      74              : {
      75            1 :     struct MsgHead *recvMsgHead = (struct MsgHead *)recvBuf;
      76            1 :     bool closeSession = false;
      77              : 
      78              :     // should handle RA_RS_HDC_SESSION_CLOSE on recv thread
      79            1 :     if (recvLen < sizeof(struct MsgHead) || recvMsgHead->opcode == RA_RS_HDC_SESSION_CLOSE) {
      80            1 :         closeSession = true;
      81              :     }
      82            1 :     if (closeSession) {
      83            1 :         (void)RaHdcHandleSendPkt(chipId, recvBuf, recvLen);
      84            1 :         RA_PTHREAD_MUTEX_LOCK(&gHdcAsyncInitPara.mutex);
      85            1 :         gHdcAsyncInitPara.connectStatus = HDC_UNCONNECTED;
      86            1 :         RA_PTHREAD_MUTEX_UNLOCK(&gHdcAsyncInitPara.mutex);
      87            1 :         return;
      88              :     }
      89              : 
      90              :     // handle other opcode: generate task and process the msg with work thread
      91            0 :     RaHdcPoolAddTask(gHdcAsync[chipId].pool, RaHdcHandleSendPkt, chipId, recvBuf, recvLen);
      92              : }
      93              : 
      94            1 : STATIC void *RaAsyncPthread(void *arg)
      95              : {
      96              :     (void)arg;
      97            1 :     unsigned int chipId = gHdcAsyncInitPara.chipId;
      98            1 :     unsigned int recvLen = 0;
      99            1 :     void *recvBuf = NULL;
     100              :     int ret;
     101              : 
     102            1 :     ret = pthread_detach(pthread_self());
     103            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("pthread detach failed ret %d", ret), NULL);
     104              : 
     105            1 :     (void)prctl(PR_SET_NAME, (uintptr_t) "hccp_ra_async", 0, 0, 0);
     106              : 
     107            1 :     RA_PTHREAD_MUTEX_LOCK(&gHdcAsyncInitPara.mutex);
     108            1 :     gHdcAsyncInitPara.threadStatus = THREAD_RUNNING;
     109            1 :     RA_PTHREAD_MUTEX_UNLOCK(&gHdcAsyncInitPara.mutex);
     110              : 
     111            1 :     RsGetCurTime(&gRaAsyncThreadInfo.lastCheckTime);
     112            1 :     ret = strncpy_s((char *)gRaAsyncThreadInfo.pthreadName, sizeof(gRaAsyncThreadInfo.pthreadName), "ra_async_thread",
     113              :         strlen("ra_async_thread"));
     114            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("strncpy_s pthread name failed, ret[%d]", ret), NULL);
     115              : 
     116            1 :     hccp_run_info("pthread[%s] is alive!", gRaAsyncThreadInfo.pthreadName);
     117              :     while (1) {
     118            1 :         if (gHdcAsyncInitPara.threadStatus == THREAD_DESTROYING) {
     119            0 :             break;
     120              :         }
     121              : 
     122            1 :         if (gHdcAsyncInitPara.connectStatus != HDC_CONNECTED) {
     123            0 :             usleep(THREAD_SLEEP_TIME);
     124            0 :             continue;
     125              :         }
     126            1 :         RsHeartbeatAlivePrint(&gRaAsyncThreadInfo);
     127              :         // recv msg from hdc, alloc recv_buf in ra_async_pthread, free in work_pthread
     128            1 :         ret = RaHdcAsyncRecvPkt(&gHdcAsync[chipId], chipId, &recvBuf, &recvLen);
     129            1 :         if (ret != 0) {
     130            1 :             hccp_err("ra_hdc_async_recv_pkt failed, ret:%d chipId:%u", ret, chipId);
     131            1 :             break;
     132              :         }
     133              : 
     134            0 :         RaAsyncHandlePkt(chipId, recvBuf, recvLen);
     135              :     }
     136              : 
     137            1 :     hccp_info("thread [%d] is out, cleaning resources", getpid());
     138            1 :     RA_PTHREAD_MUTEX_LOCK(&gHdcAsyncInitPara.mutex);
     139            1 :     gHdcAsyncInitPara.threadStatus = THREAD_HALT;
     140            1 :     RA_PTHREAD_MUTEX_UNLOCK(&gHdcAsyncInitPara.mutex);
     141            1 :     RA_PTHREAD_MUTEX_LOCK(&gHdcAsync[chipId].sendMutex);
     142            1 :     RaHdcCloseSession(&gHdcAsync[chipId].hdcSession);
     143            1 :     RA_PTHREAD_MUTEX_UNLOCK(&gHdcAsync[chipId].sendMutex);
     144            1 :     return NULL;
     145              : }
     146              : 
     147            1 : STATIC void RaHwAsyncHdcInit(void *arg)
     148              : {
     149              :     (void)arg;
     150            1 :     unsigned int chipId = gHdcAsyncInitPara.chipId;
     151              :     pthread_t tidp;
     152              :     int ret;
     153              : 
     154            1 :     ret = pthread_detach(pthread_self());
     155            1 :     if (ret != 0) {
     156            0 :         hccp_err("pthread detach failed chip_id(%u), ret %d", chipId, ret);
     157            0 :         return;
     158              :     }
     159              : 
     160            1 :     (void)prctl(PR_SET_NAME, (uintptr_t) "hccp_hw_async", 0, 0, 0);
     161              : 
     162            1 :     hccp_info("chip_id(%u)", chipId);
     163            1 :     gHdcAsyncInitPara.hdcFlag = 1;
     164              : 
     165            1 :     ret = pthread_create(&tidp, NULL, (void *)RaAsyncPthread, NULL);
     166            1 :     if (ret != 0) {
     167            0 :         hccp_err("Create pthread failed, chipId(%u), ret(%d) ", chipId, ret);
     168            0 :         return;
     169              :     }
     170              : 
     171              :     while (1) {
     172            1 :         if (gHdcAsyncInitPara.connectStatus != HDC_UNCONNECTED) {
     173            0 :             usleep(HDC_ACCEPT_SLEEP_TIME);
     174            0 :             continue;
     175              :         }
     176            1 :         ret = RaHdcSessionAccept(chipId, &gHdcAsync[chipId].hdcSession, (int)gHdcAsyncInitPara.hostTgid);
     177            1 :         if (ret != 0) {
     178            0 :             gHdcAsyncInitPara.hdcFlag = 0;
     179            0 :             return;
     180              :         }
     181              :         // should continue to accept: host_tgid != g_hdc_async_init_para.host_tgid
     182            1 :         if (ret == 0 && gHdcAsync[chipId].hdcSession == NULL) {
     183            0 :             continue;
     184              :         }
     185              : 
     186            1 :         RA_PTHREAD_MUTEX_LOCK(&gHdcAsyncInitPara.mutex);
     187            1 :         gHdcAsyncInitPara.connectStatus = HDC_CONNECTED;
     188            1 :         RA_PTHREAD_MUTEX_UNLOCK(&gHdcAsyncInitPara.mutex);
     189            1 :         return;
     190              :     }
     191              : }
     192              : 
     193          122 : void RaHwAsyncDeinit(void)
     194              : {
     195          122 :     pthread_mutex_destroy(&gHdcAsync[gHdcAsyncInitPara.chipId].sendMutex);
     196          122 :     pthread_mutex_destroy(&gHdcAsyncInitPara.mutex);
     197          122 : }
     198              : 
     199            1 : int RaRsAsyncHdcSessionConnect(char *inBuf, char *outBuf, int *outLen, int *opResult, int rcvBufLen)
     200              : {
     201              :     (void)outBuf;
     202              :     (void)outLen;
     203            1 :     union OpAsyncHdcConnectData *asyncData = NULL;
     204            1 :     int timeout = RA_THREAD_TRY_TIME;
     205            1 :     unsigned int phyId = 0;
     206              :     pthread_t tidp;
     207              :     int ret;
     208              : 
     209              :     HCCP_CHECK_PARAM_LEN_RET_HOST(sizeof(union OpAsyncHdcConnectData), sizeof(struct MsgHead), rcvBufLen, opResult);
     210            1 :     asyncData = (union OpAsyncHdcConnectData *)(inBuf + sizeof(struct MsgHead));
     211              :     HCCP_CHECK_PARAM_LEN_RET_HOST(asyncData->txData.queueSize, 0, MAX_POOL_QUEUE_SIZE, opResult);
     212              :     HCCP_CHECK_PARAM_LEN_RET_HOST(asyncData->txData.threadNum, 0, MAX_POOL_THREAD_NUM, opResult);
     213              : 
     214            1 :     phyId = gHdcAsyncInitPara.chipId;
     215            1 :     gHdcAsync[phyId].pool = RaHdcPoolCreate(asyncData->txData.queueSize, asyncData->txData.threadNum);
     216            1 :     if (gHdcAsync[phyId].pool == NULL) {
     217            0 :         hccp_err("ra_hdc_pool_create failed, queueSize:%u threadNum:%u phyId:%u", asyncData->txData.queueSize,
     218              :             asyncData->txData.threadNum, asyncData->txData.phyId);
     219            0 :         *opResult = -ESYSFUNC;
     220            0 :         return 0;
     221              :     }
     222              : 
     223            1 :     ret = pthread_create(&tidp, NULL, (void *)RaHwAsyncHdcInit, NULL);
     224            1 :     if (ret != 0) {
     225            0 :         hccp_err("Create pthread failed, ret(%d)", ret);
     226            0 :         *opResult = -ESYSFUNC;
     227            0 :         RaHdcPoolDestroy(gHdcAsync[phyId].pool);
     228            0 :         gHdcAsync[phyId].pool = NULL;
     229            0 :         return 0;
     230              :     }
     231              : 
     232              :     // will block until time out: RA_THREAD_TRY_TIME * RA_THREAD_SLEEP_TIME us
     233            2 :     while (gHdcAsyncInitPara.hdcFlag != 1 && timeout > 0) {
     234            1 :         usleep(RA_THREAD_SLEEP_TIME);
     235            1 :         timeout--;
     236              :     }
     237              : 
     238            1 :     if (gHdcAsyncInitPara.hdcFlag == 0 || timeout <= 0) {
     239            0 :         hccp_err("HDC server thread create timeout, flag %d, timeout %d", gHdcAsyncInitPara.hdcFlag, timeout);
     240            0 :         *opResult = -ESRCH;
     241            0 :         RaHdcPoolDestroy(gHdcAsync[phyId].pool);
     242            0 :         gHdcAsync[phyId].pool = NULL;
     243            0 :         return 0;
     244              :     }
     245              : 
     246            1 :     *opResult = 0;
     247            1 :     return 0;
     248              : }
     249              : 
     250            1 : int RaRsAsyncHdcSessionClose(char *inBuf, char *outBuf, int *outLen, int *opResult, int rcvBufLen)
     251              : {
     252              :     (void)inBuf;
     253              :     (void)outBuf;
     254              :     (void)outLen;
     255            1 :     int tryAgain = HDC_TRY_TIME;
     256            1 :     unsigned int phyId = 0;
     257              : 
     258              :     HCCP_CHECK_PARAM_LEN_RET_HOST(sizeof(union OpAsyncHdcCloseData), sizeof(struct MsgHead), rcvBufLen, opResult);
     259              : 
     260            1 :     RA_PTHREAD_MUTEX_LOCK(&gHdcAsyncInitPara.mutex);
     261            1 :     gHdcAsyncInitPara.threadStatus = THREAD_DESTROYING;
     262            1 :     RA_PTHREAD_MUTEX_UNLOCK(&gHdcAsyncInitPara.mutex);
     263              : 
     264          201 :     while ((gHdcAsyncInitPara.threadStatus != THREAD_HALT) && tryAgain != 0) {
     265          200 :         usleep(HDC_USLEEP_TIME);
     266          200 :         tryAgain--;
     267              :     }
     268              : 
     269            1 :     if (tryAgain <= 0) {
     270            1 :         hccp_warn("hdc async message thread quit timeout");
     271              :     }
     272              : 
     273            1 :     phyId = gHdcAsyncInitPara.chipId;
     274            1 :     RaHdcPoolDestroy(gHdcAsync[phyId].pool);
     275            1 :     gHdcAsync[phyId].pool = NULL;
     276            1 :     *opResult = 0;
     277            1 :     return 0;
     278              : }
        

Generated by: LCOV version 2.0-1