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: 84.4 % 601 507
Test Date: 2026-07-28 12:11:00 Functions: 90.0 % 50 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           26 :     const auto tokenIdHandle = ccuRmaBuffer->GetTokenIdHandle();
     502              :     
     503           26 :     const auto &tpInfo = GetTpInfo(ipAddr);
     504           26 :     const auto tpAttrInfo = GetLoopTpAttr(ipAddr, tpInfo.tpHandle);
     505           26 :     const uint8_t errTimeout = TpManager::CalcTaTimeout(tpAttrInfo);
     506              : 
     507           26 :     auto &createdVec = createdOutParamMap[dieId];
     508           26 :     auto &importedVec = importedOutParamMap[dieId];
     509              : 
     510           26 :     const TpInfo loopTpInfo = GetTpInfo(ipAddr);
     511           26 :     const uint8_t loopJettyQos = ResolveLoopJettyQosFromTpSl(rdmaHandle, loopTpInfo.tpHandle, devPhyId);
     512              : 
     513           52 :     for (const auto &jettyInfo : jettyInfos) {
     514           26 :         const auto jettyMode = HrtJettyMode::CCU_CCUM_CACHE; // 当前仅支持该模式
     515              :         HrtRaUbCreateJettyParam req{jfcHandle, jfcHandle, ccuBufTokenValue,
     516           26 :             tokenIdHandle, jettyMode, jettyInfo.taJettyId, jettyInfo.sqBufVa,
     517           26 :             jettyInfo.sqBufSize, jettyInfo.wqeBBStartId, jettyInfo.sqDepth, errTimeout};
     518           26 :         req.qos = loopJettyQos;
     519           26 :         auto createdOutParam = HrtRaUbCreateJetty(rdmaHandle, req);
     520           26 :         createdVec.emplace_back(createdOutParam);
     521              : 
     522           26 :         const auto psn = GetPsn(ipAddr);
     523           26 :         const auto jettyImportCfg = GetJettyImportCfg(loopTpInfo, psn);
     524           26 :         const auto importedOutParam = RaUbTpImportJetty(rdmaHandle, createdOutParam.key,
     525              :             createdOutParam.keySize, ccuBufTokenValue, jettyImportCfg);
     526           26 :         importedVec.emplace_back(ImportOutParamPair{rdmaHandle, importedOutParam});
     527              :     }
     528              : 
     529           26 :     return HcclResult::HCCL_SUCCESS;
     530              : }
     531              : 
     532           12 : TpInfo CcuComponent::RequestNewTpInfo(const IpAddress &srcIpAddr, const IpAddress &dstIpAddr) const
     533              : {
     534           12 :     TpInfo tpInfo{};
     535              : 
     536           12 :     auto &tpManager = TpManager::GetInstance(devLogicId);
     537              :     // 与 Next `MakeLoopGetTpInfoParam` 对齐:环回与通信域 hcclQos 解耦;SL 由 GetTpAttr.slBitmap + loopFirstTpLowestSl 决定
     538           12 :     const RaUbGetTpInfoParam loopParam = MakeCcuLoopRaUbGetTpInfoParam(srcIpAddr, dstIpAddr);
     539              : 
     540           12 :     const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
     541           12 :     const auto startTime = std::chrono::steady_clock::now();
     542           12 :     auto ret = tpManager.GetTpInfo(loopParam, tpInfo);
     543           14 :     while (ret == HcclResult::HCCL_E_AGAIN) {
     544            2 :         ret = tpManager.GetTpInfo(loopParam, tpInfo);
     545            2 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     546            0 :             THROW<InternalException>("[CcuComponent][%s] failed, get tp info "
     547            0 :                 "timeout[%d ms], devLogicId[%d].", __func__, timeout, devLogicId);
     548              :         }
     549              :     }
     550              : 
     551           12 :     if (ret != HcclResult::HCCL_SUCCESS) {
     552            0 :         THROW<InternalException>("[CcuComponent][%s] failed, ret[%d], "
     553            0 :             "devLogicId[%d].", __func__, static_cast<int>(ret), devLogicId);
     554              :     }
     555              : 
     556           12 :     return tpInfo;
     557              : }
     558              : 
     559           52 : TpInfo CcuComponent::GetTpInfo(const IpAddress &ipAddr)
     560              : {
     561           52 :     const auto &srcIter = tpInfoMap.find(ipAddr);
     562              :     // 优先使用已经创建过的tpHandle
     563           52 :     if (srcIter == tpInfoMap.end()) {
     564           12 :         const auto &tpInfo = RequestNewTpInfo(ipAddr, ipAddr);
     565           12 :         tpInfoMap[ipAddr] = tpInfo;
     566           12 :         return tpInfo;
     567              :     }
     568              : 
     569           40 :     return srcIter->second;
     570              : }
     571              : 
     572           28 : TpAttrInfo CcuComponent::GetLoopTpAttr(const IpAddress &ipAddr, const TpHandle tpHandle)
     573              : {
     574           28 :     const auto &srcIter = tpAttrInfoMap.find(ipAddr);
     575           28 :     if (srcIter != tpAttrInfoMap.end()) {
     576           15 :         return srcIter->second;
     577              :     }
     578              : 
     579           13 :     auto &rdmaHandleMgr = RdmaHandleManager::GetInstance();
     580           13 :     const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
     581              : 
     582           13 :     constexpr uint32_t TP_ATTR_BITMAP = 0;
     583           13 :     const GetTpAttrParam tpAttrParam = {tpHandle, TP_ATTR_BITMAP};
     584              : 
     585           13 :     TpAttrInfo tpAttrInfo{};
     586           13 :     auto &tpMgr = TpManager::GetInstance(devLogicId);
     587           13 :     const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
     588           13 :     const auto startTime = std::chrono::steady_clock::now();
     589              : 
     590           13 :     HcclResult ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
     591           16 :     while (ret == HcclResult::HCCL_E_AGAIN) {
     592            3 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     593            0 :             THROW<InternalException>("[CcuComponent][%s] failed, get tp attr "
     594              :                 "timeout[%d ms], devLogicId[%d].", __func__, timeout, devLogicId);
     595              :         }
     596            3 :         ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
     597              :     }
     598              : 
     599           13 :     if (ret != HcclResult::HCCL_SUCCESS) {
     600            0 :         THROW<InternalException>("[CcuComponent][%s] failed, ret[%u], "
     601              :             "devLogicId[%d].", __func__, ret, devLogicId);
     602              :     }
     603              : 
     604           13 :     tpAttrInfoMap[ipAddr] = tpAttrInfo;
     605           13 :     return tpAttrInfo;
     606              : }
     607              : 
     608            0 : inline uint32_t GetRandomNum()
     609              : {
     610            0 :     uint32_t randNum = std::rand();
     611            0 :     return randNum;
     612              : }
     613              : 
     614           26 : uint32_t CcuComponent::GetPsn(const IpAddress &ipAddr)
     615              : {
     616           26 :     const auto &srcIter = psnMap.find(ipAddr);
     617           26 :     if (srcIter == psnMap.end()) {
     618           14 :         const auto psn = GetRandomNum();
     619           14 :         psnMap[ipAddr] = psn;
     620           14 :         return psn;
     621              :     }
     622              : 
     623           12 :     return srcIter->second;
     624              : }
     625              : 
     626           24 : HcclResult CcuComponent::ConfigLoopChannel(const uint8_t dieId, const IpAddress &ipAddr,
     627              :     const ChannelInfo &channelInfo)
     628              : {
     629           72 :     HCCL_INFO("[CcuComponent][%s] Create loop channel with another die's address, my dieId[%u]", __func__, dieId);
     630           24 :     auto rmaBufferIter = ccuRmaBufferMap.find(1 - dieId); // 需要配置另一die的rma buffer
     631           24 :     if (rmaBufferIter == ccuRmaBufferMap.end()) {
     632            0 :         HCCL_WARNING("[CcuComponent][%s] Another die is not enable, create loop channel with my die[%u]",
     633              :                     __func__, dieId);
     634            0 :         rmaBufferIter = ccuRmaBufferMap.find(dieId);
     635              :     }
     636           24 :     CHK_PRT_RET(rmaBufferIter == ccuRmaBufferMap.end(),
     637              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     638              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     639              :         HcclResult::HCCL_E_NOT_FOUND);
     640              : 
     641           24 :     const auto &ccuRmaBuffer = rmaBufferIter->second;
     642           24 :     const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
     643              : 
     644           24 :     ChannelCfg cfg{};
     645           24 :     cfg.channelId    = channelInfo.channelId;
     646           24 :     cfg.remoteEid = ipAddr.GetReverseEid();
     647           72 :     HCCL_INFO("[CcuComponent::ConfigLoopChannel] remoteEid=%s", cfg.remoteEid.Describe().c_str());
     648           24 :     cfg.tpn       = importedOutParamMap[dieId][0].second.tpn;
     649              : 
     650           24 :     cfg.remoteCcuVa   = ccuRmaBuffer->GetBuf()->GetAddr();
     651           24 :     cfg.memTokenId    = ccuRmaBuffer->GetTokenId();
     652           24 :     cfg.memTokenValue = ccuBufTokenValue;
     653              : 
     654           24 :     const auto &jettyInfos = channelInfo.jettyInfos;
     655           24 :     const auto &createdVec = createdOutParamMap[dieId];
     656           24 :     const uint32_t jettyNum = jettyInfos.size();
     657           48 :     for (uint32_t i = 0; i < jettyNum; i++) {
     658           24 :         cfg.jettyCfgs.emplace_back(JettyCfg{
     659           24 :             jettyInfos[i].jettyCtxId,
     660           24 :             createdVec[i].dbVa,
     661           24 :             createdVec[i].dbTokenId,
     662              :             ccuBufTokenValue
     663              :         });
     664              :     }
     665              : 
     666           24 :     CHK_PTR_NULL(channelMgrs[dieId]);
     667           24 :     return channelMgrs[dieId]->Config(cfg);
     668           24 : }
     669              : 
     670           12 : void CcuComponent::ConfigMsIdToken()
     671              : {
     672           12 :     bool isAX = CcuResSpecifications::GetInstance(devLogicId).GetAXFlag();
     673           12 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
     674           12 :     CHECK_NULLPTR(tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
     675              : 
     676           12 :     struct CustomChannelInfoIn  inBuff{};
     677           12 :     struct CustomChannelInfoOut outBuff{};
     678              : 
     679           36 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     680           24 :         const auto &dieIter = localCcuRmaBufferMap.find(dieId);
     681           24 :         if (dieIter == localCcuRmaBufferMap.end()) {
     682            0 :             HCCL_WARNING("[CcuComponent][%s] failed but passed, ccu rma buffer of die[%u] "
     683              :                 "is not existed, devLogicId[%d].", __func__, dieId, devLogicId);
     684            0 :             continue;
     685            0 :         }
     686           24 :         const auto &ccuRmaBuffer = dieIter->second;
     687           24 :         const uint32_t tokenId = ccuRmaBuffer->GetTokenId();
     688           24 :         const uint32_t tokenValue = ccuRmaBuffer->GetTokenValue();
     689           24 :         uint32_t msId = 0;
     690           24 :         CHK_RET_THROW(InternalException,
     691              :             StringFormat("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].",
     692              :                 __func__, devLogicId, dieId),
     693              :             CcuResSpecifications::GetInstance(devLogicId).GetMsId(dieId, msId));
     694              :         
     695           24 :         inBuff.op                    = CcuOpcodeType::CCU_U_OP_SET_MSID_TOKEN;
     696           24 :         inBuff.offsetStartIdx        = 0;
     697           24 :         inBuff.data.dataInfo.udieIdx = dieId;
     698              : 
     699           24 :         if (isAX && dieId == 0) { // A+X环境,给udie0配置新的交织粒度
     700            0 :             msId = MSID_CONFIG_AX_MAINBOARD;
     701              :         }
     702           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.msId       = msId;
     703           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.tokenId    = tokenId;
     704           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.tokenValue = tokenValue;
     705              : 
     706           24 :         HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     707              : 
     708           72 :         HCCL_INFO("[CcuComponent][%s] config MS ID token success, dieId[%u], msid[%u]",
     709              :             __func__, dieId, msId);
     710              :     }
     711           12 : }
     712              : 
     713            0 : HcclResult CcuComponent::GetCcuResourceSpaceBufInfo(const uint8_t dieId, uint64_t &addr,
     714              :     uint64_t &size) const
     715              : {
     716            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     717              : 
     718            0 :     auto res = ccuRmaBufferMap.find(dieId);
     719            0 :     CHK_PRT_RET(res == ccuRmaBufferMap.end(),
     720              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     721              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     722              :         HcclResult::HCCL_E_NOT_FOUND);
     723              : 
     724            0 :     const auto rawBuffer = res->second->GetBuf();
     725            0 :     addr = static_cast<uint64_t>(rawBuffer->GetAddr());
     726            0 :     size = static_cast<uint64_t>(rawBuffer->GetSize());
     727            0 :     return HcclResult::HCCL_SUCCESS;
     728              : }
     729              : 
     730            0 : HcclResult CcuComponent::GetCcuResourceSpaceTokenInfoForLocal(const uint8_t dieId, uint64_t &tokenId,
     731              :     uint64_t &tokenValue) const
     732              : {
     733            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     734              : 
     735            0 :     auto res = localCcuRmaBufferMap.find(dieId);
     736            0 :     CHK_PRT_RET(res == localCcuRmaBufferMap.end(),
     737              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     738              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     739              :         HcclResult::HCCL_E_NOT_FOUND);
     740              : 
     741            0 :     const auto &ccuRmaBuffer = res->second;
     742            0 :     tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
     743            0 :     tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
     744            0 :     return HcclResult::HCCL_SUCCESS;
     745              : }
     746              : 
     747            0 : HcclResult CcuComponent::GetCcuResourceSpaceTokenInfo(const uint8_t dieId, uint64_t &tokenId,
     748              :     uint64_t &tokenValue) const
     749              : {
     750            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     751              : 
     752            0 :     auto res = ccuRmaBufferMap.find(dieId);
     753            0 :     CHK_PRT_RET(res == ccuRmaBufferMap.end(),
     754              :         HCCL_WARNING("[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     755              :             "devLogicId[%d].", __func__, dieId, devLogicId),
     756              :         HcclResult::HCCL_E_NOT_FOUND);
     757              : 
     758            0 :     const auto &ccuRmaBuffer = res->second;
     759            0 :     tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
     760            0 :     tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
     761            0 :     return HcclResult::HCCL_SUCCESS;
     762              : }
     763              : 
     764            5 : HcclResult CcuComponent::AllocChannels(const uint8_t dieId, const ChannelPara &channelPara,
     765              :     std::vector<ChannelInfo> &channelInfos)
     766              : {
     767            8 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     768              : 
     769            4 :     CHK_PTR_NULL(channelMgrs[dieId]);
     770            4 :     auto ret = channelMgrs[dieId]->Alloc(channelPara, channelInfos);
     771            4 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     772              :         HCCL_WARNING("[CcuComponent][%s] failed, feId[%u], devLogicId[%d], dieId[%u].",
     773              :             __func__, channelPara.feId, devLogicId, dieId),
     774              :         ret);
     775              : 
     776            4 :     return HcclResult::HCCL_SUCCESS;
     777              : }
     778              : 
     779            6 : HcclResult CcuComponent::ConfigChannel(const uint8_t dieId, const ChannelCfg &cfg)
     780              : {
     781            6 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     782              : 
     783            6 :     uint32_t channelId = cfg.channelId;
     784            9 :     CHK_PRT_RET(channelId == loopChannelIds[dieId],
     785              :         HCCL_WARNING("[CcuComponent][%s] failed, refused to config loop channel[%u], "
     786              :             "devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId, dieId),
     787              :         HcclResult::HCCL_E_PARA);
     788              : 
     789            5 :     CHK_PTR_NULL(channelMgrs[dieId]);
     790            5 :     auto ret = channelMgrs[dieId]->Config(cfg);
     791           14 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     792              :         HCCL_WARNING("[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].",
     793              :             __func__, channelId, devLogicId, dieId),
     794              :         ret);
     795              : 
     796            2 :     return HcclResult::HCCL_SUCCESS;
     797              : }
     798              : 
     799            4 : HcclResult CcuComponent::ReleaseChannel(const uint8_t dieId, const uint32_t channelId)
     800              : {
     801            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     802            7 :     CHK_PRT_RET(channelId == loopChannelIds[dieId],
     803              :         HCCL_WARNING("[CcuComponent][%s] failed, refused to release loop channel[%u], "
     804              :             "devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId, dieId),
     805              :         HcclResult::HCCL_E_PARA);
     806              : 
     807            3 :     CHK_PTR_NULL(channelMgrs[dieId]);
     808            3 :     auto ret = channelMgrs[dieId]->Release(channelId);
     809            6 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     810              :         HCCL_WARNING("[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].",
     811              :             __func__, channelId, devLogicId, dieId),
     812              :         ret);
     813              : 
     814            2 :     return HcclResult::HCCL_SUCCESS;
     815              : }
     816              : 
     817            4 : HcclResult CcuComponent::GetLoopChannelId(const uint8_t srcDieId, const uint8_t dstDieId,
     818              :     uint32_t &channelId) const
     819              : {
     820            4 :     channelId = INVAILD_LOOP_CHANNEL_ID; // 允许die未启用时查询环回channelId
     821            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, srcDieId, {true, true}));
     822            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, dstDieId, {true, true}));
     823              : 
     824            4 :     CHK_PRT_RET(loopChannelIds[srcDieId] == INVAILD_LOOP_CHANNEL_ID, // 环回channel每个die共用1个
     825              :         HCCL_WARNING("[CcuComponent][%s] failed, invalid loop channel id, "
     826              :             "devLogicId[%d], srcDieId[%u].", __func__, devLogicId, srcDieId),
     827              :         HcclResult::HCCL_E_INTERNAL);
     828              : 
     829            4 :     channelId = loopChannelIds[srcDieId];
     830            4 :     return HcclResult::HCCL_SUCCESS;
     831              : }
     832              : 
     833           26 : HcclResult CcuComponent::AllocRes(const uint8_t dieId, const ResType resType, const uint32_t num,
     834              :     const bool consecutive, vector<ResInfo> &resInfos)
     835              : {
     836           26 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     837              : 
     838           26 :     CHK_PTR_NULL(resAllocators[dieId]);
     839           26 :     auto ret = resAllocators[dieId]->Alloc(resType, num, consecutive, resInfos);
     840           29 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     841              :         HCCL_WARNING("[CcuComponent][%s] failed, resType[%s], num[%u], devLogicId[%d], dieId[%u].",
     842              :             __func__, resType.Describe().c_str(), num, devLogicId, dieId),
     843              :         ret);
     844              : 
     845           25 :     return HcclResult::HCCL_SUCCESS;
     846              : }
     847              : 
     848            9 : HcclResult CcuComponent::ReleaseRes(const uint8_t dieId, const ResType resType, const uint32_t startId,
     849              :     const uint32_t num)
     850              : {
     851            9 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     852              : 
     853            9 :     CHK_PTR_NULL(resAllocators[dieId]);
     854            9 :     auto ret = resAllocators[dieId]->Release(resType, startId, num);
     855            9 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     856              :         HCCL_WARNING("[CcuComponent][%s] failed, resType[%s], startId[%u], num[%u], "
     857              :             "devLogicId[%d], dieId[%u].", __func__, resType.Describe().c_str(),
     858              :             startId, num, devLogicId, dieId),
     859              :         ret);
     860              : 
     861            9 :     return HcclResult::HCCL_SUCCESS;
     862              : }
     863              : 
     864            7 : HcclResult CcuComponent::AllocIns(const uint8_t dieId, const uint32_t num, ResInfo &insInfo)
     865              : {
     866           10 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     867            6 :     CHK_PTR_NULL(resAllocators[dieId]);
     868              : 
     869            6 :     vector<ResInfo> resInfos;
     870            6 :     auto ret = resAllocators[dieId]->Alloc(ResType::INS, num, true, resInfos);
     871           15 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     872              :         HCCL_WARNING("[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].",
     873              :             __func__, num, devLogicId, dieId),
     874              :         ret);
     875              : 
     876            3 :     insInfo = resInfos[0]; // 申请连续资源只会有一份
     877            3 :     return HcclResult::HCCL_SUCCESS;
     878            6 : }
     879              : 
     880            4 : HcclResult CcuComponent::ReleaseIns(const uint8_t dieId, const ResInfo &insInfo)
     881              : {
     882            7 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     883            3 :     CHK_PTR_NULL(resAllocators[dieId]);
     884              : 
     885            3 :     auto ret = resAllocators[dieId]->Release(ResType::INS, insInfo.startId, insInfo.num);
     886            3 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     887              :         HCCL_WARNING("[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].",
     888              :             __func__, insInfo.Describe().c_str(), devLogicId, dieId),
     889              :         ret);
     890              : 
     891            3 :     return HcclResult::HCCL_SUCCESS;
     892              : }
     893              : 
     894          184 : HcclResult CcuComponent::AllocCke(const uint8_t dieId, const uint32_t num, vector<ResInfo> &ckeInfos)
     895              : {
     896          715 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     897            7 :     CHK_PTR_NULL(resAllocators[dieId]);
     898              : 
     899            7 :     auto ret = resAllocators[dieId]->Alloc(ResType::CKE, num, false, ckeInfos);
     900           16 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     901              :         HCCL_WARNING("[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].",
     902              :             __func__, num, devLogicId, dieId),
     903              :         ret);
     904              : 
     905            4 :     return HcclResult::HCCL_SUCCESS;
     906              : }
     907              : 
     908           30 : HcclResult CcuComponent::ReleaseCke(const uint8_t dieId, const vector<ResInfo> &ckeInfos)
     909              : {
     910           99 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     911            7 :     CHK_PTR_NULL(resAllocators[dieId]);
     912              : 
     913           12 :     for (auto &ckeInfo : ckeInfos) {
     914            7 :         auto ret = resAllocators[dieId]->Release(ResType::CKE, ckeInfo.startId, ckeInfo.num);
     915           13 :         CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     916              :             HCCL_WARNING("[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].",
     917              :                 __func__, ckeInfo.Describe().c_str(), devLogicId, dieId),
     918              :             ret);
     919              :     }
     920              : 
     921            5 :     return HcclResult::HCCL_SUCCESS;
     922              : }
     923              : 
     924            7 : HcclResult CcuComponent::AllocXn(const uint8_t dieId, const uint32_t num, vector<ResInfo> &xnInfos)
     925              : {
     926           10 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     927            6 :     CHK_PTR_NULL(resAllocators[dieId]);
     928              : 
     929            6 :     auto ret = resAllocators[dieId]->Alloc(ResType::XN, num, false, xnInfos);
     930           15 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     931              :         HCCL_WARNING("[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].",
     932              :             __func__, num, devLogicId, dieId),
     933              :         ret);
     934              : 
     935            3 :     return HcclResult::HCCL_SUCCESS;
     936              : }
     937              : 
     938            4 : HcclResult CcuComponent::ReleaseXn(const uint8_t dieId, const vector<ResInfo> &xnInfos)
     939              : {
     940            7 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     941            3 :     CHK_PTR_NULL(resAllocators[dieId]);
     942              : 
     943            6 :     for (auto &xnInfo : xnInfos) {
     944            3 :         auto ret = resAllocators[dieId]->Release(ResType::XN, xnInfo.startId, xnInfo.num);
     945            3 :         CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     946              :             HCCL_WARNING("[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].",
     947              :                 __func__, xnInfo.Describe().c_str(), devLogicId, dieId),
     948              :             ret);
     949              :     }
     950              : 
     951            3 :     return HcclResult::HCCL_SUCCESS;
     952              : }
     953              : 
     954              : // 以下接口用于n秒快恢与TaskException
     955           29 : HcclResult CcuComponent::CleanDieCkes(const uint8_t dieId) const
     956              : {
     957           29 :     CHK_PRT_RET(dieId >= MAX_CCU_IODIE_NUM,
     958              :         HCCL_WARNING("[CcuComponent][%s] failed, dieId[%u] is invalid, shoudle be in [0-%u), devLogicId[%d].",
     959              :             __func__, dieId, MAX_CCU_IODIE_NUM, devLogicId),
     960              :         HcclResult::HCCL_E_PARA);
     961              : 
     962           29 :     if (!dieEnableFlags[dieId]) {
     963            4 :         return HcclResult::HCCL_SUCCESS;
     964              :     }
     965              :     
     966           25 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
     967           25 :     CHK_PTR_NULL(tlvHandle);
     968           25 :     CustomChannelInfoIn  inBuff{};
     969           25 :     CustomChannelInfoOut outBuff{};
     970              : 
     971              :     // 设置操作码和数据
     972           25 :     uint32_t ckeNum = 0;
     973           25 :     CHK_RET(CcuResSpecifications::GetInstance(devLogicId).GetCkeNum(dieId, ckeNum));
     974           75 :     HCCL_INFO("[CcuComponent][CleanAllCke]Nsrecovery devLogicId[%d], dieId[%u] ckeNum[%u].",
     975              :         devLogicId, dieId, ckeNum);
     976              :     
     977           25 :     inBuff.op                          = CcuOpcodeType::CCU_U_OP_SET_CKE;
     978           25 :     inBuff.data.dataInfo.udieIdx       = dieId;
     979              :     // 接口限制,目前方案每次最多清理8个cke,超过8个时分多次清理
     980         3225 :     for (uint32_t startIdx = 0; startIdx < ckeNum; startIdx += MAX_CKE_DATA_ARRAY_SIZE) {
     981         3200 :         inBuff.data.dataInfo.dataArraySize = std::min(ckeNum - startIdx, MAX_CKE_DATA_ARRAY_SIZE);
     982         3200 :         inBuff.data.dataInfo.dataLen       = sizeof(CcuDataByte8) * inBuff.data.dataInfo.dataArraySize;
     983         3200 :         inBuff.offsetStartIdx              = startIdx;
     984         3200 :         HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     985              :     }
     986              : 
     987           25 :     return HcclResult::HCCL_SUCCESS;
     988              : }
     989              : 
     990           26 : void CcuComponent::SetProcess(CcuOpcodeType opCode) const
     991              : {
     992           26 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
     993           26 :     CHECK_NULLPTR(tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
     994              : 
     995           26 :     struct CustomChannelInfoIn  inBuff;
     996           26 :     struct CustomChannelInfoOut outBuff;
     997              : 
     998           26 :     inBuff.op = opCode;
     999           78 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
    1000           52 :         if (!dieEnableFlags[dieId]) {
    1001            0 :             HCCL_WARNING("[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] is not enable,"
    1002              :                 "skip SetProcess.", devLogicId, dieId);
    1003            0 :             continue;
    1004            0 :         }
    1005          156 :         HCCL_INFO("[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] start.", devLogicId, dieId);
    1006           52 :         inBuff.data.dataInfo.udieIdx = dieId;
    1007           52 :         HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
    1008              :     }
    1009           26 : }
    1010              : 
    1011           13 : HcclResult CcuComponent::SetTaskKill()
    1012              : {
    1013           13 :     std::lock_guard<std::mutex> _lock(taskKillMutex_);
    1014              : 
    1015           13 :     if (status == CcuTaskKillStatus::INVALID) {
    1016           12 :         status = CcuTaskKillStatus::INIT;
    1017              :     }
    1018              : 
    1019           13 :     if (status == CcuTaskKillStatus::TASK_KILL) {
    1020            0 :         HCCL_INFO("No need to set task kill, state = %u, devLogicId = %u", status, devLogicId);
    1021            0 :         return HcclResult::HCCL_SUCCESS;
    1022              :     }
    1023              : 
    1024           13 :     if (status != CcuTaskKillStatus::INIT) {
    1025            0 :         HCCL_ERROR("[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1026              :             "state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1027            0 :         return HcclResult::HCCL_E_INTERNAL;
    1028              :     }
    1029              : 
    1030           13 :     SetProcess(CcuOpcodeType::CCU_U_OP_SET_TASKKILL);
    1031           13 :     status = CcuTaskKillStatus::TASK_KILL;
    1032           39 :     HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1033           13 :     return HcclResult::HCCL_SUCCESS;
    1034           13 : }
    1035              : 
    1036           13 : HcclResult CcuComponent::SetTaskKillDone()
    1037              : {
    1038           13 :     std::lock_guard<std::mutex> _lock(taskKillMutex_);
    1039              : 
    1040           13 :     if (status == CcuTaskKillStatus::INVALID) {
    1041            0 :         HCCL_ERROR("[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1042              :             "state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1043            0 :         return HcclResult::HCCL_E_INTERNAL;
    1044              :     }
    1045              : 
    1046           13 :     if (status == CcuTaskKillStatus::INIT) {
    1047            0 :         HCCL_INFO("No need to set task kill done, state = %u, devLogicId = %u", status, devLogicId);
    1048            0 :         return HcclResult::HCCL_SUCCESS;
    1049              :     }
    1050              : 
    1051           13 :     if (status != CcuTaskKillStatus::TASK_KILL) {
    1052            0 :         HCCL_ERROR("[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1053              :             "state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1054            0 :         return HcclResult::HCCL_E_INTERNAL;
    1055              :     }
    1056              : 
    1057           13 :     SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
    1058           13 :     status = CcuTaskKillStatus::INIT;
    1059           39 :     HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d", __func__, status, devLogicId);
    1060           13 :     return HcclResult::HCCL_SUCCESS;
    1061           13 : }
    1062              : 
    1063            0 : HcclResult CcuComponent::CleanTaskKillState() const
    1064              : {
    1065            0 :     SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
    1066            0 :     return HcclResult::HCCL_SUCCESS;
    1067              : }
    1068              : 
    1069            2 : const std::array<bool, MAX_CCU_IODIE_NUM> &CcuComponent::GetDieEnableFlags() const
    1070              : {
    1071            2 :     return dieEnableFlags;
    1072              : }
    1073              : 
    1074           81 : CcuComponent::~CcuComponent()
    1075              : {
    1076           81 :     DECTOR_TRY_CATCH("CcuComponent", ReleaseJettyRes());
    1077           81 : }
    1078              : 
    1079           83 : void CcuComponent::ReleaseJettyRes()
    1080              : {
    1081           83 :     UnimportAllJetty();
    1082           83 :     DestroyAllJetty();
    1083              :     // HrtRaUbLocalMemReg 跟随 LocalUbRmaBuffer 析构时释放
    1084              :     // 环回channel不需要手动释放,channelMgr跟随CcuComponent释放
    1085           83 : }
    1086              : 
    1087           83 : void CcuComponent::UnimportAllJetty()
    1088              : {
    1089              :     // tpInfo不需要主动释放,因为CcuComponent生命周期与TpManager一致
    1090          109 :     for (auto &importedVec : importedOutParamMap) {
    1091           52 :         for (auto &paramPair : importedVec.second) {
    1092           26 :             const auto rdmaHandle = paramPair.first;
    1093           26 :             const auto remoteJettyHandle = paramPair.second.handle;
    1094           26 :             if (rdmaHandle != nullptr && remoteJettyHandle != 0) {
    1095            0 :                 paramPair.second.handle = 0;
    1096            0 :                 HrtRaUbUnimportJetty(rdmaHandle, remoteJettyHandle);
    1097              :             }
    1098              :         }
    1099              :     }
    1100              : 
    1101           83 :     importedOutParamMap.clear();
    1102           83 : }
    1103              : 
    1104           83 : void CcuComponent::DestroyAllJetty()
    1105              : {
    1106          109 :     for (auto &createdVec : createdOutParamMap) {
    1107           52 :         for (auto &param : createdVec.second) {
    1108           26 :             const auto jettyHandle = param.handle;
    1109           26 :             if (jettyHandle != 0) {
    1110            0 :                 param.handle = 0; 
    1111            0 :                 HrtRaUbDestroyJetty(jettyHandle);
    1112              :             }
    1113              :         }
    1114              :     }
    1115              : 
    1116           83 :     createdOutParamMap.clear();
    1117           83 : }
    1118              : 
    1119              : }; // namespace Hccl
        

Generated by: LCOV version 2.0-1