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

Generated by: LCOV version 2.0-1