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.6 % 180 172
Test Date: 2026-08-31 10:07:09 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          268 : AicpuDrvManager& AicpuDrvManager::GetInstance()
      49              : {
      50          268 :     static AicpuDrvManager instance;
      51          268 :     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           16 : int32_t AicpuDrvManager::InitDrvMgr(
      89              :     const uint32_t deviceId, const pid_t hostPid, const uint32_t vfId, const bool hasThread)
      90              : {
      91           16 :     if (deviceId >= DEVICE_NUM) {
      92            2 :         aicpusd_err("invalid device id[%u]", deviceId);
      93            2 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      94              :     }
      95           14 :     SetSafeVerifyFlag(deviceId);
      96           14 :     InitSocType(deviceId);
      97              :     int32_t ret;
      98           14 :     if (!FeatureCtrl::IsAosCore()) {
      99           11 :         ret = GetNormalAicpuInfo(deviceId);
     100           11 :         if (ret != 0) {
     101            1 :             aicpusd_err("GetNormalAicpuInfo error, ret[%d]", ret);
     102            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     103              :         }
     104           10 :         ret = GetCcpuInfo(deviceId);
     105           10 :         if ((ret != AICPU_SCHEDULE_OK) && (GetAicpuNum() == 0U)) {
     106            1 :             aicpusd_err("GetCcpuInfo error, ret[%d]", ret);
     107            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     108              :         }
     109              :     }
     110              : 
     111           12 :     uint32_t deviceIdTmp = deviceId;
     112           12 :     if (FeatureCtrl::IsVfModeDie1(deviceId)) {
     113            2 :         int64_t pfDeviceId = 0;
     114            2 :         ret = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_PHY_DIE_ID, &pfDeviceId);
     115            2 :         if (ret != DRV_ERROR_NONE) {
     116            1 :             aicpusd_err("halGetDeviceInfo get pfDeviceId fail in device[%d], ret[%d]", deviceId, ret);
     117            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     118              :         }
     119            1 :         deviceIdTmp = static_cast<uint32_t>(pfDeviceId);
     120              :     }
     121              : 
     122           11 :     int64_t aicpuNum = 0;
     123           11 :     int64_t aicpuOsSched = 0;
     124           11 :     int64_t ccpuNum = 0;
     125           11 :     int64_t ccpuOsSched = 0;
     126           11 :     int64_t dcpuNum = 0;
     127           11 :     int64_t dcpuOsSched = 0;
     128           11 :     int64_t tsCpuNum = 0;
     129           11 :     int64_t tsCpuOsSched = 0;
     130              :     uint32_t retDrv =
     131           11 :         static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum));
     132           11 :     retDrv |=
     133           11 :         static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_OS_SCHED, &aicpuOsSched));
     134           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_CORE_NUM, &ccpuNum));
     135           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_OS_SCHED, &ccpuOsSched));
     136           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_CORE_NUM, &dcpuNum));
     137           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_OS_SCHED, &dcpuOsSched));
     138           11 :     retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_CORE_NUM, &tsCpuNum));
     139           11 :     retDrv |=
     140           11 :         static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_OS_SCHED, &tsCpuOsSched));
     141           11 :     if (retDrv != 0U) {
     142            0 :         aicpusd_err("halGetDeviceInfo failed, ret[%u]", retDrv);
     143            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     144              :     }
     145           11 :     if (FeatureCtrl::IsAosCore()) {
     146            2 :         aicpuNum_ = aicpuNum;
     147            2 :         if (ccpuOsSched != 0) {
     148            1 :             aicpuBaseId_ += ccpuNum;
     149              :         }
     150            2 :         if (dcpuOsSched != 0) {
     151            1 :             aicpuBaseId_ += dcpuNum;
     152              :         }
     153              :     }
     154              :     // connot overflow
     155           11 :     coreNumPerDev_ =
     156           11 :         (ccpuNum * ccpuOsSched) + (dcpuNum * dcpuOsSched) + (aicpuNum * aicpuOsSched) + (tsCpuNum * tsCpuOsSched);
     157           11 :     dcpuBase_ = (deviceIdTmp * coreNumPerDev_) + ccpuNum;
     158           11 :     dcpuNum_ = dcpuNum;
     159           11 :     aicpusd_run_info(
     160              :         "device id[%u], host pid[%d], first aicpu index[%u], aicpu num[%u],"
     161              :         " dcpu base index[%u], dcpu num[%u], vf id[%u]",
     162              :         deviceIdTmp, hostPid, aicpuBaseId_, aicpuNum_, dcpuBase_, dcpuNum_, vfId);
     163           11 :     deviceId_ = deviceId;
     164           11 :     hostPid_ = hostPid;
     165           11 :     vfId_ = vfId;
     166           11 :     hasThread_ = hasThread;
     167           11 :     isInit_ = true;
     168              : 
     169           11 :     if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceId)) {
     170            2 :         uniqueVfId_ = deviceId;
     171              :     } else {
     172            9 :         uniqueVfId_ = vfId;
     173            9 :         if (FeatureCtrl::IsAosCore()) {
     174            1 :             return AICPU_SCHEDULE_OK;
     175              :         }
     176            8 :         if ((deviceId != 0U) && (vfId != 0U)) {
     177            1 :             uint32_t maxNumSpDev = 0U;
     178            1 :             const auto vfMaxRet = halGetDeviceVfMax(deviceId, &maxNumSpDev);
     179            1 :             if ((vfMaxRet != DRV_ERROR_NONE) || (maxNumSpDev > DEVICE_MAX_SPLIT_NUM)) {
     180            0 :                 aicpusd_err("Failed to get device cat vf number, result[%d], max num[%u].", vfMaxRet, maxNumSpDev);
     181            0 :                 return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     182              :             }
     183            1 :             uniqueVfId_ = maxNumSpDev * deviceId + vfId;
     184              :         }
     185              :     }
     186              : 
     187           10 :     return AICPU_SCHEDULE_OK;
     188              : }
     189              : 
     190           15 : void AicpuDrvManager::InitSocType(const uint32_t deviceId)
     191              : {
     192           15 :     int64_t hardwareVersion = 0L;
     193           15 :     const int32_t ret = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &hardwareVersion);
     194           15 :     if (ret != DRV_ERROR_NONE) {
     195            2 :         aicpusd_err("Get device info failed, deviceId=%u", deviceId);
     196            2 :         return;
     197              :     }
     198              : 
     199           13 :     FeatureCtrl::Init(hardwareVersion, deviceId);
     200           13 :     return;
     201              : }
     202              : 
     203            8 : int32_t AicpuDrvManager::InitDrvSchedModule(const uint32_t grpId)
     204              : {
     205              :     // use driver event means has thread
     206            8 :     hasThread_ = true;
     207            8 :     aicpusd_info("Attach device[%u] to drv scheduler.", deviceId_);
     208            8 :     int32_t ret = halEschedAttachDevice(deviceId_);
     209            8 :     if (ret != DRV_ERROR_NONE) {
     210            1 :         aicpusd_err("Failed to attach device in drv, result[%d].", ret);
     211            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     212              :     }
     213              : 
     214            7 :     const GROUP_TYPE cpuGrpType = (GetAicpuNum() == 0U) ? GRP_TYPE_BIND_CP_CPU : GRP_TYPE_BIND_DP_CPU;
     215            7 :     aicpusd_info("Create group[%u], type[%d]", grpId, cpuGrpType);
     216            7 :     ret = halEschedCreateGrp(deviceId_, grpId, cpuGrpType);
     217            7 :     if (ret != DRV_ERROR_NONE) {
     218            1 :         (void)halEschedDettachDevice(deviceId_);
     219            1 :         aicpusd_err("Failed to attach device in drv, result[%d].", ret);
     220            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     221              :     }
     222            6 :     if (FeatureCtrl::ShouldInitDrvThread() && (&halDrvEventThreadInit != nullptr)) {
     223            6 :         ret = halDrvEventThreadInit(deviceId_);
     224            6 :         aicpusd_run_info("Enable process drv queue msg on ccpu, ret is %d.", static_cast<int32_t>(ret));
     225              :     }
     226              : 
     227            6 :     return AICPU_SCHEDULE_OK;
     228              : }
     229              : 
     230            5 : int32_t AicpuDrvManager::CheckBindHostPid() const
     231              : {
     232            5 :     aicpusd_run_info("Start query process host pid");
     233            5 :     if (&drvQueryProcessHostPid == nullptr) {
     234            0 :         aicpusd_run_info("drvQueryProcessHostPid does not exist");
     235            0 :         return AICPU_SCHEDULE_OK;
     236              :     }
     237            5 :     drvError_t ret = DRV_ERROR_NONE;
     238            5 :     unsigned int hostpid = 0;
     239            5 :     unsigned int cpType = DEVDRV_PROCESS_CPTYPE_MAX;
     240            5 :     const int pid = static_cast<int>(getpid());
     241           16 :     for (uint32_t i = 0; i < QUERY_BIND_HOST_PID_TIME / QUERY_BIND_HOST_PID_INTERVBALE; i++) {
     242           15 :         ret = drvQueryProcessHostPid(pid, nullptr, nullptr, &hostpid, &cpType);
     243           15 :         if ((i % QUERY_BIND_HOST_PID_LOG_INTERVAL) == 0U) {
     244            5 :             aicpusd_run_info(
     245              :                 "Query process host pid end, ret=%d, hostpid=%u, expect=%u, cpType=%u", static_cast<int32_t>(ret),
     246              :                 hostpid, hostPid_, cpType);
     247              :         }
     248           15 :         if (ret == DRV_ERROR_NO_PROCESS) {
     249           11 :             aicpusd_info("call drvQueryProcessHostPid try again");
     250           11 :             (void)usleep(QUERY_BIND_HOST_PID_INTERVBALE);
     251           11 :             continue;
     252              :         }
     253              : 
     254            4 :         if (ret != DRV_ERROR_NONE) {
     255            2 :             aicpusd_err("call drvQueryProcessHostPid failed, ret[%d]", static_cast<int32_t>(ret));
     256            2 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     257              :         }
     258              : 
     259            2 :         aicpusd_info("call drvQueryProcessHostPid result, hostpid[%d], cpType[%d]", hostpid, cpType);
     260            2 :         if (hostPid_ == static_cast<pid_t>(hostpid)) {
     261            1 :             aicpusd_run_info("call drvQueryProcessHostPid success, hostpid[%d], cpType[%d]", hostpid, cpType);
     262            1 :             return AICPU_SCHEDULE_OK;
     263              :         } else {
     264            1 :             aicpusd_err(
     265              :                 "CheckBindHostPid failed, hostpid not right. ret[%d], pid[%d], hostpid[%d], cpType[%d]",
     266              :                 static_cast<int32_t>(ret), pid, hostpid, cpType);
     267            1 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     268              :         }
     269              :     }
     270            1 :     aicpusd_err(
     271              :         "CheckBindHostPid failed, try timeout. ret[%d], pid[%d], hostpid[%d], cpType[%d]", static_cast<int32_t>(ret),
     272              :         pid, hostpid, cpType);
     273            1 :     return AICPU_SCHEDULE_ERROR_DRV_ERR;
     274              : }
     275              : 
     276           43 : uint32_t AicpuDrvManager::GetAicpuNum() const
     277              : {
     278           43 :     aicpusd_info("Get aicpu core num[%u]", aicpuNum_);
     279           43 :     return aicpuNum_;
     280              : }
     281              : 
     282           12 : int32_t AicpuDrvManager::GetCcpuInfo(const uint32_t deviceId)
     283              : {
     284           12 :     int64_t ccpuBitMap = 0;
     285           12 :     const int32_t ret = halGetDeviceInfo(deviceId, MODULE_TYPE_CCPU, INFO_TYPE_OCCUPY, &ccpuBitMap);
     286           12 :     if (ret != DRV_ERROR_NONE) {
     287            1 :         aicpusd_err("halGetDeviceInfo failed, devid:%u, ret[%d]", deviceId, ret);
     288            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     289              :     }
     290           11 :     aicpusd_run_info("ccpuBitMap[%lld].", ccpuBitMap);
     291          187 :     for (uint32_t i = 0U; i < DEVICE_MAX_CPU_NUM; i++) {
     292          176 :         if ((ccpuBitMap & 0x1LL) != 0LL) {
     293            9 :             ccpuIdVec_.push_back(i);
     294              :         }
     295          176 :         ccpuBitMap = ccpuBitMap >> 1;
     296              :     }
     297           11 :     return AICPU_SCHEDULE_OK;
     298              : }
     299              : 
     300           15 : void AicpuDrvManager::SetSafeVerifyFlag(const uint32_t deviceId)
     301              : {
     302           15 :     int64_t verifyFlag = 0;
     303           15 :     const auto drvRet = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_CUST_OP_ENHANCE, &verifyFlag);
     304           15 :     if (drvRet == DRV_ERROR_NOT_SUPPORT) {
     305            1 :         aicpusd_info("safe flag is not supported");
     306            3 :         return;
     307              :     }
     308           14 :     if (drvRet != DRV_ERROR_NONE) {
     309            2 :         aicpusd_run_warn("get device info by halGetDeviceInfo failed, errorCode[%d] deviceId[%u]", drvRet, deviceId);
     310            2 :         return;
     311              :     }
     312           12 :     if (verifyFlag == SAFE_VERIFY_OPEN) {
     313           11 :         needSafeVerify_ = false;
     314           11 :         aicpusd_info("set verify flag to false");
     315              :     }
     316              : }
     317              : } // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1