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

Generated by: LCOV version 2.0-1