LCOV - code coverage report
Current view: top level - aicpu_processer - ae_so_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.1 % 375 338
Test Date: 2026-07-28 10:54:05 Functions: 100.0 % 23 23

            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              : #include "ae_so_manager.hpp"
      12              : #include <memory>
      13              : #include <mutex>
      14              : #include <cstdlib>
      15              : #include <string>
      16              : #include <climits>
      17              : #include <securec.h>
      18              : #include <dlfcn.h>
      19              : #include <fstream>
      20              : #include <sstream>
      21              : #include <vector>
      22              : #include "ae_def.hpp"
      23              : #include "ae_kernel_lib_aicpu.hpp"
      24              : 
      25              : namespace cce {
      26              :     namespace {
      27              :         // aicpu so root dir, must be absolute path
      28              :         const std::string AICPU_SO_ROOT_DIR = "/usr/lib64/aicpu_kernels/";
      29              :         // aicpu so root dir, old path only for hccl
      30              :         const std::string AICPU_SO_ROOT_DIR_OLD_PATH = "/usr/lib64/";
      31              :         // cust so path for cust_aicpu_sd: CustAiCpuUser
      32              :         constexpr const char_t *CUST_USER_SO_PATH = "/home/CustAiCpuUser";
      33              :         // prefix of cust so dir name
      34              :         constexpr const char_t *CUSTOM_SO_DIR_NAME_PREFIX = "cust_aicpu_";
      35              :         // aicpu kernels tar uncompress path
      36              :         constexpr const char_t *AICPU_SO_UNCOMPRESS_DIR = "aicpu_kernels_device";
      37              :         // libretr_kernels.so
      38              :         constexpr const char_t *RETR_KERNELS_SO_NAME = "libretr_kernels.so";
      39              :         // libhccl_operator_call.so
      40              :         constexpr const char_t *HCCL_KERNELS_SO_NAME = "libhccl_operator_call.so";
      41              :         // libbuiltin_kernels.so
      42              :         constexpr const char_t *BUILTIN_KERNELS_SO_NAME = "libbuiltin_kernels.so";
      43              :         // pattern for custom so name
      44              :         constexpr const char_t *PATTERN_FOR_SO_NAME("abcdefghijklmnopqrstuvwxyz"
      45              :                                                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890-_.");
      46              :         // env variable name: inner aicpu kernel so path
      47              :         constexpr const char_t *AICPU_INNER_SO_PATH_ENV_VAR_NAME = "ASCEND_AICPU_KERNEL_PATH";
      48              :         // env variable name: custom aicpu kernel so path
      49              :         // If modify the env name, please modify the same env name in aicpusd_cust_so_manager.cpp
      50              :         constexpr const char_t *AICPU_CUSTOM_SO_PATH_ENV_VAR = "ASCEND_CUST_AICPU_KERNEL_CACHE_PATH";
      51              :         // physical machine VFID == 0 物理机场景
      52              :         constexpr uint32_t DEFAULT_VFID = 0U;
      53              :         // min number of vDeviceId
      54              :         constexpr const uint32_t VDEVICE_MIN_CPU_NUM = 32U;
      55              :         // max number of vDeviceId
      56              :         constexpr const uint32_t VDEVICE_MAX_CPU_NUM = 64U;
      57              :         constexpr const uint32_t DIV_NUM = 2U;
      58              :         // version.info TurstList info
      59              :         const std::string TRUST_SO_LIST_PREFIX = "Trustlist=";
      60              : 
      61              :         constexpr const char_t *THREAD_MODE_SO_PATH_FIX = "aicpu_kernels";
      62              :     }
      63              : 
      64           29 : SingleSoManager::~SingleSoManager()
      65              : {
      66              :     // Step1.  clear the critical section apiCacher_
      67           29 :     AE_RW_LOCK_WR_LOCK(&rwLock_);
      68           29 :     apiCacher_.clear();
      69           29 :     AE_RW_LOCK_UN_LOCK(&rwLock_);
      70              : 
      71              :     // Step2.  destroy the Read Write lock
      72           29 :     AE_RW_LOCK_DESTROY(&rwLock_);
      73              : 
      74              :     // Step3. close so
      75           29 :     (void)CloseSo(soHandle_);
      76           29 :     soHandle_ = nullptr;
      77           29 : }
      78              : 
      79           28 : aeStatus_t SingleSoManager::Init(const std::string &guardDirName, const std::string &soFile)
      80              : {
      81           28 :     soName_.clear();
      82           28 :     apiCacher_.clear();
      83              : 
      84           28 :     aeStatus_t ret = CheckSoFile(guardDirName, soFile);
      85           28 :     if (ret != AE_STATUS_SUCCESS) {
      86           24 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "CheckSoFile failed, soFile[%s], ret[%u].", soFile.c_str(), ret);
      87           24 :         return ret;
      88              :     }
      89              : 
      90            4 :     void *handle = nullptr;
      91            4 :     ret = OpenSo(soFile, &handle);
      92            4 :     if ((ret == AE_STATUS_SUCCESS) && (handle != nullptr)) {
      93            4 :         soHandle_ = handle;
      94            4 :         soName_ = soFile;
      95              :     }
      96            4 :     return ret;
      97              : }
      98              : 
      99           34 : aeStatus_t SingleSoManager::CheckSoFile(const std::string &guardDirName, const std::string &soFile)
     100              : {
     101           34 :     if (guardDirName.empty()) {
     102            1 :         AE_INFO_LOG(AE_MODULE_ID, "guardDirName is empty, no need check");
     103            1 :         return AE_STATUS_SUCCESS;
     104              :     }
     105              : 
     106           33 :     if (soFile.length() >= static_cast<std::string::size_type>(PATH_MAX)) {
     107            1 :         AE_ERR_LOG(AE_MODULE_ID, "soFile file length[%zu] must less than PATH_MAX[%u]", soFile.length(), PATH_MAX);
     108            1 :         return AE_STATUS_OPEN_SO_FAILED;
     109              :     }
     110              : 
     111           32 :     std::unique_ptr<char_t []> path(new (std::nothrow) char_t[PATH_MAX]);
     112           32 :     if (path == nullptr) {
     113            0 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Alloc memory for path failed.");
     114            0 :         return AE_STATUS_OPEN_SO_FAILED;
     115              :     }
     116              : 
     117           32 :     const auto eRet = memset_s(path.get(), PATH_MAX, 0, PATH_MAX);
     118           32 :     if (eRet != EOK) {
     119            1 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Mem set error, ret=%d", eRet);
     120            1 :         return AE_STATUS_OPEN_SO_FAILED;
     121              :     }
     122              : 
     123           31 :     if (realpath(soFile.data(), path.get()) == nullptr) {
     124           27 :         AE_WARN_LOG(AE_MODULE_ID, "Format to realpath failed:%s, path:%s", soFile.data(), path.get());
     125           27 :         return AE_STATUS_OPEN_SO_FAILED;
     126              :     }
     127              : 
     128            4 :     std::string tmpGuardDirName(guardDirName);
     129            4 :     if (tmpGuardDirName[tmpGuardDirName.size() - 1UL] != '/') {
     130            1 :         (void)tmpGuardDirName.append("/");
     131              :     }
     132              : 
     133            4 :     const std::string pathStr(path.get());
     134            4 :     const std::string realSoPath = GetRealCustSoPath();
     135            5 :     if ((strncmp(path.get(), tmpGuardDirName.c_str(), tmpGuardDirName.length()) != 0) &&
     136            1 :         (pathStr.find(realSoPath) == std::string::npos)) {
     137            1 :         AE_ERR_LOG(AE_MODULE_ID, "Invalid so file with dir:%s so:%s, should be %s or %s",
     138              :                    path.get(), soFile.c_str(), tmpGuardDirName.data(), realSoPath.c_str());
     139            1 :         return AE_STATUS_OPEN_SO_FAILED;
     140              :     }
     141            3 :     return AE_STATUS_SUCCESS;
     142           32 : }
     143              : 
     144            4 : std::string SingleSoManager::GetRealCustSoPath()
     145              : {
     146              :     aicpu::aicpuContext_t currentAicpuCtx;
     147            4 :     (void)aicpu::aicpuGetContext(&currentAicpuCtx);
     148              : 
     149            4 :     const uint32_t uniqueVfId = aicpu::GetUniqueVfId();
     150              : 
     151            4 :     std::string soPath = CUST_USER_SO_PATH;
     152            4 :     GetCustSoPathByUniqueVfId(soPath, uniqueVfId);
     153            4 :     (void)soPath.append("lib/");
     154            4 :     return soPath;
     155            0 : }
     156              : 
     157            7 : void SingleSoManager::GetCustSoPathByUniqueVfId(std::string &soPath, const uint32_t uniqueVfId)
     158              : {
     159            7 :     if (uniqueVfId == DEFAULT_VFID) {
     160            7 :         (void)soPath.append("/");
     161            0 :     } else if (uniqueVfId >= VDEVICE_MIN_CPU_NUM && uniqueVfId < VDEVICE_MAX_CPU_NUM) {
     162            0 :         const uint32_t custNum = (uniqueVfId - VDEVICE_MIN_CPU_NUM) / DIV_NUM + 1U;
     163            0 :         (void)soPath.append(std::to_string(custNum)).append("/");
     164            0 :     } else {
     165            0 :         (void)soPath.append(std::to_string(uniqueVfId)).append("/");
     166              :     }
     167            7 : }
     168              : 
     169           13 : aeStatus_t SingleSoManager::OpenSo(const std::string &soFile, void ** const retHandle)
     170              : {
     171              :     // Use API in glibc to open the so lib, load this so to process.
     172           13 :     std::unique_ptr<char_t []> path(new (std::nothrow) char_t[PATH_MAX]);
     173           13 :     if (path == nullptr) {
     174            0 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Alloc memory for path failed.");
     175            0 :         return AE_STATUS_OPEN_SO_FAILED;
     176              :     }
     177              : 
     178           13 :     const auto eRet = memset_s(path.get(), PATH_MAX, 0, PATH_MAX);
     179           13 :     if (eRet != EOK) {
     180            1 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Mem set error, ret=%d", eRet);
     181            1 :         return AE_STATUS_OPEN_SO_FAILED;
     182              :     }
     183              : 
     184           12 :     if (realpath(soFile.data(), path.get()) == nullptr) {
     185            8 :         AE_WARN_LOG(AE_MODULE_ID, "Format to realpath failed:[%s], path:[%s]", soFile.data(), path.get());
     186            8 :         return AE_STATUS_OPEN_SO_FAILED;
     187              :     }
     188              : 
     189            4 :     AE_INFO_LOG(AE_MODULE_ID, "Open so %s begin.", path.get());
     190            4 :     void * const handle = dlopen(path.get(), static_cast<int32_t>(
     191              :                                  (static_cast<uint32_t>(RTLD_LAZY))|(static_cast<uint32_t>(RTLD_GLOBAL))));
     192            4 :     if (handle == nullptr) {
     193            0 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Open so %s failed with error:%s", path.get(), dlerror());
     194            0 :         return AE_STATUS_OPEN_SO_FAILED;
     195              :     }
     196              : 
     197            4 :     *retHandle = handle;
     198            4 :     AE_INFO_LOG(AE_MODULE_ID, "Open so %s success.", soFile.c_str());
     199            4 :     return AE_STATUS_SUCCESS;
     200           13 : }
     201              : 
     202            2 : aeStatus_t SingleSoManager::GetFunc(void * const soHandle, const char_t * const funcName, void ** const retFuncAddr)
     203              : {
     204            2 :     void * const theFuncAddr = dlsym(soHandle, funcName);
     205            2 :     if (static_cast<bool>(unlikely((theFuncAddr == nullptr)))) {
     206            1 :         AE_ERR_LOG(AE_MODULE_ID, "Get funcAddr %s from handle is NULL: %s", funcName, dlerror());
     207            1 :         return AE_STATUS_GET_KERNEL_NAME_FAILED;
     208              :     }
     209            1 :     *retFuncAddr = theFuncAddr;
     210            1 :     return AE_STATUS_SUCCESS;
     211              : }
     212              : 
     213          127 : aeStatus_t SingleSoManager::GetApi(const char_t * const soNamePtr, const char_t * const funcName,
     214              :                                    void ** const funcAddrPtr)
     215              : {
     216          127 :     if (static_cast<bool>(unlikely((soHandle_ == nullptr)))) {
     217            3 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "soHandle_ is null, should be Init first.");
     218            3 :         return AE_STATUS_INNER_ERROR;
     219              :     }
     220              : 
     221          124 :     AE_RW_LOCK_RD_LOCK(&rwLock_);
     222          248 :     auto apiIter = apiCacher_.find(funcName);
     223          124 :     if (apiIter != apiCacher_.end()) {
     224          116 :         *funcAddrPtr = apiIter->second;
     225          116 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     226          117 :         return AE_STATUS_SUCCESS;
     227              :     }
     228            7 :     AE_RW_LOCK_UN_LOCK(&rwLock_);
     229              : 
     230            7 :     AE_RW_LOCK_WR_LOCK(&rwLock_);
     231           14 :     apiIter = apiCacher_.find(funcName);
     232            7 :     if (apiIter != apiCacher_.end()) {
     233            0 :         *funcAddrPtr = apiIter->second;
     234            0 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     235            0 :         return AE_STATUS_SUCCESS;
     236              :     }
     237              : 
     238              :     // get func
     239            7 :     void *theFuncAddr = nullptr;
     240            7 :     const aeStatus_t ret = GetFunc(soHandle_, funcName, &theFuncAddr);
     241            7 :     if (ret != AE_STATUS_SUCCESS) {
     242            1 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     243            1 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Get func %s from so %s failed, ret[%u].", funcName, soNamePtr, ret);
     244            1 :         return ret;
     245              :     }
     246              :     // cache func
     247           12 :     apiCacher_[funcName] = theFuncAddr;
     248            6 :     *funcAddrPtr = theFuncAddr;
     249            6 :     AE_RW_LOCK_UN_LOCK(&rwLock_);
     250            6 :     AE_RUN_INFO_LOG(AE_MODULE_ID, "Get api %s from so %s success.", funcName, soNamePtr);
     251            6 :     return AE_STATUS_SUCCESS;
     252              : }
     253              : 
     254            3 : aeStatus_t SingleSoManager::GetApi(const char_t * const soFile, const char_t * const funcName,
     255              :                                    void ** const funcAddrPtr, void ** const retHandle)
     256              : {
     257            3 :     void *handle = nullptr;
     258            3 :     const aeStatus_t retOpenSo = OpenSo(soFile, &handle);
     259            3 :     if ((retOpenSo == AE_STATUS_SUCCESS) && (handle != nullptr)) {
     260            1 :         void *theFuncAddr = nullptr;
     261            1 :         const aeStatus_t retGetFunc = GetFunc(handle, funcName, &theFuncAddr);
     262            1 :         if ((retGetFunc == AE_STATUS_SUCCESS) && (theFuncAddr != nullptr)) {
     263            1 :             *funcAddrPtr = theFuncAddr;
     264              :         }
     265              : 
     266            1 :         *retHandle = handle;
     267            1 :         return retGetFunc;
     268              :     }
     269              : 
     270            2 :     AE_ERR_LOG(AE_MODULE_ID, "Open so failed when get api, soFile[%s], ret[%u].", soFile, retOpenSo);
     271            2 :     return retOpenSo;
     272              : }
     273              : 
     274           55 : aeStatus_t SingleSoManager::CloseSo(void * const retHandle)
     275              : {
     276           55 :     if (retHandle != nullptr) {
     277            8 :         const int32_t ret = dlclose(retHandle);
     278            8 :         if (ret != 0) {
     279            1 :             AE_ERR_LOG(AE_MODULE_ID, "Close so failed with error:%s", dlerror());
     280            1 :             return AE_STATUS_INNER_ERROR;
     281              :         } else {
     282            7 :             AE_DEBUG_LOG(AE_MODULE_ID, "Close success:");
     283            7 :             return AE_STATUS_SUCCESS;
     284              :         }
     285              :     }
     286           47 :     return AE_STATUS_SUCCESS;
     287              : }
     288              : 
     289           81 : MultiSoManager::~MultiSoManager()
     290              : {
     291              :     // Step1.  clear the critical section apiCacher_
     292           81 :     AE_RW_LOCK_WR_LOCK(&rwLock_);
     293           84 :     for (auto iter = soCacher_.begin(); iter != soCacher_.end(); ++iter) {
     294            3 :         const SingleSoManager * const soMngr = iter->second;
     295            3 :         if (soMngr != nullptr) {
     296            3 :             delete soMngr; // Release each SingleSoManager * stored in cache
     297              :         }
     298              :     }
     299           81 :     soCacher_.clear();
     300           81 :     AE_RW_LOCK_UN_LOCK(&rwLock_);
     301              :     // Step2.  destroy the Read Write lock
     302           81 :     AE_RW_LOCK_DESTROY(&rwLock_);
     303           81 : };
     304              : 
     305            8 : aeStatus_t MultiSoManager::Init()
     306              : {
     307            8 :     soCacher_.clear();
     308            8 :     const aicpu::status_t status = aicpu::GetAicpuRunMode(runMode_);
     309            8 :     if (status != aicpu::AICPU_ERROR_NONE) {
     310            1 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Get aicpu runmode failed.");
     311            1 :         return AE_STATUS_INNER_ERROR;
     312              :     }
     313              :     // get aicpu so path
     314            7 :     const char_t * const innerDirName = getenv(AICPU_INNER_SO_PATH_ENV_VAR_NAME);
     315            7 :     if (innerDirName != nullptr) {
     316            1 :         const std::string str =  innerDirName;
     317            1 :         const size_t len = str.length();
     318            1 :         if ((len == 0U) || (len >= static_cast<size_t>(PATH_MAX))) {
     319            0 :             AE_ERR_LOG(AE_MODULE_ID, "Length of inner so dir %zu is invalid.", len);
     320            0 :             return AE_STATUS_INNER_ERROR;
     321              :         }
     322            1 :         innerKernelPath_ = str;
     323            1 :         if (innerKernelPath_[innerKernelPath_.size() - 1UL] != '/') {
     324            0 :             (void)innerKernelPath_.append("/");
     325              :         }
     326            1 :     }
     327              :     // get cust aicpu so path
     328            7 :     const char_t * const custDirName = getenv(AICPU_CUSTOM_SO_PATH_ENV_VAR);
     329            7 :     if (custDirName != nullptr) {
     330            1 :         const std::string str =  custDirName;
     331            1 :         const size_t len = str.length();
     332            1 :         if ((len == 0U) || (len >= static_cast<size_t>(PATH_MAX))) {
     333            0 :             AE_ERR_LOG(AE_MODULE_ID, "Length of cust so dir %zu is invalid.", len);
     334            0 :             return AE_STATUS_INNER_ERROR;
     335              :         }
     336            1 :         custKernelPath_ = str;
     337            1 :         if (custKernelPath_[custKernelPath_.size() - 1UL] != '/') {
     338            0 :             (void)custKernelPath_.append("/");
     339              :         }
     340            1 :     }
     341            7 :     return AE_STATUS_SUCCESS;
     342              : }
     343              : 
     344          125 : aeStatus_t MultiSoManager::GetApi(const aicpu::KernelType kernelType, const char_t * const soName,
     345              :                                   const char_t * const funcName, void ** const funcAddrPtr)
     346              : {
     347          125 :     SingleSoManager *soMgr = nullptr;
     348          125 :     const aeStatus_t ret = LoadSo(kernelType, soName, soMgr);
     349          125 :     if ((ret != AE_STATUS_SUCCESS) || (soMgr == nullptr)) {
     350            3 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Load so %s failed.", soName);
     351            3 :         return AE_STATUS_OPEN_SO_FAILED;
     352              :     }
     353          122 :     return soMgr->GetApi(soName, funcName, funcAddrPtr);
     354              : }
     355              : 
     356           12 : aeStatus_t MultiSoManager::GetSoPath(const aicpu::KernelType kernelType, const std::string &soName,
     357              :                                      std::string &soPath) const
     358              : {
     359           12 :     if (kernelType == aicpu::KERNEL_TYPE_AICPU_CUSTOM || kernelType == aicpu::KERNEL_TYPE_AICPU_CUSTOM_KFC) {
     360            0 :         return GetCustSoPath(soPath);
     361              :     }
     362           12 :     return GetInnerSoPath(soName, soPath);
     363              : }
     364              : 
     365           11 : aeStatus_t MultiSoManager::GetThreadModeSoPath(std::string &soPath) const
     366              : {
     367           11 :     const char_t * const innerDirName = getenv("HOME");
     368           11 :     if (innerDirName != nullptr) {
     369           10 :         const std::string str =  innerDirName;
     370           10 :         const size_t len = str.length();
     371           10 :         if ((len == 0U) || (len >= static_cast<size_t>(PATH_MAX))) {
     372            0 :             AE_ERR_LOG(AE_MODULE_ID, "Length[%zu] of inner so dir is invalid.", len);
     373            0 :             return AE_STATUS_INNER_ERROR;
     374              :         }
     375           10 :         soPath = str;
     376           10 :         if (soPath[soPath.size() - 1UL] != '/') {
     377           10 :             (void)soPath.append("/");
     378              :         }
     379           10 :         (void)soPath.append(THREAD_MODE_SO_PATH_FIX).append("/")
     380           20 :             .append(std::to_string(aicpu::GetUniqueVfId())).append("/")
     381           10 :             .append(AICPU_SO_UNCOMPRESS_DIR).append("/");
     382           10 :         return AE_STATUS_SUCCESS;
     383           10 :     } else {
     384            1 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Get HOME env failed, get thread mode so path failed.");
     385            1 :         return AE_STATUS_INNER_ERROR;
     386              :     }
     387              : }
     388           21 : aeStatus_t MultiSoManager::GetInnerSoPath(const std::string &soName, std::string &soPath) const
     389              : {
     390              :     uint32_t runMode;
     391           21 :     aicpu::status_t status = aicpu::GetAicpuRunMode(runMode);
     392           21 :     if (status != aicpu::AICPU_ERROR_NONE) {
     393            1 :         AE_ERR_LOG(AE_MODULE_ID, "Get current aicpu ctx failed.");
     394            1 :         return AE_STATUS_INNER_ERROR;
     395              :     }
     396              : 
     397              :     // aicpu kernel path for lhisi from env: ASCEND_AICPU_KERNEL_PATH
     398           20 :     if ((runMode == aicpu::AicpuRunMode::THREAD_MODE) && (!innerKernelPath_.empty())) {
     399            1 :         soPath = innerKernelPath_;
     400            1 :         return AE_STATUS_SUCCESS;
     401              :     }
     402              : 
     403              :     // libretr_kernels.so in /usr/lib64/aicpu_kernel/
     404           19 :     if (soName == RETR_KERNELS_SO_NAME) {
     405            1 :         soPath = AICPU_SO_ROOT_DIR;
     406            1 :         return AE_STATUS_SUCCESS;
     407              :     }
     408              : 
     409              :     // libhccl_operator_call.so in /usr/lib64/
     410           18 :     if ((soName == HCCL_KERNELS_SO_NAME) || (soName == BUILTIN_KERNELS_SO_NAME)) {
     411            1 :         soPath = AICPU_SO_ROOT_DIR_OLD_PATH;
     412            1 :         return AE_STATUS_SUCCESS;
     413              :     }
     414              : 
     415           17 :     if (runMode == aicpu::AicpuRunMode::THREAD_MODE) {
     416            7 :         if (GetThreadModeSoPath(soPath) == AE_STATUS_SUCCESS) {
     417            7 :             return AE_STATUS_SUCCESS;
     418              :         }
     419            0 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "thread mode home path invalid use default path [%s].", soPath.c_str());
     420              :     }
     421              :     // get aicpu context
     422              :     aicpu::aicpuContext_t currentAicpuCtx;
     423           10 :     status = aicpu::aicpuGetContext(&currentAicpuCtx);
     424           10 :     if (status != aicpu::AICPU_ERROR_NONE) {
     425            1 :         AE_ERR_LOG(AE_MODULE_ID, "Get current ctx failed.");
     426            1 :         return AE_STATUS_INNER_ERROR;
     427              :     }
     428              :     // libtf_kernels.so and libaicpu_kernels.so and libcpu_kernels.so and libpt_kernels.so path from context
     429            9 :     soPath = AICPU_SO_ROOT_DIR;
     430            9 :     (void)soPath.append(std::to_string(aicpu::GetUniqueVfId())).append("/").append(AICPU_SO_UNCOMPRESS_DIR).append("/");
     431              : 
     432            9 :     return AE_STATUS_SUCCESS;
     433              : }
     434              : 
     435            9 : aeStatus_t MultiSoManager::BuildCustSoPath(std::string &soPath, const uint32_t uniqueVfId) const
     436              : {
     437              :     uint32_t runMode;
     438            9 :     const aicpu::status_t statusMode = aicpu::GetAicpuRunMode(runMode);
     439            9 :     if (statusMode != aicpu::AICPU_ERROR_NONE) {
     440            1 :         AE_ERR_LOG(AE_MODULE_ID, "Get current aicpu ctx failed.");
     441            1 :         return AE_STATUS_INNER_ERROR;
     442              :     }
     443              :     // dc
     444            8 :     if (runMode == aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
     445            1 :         soPath = CUST_USER_SO_PATH;
     446            1 :         SingleSoManager::GetCustSoPathByUniqueVfId(soPath, uniqueVfId);
     447            7 :     } else if (runMode == aicpu::AicpuRunMode::PROCESS_SOCKET_MODE) {
     448            3 :         const char_t * const custDirName = getenv("HOME");
     449            3 :         if (custDirName == nullptr) {
     450            1 :             AE_ERR_LOG(AE_MODULE_ID, "Get current dir name by HOME in socket_mode failed.");
     451            1 :             return AE_STATUS_INNER_ERROR;
     452              :         }
     453            2 :         soPath = custDirName;
     454            2 :         AE_RUN_INFO_LOG(AE_MODULE_ID, "Get soPath[%s] in socket_mode", soPath.c_str());
     455            2 :         SingleSoManager::GetCustSoPathByUniqueVfId(soPath, uniqueVfId);
     456              :     } else {
     457            4 :         const char_t * const curDirName = getenv("HOME");
     458            4 :         if (curDirName == nullptr) {
     459            2 :             AE_ERR_LOG(AE_MODULE_ID, "Get current home directory failed.");
     460            3 :             return AE_STATUS_INNER_ERROR;
     461              :         }
     462            2 :         const std::string dirName = curDirName;
     463            2 :         const size_t len = dirName.length();
     464            2 :         if ((len == 0LU) || (len >= static_cast<size_t>(PATH_MAX))) {
     465            1 :             AE_ERR_LOG(AE_MODULE_ID, "Length of current dir name %zu is invalid.", len);
     466            1 :             return AE_STATUS_INNER_ERROR;
     467              :         }
     468            1 :         soPath = dirName;
     469            1 :         if (soPath[soPath.size() - 1LU] != '/') {
     470            1 :             (void)soPath.append("/");
     471              :         }
     472            2 :     }
     473            4 :     return AE_STATUS_SUCCESS;
     474              : }
     475              : 
     476            8 : aeStatus_t MultiSoManager::GetCustSoPath(std::string &soPath) const
     477              : {
     478              :     // get aicpu context
     479              :     aicpu::aicpuContext_t currentAicpuCtx;
     480            8 :     const aicpu::status_t status = aicpu::aicpuGetContext(&currentAicpuCtx);
     481            8 :     if (status != aicpu::AICPU_ERROR_NONE) {
     482            1 :         AE_ERR_LOG(AE_MODULE_ID, "Get current ctx failed.");
     483            1 :         return AE_STATUS_INNER_ERROR;
     484              :     }
     485            7 :     const uint32_t uniqueVfId = aicpu::GetUniqueVfId();
     486              :     // minirc or ctrlcpu, cust so load in current user root path; else, so load in cust aicpu_sd thread
     487              :     // lhisi, so load path from env ASCEND_CUST_AICPU_KERNEL_PATH
     488            7 :     if (!custKernelPath_.empty()) {
     489            0 :         soPath = custKernelPath_;
     490              :     } else {
     491            7 :         const auto ret = BuildCustSoPath(soPath, uniqueVfId);
     492            7 :         if (ret != AE_STATUS_SUCCESS) {
     493            4 :             AE_ERR_LOG(AE_MODULE_ID, "BuildCustSoPath failed.");
     494            4 :             return ret;
     495              :         }
     496              :     }
     497            3 :     (void)soPath.append(CUSTOM_SO_DIR_NAME_PREFIX)
     498            3 :         .append(std::to_string(currentAicpuCtx.deviceId)).append("_")
     499            6 :         .append(std::to_string(uniqueVfId)).append("_")
     500            3 :         .append(std::to_string(static_cast<int32_t>(currentAicpuCtx.hostPid))).append("/");
     501            3 :     return AE_STATUS_SUCCESS;
     502              : }
     503              : 
     504            8 : aeStatus_t MultiSoManager::LoadSo(const aicpu::KernelType kernelType, const std::string &soName)
     505              : {
     506            8 :     SingleSoManager *soMgr = nullptr;
     507           16 :     return LoadSo(kernelType, soName, soMgr);
     508              : }
     509              : 
     510          133 : aeStatus_t MultiSoManager::LoadSo(const aicpu::KernelType kernelType,
     511              :                                   const std::string &soName, SingleSoManager *&soMgr)
     512              : {
     513          133 :     if (soName.empty()) {
     514            1 :         AE_ERR_LOG(AE_MODULE_ID, "So name is empty.");
     515            1 :         return AE_STATUS_BAD_PARAM;
     516              :     }
     517              : 
     518          132 :     if (!aicpu::IsCustAicpuSd())  {
     519          132 :         if ((runMode_ != aicpu::AicpuRunMode::THREAD_MODE) && ((kernelType == aicpu::KERNEL_TYPE_AICPU_CUSTOM) ||
     520              :             (kernelType == aicpu::KERNEL_TYPE_AICPU_CUSTOM_KFC))) {
     521            1 :             AE_ERR_LOG(AE_MODULE_ID, "runmode is not THREAD_MODE AND kernelType is [%u]", kernelType);
     522            1 :             return AE_STATUS_BAD_PARAM;
     523              :         }
     524              :     }
     525              : 
     526          131 :     AE_RW_LOCK_RD_LOCK(&rwLock_);
     527          131 :     auto soIter = soCacher_.find(soName);
     528          130 :     if ((soCacher_.end() != soIter) && (soIter->second != nullptr)) {
     529          117 :         soMgr = soIter->second;
     530          117 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     531          118 :         return AE_STATUS_SUCCESS;
     532              :     }
     533           13 :     AE_RW_LOCK_UN_LOCK(&rwLock_);
     534              : 
     535           13 :     AE_RW_LOCK_WR_LOCK(&rwLock_);
     536           13 :     soIter = soCacher_.find(soName);
     537           13 :     if ((soCacher_.end() != soIter) && (soIter->second != nullptr)) {
     538            0 :         soMgr = soIter->second;
     539            0 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     540            0 :         return AE_STATUS_SUCCESS;
     541              :     }
     542           13 :     const auto ret = CreateSingleSoMgr(kernelType, soName, soMgr);
     543           13 :     if (ret != AE_STATUS_SUCCESS) {
     544            8 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     545            8 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "CreateSingleSoMgr failed, soName[%s], ret[%u].", soName.c_str(), ret);
     546            8 :         return ret;
     547              :     }
     548            5 :     AE_RW_LOCK_UN_LOCK(&rwLock_);
     549            5 :     return AE_STATUS_SUCCESS;
     550              : }
     551              : 
     552           13 : aeStatus_t MultiSoManager::CreateSingleSoMgr(const aicpu::KernelType kernelType,
     553              :                                              const std::string &soName, SingleSoManager *&soMgr)
     554              : {
     555              :     // check so name
     556           13 :     if (soName.find_first_not_of(PATTERN_FOR_SO_NAME) != std::string::npos) {
     557            0 :         AE_ERR_LOG(AE_MODULE_ID, "So name %s is not invalid. Please check!", soName.c_str());
     558            0 :         return AE_STATUS_BAD_PARAM;
     559              :     }
     560              :     // get so real path
     561           13 :     std::string realSoPath;
     562           13 :     auto ret = GetSoPath(kernelType, soName, realSoPath);
     563           13 :     if (ret != AE_STATUS_SUCCESS) {
     564            1 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "GetSoPath failed, soName[%s], ret[%u].", soName.c_str(), ret);
     565            1 :         return ret;
     566              :     }
     567           12 :     std::string soFile(realSoPath);
     568           12 :     (void)soFile.append(soName);
     569           12 :     AE_INFO_LOG(AE_MODULE_ID, "soname[%s]", soFile.c_str());
     570              :     // This thread get the lock and create the new single so Manager
     571           12 :     SingleSoManager * const newSSoMngr = new(std::nothrow) SingleSoManager();
     572           12 :     AE_MEMORY_LOG(AE_MODULE_ID, "MallocMemory, func=new, size=%zu, purpose=SingleSoManager object",
     573              :         sizeof(SingleSoManager));
     574           12 :     if (newSSoMngr == nullptr) {
     575            0 :         AE_ERR_LOG(AE_MODULE_ID, "Create newSSoMngr ptr failed");
     576            0 :         return AE_STATUS_INNER_ERROR;
     577              :     }
     578           12 :     ret = newSSoMngr->Init(realSoPath, soFile);
     579           12 :     if (ret != AE_STATUS_SUCCESS) {
     580            7 :         AE_RUN_INFO_LOG(AE_MODULE_ID, "So does not exist, try to load at another path. currentSoFile=%s.", soFile.c_str());
     581            7 :         if (realSoPath != AICPU_SO_ROOT_DIR) {
     582              :             // try to load so from /usr/lib64/aicpu_kernel/
     583            7 :             std::string oriPath = realSoPath;
     584            7 :             realSoPath = AICPU_SO_ROOT_DIR;
     585            7 :             soFile = realSoPath + soName;
     586            7 :             ret = newSSoMngr->Init(realSoPath, soFile);
     587            7 :             if (ret != AE_STATUS_SUCCESS) {
     588            7 :                 ret = GetSoInHostPidPath(soName, oriPath, newSSoMngr, soFile);
     589              :             }
     590            7 :         }
     591              :     }
     592              : 
     593              :     // check init result
     594           12 :     if (ret != AE_STATUS_SUCCESS) {
     595            7 :         delete newSSoMngr;
     596            7 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Single so manager init failed, soFile is %s.", soFile.c_str());
     597            7 :         return ret;
     598              :     }
     599              :     // Cache it so that we can get it from cache next time.
     600            5 :     soCacher_[soName] = newSSoMngr;
     601            5 :     soMgr = newSSoMngr;
     602            5 :     AE_INFO_LOG(AE_MODULE_ID, "Loaded so successfully, soFile=%s.", soFile.c_str());
     603            5 :     return AE_STATUS_SUCCESS;
     604           13 : }
     605              : 
     606            1 : aeStatus_t MultiSoManager::CloseSo(const std::string &soName)
     607              : {
     608            1 :     if (soName.empty()) {
     609            0 :         AE_ERR_LOG(AE_MODULE_ID, "So name is empty.");
     610            0 :         return AE_STATUS_BAD_PARAM;
     611              :     }
     612              : 
     613            1 :     AE_RW_LOCK_WR_LOCK(&rwLock_);
     614            1 :     const auto iter = soCacher_.find(soName);
     615            1 :     if (iter != soCacher_.end()) {
     616            1 :         const SingleSoManager * const sSoMngr = iter->second;
     617            1 :         if (sSoMngr != nullptr) {
     618            1 :             delete sSoMngr;
     619              :         }
     620            1 :         (void)soCacher_.erase(iter);
     621              :     }
     622            1 :     AE_RW_LOCK_UN_LOCK(&rwLock_);
     623              : 
     624            1 :     return AE_STATUS_SUCCESS;
     625              : }
     626              : 
     627            7 : aeStatus_t MultiSoManager::GetSoInHostPidPath(const std::string &soName, std::string &oriPath,
     628              :                                               SingleSoManager * const newSSoMngr, std::string &soFile) const
     629              : {
     630              :     aicpu::aicpuContext_t currentAicpuCtx;
     631            7 :     const aicpu::status_t status = aicpu::aicpuGetContext(&currentAicpuCtx);
     632            7 :     if (status != aicpu::AICPU_ERROR_NONE) {
     633            0 :         AE_ERR_LOG(AE_MODULE_ID, "Get current ctx failed.");
     634            0 :         return AE_STATUS_INNER_ERROR;
     635              :     }
     636            7 :     oriPath.append(std::to_string(currentAicpuCtx.hostPid)).append("_").
     637            7 :         append(std::to_string(currentAicpuCtx.deviceId)).append("/");
     638            7 :     soFile = oriPath + soName;
     639            7 :     AE_RUN_INFO_LOG(AE_MODULE_ID, "So does not exist, try to load at another path. currentSoFile=%s.", 
     640              :                 soFile.c_str());
     641            7 :     return newSSoMngr->Init(oriPath, soFile);
     642              : }
     643              : }
        

Generated by: LCOV version 2.0-1