LCOV - code coverage report
Current view: top level - aicpu_cust_schedule/core - aicpusd_drv_manager.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 95.5 % 176 168
Test Date: 2026-08-12 11:05:02 Functions: 100.0 % 9 9

            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              : #include "aicpusd_drv_manager.h"
      11              : 
      12              : #include <map>
      13              : #include <sys/time.h>
      14              : #include "driver/ascend_hal.h"
      15              : #include "aicpusd_status.h"
      16              : #include "securec.h"
      17              : #include "aicpusd_common.h"
      18              : #include "aicpusd_hal_interface_ref.h"
      19              : 
      20              : #ifdef __cplusplus
      21              : extern "C" {
      22              : #endif
      23              : #ifdef __cplusplus
      24              : }
      25              : #endif
      26              : 
      27              : namespace {
      28              : constexpr const uint32_t DEVICE_NUM = 64U;
      29              : // max number of eatch device can split
      30              : constexpr const uint32_t DEVICE_MAX_SPLIT_NUM = 16U;
      31              : // max number of eatch device cpu
      32              : constexpr const uint32_t DEVICE_MAX_CPU_NUM = 16U;
      33              : // 查询bind信息间隔
      34              : constexpr uint32_t QUERY_BIND_HOST_PID_INTERVBALE = 10000U;
      35              : // 查询bind超时时间
      36              : #ifndef aicpusd_UT
      37              : constexpr uint32_t QUERY_BIND_HOST_PID_TIME = 120000000U;
      38              : #else
      39              : constexpr uint32_t QUERY_BIND_HOST_PID_TIME = 100000U;
      40              : #endif
      41              : // bind结果的日志输出周期
      42              : constexpr uint32_t QUERY_BIND_HOST_PID_LOG_INTERVAL = 1000U;
      43              : // 特权开关打开为1
      44              : constexpr int64_t SAFE_VERIFY_OPEN = 1;
      45              : } // namespace
      46              : 
      47              : namespace AicpuSchedule {
      48          226 : AicpuDrvManager& AicpuDrvManager::GetInstance()
      49              : {
      50          226 :     static AicpuDrvManager instance;
      51          226 :     return instance;
      52              : }
      53              : 
      54           10 : int32_t AicpuDrvManager::GetNormalAicpuInfo(const uint32_t deviceId)
      55              : {
      56           10 :     int64_t aicpuNum = 0;
      57           10 :     int64_t aicpuBitMap = 0;
      58           10 :     int32_t ret = 0;
      59           10 :     if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceId)) {
      60            2 :         ret = halGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_PF_CORE_NUM, &aicpuNum) +
      61            2 :               halGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_PF_OCCUPY, &aicpuBitMap);
      62              :     } else {
      63            8 :         ret = halGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum) +
      64            8 :               halGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_OCCUPY, &aicpuBitMap);
      65              :     }
      66           10 :     if (ret != DRV_ERROR_NONE) {
      67            1 :         aicpusd_err(
      68              :             "halGetDeviceInfo failed, ret[%d], deviceId[%u], DEV_MODULE_TYPE[%d], DEV_INFO_TYPE[%d]", ret, deviceId,
      69              :             static_cast<int32_t>(MODULE_TYPE_AICPU), static_cast<int32_t>(INFO_TYPE_PF_OCCUPY));
      70            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      71              :     }
      72            9 :     aicpusd_run_info("aicpuBitMap[%lld], aicpuNum[%lld]", aicpuBitMap, aicpuNum);
      73            9 :     aicpuNum_ = static_cast<uint32_t>(aicpuNum);
      74            9 :     aicpuIdVec_.clear();
      75          153 :     for (uint32_t i = 0U; i < DEVICE_MAX_CPU_NUM; i++) {
      76          144 :         if ((static_cast<uint64_t>(aicpuBitMap) & 0x1UL) != 0) {
      77            9 :             aicpuIdVec_.push_back(i);
      78              :         }
      79          144 :         aicpuBitMap = aicpuBitMap >> 1;
      80              :     }
      81            9 :     if (static_cast<uint32_t>(aicpuNum) != aicpuIdVec_.size()) {
      82            0 :         aicpusd_err("aicpunum bitmap error, aicpuNum[%lld],aicpuIdVecSize[%u]", aicpuNum, aicpuIdVec_.size());
      83            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      84              :     }
      85            9 :     return AICPU_SCHEDULE_OK;
      86              : }
      87              : 
      88           15 : int32_t AicpuDrvManager::InitDrvMgr(
      89              :     const uint32_t deviceId, const pid_t hostPid, const uint32_t vfId, const bool hasThread)
      90              : {
      91           15 :     if (deviceId >= DEVICE_NUM) {
      92            2 :         aicpusd_err("invalid device id[%u]", deviceId);
      93            2 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      94              :     }
      95           13 :     SetSafeVerifyFlag(deviceId);
      96           13 :     InitSocType(deviceId);
      97              :     int32_t ret;
      98           13 :     if (!FeatureCtrl::IsAosCore()) {
      99           10 :         ret = GetNormalAicpuInfo(deviceId);
     100           10 :         if (ret != 0) {
     101            1 :             aicpusd_err("GetNormalAicpuInfo error, ret[%d]", ret);
     102            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     103              :         }
     104            9 :         GetCcpuInfo(deviceId);
     105              :     }
     106              : 
     107           12 :     uint32_t deviceIdTmp = deviceId;
     108           12 :     if (FeatureCtrl::IsVfModeDie1(deviceId)) {
     109            2 :         int64_t pfDeviceId = 0;
     110            2 :         ret = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_PHY_DIE_ID, &pfDeviceId);
     111            2 :         if (ret != DRV_ERROR_NONE) {
     112            1 :             aicpusd_err("halGetDeviceInfo get pfDeviceId fail in device[%d], ret[%d]", deviceId, ret);
     113            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     114              :         }
     115            1 :         deviceIdTmp = static_cast<uint32_t>(pfDeviceId);
     116              :     }
     117              : 
     118           11 :     int64_t aicpuNum = 0;
     119           11 :     int64_t aicpuOsSched = 0;
     120           11 :     int64_t ccpuNum = 0;
     121           11 :     int64_t ccpuOsSched = 0;
     122           11 :     int64_t dcpuNum = 0;
     123           11 :     int64_t dcpuOsSched = 0;
     124           11 :     int64_t tsCpuNum = 0;
     125           11 :     int64_t tsCpuOsSched = 0;
     126              :     uint32_t retDrv =
     127           11 :         static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum));
     128           11 :     retDrv |=
     129           11 :         static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_OS_SCHED, &aicpuOsSched));
     130           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_CORE_NUM, &ccpuNum));
     131           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_OS_SCHED, &ccpuOsSched));
     132           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_CORE_NUM, &dcpuNum));
     133           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_OS_SCHED, &dcpuOsSched));
     134           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_CORE_NUM, &tsCpuNum));
     135           11 :     retDrv |=
     136           11 :         static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_OS_SCHED, &tsCpuOsSched));
     137           11 :     if (retDrv != 0U) {
     138            0 :         aicpusd_err("halGetDeviceInfo failed, ret[%u]", retDrv);
     139            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     140              :     }
     141           11 :     if (FeatureCtrl::IsAosCore()) {
     142            2 :         aicpuNum_ = aicpuNum;
     143            2 :         if (ccpuOsSched != 0) {
     144            1 :             aicpuBaseId_ += ccpuNum;
     145              :         }
     146            2 :         if (dcpuOsSched != 0) {
     147            1 :             aicpuBaseId_ += dcpuNum;
     148              :         }
     149              :     }
     150              :     // connot overflow
     151           11 :     coreNumPerDev_ =
     152           11 :         (ccpuNum * ccpuOsSched) + (dcpuNum * dcpuOsSched) + (aicpuNum * aicpuOsSched) + (tsCpuNum * tsCpuOsSched);
     153           11 :     dcpuBase_ = (deviceIdTmp * coreNumPerDev_) + ccpuNum;
     154           11 :     dcpuNum_ = dcpuNum;
     155           11 :     aicpusd_run_info(
     156              :         "device id[%u], host pid[%d], first aicpu index[%u], aicpu num[%u],"
     157              :         " dcpu base index[%u], dcpu num[%u], vf id[%u]",
     158              :         deviceIdTmp, hostPid, aicpuBaseId_, aicpuNum_, dcpuBase_, dcpuNum_, vfId);
     159           11 :     deviceId_ = deviceId;
     160           11 :     hostPid_ = hostPid;
     161           11 :     vfId_ = vfId;
     162           11 :     hasThread_ = hasThread;
     163           11 :     isInit_ = true;
     164              : 
     165           11 :     if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceId)) {
     166            2 :         uniqueVfId_ = deviceId;
     167              :     } else {
     168            9 :         uniqueVfId_ = vfId;
     169            9 :         if (FeatureCtrl::IsAosCore()) {
     170            1 :             return AICPU_SCHEDULE_OK;
     171              :         }
     172            8 :         if ((deviceId != 0U) && (vfId != 0U)) {
     173            1 :             uint32_t maxNumSpDev = 0U;
     174            1 :             const auto vfMaxRet = halGetDeviceVfMax(deviceId, &maxNumSpDev);
     175            1 :             if ((vfMaxRet != DRV_ERROR_NONE) || (maxNumSpDev > DEVICE_MAX_SPLIT_NUM)) {
     176            0 :                 aicpusd_err("Failed to get device cat vf number, result[%d], max num[%u].", vfMaxRet, maxNumSpDev);
     177            0 :                 return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     178              :             }
     179            1 :             uniqueVfId_ = maxNumSpDev * deviceId + vfId;
     180              :         }
     181              :     }
     182              : 
     183           10 :     return AICPU_SCHEDULE_OK;
     184              : }
     185              : 
     186           14 : void AicpuDrvManager::InitSocType(const uint32_t deviceId)
     187              : {
     188           14 :     int64_t hardwareVersion = 0L;
     189           14 :     const int32_t ret = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &hardwareVersion);
     190           14 :     if (ret != DRV_ERROR_NONE) {
     191            2 :         aicpusd_err("Get device info failed, deviceId=%u", deviceId);
     192            2 :         return;
     193              :     }
     194              : 
     195           12 :     FeatureCtrl::Init(hardwareVersion, deviceId);
     196           12 :     return;
     197              : }
     198              : 
     199            7 : int32_t AicpuDrvManager::InitDrvSchedModule(const uint32_t grpId)
     200              : {
     201              :     // use driver event means has thread
     202            7 :     hasThread_ = true;
     203            7 :     aicpusd_info("Attach device[%u] to drv scheduler.", deviceId_);
     204            7 :     int32_t ret = halEschedAttachDevice(deviceId_);
     205            7 :     if (ret != DRV_ERROR_NONE) {
     206            1 :         aicpusd_err("Failed to attach device in drv, result[%d].", ret);
     207            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     208              :     }
     209              : 
     210            6 :     aicpusd_info("Create group[%u], type[%d]", grpId, GRP_TYPE_BIND_DP_CPU);
     211            6 :     ret = halEschedCreateGrp(deviceId_, grpId, GRP_TYPE_BIND_DP_CPU);
     212            6 :     if (ret != DRV_ERROR_NONE) {
     213            1 :         (void)halEschedDettachDevice(deviceId_);
     214            1 :         aicpusd_err("Failed to attach device in drv, result[%d].", ret);
     215            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     216              :     }
     217            5 :     if (FeatureCtrl::ShouldInitDrvThread() && (&halDrvEventThreadInit != nullptr)) {
     218            5 :         ret = halDrvEventThreadInit(deviceId_);
     219            5 :         aicpusd_run_info("Enable process drv queue msg on ccpu, ret is %d.", static_cast<int32_t>(ret));
     220              :     }
     221              : 
     222            5 :     return AICPU_SCHEDULE_OK;
     223              : }
     224              : 
     225            5 : int32_t AicpuDrvManager::CheckBindHostPid() const
     226              : {
     227            5 :     aicpusd_run_info("Start query process host pid");
     228            5 :     if (&drvQueryProcessHostPid == nullptr) {
     229            0 :         aicpusd_run_info("drvQueryProcessHostPid does not exist");
     230            0 :         return AICPU_SCHEDULE_OK;
     231              :     }
     232            5 :     drvError_t ret = DRV_ERROR_NONE;
     233            5 :     unsigned int hostpid = 0;
     234            5 :     unsigned int cpType = DEVDRV_PROCESS_CPTYPE_MAX;
     235            5 :     const int pid = static_cast<int>(getpid());
     236           16 :     for (uint32_t i = 0; i < QUERY_BIND_HOST_PID_TIME / QUERY_BIND_HOST_PID_INTERVBALE; i++) {
     237           15 :         ret = drvQueryProcessHostPid(pid, nullptr, nullptr, &hostpid, &cpType);
     238           15 :         if ((i % QUERY_BIND_HOST_PID_LOG_INTERVAL) == 0U) {
     239            5 :             aicpusd_run_info(
     240              :                 "Query process host pid end, ret=%d, hostpid=%u, expect=%u, cpType=%u", static_cast<int32_t>(ret),
     241              :                 hostpid, hostPid_, cpType);
     242              :         }
     243           15 :         if (ret == DRV_ERROR_NO_PROCESS) {
     244           11 :             aicpusd_info("call drvQueryProcessHostPid try again");
     245           11 :             (void)usleep(QUERY_BIND_HOST_PID_INTERVBALE);
     246           11 :             continue;
     247              :         }
     248              : 
     249            4 :         if (ret != DRV_ERROR_NONE) {
     250            2 :             aicpusd_err("call drvQueryProcessHostPid failed, ret[%d]", static_cast<int32_t>(ret));
     251            2 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     252              :         }
     253              : 
     254            2 :         aicpusd_info("call drvQueryProcessHostPid result, hostpid[%d], cpType[%d]", hostpid, cpType);
     255            2 :         if (hostPid_ == static_cast<pid_t>(hostpid)) {
     256            1 :             aicpusd_run_info("call drvQueryProcessHostPid success, hostpid[%d], cpType[%d]", hostpid, cpType);
     257            1 :             return AICPU_SCHEDULE_OK;
     258              :         } else {
     259            1 :             aicpusd_err(
     260              :                 "CheckBindHostPid failed, hostpid not right. ret[%d], pid[%d], hostpid[%d], cpType[%d]",
     261              :                 static_cast<int32_t>(ret), pid, hostpid, cpType);
     262            1 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     263              :         }
     264              :     }
     265            1 :     aicpusd_err(
     266              :         "CheckBindHostPid failed, try timeout. ret[%d], pid[%d], hostpid[%d], cpType[%d]", static_cast<int32_t>(ret),
     267              :         pid, hostpid, cpType);
     268            1 :     return AICPU_SCHEDULE_ERROR_DRV_ERR;
     269              : }
     270              : 
     271           29 : uint32_t AicpuDrvManager::GetAicpuNum() const
     272              : {
     273           29 :     aicpusd_info("Get aicpu core num[%u]", aicpuNum_);
     274           29 :     return aicpuNum_;
     275              : }
     276              : 
     277           12 : int32_t AicpuDrvManager::GetCcpuInfo(const uint32_t deviceId)
     278              : {
     279           12 :     int64_t ccpuBitMap = 0;
     280           12 :     const int32_t ret = halGetDeviceInfo(deviceId, MODULE_TYPE_CCPU, INFO_TYPE_OCCUPY, &ccpuBitMap);
     281           12 :     if (ret != DRV_ERROR_NONE) {
     282            1 :         aicpusd_err("halGetDeviceInfo failed, devid:%u, ret[%d]", deviceId, ret);
     283            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     284              :     }
     285           11 :     aicpusd_run_info("ccpuBitMap[%lld].", ccpuBitMap);
     286          187 :     for (uint32_t i = 0U; i < DEVICE_MAX_CPU_NUM; i++) {
     287          176 :         if ((ccpuBitMap & 0x1LL) != 0LL) {
     288            9 :             ccpuIdVec_.push_back(i);
     289              :         }
     290          176 :         ccpuBitMap = ccpuBitMap >> 1;
     291              :     }
     292           11 :     return AICPU_SCHEDULE_OK;
     293              : }
     294              : 
     295           14 : void AicpuDrvManager::SetSafeVerifyFlag(const uint32_t deviceId)
     296              : {
     297           14 :     int64_t verifyFlag = 0;
     298           14 :     const auto drvRet = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_CUST_OP_ENHANCE, &verifyFlag);
     299           14 :     if (drvRet == DRV_ERROR_NOT_SUPPORT) {
     300            1 :         aicpusd_info("safe flag is not supported");
     301            3 :         return;
     302              :     }
     303           13 :     if (drvRet != DRV_ERROR_NONE) {
     304            2 :         aicpusd_run_warn("get device info by halGetDeviceInfo failed, errorCode[%d] deviceId[%u]", drvRet, deviceId);
     305            2 :         return;
     306              :     }
     307           11 :     if (verifyFlag == SAFE_VERIFY_OPEN) {
     308           10 :         needSafeVerify_ = false;
     309           10 :         aicpusd_info("set verify flag to false");
     310              :     }
     311              : }
     312              : } // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1