LCOV - code coverage report
Current view: top level - base_comm/resources/hccp/rdma_service - rs_epoll.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 71.6 % 455 326
Test Date: 2026-08-18 17:47:01 Functions: 90.9 % 22 20

            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              : #define _GNU_SOURCE
      12              : #include <unistd.h>
      13              : #include <stdlib.h>
      14              : #include <netinet/in.h>
      15              : #include <arpa/inet.h>
      16              : #include <sys/types.h>
      17              : #include <sys/eventfd.h>
      18              : #include <sys/epoll.h>
      19              : #include <sys/syscall.h>
      20              : #include <sys/prctl.h>
      21              : 
      22              : #include "rs_tls.h"
      23              : #include "ssl_adp.h"
      24              : #include "securec.h"
      25              : #include "rs.h"
      26              : #include "rs_inner.h"
      27              : #include "ra_rs_comm.h"
      28              : #include "ra_rs_err.h"
      29              : #include "rs_drv_rdma.h"
      30              : #include "dl_hal_function.h"
      31              : #include "rs_drv_socket.h"
      32              : #include "rs_socket.h"
      33              : #ifdef CONFIG_TLV
      34              : #include "rs_adp_nslb.h"
      35              : #endif
      36              : #include "rs_ub_dfx.h"
      37              : #include "rs_epoll.h"
      38              : 
      39              : #define BIND_MIN_DCPU_NUM 1
      40              : #define COMMAND_LENGTH 100
      41              : #define ADD_TID_SHELL_PATH 50
      42              : #define TID_LENGTH 20
      43              : #define HOST ((uint32_t)1)
      44              : 
      45              : struct RsPthreadInfo gEpollThreadInfo = {0}; // lint !e17
      46              : struct RsPthreadInfo gConnectThreadInfo = {0};
      47              : 
      48              : /*
      49              :  * opcode:
      50              :  *  ADD: EPOLL_CTL_ADD
      51              :  *  MOD: EPOLL_CTL_MOD
      52              :  *  DEL: EPOLL_CTL_DEL
      53              :  */
      54          230 : int RsEpollCtl(int epollfd, int op, int fd, unsigned int state)
      55              : {
      56              :     int ret;
      57              :     struct epoll_event ev;
      58              : 
      59          230 :     ev.events = state;
      60          230 :     ev.data.fd = fd;
      61          230 :     ret = epoll_ctl(epollfd, op, fd, &ev);
      62          230 :     if (ret) {
      63          108 :         hccp_warn("epoll_ctl for fd %d unsuccessful! ret:%d errno:%d op:%d state:%u", fd, ret, errno, op, state);
      64              :     }
      65          230 :     return ret;
      66              : }
      67              : 
      68            1 : int RsEpollCtlFdHandle(int epollfd, int op, int fd, unsigned int state, void *fdHandle)
      69              : {
      70              :     int ret;
      71              :     struct epoll_event ev;
      72              : 
      73            1 :     ev.events = state;
      74            1 :     ev.data.ptr = fdHandle;
      75            1 :     ret = epoll_ctl(epollfd, op, fd, &ev);
      76            1 :     if (ret) {
      77            1 :         hccp_warn("epoll_ctl for fd %d unsuccessful! ret:%d errno:%d op:%d state:%u", fd, ret, errno, op, state);
      78              :     }
      79            1 :     return ret;
      80              : }
      81              : 
      82              : int RsWlistCheckConnAdd(struct rs_cb *rsCb, struct RsConnInfo *connTmp)
      83              : {
      84              :     int ret;
      85              :     int retClose;
      86           16 :     struct RsConnInfo *conn = NULL;
      87              : 
      88           16 :     if (rsCb->connCb.wlistEnable == 1) {
      89            0 :         ret = RsWhiteListCheckValid(rsCb->chipId, &rsCb->connCb, connTmp);
      90            0 :         if (ret) {
      91            0 :             hccp_info("invalid client node found: chip_id %u, fd %d accept, server ip:%s, client ip:%s, port:%u, "
      92              :                       "state:%d, tag:%s",
      93              :                 rsCb->chipId, connTmp->connfd, connTmp->serverIp.readAddr, connTmp->clientIp.readAddr, connTmp->port,
      94              :                 connTmp->state, connTmp->tag);
      95            0 :             return ret;
      96              :         }
      97              :     }
      98              : 
      99              :     /* add conn node to server list */
     100           16 :     ret = RsAllocConnNode(&conn, connTmp->port);
     101           16 :     if (ret) {
     102            0 :         hccp_err("server IP:0x%s add conn info to list failed, fd:%d, ret:%d", connTmp->serverIp.readAddr,
     103              :             connTmp->connfd, ret);
     104            0 :         goto alloc_err;
     105              :     }
     106              : 
     107           16 :     ret = RsSocketCopyConnInfo(connTmp, conn);
     108           16 :     if (ret) {
     109            0 :         hccp_err("rs_socket_copy_conn_info failed, ret[%d]", ret);
     110            0 :         goto out;
     111              :     }
     112              : 
     113           16 :     if (rsCb->sslEnable == RS_SSL_ENABLE) {
     114            0 :         ret = RsEpollCtl(rsCb->connCb.epollfd, EPOLL_CTL_DEL, connTmp->connfd, EPOLLIN);
     115            0 :         if (ret) {
     116            0 :             hccp_err("rs epoll ctl failed, ret %d", ret);
     117            0 :             goto out;
     118              :         }
     119              :     }
     120              : 
     121           16 :     RS_PTHREAD_MUTEX_LOCK(&rsCb->connCb.connMutex);
     122           16 :     RsListAddTail(&conn->list, &rsCb->connCb.serverConnList);
     123           16 :     RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
     124              : 
     125           16 :     hccp_info("[Server]chip_id %u, fd %d accept, server ip:%s, client ip:%s, state:%d, tag:%s", rsCb->chipId,
     126              :         connTmp->connfd, connTmp->serverIp.readAddr, connTmp->clientIp.readAddr, connTmp->state, connTmp->tag);
     127           16 :     ShowConnNode(&(rsCb->connCb.serverConnList));
     128           16 :     return 0;
     129              : 
     130            0 : out:
     131            0 :     free(conn);
     132            0 :     conn = NULL;
     133            0 : alloc_err:
     134            0 :     RS_CLOSE_RETRY_FOR_EINTR(retClose, connTmp->connfd);
     135            0 :     return ret;
     136              : }
     137              : 
     138            1 : STATIC int RsSslRecvTagInHandle(struct RsAcceptInfo *acceptInfo, struct RsConnInfo *connTmp)
     139              : {
     140            1 :     int expSize = SOCK_CONN_TAG_SIZE + SOCK_CONN_DEV_ID_SIZE;
     141            1 :     char *recvBuff = connTmp->tag;
     142              :     struct timeval startTime, now;
     143            1 :     float timeCost = 0.0;
     144            1 :     int size = expSize;
     145              : 
     146            1 :     RsGetCurTime(&startTime);
     147            1 :     while (expSize > 0 && size != 0) {
     148            1 :         connTmp->tagSyncTimes++;
     149            1 :         size = ssl_adp_read(acceptInfo->ssl, recvBuff, expSize);
     150            1 :         if ((size < 0) && (errno == EINTR)) {
     151            0 :             connTmp->tagEintrTimes++;
     152            0 :             continue;
     153              :         }
     154            1 :         expSize -= size;
     155            1 :         recvBuff += size;
     156            1 :         RsGetCurTime(&now);
     157            1 :         HccpTimeInterval(&now, &startTime, &timeCost);
     158            1 :         if (timeCost >= RS_RECV_MAX_TIME) {
     159            1 :             hccp_run_info("recv tag time out, server:{%s:%u} client:%s tagSyncTime:%u tagEintrTime:%u",
     160              :                 acceptInfo->serverIpAddr.readAddr, acceptInfo->sockPort, acceptInfo->clientIpAddr.readAddr,
     161              :                 connTmp->tagSyncTimes, connTmp->tagEintrTimes);
     162            1 :             return -ETIME;
     163              :         }
     164              : 
     165            0 :         if (timeCost <= 0) {
     166            0 :             RsGetCurTime(&startTime);
     167              :         }
     168              :     }
     169              : 
     170            0 :     connTmp->serverIp = acceptInfo->serverIpAddr;
     171            0 :     connTmp->clientIp = acceptInfo->clientIpAddr;
     172            0 :     connTmp->connfd = acceptInfo->connFd;
     173            0 :     connTmp->state = RS_CONN_STATE_TAG_SYNC;
     174            0 :     connTmp->port = acceptInfo->sockPort;
     175            0 :     connTmp->ssl = acceptInfo->ssl;
     176              : 
     177            0 :     hccp_info("recv tag success, server:{%s:%u} client:%s timeCost:%fms tagSyncTime:%u tagEintrTime:%u",
     178              :         acceptInfo->serverIpAddr.readAddr, acceptInfo->sockPort, acceptInfo->clientIpAddr.readAddr, timeCost,
     179              :         connTmp->tagSyncTimes, connTmp->tagEintrTimes);
     180            0 :     return 0;
     181              : }
     182              : 
     183            1 : STATIC void RsEpollEventSslRecvTagInHandle(struct rs_cb *rsCb, struct RsAcceptInfo *acceptInfo)
     184              : {
     185            1 :     struct RsConnInfo connTmp = {0};
     186              :     int retClose;
     187              :     int ret;
     188              : 
     189            1 :     ret = RsSslRecvTagInHandle(acceptInfo, &connTmp);
     190            1 :     if (ret != 0) {
     191            0 :         RS_CLOSE_RETRY_FOR_EINTR(retClose, acceptInfo->connFd);
     192            0 :         goto out;
     193              :     }
     194              : 
     195            1 :     ret = RsWlistCheckConnAdd(rsCb, &connTmp);
     196            1 : out:
     197            1 :     if (ret != 0) {
     198            1 :         hccp_warn("recv tag or add conn unsuccessful ret:%d", ret);
     199            1 :         ssl_adp_shutdown(acceptInfo->ssl);
     200            1 :         ssl_adp_free(acceptInfo->ssl);
     201            1 :         acceptInfo->ssl = NULL;
     202              :     }
     203              : 
     204              :     /* do not shutdown ssl */
     205            1 :     RS_PTHREAD_MUTEX_LOCK(&rsCb->connCb.connMutex);
     206            1 :     RsListDel(&acceptInfo->list);
     207            1 :     free(acceptInfo);
     208            1 :     acceptInfo = NULL;
     209            1 :     RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
     210              : 
     211            1 :     return;
     212              : }
     213              : 
     214            0 : STATIC void RsDoSslHandshake(struct RsAcceptInfo *acceptInfo, struct rs_cb *rscb)
     215              : {
     216              :     int ret;
     217              :     int err;
     218              : 
     219            0 :     ret = ssl_adp_do_handshake(acceptInfo->ssl);
     220            0 :     if (ret == 1) {
     221            0 :         ret = rs_tls_peer_cert_verify(acceptInfo->ssl, rscb);
     222            0 :         if (ret) {
     223            0 :             hccp_err("tls verify peer cert failed");
     224            0 :             return;
     225              :         }
     226            0 :         acceptInfo->state = RS_CONN_STATE_SSL_CONNECTED;
     227              :     } else {
     228            0 :         err = ssl_adp_get_error(acceptInfo->ssl, ret);
     229            0 :         if (err == SSL_ERROR_WANT_WRITE) {
     230            0 :             hccp_info("return want write");
     231            0 :             return;
     232            0 :         } else if (err == SSL_ERROR_WANT_READ) {
     233            0 :             hccp_info("return want read");
     234            0 :             return;
     235              :         } else {
     236            0 :             rs_ssl_err_string(acceptInfo->connFd, err);
     237            0 :             return;
     238              :         }
     239              :     }
     240              : 
     241            0 :     return;
     242              : }
     243              : 
     244            1 : STATIC int RsEpollEventSslAcceptInHandle(struct rs_cb *rsCb, int fd)
     245              : {
     246              :     int ret;
     247              : 
     248            1 :     struct RsAcceptInfo *acceptInfo = NULL;
     249            1 :     struct RsAcceptInfo *acceptInfo2 = NULL;
     250              : 
     251              :     /* Server event: ssl accept */
     252            1 :     RS_LIST_GET_HEAD_ENTRY(acceptInfo, acceptInfo2, &rsCb->connCb.serverAcceptList, list, struct RsAcceptInfo);
     253            1 :     for (; (&acceptInfo->list) != &rsCb->connCb.serverAcceptList;
     254            0 :          acceptInfo = acceptInfo2, acceptInfo2 = list_entry(acceptInfo2->list.next, struct RsAcceptInfo, list)) {
     255              :         /* connection request for Server */
     256            0 :         if (fd == acceptInfo->connFd) {
     257            0 :             if (acceptInfo->ssl == NULL) {
     258            0 :                 acceptInfo->ssl = ssl_adp_new(rsCb->serverSslCtx);
     259            0 :                 CHK_PRT_RETURN(acceptInfo->ssl == NULL, hccp_err("server ssl ctx alloc failed"), -ENOMEM);
     260              : 
     261            0 :                 ret = ssl_adp_set_fd(acceptInfo->ssl, acceptInfo->connFd);
     262            0 :                 if (ret != 1) {
     263            0 :                     hccp_err("bind connfd and ssl failed, ret %d", ret);
     264            0 :                     ssl_adp_shutdown(acceptInfo->ssl);
     265            0 :                     ssl_adp_free(acceptInfo->ssl);
     266            0 :                     acceptInfo->ssl = NULL;
     267            0 :                     return -EINVAL;
     268              :                 }
     269              : 
     270            0 :                 ssl_adp_set_mode(acceptInfo->ssl, SSL_MODE_AUTO_RETRY);
     271            0 :                 ssl_adp_set_accept_state(acceptInfo->ssl);
     272              :             }
     273              : 
     274            0 :             if (acceptInfo->state == RS_CONN_STATE_RESET) {
     275            0 :                 RsDoSslHandshake(acceptInfo, rsCb);
     276            0 :                 return 0;
     277              :             }
     278              : 
     279            0 :             if (acceptInfo->state == RS_CONN_STATE_SSL_CONNECTED) {
     280            0 :                 RsEpollEventSslRecvTagInHandle(rsCb, acceptInfo);
     281            0 :                 return 0;
     282              :             }
     283              :         }
     284              :     }
     285              : 
     286            1 :     return -ENODEV;
     287              : }
     288              : 
     289            2 : STATIC int RsEpollTcpRecv(struct rs_cb *rsCb, int fd)
     290              : {
     291            2 :     if (rsCb->tcpRecvCallback != NULL) {
     292            1 :         rsCb->tcpRecvCallback(rsCb->fdMap[fd]);
     293              :     } else {
     294            1 :         hccp_err("[rs_epoll_tcp_recv]tcp_recv_callback is null.");
     295            1 :         return -EINVAL;
     296              :     }
     297            1 :     return 0;
     298              : }
     299              : 
     300            0 : STATIC int RsEpollEventHeterogTcpRecvInHandle(struct rs_cb *rsCb, int fd)
     301              : {
     302              :     int ret;
     303            0 :     struct RsHeterogTcpFdInfo *fdNode = NULL;
     304            0 :     struct RsHeterogTcpFdInfo *fdNode1 = NULL;
     305              : 
     306            0 :     RS_LIST_GET_HEAD_ENTRY(fdNode, fdNode1, &rsCb->heterogTcpFdList, list, struct RsHeterogTcpFdInfo);
     307            0 :     for (; (&fdNode->list) != &rsCb->heterogTcpFdList;
     308            0 :          fdNode = fdNode1, fdNode1 = list_entry(fdNode1->list.next, struct RsHeterogTcpFdInfo, list)) {
     309            0 :         if (fdNode->fd == fd) {
     310              :             // 处理tcp recv
     311            0 :             ret = RsEpollTcpRecv(rsCb, fd);
     312            0 :             return ret;
     313              :         }
     314              :     }
     315            0 :     return -ENODEV;
     316              : }
     317              : 
     318           18 : STATIC void RsEpollEventInHandle(struct rs_cb *rsCb, struct epoll_event *events)
     319              : {
     320           18 :     int fd = events->data.fd;
     321              :     int ret;
     322              : 
     323           18 :     ret = RsEpollEventPingHandle(rsCb, fd);
     324           18 :     if (ret != -ENODEV) {
     325            0 :         hccp_info("the fd:%d is for ping, no need to go on, ret:%d", fd, ret);
     326            0 :         return;
     327              :     }
     328              : 
     329           18 :     ret = RsEpollEventListenInHandle(rsCb, fd);
     330           18 :     if (ret != -ENODEV) {
     331           16 :         hccp_info("the fd:%d is tcp listened, no need to go on, ret:%d", fd, ret);
     332           16 :         return;
     333              :     }
     334              : 
     335            2 :     if (rsCb->sslEnable == RS_SSL_ENABLE) {
     336            1 :         ret = RsEpollEventSslAcceptInHandle(rsCb, fd);
     337            1 :         if (ret != -ENODEV) {
     338            1 :             hccp_info("the fd:%d is ssl accept, no need to go on, ret:%d", fd, ret);
     339            1 :             return;
     340              :         }
     341              :     }
     342              : 
     343            1 :     ret = RsEpollEventQpMrInHandle(rsCb, fd);
     344            1 :     if (ret != -ENODEV) {
     345            0 :         hccp_info("the fd:%d is for qp mr, no need to go on, ret:%d", fd, ret);
     346            0 :         return;
     347              :     }
     348              : 
     349            1 :     ret = RsEpollEventHeterogTcpRecvInHandle(rsCb, fd);
     350            1 :     if (ret != -ENODEV) {
     351            1 :         hccp_info("the fd:%d is for tcp recv, no need to go on, ret:%d", fd, ret);
     352            1 :         return;
     353              :     }
     354              : 
     355            0 :     if (RsIsUdmaSupported()) {
     356            0 :         ret = RsEpollEventJfcInHandle(rsCb, fd);
     357            0 :         if (ret != -ENODEV) {
     358            0 :             hccp_info("the fd:%d is for poll jfc, no need to go on, ret:%d", fd, ret);
     359            0 :             return;
     360              :         }
     361              : 
     362            0 :         ret = RsEpollEventUrmaAsyncEventInHandle(rsCb, fd);
     363            0 :         if (ret != -ENODEV) {
     364            0 :             hccp_info("the fd:%d is for urma async event, no need to go on, ret:%d", fd, ret);
     365            0 :             return;
     366              :         }
     367              :     }
     368              : 
     369            0 :     return;
     370              : }
     371              : 
     372           13 : STATIC void RsEpollEventHandleOne(struct rs_cb *rsCb, struct epoll_event *events)
     373              : {
     374           13 :     int ret = 0;
     375              : 
     376              :     (void)ret;
     377           13 :     RS_CHECK_POINTER_NULL_RETURN_VOID(events);
     378           13 :     RS_CHECK_POINTER_NULL_RETURN_VOID(rsCb);
     379              : 
     380              : #ifdef CONFIG_TLV
     381              :     if (RsIsTlvSupported()) {
     382              :         ret = RsEpollNslbEventHandle(&rsCb->tlvCb.nslbCb, events->data.fd, events->events);
     383              :         if (ret != -ENODEV) {
     384              :             hccp_info("the fd:%d is nslb event, no need to go on, ret:%d", events->data.fd, ret);
     385              :             return;
     386              :         }
     387              :     }
     388              : #endif
     389              : 
     390           13 :     if (events->events & EPOLLIN) {
     391           12 :         if (events->events & EPOLLRDHUP) {
     392            0 :             hccp_dbg("Peer socket has been closed!");
     393            0 :             return;
     394              :         }
     395           12 :         RsEpollEventInHandle(rsCb, events);
     396              :     } else {
     397            1 :         hccp_warn("unknown event(0x%x)!", events->events);
     398              :     }
     399              : 
     400           13 :     return;
     401              : }
     402              : 
     403            1 : STATIC int SetAffinity(unsigned int chipId, unsigned int cpuId)
     404              : {
     405              :     cpu_set_t mask;
     406              :     cpu_set_t get;
     407              :     int ret;
     408              : 
     409            1 :     CPU_ZERO(&mask);
     410              : 
     411              :     // 设置线程CPU亲和力
     412            1 :     CPU_SET(cpuId, &mask);
     413            1 :     ret = pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask);
     414            1 :     CHK_PRT_RETURN(ret < 0, hccp_err("could not set CPU affinity"), ret);
     415              : 
     416              :     // 获取线程cpu亲和力
     417            1 :     CPU_ZERO(&get);
     418            1 :     ret = pthread_getaffinity_np(pthread_self(), sizeof(get), &get);
     419            1 :     CHK_PRT_RETURN(ret, hccp_err("could not get CPU affinity"), ret);
     420              : 
     421            1 :     if (CPU_ISSET(cpuId, &get)) { // 检查cpuid是否在这个集合中
     422            1 :         hccp_info("dev is %d thread %llu is running in processor %d.", chipId, pthread_self(), cpuId);
     423              :     } else {
     424            0 :         hccp_warn("dev is %d thread %llu is not running in processor %d.", chipId, pthread_self(), cpuId);
     425              :     }
     426              : 
     427            1 :     return ret;
     428              : }
     429              : 
     430           41 : STATIC int BindDataCpu(unsigned int chipId)
     431              : {
     432              :     int ret;
     433              :     unsigned int cpuId;
     434           41 :     uint32_t info = 0;
     435           41 :     uint32_t devNum = 0;
     436              :     int64_t ccpuNum;
     437              :     int64_t dcpuNum;
     438              :     int64_t acpuNum;
     439              :     int64_t cpuNum;
     440              : 
     441              :     // 判断当前处于host or device侧,如果在host侧,无需进行绑核操作
     442           41 :     ret = DlDrvGetPlatformInfo(&info);
     443           41 :     CHK_PRT_RETURN(ret, hccp_err("get PlatformInfo failed, ret[%d]", ret), ret);
     444           41 :     if (info == HOST) {
     445            0 :         hccp_info("host not need bind cpu, info[%u]", info);
     446            0 :         return 0;
     447              :     }
     448              : 
     449              :     // 获取当前os的device数量
     450           41 :     ret = DlDrvGetDevNum(&devNum);
     451           41 :     CHK_PRT_RETURN(ret, hccp_err("get device_num failed, ret[%d]", ret), ret);
     452           39 :     if (devNum == 0) {
     453            0 :         hccp_info("no device need bind cpu, device num %u", devNum);
     454            0 :         return 0;
     455              :     }
     456              : 
     457              :     // 获取data cpu数量
     458           39 :     ret = DlHalGetDeviceInfo(chipId, MODULE_TYPE_DCPU, INFO_TYPE_CORE_NUM, &dcpuNum);
     459           39 :     CHK_PRT_RETURN(ret, hccp_err("get dcpu_num failed, ret(%d)", ret), ret);
     460              : 
     461              :     // 如果dcpu_num < 1,无需绑核直接返回
     462           39 :     if (dcpuNum < BIND_MIN_DCPU_NUM) {
     463           38 :         hccp_info("data cpu num %d, device not need bind cpu", dcpuNum);
     464           38 :         return 0;
     465              :     }
     466              : 
     467              :     // 获取ctrl cpu数量
     468            1 :     ret = DlHalGetDeviceInfo(chipId, MODULE_TYPE_CCPU, INFO_TYPE_CORE_NUM, &ccpuNum);
     469            1 :     CHK_PRT_RETURN(ret, hccp_err("get ccpu_num failed, ret(%d)", ret), ret);
     470              : 
     471              :     // 获取ai cpu数量
     472            1 :     ret = DlHalGetDeviceInfo(chipId, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &acpuNum);
     473            1 :     CHK_PRT_RETURN(ret, hccp_err("get acpu_num failed, ret(%d)", ret), ret);
     474              : 
     475              :     // 计算单个device上的核数
     476            1 :     cpuNum = ccpuNum + dcpuNum + acpuNum;
     477            1 :     hccp_info("halGetDeviceInf chip = %u dev_num = %u, ccpu = %lld dcpu = %lld acpu = %lld cpuNum = %lld", chipId,
     478              :         devNum, ccpuNum, dcpuNum, acpuNum, cpuNum);
     479              : 
     480            1 :     cpuId = (unsigned int)((int64_t)(chipId % devNum) * cpuNum + ccpuNum);
     481              : 
     482              :     // 进行绑核
     483            1 :     ret = DlHalBindCgroup(BIND_DATACPU_CGROUP);
     484            1 :     CHK_PRT_RETURN(ret, hccp_err("bind cgroup failed, ret[%d], strerror[%s]", ret, strerror(errno)), ret);
     485            1 :     hccp_info("bind cgroup success!");
     486              : 
     487            1 :     ret = SetAffinity(chipId, cpuId);
     488            1 :     CHK_PRT_RETURN(ret, hccp_err("set affinity with cpu[%u] failed", cpuId), ret);
     489              : 
     490            1 :     hccp_info("chip_id[%u] bind data cpu[%u] success", chipId, cpuId);
     491              : 
     492            1 :     return ret;
     493              : }
     494              : 
     495           57 : STATIC void RsSocketSaveEpollWaitErrInfo(int eventNum, int errNo, struct SocketErrInfo *epollErrInfo)
     496              : {
     497           57 :     if (eventNum > 0) {
     498           57 :         return;
     499              :     }
     500              : 
     501            0 :     RsSocketSaveErrInfo(RS_CONN_STATE_RESET, errNo, epollErrInfo);
     502              : }
     503              : 
     504           41 : STATIC void *RsEpollHandle(void *arg)
     505              : {
     506           41 :     struct RsConnCb *connCb = NULL;
     507           41 :     struct rs_cb *rsCb = NULL;
     508              :     eventfd_t val;
     509              :     int ret;
     510              :     int num;
     511              :     int i;
     512              : 
     513           41 :     RS_CHECK_POINTER_NULL_RETURN_NULL(arg);
     514              : 
     515           41 :     hccp_info("<EPOLL> thread begin! thread_id:%lu, pid:%d, ppid:%d", pthread_self(), getpid(), getppid());
     516              : 
     517              :     struct epoll_event events[RS_EPOLL_EVENT];
     518              : 
     519           41 :     CHK_PRT_RETURN(pthread_detach(pthread_self()),
     520              :         hccp_err("pthread_detach failed! thread_id:%lu, errno:%d", pthread_self(), errno), NULL);
     521              : 
     522           41 :     (void)prctl(PR_SET_NAME, (uintptr_t) "hccp_epoll", 0, 0, 0);
     523              : 
     524           41 :     rsCb = (struct rs_cb *)arg;
     525           41 :     gRsCb = rsCb;
     526           41 :     connCb = &rsCb->connCb;
     527              : 
     528           41 :     ret = BindDataCpu(rsCb->chipId);
     529           41 :     if (ret) {
     530            2 :         hccp_warn("bind data cpu unsuccessful! thread_id:%lu, errno:%d", pthread_self(), errno);
     531              :     }
     532              : 
     533           41 :     rsCb->state &= ~RS_STATE_HALT;
     534           41 :     RsGetCurTime(&gEpollThreadInfo.lastCheckTime);
     535           41 :     ret = strncpy_s((char *)gEpollThreadInfo.pthreadName, sizeof(gEpollThreadInfo.pthreadName), "epoll_pthread",
     536              :         strlen("epoll_pthread"));
     537           41 :     CHK_PRT_RETURN(ret, hccp_err("strncpy_s pthread name failed, ret[%d]", ret), NULL);
     538              : 
     539           41 :     hccp_run_info("pthread[%s] is alive!", gEpollThreadInfo.pthreadName);
     540              : 
     541           41 :     ret = RsDrvInitCqeErrInfo();
     542           41 :     CHK_PRT_RETURN(ret, hccp_err("rs_drv_init_cqe_err_info failed, ret[%d]", ret), NULL);
     543           16 :     while (1) {
     544              :         do {
     545           57 :             num = epoll_wait(connCb->epollfd, events, RS_EPOLL_EVENT, -1);
     546           57 :         } while ((num < 0) && (errno == EINTR));
     547           57 :         RsSocketSaveEpollWaitErrInfo(num, -errno, &connCb->epollErrInfo);
     548              : 
     549              :         /* eventfd is for wake up epoll wait, value is ignored */
     550           57 :         if (events[0].data.fd == connCb->eventfd) {
     551           41 :             hccp_warn("<EPOLL> SHUT DOWN event eventfd:%d", connCb->eventfd);
     552              :             do {
     553           41 :                 num = read(connCb->eventfd, &val, sizeof(eventfd_t));
     554           41 :             } while ((num < 0) && (errno == EINTR));
     555           41 :             RS_PTHREAD_MUTEX_LOCK(&rsCb->mutex);
     556           41 :             rsCb->state |= RS_STATE_HALT;
     557           41 :             RS_PTHREAD_MUTEX_ULOCK(&rsCb->mutex);
     558              : 
     559           41 :             break;
     560              :         }
     561              : 
     562           16 :         RsHeartbeatAlivePrint(&gEpollThreadInfo);
     563           16 :         RS_PTHREAD_MUTEX_LOCK(&rsCb->mutex);
     564              :         /* events handle one by one */
     565           32 :         for (i = 0; i < num; i++) {
     566           16 :             RsEpollEventHandleOne(rsCb, &events[i]);
     567              :         }
     568              : 
     569           16 :         RS_PTHREAD_MUTEX_ULOCK(&rsCb->mutex);
     570              :     }
     571           41 :     RsDrvDeinitCqeErrInfo();
     572           41 :     hccp_info("<EPOLL> QUIT thread_id:%lu, pid:%d, read num:%d", pthread_self(), getpid(), num);
     573              : 
     574           41 :     return NULL;
     575              : }
     576              : 
     577           44 : STATIC int RsCreateEpoll(struct rs_cb *rsCb)
     578              : {
     579              :     int ret, retFd;
     580           44 :     struct RsConnCb *connCb = NULL;
     581              : 
     582           44 :     connCb = &rsCb->connCb;
     583              : 
     584           44 :     connCb->epollfd = epoll_create(1);
     585           44 :     CHK_PRT_RETURN(connCb->epollfd < 0, hccp_err("epollfd[%d] failed, errno[%d]", connCb->epollfd, errno), -EINVAL);
     586              : 
     587           43 :     connCb->eventfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
     588           43 :     if (connCb->eventfd == RS_FD_INVALID) {
     589            0 :         RS_CLOSE_RETRY_FOR_EINTR(retFd, connCb->epollfd);
     590            0 :         connCb->epollfd = RS_FD_INVALID;
     591            0 :         hccp_err("create eventfd for rs cb failed !");
     592            0 :         return -EINVAL;
     593              :     }
     594              : 
     595           43 :     ret = RsEpollCtl(connCb->epollfd, EPOLL_CTL_ADD, connCb->eventfd, EPOLLIN);
     596           43 :     if (ret) {
     597            0 :         hccp_err("re epoll ctl failed, epollfd[%d], eventfd[%d]", connCb->epollfd, connCb->eventfd);
     598            0 :         RS_CLOSE_RETRY_FOR_EINTR(retFd, connCb->eventfd);
     599            0 :         connCb->eventfd = RS_FD_INVALID;
     600            0 :         RS_CLOSE_RETRY_FOR_EINTR(retFd, connCb->epollfd);
     601            0 :         connCb->epollfd = RS_FD_INVALID;
     602            0 :         return ret;
     603              :     }
     604              : 
     605           43 :     return 0;
     606              : }
     607              : 
     608           43 : void RsDestroyEpoll(struct rs_cb *rsCb)
     609              : {
     610              :     int ret;
     611           43 :     struct RsConnCb *connCb = NULL;
     612              : 
     613           43 :     connCb = &rsCb->connCb;
     614              : 
     615           43 :     ret = RsEpollCtl(connCb->epollfd, EPOLL_CTL_DEL, connCb->eventfd, EPOLLIN);
     616           43 :     if (ret) {
     617            0 :         hccp_warn("re epoll ctl unsuccessful, epollfd[%d], eventfd[%d]", connCb->epollfd, connCb->eventfd);
     618              :     }
     619              : 
     620           43 :     RS_CLOSE_RETRY_FOR_EINTR(ret, connCb->eventfd);
     621           43 :     connCb->eventfd = RS_FD_INVALID;
     622              : 
     623           43 :     RS_CLOSE_RETRY_FOR_EINTR(ret, connCb->epollfd);
     624           43 :     connCb->epollfd = RS_FD_INVALID;
     625              : 
     626           43 :     return;
     627              : }
     628              : 
     629           61 : STATIC void RsUsleepWaitConn(sem_t *sem, uint32_t timeoutUs)
     630              : {
     631           61 :     uint32_t sleepUs = 1000; // 每 1000us 查看sem是否为零
     632           61 :     uint32_t elapsedUs = 0;
     633              :     do {
     634         9266 :         if (sem_trywait(sem) == 0) {
     635           15 :             return;
     636              :         }
     637         9251 :         usleep(sleepUs);
     638         9251 :         elapsedUs += sleepUs;
     639         9251 :     } while (elapsedUs < timeoutUs);
     640           46 :     return;
     641              : }
     642              : 
     643           43 : STATIC void *RsConnectHandle(void *arg)
     644              : {
     645           43 :     struct RsConnInfo *connTmp2 = NULL;
     646           43 :     struct RsConnInfo *connTmp = NULL;
     647           43 :     bool promoteConnect = false;
     648              :     int ret;
     649              : 
     650           43 :     hccp_info("<SOCKET> thread begin! thread_id:%lu, pid:%d, ppid:%d", pthread_self(), getpid(), getppid());
     651           43 :     CHK_PRT_RETURN(pthread_detach(pthread_self()),
     652              :         hccp_err("pthread_detach failed! thread_id:%lu, errno:%d", pthread_self(), errno), NULL);
     653              : 
     654           42 :     (void)prctl(PR_SET_NAME, (uintptr_t) "hccp_connect", 0, 0, 0);
     655              : 
     656           42 :     RsGetCurTime(&gConnectThreadInfo.lastCheckTime);
     657           42 :     ret = strncpy_s((char *)gConnectThreadInfo.pthreadName, sizeof(gConnectThreadInfo.pthreadName), "connect_pthread",
     658              :         strlen("connect_pthread"));
     659           42 :     CHK_PRT_RETURN(ret, hccp_err("strncpy_s pthread name failed, ret[%d]", ret), NULL);
     660           42 :     struct rs_cb *rsCb = (struct rs_cb *)arg;
     661           42 :     if (rsCb == NULL) {
     662            1 :         return NULL;
     663              :     }
     664              : 
     665           41 :     gRsCb = rsCb;
     666           41 :     sem_init(&rsCb->connectTrigSem, 0, 0);
     667              : 
     668           41 :     hccp_run_info("pthread[%s] is alive!", gConnectThreadInfo.pthreadName);
     669              :     while (1) {
     670          102 :         if (rsCb == NULL) {
     671            0 :             return NULL;
     672              :         }
     673              : 
     674          102 :         if (rsCb->connFlag == 0) {
     675           41 :             break;
     676              :         }
     677              : 
     678           61 :         promoteConnect = false;
     679           61 :         RsHeartbeatAlivePrint(&gConnectThreadInfo);
     680           61 :         RS_PTHREAD_MUTEX_LOCK(&rsCb->mutex);
     681           61 :         RS_LIST_GET_HEAD_ENTRY(connTmp, connTmp2, &rsCb->connCb.clientConnList, list, struct RsConnInfo);
     682           82 :         for (; (&connTmp->list) != &rsCb->connCb.clientConnList;
     683           21 :              connTmp = connTmp2, connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list)) {
     684           21 :             ret = RsSocketConnectAsync(connTmp, rsCb);
     685           21 :             if (ret != 0 && connTmp->state == RS_CONN_STATE_RESET) {
     686            0 :                 connTmp->state = RS_CONN_STATE_ERR;
     687            0 :                 hccp_err("[client]rs_socket_connect_async failed at RS_CONN_STATE_RESET state, ret:%d, clientIp:%s "
     688              :                          "serverIp:%s server_port:%u tag:%s",
     689              :                     ret, connTmp->clientIp.readAddr, connTmp->serverIp.readAddr, connTmp->port, connTmp->tag);
     690            0 :                 continue;
     691              :             }
     692           21 :             if ((promoteConnect == false) && (RsGetSocketConnectState(connTmp) == 0)) {
     693            0 :                 promoteConnect = true;
     694              :             }
     695              :         }
     696           61 :         RS_PTHREAD_MUTEX_ULOCK(&rsCb->mutex);
     697              : 
     698           61 :         if (promoteConnect) {
     699            0 :             usleep(RS_PROMOTE_CONN_USLEEP_TIME);
     700              :         } else {
     701           61 :             RsUsleepWaitConn(&rsCb->connectTrigSem, RS_CONN_USLEEP_TIME);
     702              :         }
     703              :     }
     704           41 :     sem_destroy(&rsCb->connectTrigSem);
     705           41 :     rsCb->connFlag = RS_CONN_EXIT_FLAG;
     706           41 :     hccp_info("<SOCKET> QUIT thread_id:%lu, pid:%d", pthread_self(), getpid());
     707              : 
     708           41 :     return NULL;
     709              : }
     710              : 
     711           44 : int RsEpollConnectHandleInit(struct rs_cb *rscb)
     712              : {
     713              :     int ret;
     714              :     pthread_t ntid;
     715              : 
     716           44 :     ret = RsCreateEpoll(rscb);
     717           44 :     CHK_PRT_RETURN(ret, hccp_err("rs_create_epoll failed ! ret:%d", ret), ret);
     718              : 
     719           43 :     hccp_info("rs_create_epoll ok");
     720           43 :     gRsCb = rscb;
     721              : 
     722           43 :     ret = pthread_create(&ntid, NULL, RsEpollHandle, (void *)rscb);
     723           43 :     if (ret != 0) {
     724            1 :         gRsCb = NULL;
     725            1 :         RsDestroyEpoll(rscb);
     726            1 :         hccp_err("pthread_create failed ! ret:%d, errno:%d", ret, errno);
     727            1 :         return -ESYSFUNC;
     728              :     }
     729              : 
     730              :     pthread_t tidp;
     731           42 :     rscb->connFlag = 1;
     732           42 :     ret = pthread_create(&tidp, NULL, RsConnectHandle, (void *)rscb);
     733           42 :     if (ret != 0) {
     734            1 :         gRsCb = NULL;
     735            1 :         RsDestroyEpoll(rscb);
     736            1 :         hccp_err("conn pthread_create failed ! ret:%d, errno:%d", ret, errno);
     737            1 :         return -ESYSFUNC;
     738              :     }
     739              : 
     740           41 :     hccp_info("RS INIT OK!");
     741              : 
     742           41 :     return ret;
     743              : }
     744              : 
     745            6 : int RsEpollCreateEpollfd(int *epollfd)
     746              : {
     747            6 :     RS_CHECK_POINTER_NULL_WITH_RET(epollfd);
     748              : 
     749              :     // 1024 specify the max fd num, this arg will be ignored since Linux 2.6.8
     750            4 :     *epollfd = epoll_create(1024);
     751            4 :     CHK_PRT_RETURN(*epollfd < 0, hccp_err("create epollfd[%d] failed, errno[%d]", *epollfd, errno), -EINVAL);
     752              : 
     753            4 :     return 0;
     754              : }
     755              : 
     756            6 : int RsEpollDestroyFd(int *fd)
     757              : {
     758            6 :     int ret = 0;
     759              : 
     760            6 :     RS_CHECK_POINTER_NULL_WITH_RET(fd);
     761              : 
     762            4 :     RS_CLOSE_RETRY_FOR_EINTR(ret, *fd);
     763            4 :     *fd = RS_FD_INVALID;
     764              : 
     765            4 :     return ret;
     766              : }
     767              : 
     768            2 : int RsEpollWaitHandle(int eventHandle, struct epoll_event *events, int timeout, unsigned int maxevents,
     769              :     unsigned int *eventsNum)
     770              : {
     771              :     int eventCount;
     772              : 
     773            2 :     RS_CHECK_POINTER_NULL_WITH_RET(events);
     774            1 :     RS_CHECK_POINTER_NULL_WITH_RET(eventsNum);
     775              : 
     776            1 :     eventCount = epoll_wait(eventHandle, events, (int)maxevents, timeout);
     777            1 :     if (eventCount < 0) {
     778            0 :         hccp_err("[rs_epoll_wait_handle]epoll_wait failed, strerror[%s]", strerror(errno));
     779            0 :         return -EIO;
     780              :     }
     781              : 
     782            1 :     *eventsNum = (unsigned int)eventCount;
     783            1 :     return 0;
     784              : }
     785              : 
     786              : RS_ATTRI_VISI_DEF int RsCreateEventHandle(int *eventHandle)
     787              : {
     788              :     int ret;
     789              : 
     790            4 :     ret = RsEpollCreateEpollfd(eventHandle);
     791            4 :     CHK_PRT_RETURN(ret, hccp_err("rs_epoll_create_epollfd failed ret(%d)", ret), ret);
     792            3 :     return 0;
     793              : }
     794              : 
     795              : RS_ATTRI_VISI_DEF int RsCtlEventHandle(int eventHandle, const void *fdHandle, int opcode, enum RaEpollEvent event)
     796              : {
     797            5 :     int fd = RS_FD_INVALID;
     798              :     unsigned int tmpEvent;
     799              :     int ret;
     800              : 
     801            5 :     if (eventHandle < 0) {
     802            1 :         hccp_err("event_handle[%d] is invalid", eventHandle);
     803            1 :         return -EINVAL;
     804              :     }
     805            4 :     if (fdHandle == NULL) {
     806            1 :         hccp_err("fd_handle is NULL");
     807            1 :         return -EINVAL;
     808              :     }
     809            3 :     if (opcode != EPOLL_CTL_ADD && opcode != EPOLL_CTL_DEL && opcode != EPOLL_CTL_MOD) {
     810            1 :         hccp_err("opcode[%d] invalid, valid opcode includes {%d, %d, %d}", opcode, EPOLL_CTL_ADD, EPOLL_CTL_DEL,
     811              :             EPOLL_CTL_MOD);
     812            1 :         return -EINVAL;
     813              :     }
     814              : 
     815            2 :     if (event == RA_EPOLLONESHOT) {
     816            1 :         tmpEvent = EPOLLIN | EPOLLET | EPOLLONESHOT;
     817            1 :     } else if (event == RA_EPOLLIN) {
     818            0 :         tmpEvent = EPOLLIN;
     819            1 :     } else if (event == RA_EPOLLOUT) {
     820            0 :         tmpEvent = EPOLLOUT;
     821            1 :     } else if (event == RA_EPOLLOUT_LET_ONESHOT) {
     822            0 :         tmpEvent = EPOLLOUT | EPOLLET | EPOLLONESHOT;
     823              :     } else {
     824            1 :         hccp_err("unknown event[%d]", event);
     825            1 :         return -EINVAL;
     826              :     }
     827              : 
     828            1 :     tmpEvent = tmpEvent | EPOLLRDHUP;
     829            1 :     fd = ((const struct SocketPeerInfo *)fdHandle)->fd;
     830              : 
     831            1 :     ret = RsEpollCtlFdHandle(eventHandle, opcode, fd, tmpEvent, (void *)fdHandle);
     832            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_epoll_ctl_fd_handle failed ret(%d), fd:%d", ret, fd), ret);
     833            0 :     return 0;
     834              : }
     835              : 
     836              : RS_ATTRI_VISI_DEF int RsWaitEventHandle(int eventHandle, struct SocketEventInfoT *eventInfos, int timeout,
     837              :     unsigned int maxevents, unsigned int *eventsNum)
     838              : {
     839              :     int ret;
     840              : 
     841            4 :     if (eventHandle < 0) {
     842            1 :         hccp_err("event_handle[%d] is invalid", eventHandle);
     843            1 :         return -EINVAL;
     844              :     }
     845              : 
     846            3 :     if (eventInfos == NULL) {
     847            1 :         hccp_err("event_info is NULL");
     848            1 :         return -EINVAL;
     849              :     }
     850              : 
     851            2 :     if (timeout < -1) {
     852            1 :         hccp_err("timeout[%d ms] is invalid", timeout);
     853            1 :         return -EINVAL;
     854              :     }
     855              : 
     856            1 :     if (maxevents > MAX_SOCKET_EVENT_NUM) {
     857            0 :         hccp_err("maxevents[%u] exceeds %u", maxevents, MAX_SOCKET_EVENT_NUM);
     858            0 :         return -EINVAL;
     859              :     }
     860              : 
     861            1 :     if (eventsNum == NULL) {
     862            0 :         hccp_err("events_num is NULL");
     863            0 :         return -EINVAL;
     864              :     }
     865              : 
     866            1 :     ret = RsEpollWaitHandle(eventHandle, (struct epoll_event *)eventInfos, timeout, maxevents, eventsNum);
     867            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_epoll_wait_handle failed ret(%d)", ret), ret);
     868              : 
     869            1 :     return 0;
     870              : }
     871              : 
     872              : RS_ATTRI_VISI_DEF int RsDestroyEventHandle(int *eventHandle)
     873              : {
     874              :     int ret;
     875              : 
     876            4 :     ret = RsEpollDestroyFd(eventHandle);
     877            4 :     CHK_PRT_RETURN(ret, hccp_err("rs_epoll_destroy_fd failed ret(%d)", ret), ret);
     878            3 :     return 0;
     879              : }
        

Generated by: LCOV version 2.0-1