LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/ccu/ccu_device/ccu_component - ccu_component.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.8 % 604 506
Test Date: 2026-08-04 10:52:23 Functions: 88.2 % 51 45

            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 <cstdlib>
      12              : 
      13              : #include "ccu_component.h"
      14              : 
      15              : #include "exception_util.h"
      16              : #include "hccl_common_v2.h"
      17              : #include "ccu_api_exception.h"
      18              : #include "orion_adapter_rts.h"
      19              : #include "internal_exception.h"
      20              : #include "rdma_handle_manager.h"
      21              : 
      22              : #include "ccu_eid_info.h"
      23              : #include "ccu_res_specs.h"
      24              : 
      25              : #include "ccu_channel_mgr_v1.h"
      26              : #include "env_config.h"
      27              : #include "hccp_ctx_tp.h"
      28              : #include "hccp_tlv_hdc_manager.h"
      29              : 
      30              : namespace Hccl {
      31              : 
      32              : namespace {
      33              : constexpr uint32_t kLoopTpAttrSlAvailableBit = 18U;
      34              : constexpr uint32_t kLoopTpAttrBitmapSl = (1U << 10U);
      35              : constexpr uint8_t CCU_MAX_MISSION_NUM = 16;
      36              : 
      37            1 : static uint32_t SlValueAtRankInMask16(uint32_t mask, uint32_t rank)
      38              : {
      39            1 :     uint32_t seen = 0;
      40            8 :     for (uint32_t bit = 0; bit < 16U; ++bit) {
      41            8 :         if ((mask & (1U << bit)) != 0U) {
      42            1 :             if (seen == rank) {
      43            1 :                 return bit;
      44              :             }
      45            0 :             ++seen;
      46              :         }
      47              :     }
      48            0 :     return 0;
      49              : }
      50              : 
      51              : // 与 Next 侧环回 MakeLoopGetTpInfoParam(loopFirstTpLowestSl=true) 一致:首 TP + slBitmap 中最低档 SL → jetty qos
      52           26 : static uint8_t ResolveLoopJettyQosFromTpSl(RdmaHandle rdmaHandle, uint64_t tpHandle, uint32_t devPhyId)
      53              : {
      54           26 :     if (tpHandle == 0U) {
      55            1 :         return static_cast<uint8_t>(UB_QOS_DEFAULT);
      56              :     }
      57              : 
      58           25 :     struct TpAttr tpAttr {};
      59           25 :     uint32_t attrBitmap = (1U << kLoopTpAttrSlAvailableBit) | kLoopTpAttrBitmapSl;
      60           25 :     RequestHandle reqHandle = 0;
      61              :     const HcclResult startRet =
      62           25 :         HrtRaGetTpAttrAsync(devPhyId, rdmaHandle, tpHandle, attrBitmap, tpAttr, reqHandle);
      63           25 :     if (startRet == HcclResult::HCCL_E_NOT_SUPPORT) {
      64           72 :         HCCL_WARNING("[CcuComponent][ResolveLoopJettyQosFromTpSl] HrtRaGetTpAttrAsync not supported, "
      65              :             "use UB_QOS_DEFAULT.");
      66           24 :         return static_cast<uint8_t>(UB_QOS_DEFAULT);
      67              :     }
      68            1 :     if (startRet != HcclResult::HCCL_SUCCESS) {
      69            0 :         HCCL_WARNING("[CcuComponent][ResolveLoopJettyQosFromTpSl] HrtRaGetTpAttrAsync failed ret[%u], "
      70              :             "use UB_QOS_DEFAULT.", static_cast<uint32_t>(startRet));
      71            0 :         return static_cast<uint8_t>(UB_QOS_DEFAULT);
      72              :     }
      73              : 
      74            1 :     const uint16_t slMask = static_cast<uint16_t>(tpAttr.slBitmap);
      75            1 :     if (slMask == 0U) {
      76            0 :         HCCL_WARNING("[CcuComponent][ResolveLoopJettyQosFromTpSl] slBitmap empty, use UB_QOS_DEFAULT.");
      77            0 :         return static_cast<uint8_t>(UB_QOS_DEFAULT);
      78              :     }
      79            1 :     const uint32_t mappedSl = SlValueAtRankInMask16(slMask, 0U);
      80            1 :     return static_cast<uint8_t>(mappedSl & 0xFU);
      81              : }
      82              : } // namespace
      83              : 
      84              : constexpr uint16_t INVAILD_LOOP_CHANNEL_ID = 0xFFFF;
      85              : 
      86              : // 设置为0,分配数量由channelMgr决定,v1 默认1个
      87              : constexpr uint32_t LOOP_CHANNEL_USE_JETTY = 0;
      88              : constexpr uint32_t LOOP_CHANNEL_USE_SQSIZE = 16;
      89              : 
      90              : // 环回获取TP信息超时等待10s
      91              : constexpr uint32_t LOOP_CHANNEL_WAIT_TIMEOUT_MS = 10000;
      92              : // 环回获取TP信息间隔1ms
      93              : constexpr u32 ONE_MILLISECOND_OF_USLEEP         = 1000;
      94              : 
      95              : // 清理CKE批量申请大小
      96              : constexpr u32 MAX_CKE_DATA_ARRAY_SIZE = 8;
      97              : 
      98              : // 环境是A+X时,配置die0的MS交织粒度为1<<7 = 128
      99              : constexpr uint32_t MSID_CONFIG_AX_MAINBOARD = 7;
     100              : constexpr TpProtocol LOOP_JETTY_PROTOCOL = TpProtocol::TP; // 环回使用TP避免被环境link down阻塞
     101              : 
     102              : // 与 TpManager 缓存键一致:须与 RequestNewTpInfo / Deinit::ReleaseTpInfo 使用同一套 qos 与环回标志
     103           12 : static RaUbGetTpInfoParam MakeCcuLoopRaUbGetTpInfoParam(const IpAddress &locAddr, const IpAddress &rmtAddr)
     104              : {
     105           12 :     RaUbGetTpInfoParam p{};
     106           12 :     p.locAddr = locAddr;
     107           12 :     p.rmtAddr = rmtAddr;
     108           12 :     p.tpProtocol = LOOP_JETTY_PROTOCOL;
     109           12 :     p.qos = 0U;
     110           12 :     p.slLevelCount = 0U;
     111           12 :     p.loopFirstTpLowestSl = true;
     112           12 :     p.ccuLoopbackGetTpInfo = true;
     113           12 :     return p;
     114              : }
     115              : 
     116          272 : CcuComponent &CcuComponent::GetInstance(const int32_t deviceLogicId)
     117              : {
     118          338 :     static CcuComponent ccuComponent[MAX_MODULE_DEVICE_NUM + 1];
     119              : 
     120          272 :     if (deviceLogicId < 0 || static_cast<uint32_t>(deviceLogicId) > MAX_MODULE_DEVICE_NUM) {
     121            0 :         THROW<InvalidParamsException>("[CcuComponent][%s] failed, devLogicId[%d] should be less "
     122              :             "than %u.", __func__, deviceLogicId, MAX_MODULE_DEVICE_NUM);
     123              :     }
     124              : 
     125          272 :     ccuComponent[deviceLogicId].devLogicId = deviceLogicId;
     126          272 :     return ccuComponent[deviceLogicId];
     127              : }
     128              : 
     129           24 : void CcuComponent::PrintCcuMissionStatus(int32_t devLogicId) const
     130              : {
     131           24 :     uint16_t status = 0;
     132           72 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     133           48 :         if (!dieEnableFlags[dieId]) {
     134            0 :             HCCL_WARNING("[%s]devLogicId[%d], dieId[%u] is not enable, skip." , __func__, devLogicId, dieId);
     135            0 :             continue;
     136            0 :         }
     137           48 :         std::string missionStatus;
     138          816 :         for (uint8_t missionId = 0; missionId < CCU_MAX_MISSION_NUM; missionId++) {
     139          768 :             status = Hccl::CcuErrorHandler::GetCcuMissionContext(devLogicId, dieId, missionId).GetStatus();
     140          768 :             missionStatus += "missionId[" + std::to_string(missionId) + "]=status[" + std::to_string(status) + "] ";
     141              :         }
     142          144 :         HCCL_RUN_INFO("Init devLogicId[%d], dieId[%d], content[%s]", devLogicId, dieId, missionStatus.c_str());
     143           48 :     }
     144           24 : }
     145              : 
     146           18 : void CcuComponent::Init()
     147              : {
     148           18 :     std::lock_guard<std::mutex> _lock(innerMutex);
     149              : 
     150           18 :     if (ifInit) {
     151            5 :         return;
     152              :     }
     153              : 
     154           13 :     devPhyId = HrtGetDevicePhyIdByIndex(devLogicId);
     155           13 :     CheckDiesEnable();
     156           36 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     157           24 :         CleanDieCkes(dieId);
     158              :     }
     159           12 :     CreateCcuRmaBuffer();
     160           12 :     CreateResourceManagers();
     161           12 :     CreateLoopChannels();
     162           12 :     ConfigMsIdToken();
     163              :     // 打印最初的mission状态
     164           12 :     PrintCcuMissionStatus(devLogicId);
     165           12 :     SetTaskKill();
     166           12 :     SetTaskKillDone();
     167              :     // 打印taskKill恢复后的mission状态
     168           12 :     PrintCcuMissionStatus(devLogicId);
     169           12 :     ifInit = true;
     170           18 : }
     171              : // 资源清理
     172            2 : void CcuComponent::Deinit()
     173              : {
     174            2 :     std::lock_guard<std::mutex> _lock(innerMutex);
     175            2 :     ReleaseJettyRes();
     176              : 
     177            6 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     178            4 :         CleanDieCkes(dieId);
     179              :     }
     180              : 
     181            2 :     for (const auto &item : tpAttrInfoMap) {
     182            0 :         const auto &ipAddr = item.first;
     183            0 :         const auto &tpAttrInfo = item.second;
     184            0 :         const auto &tpInfoIter = tpInfoMap.find(ipAddr);
     185            0 :         if (tpInfoIter != tpInfoMap.end() && tpInfoIter->second.tpHandle != 0) {
     186            0 :             (void)TpManager::GetInstance(devLogicId)
     187            0 :                 .ReleaseTpAttr(tpInfoIter->second.tpHandle, tpAttrInfo);
     188              :         }
     189              :     }
     190            2 :     tpAttrInfoMap.clear();
     191              : 
     192            2 :     for (const auto &item : tpInfoMap) {
     193            0 :         const auto &ipAddr = item.first;
     194            0 :         const auto &tpInfo = item.second;
     195            0 :         (void)TpManager::GetInstance(devLogicId).ReleaseTpInfo(MakeCcuLoopRaUbGetTpInfoParam(ipAddr, ipAddr), tpInfo);
     196              :     }
     197              : 
     198            2 :     createdOutParamMap.clear();
     199            2 :     importedOutParamMap.clear();
     200            2 :     tpInfoMap.clear();
     201            2 :     psnMap.clear();
     202              : 
     203            2 :     loopFeIpAddrMap.clear();
     204            2 :     ccuRmaBufferMap.clear();
     205            2 :     localCcuRmaBufferMap.clear();
     206            2 :     additionalCcuRmaBufferMap.clear();
     207            6 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     208            4 :         channelMgrs[dieId] = nullptr;
     209            4 :         resAllocators[dieId] = nullptr;
     210            4 :         loopChannelIds[dieId] = INVAILD_LOOP_CHANNEL_ID;
     211              :     }
     212              : 
     213            2 :     ifInit = false;
     214            2 : }
     215              : 
     216           13 : void CcuComponent::CheckDiesEnable()
     217              : {
     218           13 :     ccuVersion = CcuResSpecifications::GetInstance(devLogicId).GetCcuVersion();
     219           39 :     HCCL_INFO("[CcuComponent][%s] ccu version[%s], devLogicId[%d].",
     220              :         __func__, ccuVersion.Describe().c_str(), devLogicId);
     221              : 
     222           13 :     std::array<bool, MAX_CCU_IODIE_NUM> dieDrvEnableFlags{false, false};
     223           13 :     bool allDieDisable = true;
     224           13 :     const auto &ccuResSpecs = CcuResSpecifications::GetInstance(devLogicId);
     225           39 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     226           26 :         dieEnableFlags[dieId] = false;
     227           26 :         (void)ccuResSpecs.GetDieEnableFlag(dieId, dieDrvEnableFlags[dieId]);
     228           26 :         ChooseLoopEid(dieDrvEnableFlags[dieId], dieId);
     229           26 :         allDieDisable = allDieDisable && !dieEnableFlags[dieId];
     230           26 :         if (!dieEnableFlags[dieId]) { // 调用接口失败时不会改变dieEnableFlags[i]
     231            6 :             HCCL_WARNING("[CcuComponent][%s] devLogicId[%d], dieId[%u] is not usable.",
     232              :                 __func__, devLogicId, dieId);
     233            2 :             continue;
     234            2 :         }
     235              : 
     236           72 :         HCCL_INFO("[CcuComponent][%s] devLogicId[%d] die[%u] is usable.",
     237              :             __func__, devLogicId, dieId);
     238              :     }
     239              : 
     240           13 :     if (allDieDisable) {
     241            1 :         THROW<CcuApiException>("[CcuComponent][%s] failed, because all dies are "
     242              :             "disabled, devLogicId[%d].", __func__, devLogicId);
     243              :     }
     244           12 : }
     245              : 
     246           26 : static HcclResult FindOneUsableEid(const uint32_t devLogicId, const uint8_t dieId, uint32_t &feId, IpAddress &ipAddr)
     247              : {
     248           26 :     std::vector<HrtDevEidInfo> eidInfoList;
     249           26 :     auto ret = CcuEidInfo::GetInstance(devLogicId).GetEidInfo(devLogicId, eidInfoList);
     250           32 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     251              :         HCCL_WARNING("[CcuComponent][%s] failed, devLogicId[%u], dieId[%u].",
     252              :             __func__, devLogicId, dieId),
     253              :         ret);
     254              : 
     255           24 :     std::string name;
     256           24 :     bool findFlag = false;
     257           24 :     u32 devPhyId = HrtGetDevicePhyIdByIndex(devLogicId);
     258              : 
     259              :     // 如果无法查询设备是否为uboe设备,报错退出
     260           24 :     CHK_RET(HrtGetUboeFlagEnable(devPhyId));
     261              : 
     262           24 :     auto &rdmaHandleMgr = RdmaHandleManager::GetInstance();
     263              :     // 当前结论,需要选择可以申请到Tp handle的eid
     264           36 :     for (auto &eidInfo : eidInfoList) {
     265              :         // 如果是UBOE设备,则跳过
     266           36 :         if (HrtCheckUboeSupported(eidInfo.devFeature) || (eidInfo.dieId != dieId)) {
     267           12 :             continue;
     268              :         }
     269           24 :         const RdmaHandle rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, eidInfo.ipAddress);
     270           24 :         const bool rtpEnable = rdmaHandleMgr.GetRtpEnable(rdmaHandle);
     271           24 :         if (rtpEnable) {
     272           24 :             feId = eidInfo.funcId;
     273           24 :             ipAddr = eidInfo.ipAddress;
     274           24 :             name = eidInfo.name;
     275           72 :             HCCL_RUN_INFO("[%s] rtpEnable[%d] dieId[%u] choose:"
     276              :                 "name[%s] feId[%u] ipAddr[%s], devLogicId[%u]",
     277              :                 __func__, rtpEnable, dieId, name.c_str(), feId,
     278              :                 ipAddr.Describe().c_str(), devLogicId);
     279           24 :             findFlag = true;
     280           24 :             break;
     281              :         }
     282              :     }
     283              : 
     284           24 :     if (!findFlag) {
     285            0 :         HCCL_RUN_INFO("[CcuComponent][%s] dieId[%u] doesn't have usable func ID, "
     286              :             "devLogicId[%u].", __func__, dieId, devLogicId);
     287            0 :         return HcclResult::HCCL_E_INTERNAL;
     288              :     }
     289              : 
     290           72 :     HCCL_INFO("[CcuComponent][%s] dieId[%u] choose: name[%s] feId[%u] ipAddr[%s], "
     291              :         "devLogicId[%u].", __func__, dieId, name.c_str(), feId,
     292              :         ipAddr.Describe().c_str(), devLogicId);
     293              : 
     294           24 :     return HcclResult::HCCL_SUCCESS;
     295           26 : }
     296              : 
     297           26 : void CcuComponent::ChooseLoopEid(bool &dieDrvEnableFlag, uint8_t dieId)
     298              : {
     299           26 :     if (!dieDrvEnableFlag) {
     300            2 :         return;
     301              :     }
     302              : 
     303           26 :     uint32_t feId = 0;
     304           26 :     IpAddress ipAddr = IpAddress();
     305           26 :     if (FindOneUsableEid(devLogicId, dieId, feId, ipAddr) != HcclResult::HCCL_SUCCESS) {
     306            6 :         HCCL_WARNING("[CcuComponent][%s] failed to find feId eid, but passed, "
     307              :             "devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId);
     308            2 :         return;
     309              :     }
     310              : 
     311           24 :     loopFeIpAddrMap[dieId] = {feId, ipAddr};
     312           24 :     dieEnableFlags[dieId] = dieDrvEnableFlag;
     313           72 :     HCCL_INFO("[CcuComponent][%s] die[%u] is enable", __func__, dieId);
     314              : }
     315              : 
     316           48 : HcclResult CcuComponent::GetLoopFeIpByDieId(const uint8_t dieId, uint32_t &feId, IpAddress &ipAddr)
     317              : {
     318           48 :     const auto &dieIter = loopFeIpAddrMap.find(dieId);
     319           48 :     CHK_PRT_RET(dieIter == loopFeIpAddrMap.end(),
     320              :         HCCL_WARNING("[CcuComponent][%s] failed, dieId[%u] doesn't have usable loop feId, "
     321              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     322              :         HcclResult::HCCL_E_NOT_FOUND);
     323              : 
     324           48 :     const auto &feIdIpAddr = dieIter->second;
     325           48 :     feId = feIdIpAddr.first;
     326           48 :     ipAddr = feIdIpAddr.second;
     327              : 
     328           48 :     return HcclResult::HCCL_SUCCESS;
     329              : }
     330              : 
     331           12 : void CcuComponent::CreateCcuRmaBuffer()
     332              : {
     333           12 :     auto &ccuResSpecs = CcuResSpecifications::GetInstance(devLogicId);
     334           12 :     auto &rdmaHandleMgr = RdmaHandleManager::GetInstance();
     335           36 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     336           24 :         if (!dieEnableFlags[dieId]) {
     337            0 :             continue;
     338              :         }
     339              : 
     340           24 :         uint32_t feId = 0;
     341           24 :         IpAddress ipAddr{};
     342           24 :         if (GetLoopFeIpByDieId(dieId, feId, ipAddr) != HcclResult::HCCL_SUCCESS) {
     343            0 :             continue;
     344              :         }
     345              : 
     346           24 :         uint64_t ccuResAddr = 0;
     347           24 :         (void)ccuResSpecs.GetResourceAddr(dieId, ccuResAddr);
     348           24 :         if (ccuResAddr == 0) {
     349            0 :             HCCL_WARNING("[CcuComponent][%s] failed, ccu resource space address[0] is invalid, "
     350              :                 "devLogicId[%d] dieId[%u]", __func__, devLogicId, dieId);
     351            0 :             continue;
     352            0 :         }
     353              : 
     354           24 :         const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
     355           24 :         CHECK_NULLPTR(rdmaHandle, StringFormat("[CcuComponent][%s] failed, rdmaHandle is nullptr, "
     356              :             "devLogicId[%d] dieId[%u]", __func__, devLogicId, dieId));
     357              : 
     358           24 :         std::array<CcuMemInfo, CCU_MEM_INFO_SIZE> memInfoList{};
     359           24 :         uint32_t count{0};
     360           24 :         ccuResSpecs.GetCcuMemInfoList(dieId, memInfoList.data(), count);
     361          456 :         for (uint32_t i = 0; i < count; i++) {
     362          432 :             if (memInfoList[i].memVa == ccuResAddr) {
     363           24 :                 const auto ccuBuffer = std::make_shared<Buffer>(ccuResAddr, memInfoList[i].memSize);
     364           24 :                 ccuRmaBufferMap.emplace(dieId, std::make_unique<LocalUbRmaBuffer>(ccuBuffer, rdmaHandle));
     365           24 :             } else {
     366          408 :                 const auto ccuBuffer = std::make_shared<Buffer>(memInfoList[i].memVa, memInfoList[i].memSize);
     367          408 :                 additionalCcuRmaBufferMap.emplace_back(std::make_unique<LocalUbRmaBuffer>(ccuBuffer, rdmaHandle));
     368          408 :             }
     369              :         }
     370           24 :         const auto ccuBuffer = std::make_shared<Buffer>(ccuResAddr, CCU_RESOURCE_SIZE);
     371              :         // 本端专用的buffer,具有整块内存的权限
     372           24 :         localCcuRmaBufferMap.emplace(dieId, std::make_unique<LocalUbRmaBuffer>(ccuBuffer, rdmaHandle));
     373           24 :     }
     374           12 : }
     375              : 
     376           24 : inline std::unique_ptr<CcuChannelMgr> CreateChannelMgrByVersion(const CcuVersion version,
     377              :     const uint32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId)
     378              : {
     379           24 :     switch (version) {
     380           24 :         case CcuVersion::CCU_V1:
     381           24 :             return std::make_unique<CcuChannelMgrV1>(devLogicId, dieId, devPhyId);
     382            0 :         default:
     383            0 :             break;
     384              :     }
     385              : 
     386            0 :     return nullptr;
     387              : }
     388              : 
     389           12 : void CcuComponent::CreateResourceManagers()
     390              : {
     391           36 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     392           24 :         if (!dieEnableFlags[dieId]) {
     393            0 :             continue;
     394              :         }
     395              : 
     396              :         std::unique_ptr<CcuChannelMgr> channelMgrPtr =
     397           24 :             CreateChannelMgrByVersion(ccuVersion, devLogicId, dieId, devPhyId);
     398           24 :         CHECK_NULLPTR(channelMgrPtr,
     399           48 :             StringFormat("[CcuComponent][%s] failed, ccu driver version[%s] is not expected, "
     400           48 :                 "devLogicId[%d] dieId[%u].", __func__, ccuVersion.Describe().c_str(),
     401              :                 devLogicId, dieId));
     402              : 
     403           24 :         channelMgrs[dieId] = std::move(channelMgrPtr);
     404           24 :         resAllocators[dieId] = std::make_unique<CcuResAllocator>(devLogicId, dieId);
     405           24 :     }
     406           12 : }
     407              : 
     408           12 : void CcuComponent::CreateLoopChannels()
     409              : {
     410           36 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     411           24 :         loopChannelIds[dieId] = INVAILD_LOOP_CHANNEL_ID;
     412              :     }
     413              : 
     414           36 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     415              :         // 失败抛异常处理,jetty资源跟随数据结构析构释放
     416           24 :         CHK_RET_THROW(InternalException,
     417              :             StringFormat("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].",
     418              :             __func__, devLogicId, dieId),
     419              :             CreateLoopChannel(dieId, loopChannelIds[dieId]));
     420              : 
     421           72 :         HCCL_INFO("[CcuComponent][%s] succeed, loop channel id[%u], "
     422              :             "devLogicId[%d], dieId[%u].", __func__, loopChannelIds[dieId],
     423              :             devLogicId, dieId);
     424              :     }
     425           12 : }
     426              : 
     427           24 : HcclResult CcuComponent::CreateLoopChannel(const uint8_t dieId, uint32_t &channelId)
     428              : {
     429           24 :     if (!dieEnableFlags[dieId]) {
     430            0 :         HCCL_WARNING("CcuComponent][%s] passed, dieId[%u] is not enable, "
     431              :             "devLogicId[%d].", __func__, dieId, devLogicId);
     432            0 :         return HcclResult::HCCL_SUCCESS;
     433              :     }
     434              : 
     435              :     // 对于单p或单die场景,可能设备或die不会配置eid,按成功处理不阻塞用例
     436           24 :     uint32_t feId = 0;
     437           24 :     IpAddress ipAddr{};
     438           24 :     if (GetLoopFeIpByDieId(dieId, feId, ipAddr) != HcclResult::HCCL_SUCCESS) {
     439            0 :         channelId = INVAILD_LOOP_CHANNEL_ID;
     440            0 :         HCCL_WARNING("[CcuComponent][%s] failed but passed, dieId[%u] doesn't have loop feId, "
     441              :             "devLogicId[%d].", __func__, dieId, devLogicId);
     442            0 :         return HcclResult::HCCL_SUCCESS;
     443              :     }
     444              : 
     445           24 :     std::vector<ChannelInfo> channelInfos; // 按jetty组分配
     446           24 :     const ChannelPara channelPara{feId, LOOP_CHANNEL_USE_JETTY, LOOP_CHANNEL_USE_SQSIZE};
     447           24 :     auto ret = channelMgrs[dieId]->Alloc(channelPara, channelInfos);
     448           24 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     449              :         HCCL_WARNING("[CcuComponent][%s] failed to alloc channel, "
     450              :             "devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId),
     451              :         ret);
     452              : 
     453           24 :     const auto &channelInfo = channelInfos[0]; // 环回只使用1个channel
     454           24 :     ret = CreateAndImportLoopJettys(dieId, ipAddr, channelInfo.jettyInfos);
     455           24 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     456              :         HCCL_WARNING("[CcuComponent][%s] failed to create or import loop jettys, "
     457              :             "devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId),
     458              :         ret);
     459              : 
     460           24 :     ret = ConfigLoopChannel(dieId, ipAddr, channelInfo);
     461           24 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     462              :         HCCL_WARNING("[CcuComponent][%s] failed to config the loop channel, "
     463              :             "devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId),
     464              :         ret);
     465              : 
     466           24 :     channelId = channelInfo.channelId;
     467           24 :     return HcclResult::HCCL_SUCCESS;
     468           24 : }
     469              : 
     470           26 : JettyImportCfg GetJettyImportCfg(const TpInfo &tpInfo, const uint32_t &psn)
     471              : {
     472           26 :     const TpHandle tpHandle = tpInfo.tpHandle;
     473           78 :     HCCL_INFO("[CcuComponent][%s] loop channel use tp handle[%llu] psn[%u].",
     474              :         __func__, tpHandle, psn);
     475              : 
     476           26 :     JettyImportCfg cfg = {};
     477           26 :     cfg.localTpHandle = tpHandle;
     478           26 :     cfg.remoteTpHandle = tpHandle;
     479           26 :     cfg.localPsn = psn;
     480           26 :     cfg.remotePsn = psn;
     481           26 :     cfg.protocol = LOOP_JETTY_PROTOCOL;
     482           26 :     return cfg;
     483              : }
     484              : 
     485           26 : HcclResult CcuComponent::CreateAndImportLoopJettys(const uint8_t dieId, const IpAddress &ipAddr,
     486              :     const vector<JettyInfo> &jettyInfos)
     487              : {
     488           26 :     Hccl::CqCreateInfo cqInfo{0};
     489           26 :     auto &rdmaHandleMgr = RdmaHandleManager::GetInstance();
     490           26 :     const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
     491           26 :     const auto jfcHandle = rdmaHandleMgr.GetJfcHandle(rdmaHandle, cqInfo, HrtUbJfcMode::CCU_POLL);
     492              : 
     493           26 :     const auto &rmaBufferIter = localCcuRmaBufferMap.find(dieId);
     494           26 :     CHK_PRT_RET(rmaBufferIter == localCcuRmaBufferMap.end(),
     495              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     496              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     497              :         HcclResult::HCCL_E_NOT_FOUND);
     498              : 
     499           26 :     const auto &ccuRmaBuffer = rmaBufferIter->second;
     500           26 :     const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
     501              :     
     502           26 :     const auto &tpInfo = GetTpInfo(ipAddr);
     503           26 :     const auto tpAttrInfo = GetLoopTpAttr(ipAddr, tpInfo.tpHandle);
     504           26 :     const uint8_t errTimeout = TpManager::CalcTaTimeout(tpAttrInfo);
     505              : 
     506           26 :     auto &createdVec = createdOutParamMap[dieId];
     507           26 :     auto &importedVec = importedOutParamMap[dieId];
     508              : 
     509           26 :     const TpInfo loopTpInfo = GetTpInfo(ipAddr);
     510           26 :     const uint8_t loopJettyQos = ResolveLoopJettyQosFromTpSl(rdmaHandle, loopTpInfo.tpHandle, devPhyId);
     511              : 
     512           52 :     for (const auto &jettyInfo : jettyInfos) {
     513           26 :         const auto jettyMode = HrtJettyMode::CCU_CCUM_CACHE; // 当前仅支持该模式
     514              :         HrtRaUbCreateJettyParam req{jfcHandle, jfcHandle, ccuBufTokenValue,
     515           26 :             0, jettyMode, jettyInfo.taJettyId, jettyInfo.sqBufVa,
     516           26 :             jettyInfo.sqBufSize, jettyInfo.wqeBBStartId, jettyInfo.sqDepth, errTimeout};
     517           26 :         req.qos = loopJettyQos;
     518           26 :         auto createdOutParam = HrtRaUbCreateJetty(rdmaHandle, req);
     519           26 :         createdVec.emplace_back(createdOutParam);
     520              : 
     521           26 :         const auto psn = GetPsn(ipAddr);
     522           26 :         const auto jettyImportCfg = GetJettyImportCfg(loopTpInfo, psn);
     523           26 :         const auto importedOutParam = RaUbTpImportJetty(rdmaHandle, createdOutParam.key,
     524              :             createdOutParam.keySize, ccuBufTokenValue, jettyImportCfg);
     525           26 :         importedVec.emplace_back(ImportOutParamPair{rdmaHandle, importedOutParam});
     526              :     }
     527              : 
     528           26 :     return HcclResult::HCCL_SUCCESS;
     529              : }
     530              : 
     531           12 : TpInfo CcuComponent::RequestNewTpInfo(const IpAddress &srcIpAddr, const IpAddress &dstIpAddr) const
     532              : {
     533           12 :     TpInfo tpInfo{};
     534              : 
     535           12 :     auto &tpManager = TpManager::GetInstance(devLogicId);
     536              :     // 与 Next `MakeLoopGetTpInfoParam` 对齐:环回与通信域 hcclQos 解耦;SL 由 GetTpAttr.slBitmap + loopFirstTpLowestSl 决定
     537           12 :     const RaUbGetTpInfoParam loopParam = MakeCcuLoopRaUbGetTpInfoParam(srcIpAddr, dstIpAddr);
     538              : 
     539           12 :     const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
     540           12 :     const auto startTime = std::chrono::steady_clock::now();
     541           12 :     auto ret = tpManager.GetTpInfo(loopParam, tpInfo);
     542           14 :     while (ret == HcclResult::HCCL_E_AGAIN) {
     543            2 :         ret = tpManager.GetTpInfo(loopParam, tpInfo);
     544            2 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     545            0 :             THROW<InternalException>("[CcuComponent][%s] failed, get tp info "
     546            0 :                 "timeout[%d ms], devLogicId[%d].", __func__, timeout, devLogicId);
     547              :         }
     548              :     }
     549              : 
     550           12 :     if (ret != HcclResult::HCCL_SUCCESS) {
     551            0 :         THROW<InternalException>("[CcuComponent][%s] failed, ret[%d], "
     552            0 :             "devLogicId[%d].", __func__, static_cast<int>(ret), devLogicId);
     553              :     }
     554              : 
     555           12 :     return tpInfo;
     556              : }
     557              : 
     558           52 : TpInfo CcuComponent::GetTpInfo(const IpAddress &ipAddr)
     559              : {
     560           52 :     const auto &srcIter = tpInfoMap.find(ipAddr);
     561              :     // 优先使用已经创建过的tpHandle
     562           52 :     if (srcIter == tpInfoMap.end()) {
     563           12 :         const auto &tpInfo = RequestNewTpInfo(ipAddr, ipAddr);
     564           12 :         tpInfoMap[ipAddr] = tpInfo;
     565           12 :         return tpInfo;
     566              :     }
     567              : 
     568           40 :     return srcIter->second;
     569              : }
     570              : 
     571           28 : TpAttrInfo CcuComponent::GetLoopTpAttr(const IpAddress &ipAddr, const TpHandle tpHandle)
     572              : {
     573           28 :     const auto &srcIter = tpAttrInfoMap.find(ipAddr);
     574           28 :     if (srcIter != tpAttrInfoMap.end()) {
     575           15 :         return srcIter->second;
     576              :     }
     577              : 
     578           13 :     auto &rdmaHandleMgr = RdmaHandleManager::GetInstance();
     579           13 :     const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
     580              : 
     581           13 :     constexpr uint32_t TP_ATTR_BITMAP = 0;
     582           13 :     const GetTpAttrParam tpAttrParam = {tpHandle, TP_ATTR_BITMAP};
     583              : 
     584           13 :     TpAttrInfo tpAttrInfo{};
     585           13 :     auto &tpMgr = TpManager::GetInstance(devLogicId);
     586           13 :     const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
     587           13 :     const auto startTime = std::chrono::steady_clock::now();
     588              : 
     589           13 :     HcclResult ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
     590           16 :     while (ret == HcclResult::HCCL_E_AGAIN) {
     591            3 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     592            0 :             THROW<InternalException>("[CcuComponent][%s] failed, get tp attr "
     593              :                 "timeout[%d ms], devLogicId[%d].", __func__, timeout, devLogicId);
     594              :         }
     595            3 :         ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
     596              :     }
     597              : 
     598           13 :     if (ret != HcclResult::HCCL_SUCCESS) {
     599            0 :         THROW<InternalException>("[CcuComponent][%s] failed, ret[%u], "
     600              :             "devLogicId[%d].", __func__, ret, devLogicId);
     601              :     }
     602              : 
     603           13 :     tpAttrInfoMap[ipAddr] = tpAttrInfo;
     604           13 :     return tpAttrInfo;
     605              : }
     606              : 
     607            0 : inline uint32_t GetRandomNum()
     608              : {
     609            0 :     uint32_t randNum = std::rand();
     610            0 :     return randNum;
     611              : }
     612              : 
     613           26 : uint32_t CcuComponent::GetPsn(const IpAddress &ipAddr)
     614              : {
     615           26 :     const auto &srcIter = psnMap.find(ipAddr);
     616           26 :     if (srcIter == psnMap.end()) {
     617           14 :         const auto psn = GetRandomNum();
     618           14 :         psnMap[ipAddr] = psn;
     619           14 :         return psn;
     620              :     }
     621              : 
     622           12 :     return srcIter->second;
     623              : }
     624              : 
     625           24 : HcclResult CcuComponent::ConfigLoopChannel(const uint8_t dieId, const IpAddress &ipAddr,
     626              :     const ChannelInfo &channelInfo)
     627              : {
     628           72 :     HCCL_INFO("[CcuComponent][%s] Create loop channel with another die's address, my dieId[%u]", __func__, dieId);
     629           24 :     auto rmaBufferIter = ccuRmaBufferMap.find(1 - dieId); // 需要配置另一die的rma buffer
     630           24 :     if (rmaBufferIter == ccuRmaBufferMap.end()) {
     631            0 :         HCCL_WARNING("[CcuComponent][%s] Another die is not enable, create loop channel with my die[%u]",
     632              :                     __func__, dieId);
     633            0 :         rmaBufferIter = ccuRmaBufferMap.find(dieId);
     634              :     }
     635           24 :     CHK_PRT_RET(rmaBufferIter == ccuRmaBufferMap.end(),
     636              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     637              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     638              :         HcclResult::HCCL_E_NOT_FOUND);
     639              : 
     640           24 :     const auto &ccuRmaBuffer = rmaBufferIter->second;
     641           24 :     const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
     642              : 
     643           24 :     ChannelCfg cfg{};
     644           24 :     cfg.channelId    = channelInfo.channelId;
     645           24 :     cfg.remoteEid = ipAddr.GetReverseEid();
     646           72 :     HCCL_INFO("[CcuComponent::ConfigLoopChannel] remoteEid=%s", cfg.remoteEid.Describe().c_str());
     647           24 :     cfg.tpn       = importedOutParamMap[dieId][0].second.tpn;
     648              : 
     649           24 :     cfg.remoteCcuVa   = ccuRmaBuffer->GetBuf()->GetAddr();
     650           24 :     cfg.memTokenId    = ccuRmaBuffer->GetTokenId();
     651           24 :     cfg.memTokenValue = ccuBufTokenValue;
     652              : 
     653           24 :     const auto &jettyInfos = channelInfo.jettyInfos;
     654           24 :     const auto &createdVec = createdOutParamMap[dieId];
     655           24 :     const uint32_t jettyNum = jettyInfos.size();
     656           48 :     for (uint32_t i = 0; i < jettyNum; i++) {
     657           24 :         cfg.jettyCfgs.emplace_back(JettyCfg{
     658           24 :             jettyInfos[i].jettyCtxId,
     659           24 :             createdVec[i].dbVa,
     660           24 :             createdVec[i].dbTokenId,
     661              :             ccuBufTokenValue
     662              :         });
     663              :     }
     664              : 
     665           24 :     CHK_PTR_NULL(channelMgrs[dieId]);
     666           24 :     return channelMgrs[dieId]->Config(cfg);
     667           24 : }
     668              : 
     669           12 : void CcuComponent::ConfigMsIdToken()
     670              : {
     671           12 :     bool isAX = CcuResSpecifications::GetInstance(devLogicId).GetAXFlag();
     672           12 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
     673           12 :     CHECK_NULLPTR(tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
     674              : 
     675           12 :     struct CustomChannelInfoIn  inBuff{};
     676           12 :     struct CustomChannelInfoOut outBuff{};
     677              : 
     678           36 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     679           24 :         const auto &dieIter = localCcuRmaBufferMap.find(dieId);
     680           24 :         if (dieIter == localCcuRmaBufferMap.end()) {
     681            0 :             HCCL_WARNING("[CcuComponent][%s] failed but passed, ccu rma buffer of die[%u] "
     682              :                 "is not existed, devLogicId[%d].", __func__, dieId, devLogicId);
     683            0 :             continue;
     684            0 :         }
     685           24 :         const auto &ccuRmaBuffer = dieIter->second;
     686           24 :         const uint32_t tokenId = ccuRmaBuffer->GetTokenId();
     687           24 :         const uint32_t tokenValue = ccuRmaBuffer->GetTokenValue();
     688           24 :         uint32_t msId = 0;
     689           24 :         CHK_RET_THROW(InternalException,
     690              :             StringFormat("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].",
     691              :                 __func__, devLogicId, dieId),
     692              :             CcuResSpecifications::GetInstance(devLogicId).GetMsId(dieId, msId));
     693              :         
     694           24 :         inBuff.op                    = CcuOpcodeType::CCU_U_OP_SET_MSID_TOKEN;
     695           24 :         inBuff.offsetStartIdx        = 0;
     696           24 :         inBuff.data.dataInfo.udieIdx = dieId;
     697              : 
     698           24 :         if (isAX && dieId == 0) { // A+X环境,给udie0配置新的交织粒度
     699            0 :             msId = MSID_CONFIG_AX_MAINBOARD;
     700              :         }
     701           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.msId       = msId;
     702           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.tokenId    = tokenId;
     703           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.tokenValue = tokenValue;
     704              : 
     705           24 :         HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     706              : 
     707           72 :         HCCL_INFO("[CcuComponent][%s] config MS ID token success, dieId[%u], msid[%u]",
     708              :             __func__, dieId, msId);
     709              :     }
     710           12 : }
     711              : 
     712            0 : HcclResult CcuComponent::GetCcuResourceSpaceBufInfo(const uint8_t dieId, uint64_t &addr,
     713              :     uint64_t &size) const
     714              : {
     715            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     716              : 
     717            0 :     auto res = ccuRmaBufferMap.find(dieId);
     718            0 :     CHK_PRT_RET(res == ccuRmaBufferMap.end(),
     719              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     720              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     721              :         HcclResult::HCCL_E_NOT_FOUND);
     722              : 
     723            0 :     const auto rawBuffer = res->second->GetBuf();
     724            0 :     addr = static_cast<uint64_t>(rawBuffer->GetAddr());
     725            0 :     size = static_cast<uint64_t>(rawBuffer->GetSize());
     726            0 :     return HcclResult::HCCL_SUCCESS;
     727              : }
     728              : 
     729            0 : HcclResult CcuComponent::GetCcuResourceSpaceTokenInfoForLocal(const uint8_t dieId, uint64_t &tokenId,
     730              :     uint64_t &tokenValue) const
     731              : {
     732            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     733              : 
     734            0 :     auto res = localCcuRmaBufferMap.find(dieId);
     735            0 :     CHK_PRT_RET(res == localCcuRmaBufferMap.end(),
     736              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     737              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     738              :         HcclResult::HCCL_E_NOT_FOUND);
     739              : 
     740            0 :     const auto &ccuRmaBuffer = res->second;
     741            0 :     tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
     742            0 :     tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
     743            0 :     return HcclResult::HCCL_SUCCESS;
     744              : }
     745              : 
     746            0 : HcclResult CcuComponent::GetCcuResourceSpaceTokenInfo(const uint8_t dieId, uint64_t &tokenId,
     747              :     uint64_t &tokenValue) const
     748              : {
     749            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     750              : 
     751            0 :     auto res = ccuRmaBufferMap.find(dieId);
     752            0 :     CHK_PRT_RET(res == ccuRmaBufferMap.end(),
     753              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     754              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     755              :         HcclResult::HCCL_E_NOT_FOUND);
     756              : 
     757            0 :     const auto &ccuRmaBuffer = res->second;
     758            0 :     tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
     759            0 :     tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
     760            0 :     return HcclResult::HCCL_SUCCESS;
     761              : }
     762              : 
     763            5 : HcclResult CcuComponent::AllocChannels(const uint8_t dieId, const ChannelPara &channelPara,
     764              :     std::vector<ChannelInfo> &channelInfos)
     765              : {
     766            8 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     767              : 
     768            4 :     CHK_PTR_NULL(channelMgrs[dieId]);
     769            4 :     auto ret = channelMgrs[dieId]->Alloc(channelPara, channelInfos);
     770            4 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     771              :         HCCL_WARNING("[CcuComponent][%s] failed, feId[%u], devLogicId[%d], dieId[%u].",
     772              :             __func__, channelPara.feId, devLogicId, dieId),
     773              :         ret);
     774              : 
     775            4 :     return HcclResult::HCCL_SUCCESS;
     776              : }
     777              : 
     778            6 : HcclResult CcuComponent::ConfigChannel(const uint8_t dieId, const ChannelCfg &cfg)
     779              : {
     780            6 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     781              : 
     782            6 :     uint32_t channelId = cfg.channelId;
     783            9 :     CHK_PRT_RET(channelId == loopChannelIds[dieId],
     784              :         HCCL_WARNING("[CcuComponent][%s] failed, refused to config loop channel[%u], "
     785              :             "devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId, dieId),
     786              :         HcclResult::HCCL_E_PARA);
     787              : 
     788            5 :     CHK_PTR_NULL(channelMgrs[dieId]);
     789            5 :     auto ret = channelMgrs[dieId]->Config(cfg);
     790           14 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     791              :         HCCL_WARNING("[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].",
     792              :             __func__, channelId, devLogicId, dieId),
     793              :         ret);
     794              : 
     795            2 :     return HcclResult::HCCL_SUCCESS;
     796              : }
     797              : 
     798            4 : HcclResult CcuComponent::ReleaseChannel(const uint8_t dieId, const uint32_t channelId)
     799              : {
     800            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     801            7 :     CHK_PRT_RET(channelId == loopChannelIds[dieId],
     802              :         HCCL_WARNING("[CcuComponent][%s] failed, refused to release loop channel[%u], "
     803              :             "devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId, dieId),
     804              :         HcclResult::HCCL_E_PARA);
     805              : 
     806            3 :     CHK_PTR_NULL(channelMgrs[dieId]);
     807            3 :     auto ret = channelMgrs[dieId]->Release(channelId);
     808            6 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     809              :         HCCL_WARNING("[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].",
     810              :             __func__, channelId, devLogicId, dieId),
     811              :         ret);
     812              : 
     813            2 :     return HcclResult::HCCL_SUCCESS;
     814              : }
     815              : 
     816            4 : HcclResult CcuComponent::GetLoopChannelId(const uint8_t srcDieId, const uint8_t dstDieId,
     817              :     uint32_t &channelId) const
     818              : {
     819            4 :     channelId = INVAILD_LOOP_CHANNEL_ID; // 允许die未启用时查询环回channelId
     820            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, srcDieId, {true, true}));
     821            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, dstDieId, {true, true}));
     822              : 
     823            4 :     CHK_PRT_RET(loopChannelIds[srcDieId] == INVAILD_LOOP_CHANNEL_ID, // 环回channel每个die共用1个
     824              :         HCCL_WARNING("[CcuComponent][%s] failed, invalid loop channel id, "
     825              :             "devLogicId[%d], srcDieId[%u].", __func__, devLogicId, srcDieId),
     826              :         HcclResult::HCCL_E_INTERNAL);
     827              : 
     828            4 :     channelId = loopChannelIds[srcDieId];
     829            4 :     return HcclResult::HCCL_SUCCESS;
     830              : }
     831              : 
     832           34 : HcclResult CcuComponent::AllocRes(const uint8_t dieId, const ResType resType, const uint32_t num,
     833              :     const bool consecutive, vector<ResInfo> &resInfos)
     834              : {
     835           34 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     836              : 
     837           34 :     CHK_PTR_NULL(resAllocators[dieId]);
     838           34 :     auto ret = resAllocators[dieId]->Alloc(resType, num, consecutive, resInfos);
     839           37 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     840              :         HCCL_WARNING("[CcuComponent][%s] failed, resType[%s], num[%u], devLogicId[%d], dieId[%u].",
     841              :             __func__, resType.Describe().c_str(), num, devLogicId, dieId),
     842              :         ret);
     843              : 
     844           33 :     return HcclResult::HCCL_SUCCESS;
     845              : }
     846              : 
     847            9 : HcclResult CcuComponent::ReleaseRes(const uint8_t dieId, const ResType resType, const uint32_t startId,
     848              :     const uint32_t num)
     849              : {
     850            9 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     851              : 
     852            9 :     CHK_PTR_NULL(resAllocators[dieId]);
     853            9 :     auto ret = resAllocators[dieId]->Release(resType, startId, num);
     854            9 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     855              :         HCCL_WARNING("[CcuComponent][%s] failed, resType[%s], startId[%u], num[%u], "
     856              :             "devLogicId[%d], dieId[%u].", __func__, resType.Describe().c_str(),
     857              :             startId, num, devLogicId, dieId),
     858              :         ret);
     859              : 
     860            9 :     return HcclResult::HCCL_SUCCESS;
     861              : }
     862              : 
     863            0 : uint32_t CcuComponent::GetInsConsecutiveRemainSize(const uint8_t dieId) const
     864              : {
     865            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     866            0 :     if (resAllocators[dieId] == nullptr) return 0;
     867            0 :     return resAllocators[dieId]->GetConsecutiveRemainSize(ResType::INS);
     868              : }
     869              : 
     870            7 : HcclResult CcuComponent::AllocIns(const uint8_t dieId, const uint32_t num, ResInfo &insInfo)
     871              : {
     872           10 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     873            6 :     CHK_PTR_NULL(resAllocators[dieId]);
     874              : 
     875            6 :     vector<ResInfo> resInfos;
     876            6 :     auto ret = resAllocators[dieId]->Alloc(ResType::INS, num, true, resInfos);
     877           15 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     878              :         HCCL_WARNING("[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].",
     879              :             __func__, num, devLogicId, dieId),
     880              :         ret);
     881              : 
     882            3 :     insInfo = resInfos[0]; // 申请连续资源只会有一份
     883            3 :     return HcclResult::HCCL_SUCCESS;
     884            6 : }
     885              : 
     886            4 : HcclResult CcuComponent::ReleaseIns(const uint8_t dieId, const ResInfo &insInfo)
     887              : {
     888            7 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     889            3 :     CHK_PTR_NULL(resAllocators[dieId]);
     890              : 
     891            3 :     auto ret = resAllocators[dieId]->Release(ResType::INS, insInfo.startId, insInfo.num);
     892            3 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     893              :         HCCL_WARNING("[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].",
     894              :             __func__, insInfo.Describe().c_str(), devLogicId, dieId),
     895              :         ret);
     896              : 
     897            3 :     return HcclResult::HCCL_SUCCESS;
     898              : }
     899              : 
     900          184 : HcclResult CcuComponent::AllocCke(const uint8_t dieId, const uint32_t num, vector<ResInfo> &ckeInfos)
     901              : {
     902          715 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     903            7 :     CHK_PTR_NULL(resAllocators[dieId]);
     904              : 
     905            7 :     auto ret = resAllocators[dieId]->Alloc(ResType::CKE, num, false, ckeInfos);
     906           16 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     907              :         HCCL_WARNING("[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].",
     908              :             __func__, num, devLogicId, dieId),
     909              :         ret);
     910              : 
     911            4 :     return HcclResult::HCCL_SUCCESS;
     912              : }
     913              : 
     914           30 : HcclResult CcuComponent::ReleaseCke(const uint8_t dieId, const vector<ResInfo> &ckeInfos)
     915              : {
     916           99 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     917            7 :     CHK_PTR_NULL(resAllocators[dieId]);
     918              : 
     919           12 :     for (auto &ckeInfo : ckeInfos) {
     920            7 :         auto ret = resAllocators[dieId]->Release(ResType::CKE, ckeInfo.startId, ckeInfo.num);
     921           13 :         CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     922              :             HCCL_WARNING("[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].",
     923              :                 __func__, ckeInfo.Describe().c_str(), devLogicId, dieId),
     924              :             ret);
     925              :     }
     926              : 
     927            5 :     return HcclResult::HCCL_SUCCESS;
     928              : }
     929              : 
     930            7 : HcclResult CcuComponent::AllocXn(const uint8_t dieId, const uint32_t num, vector<ResInfo> &xnInfos)
     931              : {
     932           10 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     933            6 :     CHK_PTR_NULL(resAllocators[dieId]);
     934              : 
     935            6 :     auto ret = resAllocators[dieId]->Alloc(ResType::XN, num, false, xnInfos);
     936           15 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     937              :         HCCL_WARNING("[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].",
     938              :             __func__, num, devLogicId, dieId),
     939              :         ret);
     940              : 
     941            3 :     return HcclResult::HCCL_SUCCESS;
     942              : }
     943              : 
     944            4 : HcclResult CcuComponent::ReleaseXn(const uint8_t dieId, const vector<ResInfo> &xnInfos)
     945              : {
     946            7 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     947            3 :     CHK_PTR_NULL(resAllocators[dieId]);
     948              : 
     949            6 :     for (auto &xnInfo : xnInfos) {
     950            3 :         auto ret = resAllocators[dieId]->Release(ResType::XN, xnInfo.startId, xnInfo.num);
     951            3 :         CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     952              :             HCCL_WARNING("[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].",
     953              :                 __func__, xnInfo.Describe().c_str(), devLogicId, dieId),
     954              :             ret);
     955              :     }
     956              : 
     957            3 :     return HcclResult::HCCL_SUCCESS;
     958              : }
     959              : 
     960              : // 以下接口用于n秒快恢与TaskException
     961           29 : HcclResult CcuComponent::CleanDieCkes(const uint8_t dieId) const
     962              : {
     963           29 :     CHK_PRT_RET(dieId >= MAX_CCU_IODIE_NUM,
     964              :         HCCL_WARNING("[CcuComponent][%s] failed, dieId[%u] is invalid, shoudle be in [0-%u), devLogicId[%d].",
     965              :             __func__, dieId, MAX_CCU_IODIE_NUM, devLogicId),
     966              :         HcclResult::HCCL_E_PARA);
     967              : 
     968           29 :     if (!dieEnableFlags[dieId]) {
     969            4 :         return HcclResult::HCCL_SUCCESS;
     970              :     }
     971              :     
     972           25 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
     973           25 :     CHK_PTR_NULL(tlvHandle);
     974           25 :     CustomChannelInfoIn  inBuff{};
     975           25 :     CustomChannelInfoOut outBuff{};
     976              : 
     977              :     // 设置操作码和数据
     978           25 :     uint32_t ckeNum = 0;
     979           25 :     CHK_RET(CcuResSpecifications::GetInstance(devLogicId).GetCkeNum(dieId, ckeNum));
     980           75 :     HCCL_INFO("[CcuComponent][CleanAllCke]Nsrecovery devLogicId[%d], dieId[%u] ckeNum[%u].",
     981              :         devLogicId, dieId, ckeNum);
     982              :     
     983           25 :     inBuff.op                          = CcuOpcodeType::CCU_U_OP_SET_CKE;
     984           25 :     inBuff.data.dataInfo.udieIdx       = dieId;
     985              :     // 接口限制,目前方案每次最多清理8个cke,超过8个时分多次清理
     986         3225 :     for (uint32_t startIdx = 0; startIdx < ckeNum; startIdx += MAX_CKE_DATA_ARRAY_SIZE) {
     987         3200 :         inBuff.data.dataInfo.dataArraySize = std::min(ckeNum - startIdx, MAX_CKE_DATA_ARRAY_SIZE);
     988         3200 :         inBuff.data.dataInfo.dataLen       = sizeof(CcuDataByte8) * inBuff.data.dataInfo.dataArraySize;
     989         3200 :         inBuff.offsetStartIdx              = startIdx;
     990         3200 :         HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     991              :     }
     992              : 
     993           25 :     return HcclResult::HCCL_SUCCESS;
     994              : }
     995              : 
     996           26 : void CcuComponent::SetProcess(CcuOpcodeType opCode) const
     997              : {
     998           26 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
     999           26 :     CHECK_NULLPTR(tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
    1000              : 
    1001           26 :     struct CustomChannelInfoIn  inBuff;
    1002           26 :     struct CustomChannelInfoOut outBuff;
    1003              : 
    1004           26 :     inBuff.op = opCode;
    1005           78 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
    1006           52 :         if (!dieEnableFlags[dieId]) {
    1007            0 :             HCCL_WARNING("[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] is not enable,"
    1008              :                 "skip SetProcess.", devLogicId, dieId);
    1009            0 :             continue;
    1010            0 :         }
    1011          156 :         HCCL_INFO("[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] start.", devLogicId, dieId);
    1012           52 :         inBuff.data.dataInfo.udieIdx = dieId;
    1013           52 :         HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
    1014              :     }
    1015           26 : }
    1016              : 
    1017           13 : HcclResult CcuComponent::SetTaskKill()
    1018              : {
    1019           13 :     std::lock_guard<std::mutex> _lock(taskKillMutex_);
    1020              : 
    1021           13 :     if (status == CcuTaskKillStatus::INVALID) {
    1022           12 :         status = CcuTaskKillStatus::INIT;
    1023              :     }
    1024              : 
    1025           13 :     if (status == CcuTaskKillStatus::TASK_KILL) {
    1026            0 :         HCCL_INFO("No need to set task kill, state = %u, devLogicId = %u", status, devLogicId);
    1027            0 :         return HcclResult::HCCL_SUCCESS;
    1028              :     }
    1029              : 
    1030           13 :     if (status != CcuTaskKillStatus::INIT) {
    1031            0 :         HCCL_ERROR("[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1032              :             "state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1033            0 :         return HcclResult::HCCL_E_INTERNAL;
    1034              :     }
    1035              : 
    1036           13 :     SetProcess(CcuOpcodeType::CCU_U_OP_SET_TASKKILL);
    1037           13 :     status = CcuTaskKillStatus::TASK_KILL;
    1038           39 :     HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1039           13 :     return HcclResult::HCCL_SUCCESS;
    1040           13 : }
    1041              : 
    1042           13 : HcclResult CcuComponent::SetTaskKillDone()
    1043              : {
    1044           13 :     std::lock_guard<std::mutex> _lock(taskKillMutex_);
    1045              : 
    1046           13 :     if (status == CcuTaskKillStatus::INVALID) {
    1047            0 :         HCCL_ERROR("[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1048              :             "state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1049            0 :         return HcclResult::HCCL_E_INTERNAL;
    1050              :     }
    1051              : 
    1052           13 :     if (status == CcuTaskKillStatus::INIT) {
    1053            0 :         HCCL_INFO("No need to set task kill done, state = %u, devLogicId = %u", status, devLogicId);
    1054            0 :         return HcclResult::HCCL_SUCCESS;
    1055              :     }
    1056              : 
    1057           13 :     if (status != CcuTaskKillStatus::TASK_KILL) {
    1058            0 :         HCCL_ERROR("[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1059              :             "state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1060            0 :         return HcclResult::HCCL_E_INTERNAL;
    1061              :     }
    1062              : 
    1063           13 :     SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
    1064           13 :     status = CcuTaskKillStatus::INIT;
    1065           39 :     HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d", __func__, status, devLogicId);
    1066           13 :     return HcclResult::HCCL_SUCCESS;
    1067           13 : }
    1068              : 
    1069            0 : HcclResult CcuComponent::CleanTaskKillState() const
    1070              : {
    1071            0 :     SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
    1072            0 :     return HcclResult::HCCL_SUCCESS;
    1073              : }
    1074              : 
    1075            2 : const std::array<bool, MAX_CCU_IODIE_NUM> &CcuComponent::GetDieEnableFlags() const
    1076              : {
    1077            2 :     return dieEnableFlags;
    1078              : }
    1079              : 
    1080           81 : CcuComponent::~CcuComponent()
    1081              : {
    1082           81 :     DECTOR_TRY_CATCH("CcuComponent", ReleaseJettyRes());
    1083           81 : }
    1084              : 
    1085           83 : void CcuComponent::ReleaseJettyRes()
    1086              : {
    1087           83 :     UnimportAllJetty();
    1088           83 :     DestroyAllJetty();
    1089              :     // HrtRaUbLocalMemReg 跟随 LocalUbRmaBuffer 析构时释放
    1090              :     // 环回channel不需要手动释放,channelMgr跟随CcuComponent释放
    1091           83 : }
    1092              : 
    1093           83 : void CcuComponent::UnimportAllJetty()
    1094              : {
    1095              :     // tpInfo不需要主动释放,因为CcuComponent生命周期与TpManager一致
    1096          109 :     for (auto &importedVec : importedOutParamMap) {
    1097           52 :         for (auto &paramPair : importedVec.second) {
    1098           26 :             const auto rdmaHandle = paramPair.first;
    1099           26 :             const auto remoteJettyHandle = paramPair.second.handle;
    1100           26 :             if (rdmaHandle != nullptr && remoteJettyHandle != 0) {
    1101            0 :                 paramPair.second.handle = 0;
    1102            0 :                 HrtRaUbUnimportJetty(rdmaHandle, remoteJettyHandle);
    1103              :             }
    1104              :         }
    1105              :     }
    1106              : 
    1107           83 :     importedOutParamMap.clear();
    1108           83 : }
    1109              : 
    1110           83 : void CcuComponent::DestroyAllJetty()
    1111              : {
    1112          109 :     for (auto &createdVec : createdOutParamMap) {
    1113           52 :         for (auto &param : createdVec.second) {
    1114           26 :             const auto jettyHandle = param.handle;
    1115           26 :             if (jettyHandle != 0) {
    1116            0 :                 param.handle = 0; 
    1117            0 :                 HrtRaUbDestroyJetty(jettyHandle);
    1118              :             }
    1119              :         }
    1120              :     }
    1121           83 :     createdOutParamMap.clear();
    1122           83 : }
    1123              : 
    1124              : }; // namespace Hccl
        

Generated by: LCOV version 2.0-1