LCOV - code coverage report
Current view: top level - base_comm/resources/ccu/ccu_device/ccu_comp - ccu_comp.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 69.5 % 741 515
Test Date: 2026-08-29 17:38:31 Functions: 76.2 % 63 48

            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 "ccu_comp.h"
      12              : 
      13              : #include <random>
      14              : 
      15              : #include "hccl_common.h"
      16              : #include "rdma_handle_manager.h"
      17              : 
      18              : #include "eid_info_mgr.h"
      19              : #include "ccu_res_specs.h"
      20              : #include "ccu_channel_ctx_mgr_v1.h"
      21              : #include "ccu_channel_ctx_mgr_v2.h"
      22              : 
      23              : #include "exception_handler.h"
      24              : #include "adapter_rts_common.h"
      25              : #include "env_config.h"
      26              : #include "orion_adapter_hccp.h"
      27              : #include "hcomm_adapter_hccp.h"
      28              : 
      29              : namespace hcomm {
      30              : 
      31              : constexpr TpProtocol LOOP_JETTY_PROTOCOL = TpProtocol::RTP; // 环回使用RTP避免被环境link down阻塞
      32              : constexpr uint8_t CCU_MAX_MISSION_NUM = 16;
      33              : 
      34              : // 设置为0,分配数量由channelCtxMgr决定,v1 默认1个
      35              : constexpr uint32_t LOOP_CHANNEL_USE_JETTY = 0;
      36              : constexpr uint32_t LOOP_CHANNEL_USE_SQSIZE_V1 = 16;
      37              : constexpr uint32_t LOOP_CHANNEL_USE_SQSIZE_V2 = 32;
      38              : 
      39              : // 环回获取TP信息超时等待10s
      40              : constexpr uint32_t LOOP_CHANNEL_WAIT_TIMEOUT_MS = 10000;
      41              : 
      42              : // 环境是ARM+X86时,配置 die0 的 MS 交织粒度为 1<<7 = 128
      43              : constexpr uint32_t MSID_CONFIG_ARMX86_MAINBOARD = 7;
      44              : // 设计支持的最大IOdie数量
      45              : constexpr uint8_t MAX_CCU_IODIE_NUM = 2;
      46              : // 清理CKE批量申请大小
      47              : constexpr u32 MAX_CKE_DATA_ARRAY_SIZE = 8;
      48              : 
      49         5782 : CcuComponent& CcuComponent::GetInstance(const int32_t deviceLogicId)
      50              : {
      51         5980 :     static CcuComponent ccuComponent[MAX_MODULE_DEVICE_NUM + 1];
      52         5782 :     int32_t devLogicId = deviceLogicId;
      53         5782 :     if (devLogicId < 0 || static_cast<uint32_t>(devLogicId) >= MAX_MODULE_DEVICE_NUM) {
      54            0 :         HCCL_WARNING(
      55              :             "[CcuComponent][%s] use the backup device, devLogicId[%d] should be "
      56              :             "less than %u.",
      57              :             __func__, devLogicId, MAX_MODULE_DEVICE_NUM);
      58            0 :         devLogicId = MAX_MODULE_DEVICE_NUM; // 使用备份设备
      59              :     }
      60              : 
      61         5782 :     ccuComponent[devLogicId].devLogicId_ = devLogicId;
      62         5782 :     return ccuComponent[devLogicId];
      63              : }
      64              : 
      65          189 : HcclResult CcuComponent::Init()
      66              : {
      67          189 :     std::lock_guard<std::mutex> _lock(innerMutex_);
      68              : 
      69          189 :     if (initFlag_) {
      70           81 :         return HcclResult::HCCL_SUCCESS;
      71              :     }
      72              : 
      73          108 :     CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<uint32_t>(devLogicId_), devPhyId_));
      74          108 :     CHK_RET(CheckDiesEnable());
      75              : 
      76              :     // 当前ccu驱动拉起时不清理资源,hcomm规避,后续需要清理cke及其他资源
      77          321 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
      78          214 :         (void)CleanDieCkes(dieId);
      79              :     }
      80              : 
      81          107 :     CHK_RET(CreateCcuRmaBuffer());
      82          107 :     CHK_RET(CreateResourceManagers());
      83          107 :     CHK_RET(CreateLoopChannels());
      84          107 :     CHK_RET(ConfigMsIdToken());
      85          107 :     initFlag_ = true;
      86          107 :     return HcclResult::HCCL_SUCCESS;
      87          189 : }
      88              : 
      89          393 : HcclResult CcuComponent::Deinit()
      90              : {
      91          393 :     std::lock_guard<std::mutex> _lock(innerMutex_);
      92          393 :     CHK_RET(ReleaseJettyRes());
      93              : 
      94          390 :     loopFeCommAddrMap_.clear();
      95          390 :     ccuRmaBufferMap_.clear();
      96              : 
      97         1170 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
      98          780 :         channelCtxMgrs_[dieId] = nullptr;
      99          780 :         resAllocators_[dieId] = nullptr;
     100          780 :         loopChannelIds_[dieId] = INVAILD_LOOP_CHANNEL_ID;
     101              :     }
     102              : 
     103          390 :     initFlag_ = false;
     104          390 :     return HcclResult::HCCL_SUCCESS;
     105          393 : }
     106              : 
     107          207 : CcuComponent::~CcuComponent() { (void)Deinit(); }
     108              : 
     109          108 : static std::array<bool, CCU_MAX_IODIE_NUM> GetDieDrvEnableFlags(const int32_t devLogicId)
     110              : {
     111              :     // 根据资源规格的记录驱动可用的die
     112          108 :     std::array<bool, CCU_MAX_IODIE_NUM> dieDrvEnableFlags{false, false};
     113          108 :     const auto& ccuResSpecs = CcuResSpecifications::GetInstance(devLogicId);
     114          324 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     115          216 :         (void)ccuResSpecs.GetDieEnableFlag(dieId, dieDrvEnableFlags[dieId]);
     116          216 :         if (!dieDrvEnableFlags[dieId]) { // 调用接口失败时不会改变dieEnableFlags[i]
     117            2 :             HCCL_WARNING(
     118              :                 "[CcuComponent][%s] devLogicId[%d], dieId[%u] driver is not usable.", __func__, devLogicId, dieId);
     119              :         }
     120              :     }
     121              : 
     122          108 :     return dieDrvEnableFlags;
     123              : }
     124              : 
     125          108 : HcclResult CcuComponent::CheckDiesEnable()
     126              : {
     127          108 :     ccuVersion_ = CcuResSpecifications::GetInstance(devLogicId_).GetCcuVersion();
     128          108 :     HCCL_INFO(
     129              :         "[CcuComponent][%s] ccu version[%s], devLogicId[%d].", __func__, ccuVersion_.Describe().c_str(), devLogicId_);
     130              : 
     131          108 :     const auto& dieDrvEnableFlags = GetDieDrvEnableFlags(devLogicId_);
     132              :     // 内部检查驱动可用的die上是否配置eid,内部更新die是否可用的标记
     133          108 :     CHK_RET(ChooseLoopEids(dieDrvEnableFlags));
     134              : 
     135          108 :     bool allDieDisable = true;
     136          324 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     137          216 :         allDieDisable = allDieDisable && !dieEnableFlags_[dieId];
     138              :     }
     139              : 
     140          108 :     if (allDieDisable) {
     141            1 :         HCCL_ERROR(
     142              :             "[CcuComponent][%s] failed, because all dies are "
     143              :             "disabled, devLogicId[%d].",
     144              :             __func__, devLogicId_);
     145            1 :         return HcclResult::HCCL_E_UNAVAIL;
     146              :     }
     147              : 
     148          107 :     return HcclResult::HCCL_SUCCESS;
     149              : }
     150              : 
     151          214 : static HcclResult FindOneUsableEid(
     152              :     const int32_t devLogicId, const uint32_t devPhyId, const uint8_t dieId, uint32_t& feId, CommAddr& commAddr)
     153              : {
     154              :     // 如果无法查询设备是否为uboe设备,报错退出
     155          214 :     CHK_RET(HccpGetUboeFlagEnable(devPhyId));
     156              : 
     157          214 :     std::vector<DevEidInfo> eidInfos;
     158          214 :     auto ret = EidInfoMgr::GetInstance(devPhyId).GetEidInfos(eidInfos);
     159          214 :     CHK_PRT_RET(
     160              :         ret != HCCL_SUCCESS,
     161              :         HCCL_WARNING("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId), ret);
     162              : 
     163          214 :     std::string name;
     164          214 :     bool findFlag = false;
     165              :     // 当前结论,除仅包含UBOE的FE外
     166              :     // 其他eid均支持源与目标eid一致时应用环回
     167              :     // 故当前版本选择首个可用eid即可
     168              :     EXCEPTION_HANDLE_BEGIN
     169          214 :     auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
     170          856 :     for (auto& eidInfo : eidInfos) {
     171              :         // 如果是UBOE设备或非本die,则跳过
     172          642 :         if (HccpCheckUboeSupported(eidInfo.devFeature) || (eidInfo.dieId != dieId)) {
     173          423 :             continue;
     174              :         }
     175              : 
     176          321 :         Hccl::IpAddress ipAddr{};
     177          321 :         CHK_RET(CommAddrToIpAddress(eidInfo.commAddr, ipAddr));
     178          321 :         const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
     179          321 :         CHK_PTR_NULL(rdmaHandle);
     180          321 :         const bool rtpEnable = rdmaHandleMgr.GetRtpEnable(rdmaHandle);
     181          321 :         if (!rtpEnable) {
     182              :             // 遍历端口可能较多,避免刷屏不打印
     183          102 :             continue;
     184              :         }
     185              : 
     186          219 :         feId = eidInfo.funcId;
     187          219 :         commAddr = eidInfo.commAddr;
     188          219 :         name = eidInfo.name;
     189          219 :         findFlag = true;
     190              :     }
     191            0 :     EXCEPTION_HANDLE_END
     192              : 
     193          214 :     if (!findFlag) {
     194            0 :         HCCL_WARNING(
     195              :             "[CcuComponent][%s] dieId[%u] doesn't have usable func ID, "
     196              :             "devLogicId[%d].",
     197              :             __func__, dieId, devLogicId);
     198            0 :         return HcclResult::HCCL_E_INTERNAL;
     199              :     }
     200              : 
     201          214 :     Hccl::IpAddress ipAddr{};
     202          214 :     CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
     203          214 :     HCCL_INFO(
     204              :         "[CcuComponent][%s] dieId[%u] choose: name[%s] feId[%u] ipAddr[%s], "
     205              :         "devLogicId[%d].",
     206              :         __func__, dieId, name.c_str(), feId, ipAddr.Describe().c_str(), devLogicId);
     207              : 
     208          214 :     return HcclResult::HCCL_SUCCESS;
     209          214 : }
     210              : 
     211          108 : HcclResult CcuComponent::ChooseLoopEids(const std::array<bool, CCU_MAX_IODIE_NUM>& dieDrvEnableFlags)
     212              : {
     213          324 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     214          216 :         if (!dieDrvEnableFlags[dieId]) {
     215            2 :             dieEnableFlags_[dieId] = false;
     216            2 :             continue;
     217              :         }
     218              : 
     219          214 :         uint32_t feId = 0;
     220          214 :         CommAddr commAddr{};
     221          214 :         if (FindOneUsableEid(devLogicId_, devPhyId_, dieId, feId, commAddr) != HcclResult::HCCL_SUCCESS) {
     222            0 :             dieEnableFlags_[dieId] = false;
     223            0 :             HCCL_WARNING(
     224              :                 "[CcuComponent][%s] failed to find feId eid, but passed, "
     225              :                 "devLogicId[%d], dieId[%u].",
     226              :                 __func__, devLogicId_, dieId);
     227            0 :             continue;
     228              :         }
     229              : 
     230          214 :         loopFeCommAddrMap_[dieId] = {feId, commAddr};
     231          214 :         dieEnableFlags_[dieId] = true;
     232          214 :         HCCL_RUN_INFO("[CcuComponent][%s] devLogicId[%d] die[%u] is usable.", __func__, devLogicId_, dieId);
     233              :     }
     234          108 :     return HcclResult::HCCL_SUCCESS;
     235              : }
     236              : 
     237          428 : HcclResult CcuComponent::GetLoopFeIpByDieId(const uint8_t dieId, uint32_t& feId, CommAddr& commAddr)
     238              : {
     239          428 :     const auto& dieIter = loopFeCommAddrMap_.find(dieId);
     240          428 :     CHK_PRT_RET(
     241              :         dieIter == loopFeCommAddrMap_.end(),
     242              :         HCCL_WARNING(
     243              :             "[CcuComponent][%s] failed but passed, "
     244              :             "dieId[%u] doesn't have usable loop feId, devLogicId[%d].",
     245              :             __func__, dieId, devLogicId_),
     246              :         HcclResult::HCCL_E_NOT_FOUND);
     247              : 
     248          428 :     const auto& feIdCommAddr = dieIter->second;
     249          428 :     feId = feIdCommAddr.first;
     250          428 :     commAddr = feIdCommAddr.second;
     251              : 
     252          428 :     return HcclResult::HCCL_SUCCESS;
     253              : }
     254              : 
     255          107 : HcclResult CcuComponent::CreateCcuRmaBuffer()
     256              : {
     257          107 :     auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
     258          107 :     auto& ccuResSpecs = CcuResSpecifications::GetInstance(devLogicId_);
     259          321 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     260          214 :         if (!dieEnableFlags_[dieId]) {
     261            0 :             continue;
     262              :         }
     263              : 
     264          214 :         uint32_t feId = 0;
     265          214 :         CommAddr commAddr{};
     266          214 :         if (GetLoopFeIpByDieId(dieId, feId, commAddr) != HcclResult::HCCL_SUCCESS) {
     267            0 :             continue;
     268              :         }
     269              : 
     270          214 :         uint64_t ccuResAddr = 0;
     271          214 :         (void)ccuResSpecs.GetResourceAddr(dieId, ccuResAddr);
     272          214 :         if (ccuResAddr == 0) {
     273            0 :             HCCL_WARNING(
     274              :                 "[CcuComponent][%s] failed, ccu resource space address[0] is invalid, "
     275              :                 "devLogicId[%d] dieId[%u]",
     276              :                 __func__, devLogicId_, dieId);
     277            0 :             continue;
     278              :         }
     279              : 
     280              :         // 申请rdmaHandle可能抛异常
     281              :         EXCEPTION_HANDLE_BEGIN
     282          214 :         Hccl::IpAddress ipAddr{};
     283          214 :         CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
     284          214 :         const CtxHandle ctxHandle = static_cast<CtxHandle>(rdmaHandleMgr.GetByIp(devPhyId_, ipAddr));
     285          214 :         CHK_PTR_NULL(ctxHandle);
     286          214 :         const auto ccuBuffer = std::make_shared<Hccl::Buffer>(ccuResAddr, CCU_RESOURCE_SIZE);
     287          214 :         ccuRmaBufferMap_.emplace(dieId, std::make_unique<Hccl::LocalUbRmaBuffer>(ccuBuffer, ctxHandle));
     288              : 
     289          214 :         EXCEPTION_HANDLE_END
     290              :     }
     291              : 
     292          107 :     return HcclResult::HCCL_SUCCESS;
     293              : }
     294              : 
     295          214 : static HcclResult CreateChannelCtxMgrByVersion(
     296              :     const CcuVersion version, const uint32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId,
     297              :     std::unique_ptr<CcuChannelCtxMgr>& channelCtxMgr)
     298              : {
     299          214 :     switch (version) {
     300          176 :         case CcuVersion::CCU_V1:
     301          176 :             channelCtxMgr.reset(new (std::nothrow) CcuChannelCtxMgrV1(devLogicId, dieId, devPhyId));
     302          176 :             break;
     303           38 :         case CcuVersion::CCU_V2:
     304           38 :             channelCtxMgr.reset(new (std::nothrow) CcuChannelCtxMgrV2(devLogicId, dieId, devPhyId));
     305           38 :             break;
     306            0 :         default:
     307            0 :             HCCL_ERROR(
     308              :                 "[CcuComponent][%s] failed, ccu driver version[%s] is not expected, "
     309              :                 "devLogicId[%d] dieId[%u].",
     310              :                 __func__, version.Describe().c_str(), devLogicId, dieId);
     311            0 :             return HcclResult::HCCL_E_NOT_SUPPORT;
     312              :     }
     313          214 :     CHK_PTR_NULL(channelCtxMgr);
     314          214 :     return HcclResult::HCCL_SUCCESS;
     315              : }
     316              : 
     317          107 : HcclResult CcuComponent::CreateResourceManagers()
     318              : {
     319          321 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     320          214 :         if (!dieEnableFlags_[dieId]) {
     321            0 :             continue;
     322              :         }
     323              : 
     324          214 :         std::unique_ptr<CcuChannelCtxMgr> channelCtxMgrPtr = nullptr;
     325          214 :         CHK_RET(CreateChannelCtxMgrByVersion(ccuVersion_, devLogicId_, dieId, devPhyId_, channelCtxMgrPtr));
     326          214 :         CHK_RET(channelCtxMgrPtr->Init());
     327              : 
     328          214 :         std::unique_ptr<CcuResAllocator> resAllocatorPtr = nullptr;
     329          214 :         resAllocatorPtr.reset(new (std::nothrow) CcuResAllocator(devLogicId_, dieId));
     330          214 :         CHK_PTR_NULL(resAllocatorPtr);
     331          214 :         CHK_RET(resAllocatorPtr->Init());
     332              : 
     333          214 :         channelCtxMgrs_[dieId] = std::move(channelCtxMgrPtr);
     334          214 :         resAllocators_[dieId] = std::move(resAllocatorPtr);
     335          214 :     }
     336          107 :     return HcclResult::HCCL_SUCCESS;
     337              : }
     338              : 
     339          107 : HcclResult CcuComponent::CreateLoopChannels()
     340              : {
     341          321 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     342          214 :         loopChannelIds_[dieId] = INVAILD_LOOP_CHANNEL_ID;
     343              :         // 失败抛异常处理,jetty资源跟随数据结构析构释放
     344          214 :         auto ret = CreateLoopChannel(dieId, loopChannelIds_[dieId]);
     345          214 :         CHK_PRT_RET(
     346              :             ret, HCCL_ERROR("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].", __func__, devLogicId_, dieId),
     347              :             ret);
     348              : 
     349          214 :         if (loopChannelIds_[dieId] == INVAILD_LOOP_CHANNEL_ID) {
     350            0 :             HCCL_RUN_WARNING(
     351              :                 "[CcuComponent][%s] failed but passed, loop channel id[%u], "
     352              :                 "devLogicId[%d], dieId[%u].",
     353              :                 __func__, loopChannelIds_[dieId], devLogicId_, dieId);
     354            0 :             continue;
     355              :         }
     356              : 
     357          214 :         HCCL_RUN_INFO(
     358              :             "[CcuComponent][%s] succeed, loop channel id[%u], "
     359              :             "devLogicId[%d], dieId[%u].",
     360              :             __func__, loopChannelIds_[dieId], devLogicId_, dieId);
     361              :     }
     362              : 
     363          107 :     return HcclResult::HCCL_SUCCESS;
     364              : }
     365              : 
     366          214 : HcclResult CcuComponent::CreateLoopChannel(const uint8_t dieId, uint32_t& channelId)
     367              : {
     368          214 :     if (!dieEnableFlags_[dieId]) {
     369            0 :         HCCL_WARNING(
     370              :             "[CcuComponent][%s] passed, dieId[%u] is not enabled, "
     371              :             "devLogicId[%d].",
     372              :             __func__, dieId, devLogicId_);
     373            0 :         return HcclResult::HCCL_SUCCESS;
     374              :     }
     375              : 
     376              :     // 对于单p或单die场景,可能设备或die不会配置eid,按成功处理不阻塞用例
     377          214 :     uint32_t feId = 0;
     378          214 :     CommAddr commAddr{};
     379          214 :     if (GetLoopFeIpByDieId(dieId, feId, commAddr) != HcclResult::HCCL_SUCCESS) {
     380            0 :         channelId = INVAILD_LOOP_CHANNEL_ID;
     381            0 :         HCCL_WARNING(
     382              :             "[CcuComponent][%s] failed but passed, dieId[%u] doesn't have loop feId, "
     383              :             "devLogicId[%d].",
     384              :             __func__, dieId, devLogicId_);
     385            0 :         return HcclResult::HCCL_SUCCESS;
     386              :     }
     387              :     const uint32_t loopChannelSqsize
     388          214 :         = (ccuVersion_ == CcuVersion::CCU_V1 ? LOOP_CHANNEL_USE_SQSIZE_V1 : LOOP_CHANNEL_USE_SQSIZE_V2);
     389          214 :     std::vector<ChannelInfo> channelInfos; // 按jetty组分配
     390          214 :     const ChannelPara channelPara{feId, LOOP_CHANNEL_USE_JETTY, loopChannelSqsize};
     391          214 :     auto ret = channelCtxMgrs_[dieId]->Alloc(channelPara, channelInfos);
     392          214 :     CHK_PRT_RET(
     393              :         ret != HCCL_SUCCESS,
     394              :         HCCL_WARNING(
     395              :             "[CcuComponent][%s] failed to alloc channel, "
     396              :             "devLogicId[%d], dieId[%u].",
     397              :             __func__, devLogicId_, dieId),
     398              :         ret);
     399              : 
     400          214 :     const auto& channelInfo = channelInfos[0]; // 环回只使用1个channel
     401          214 :     ret = CreateAndImportLoopJettys(dieId, commAddr, channelInfo.jettyInfos);
     402          214 :     CHK_PRT_RET(
     403              :         ret != HCCL_SUCCESS,
     404              :         HCCL_WARNING(
     405              :             "[CcuComponent][%s] failed to create or import loop jettys, "
     406              :             "devLogicId[%d], dieId[%u].",
     407              :             __func__, devLogicId_, dieId),
     408              :         ret);
     409              : 
     410          214 :     ret = ConfigLoopChannel(dieId, commAddr, channelInfo);
     411          214 :     CHK_PRT_RET(
     412              :         ret != HCCL_SUCCESS,
     413              :         HCCL_WARNING(
     414              :             "[CcuComponent][%s] failed to config the loop channel, "
     415              :             "devLogicId[%d], dieId[%u].",
     416              :             __func__, devLogicId_, dieId),
     417              :         ret);
     418              : 
     419          214 :     channelId = channelInfo.channelId;
     420          214 :     return HcclResult::HCCL_SUCCESS;
     421          214 : }
     422              : 
     423          216 : JettyImportCfg GetJettyImportCfg(const TpInfo& tpInfo, const uint32_t& psn)
     424              : {
     425          216 :     const TpHandle tpHandle = tpInfo.tpHandle;
     426          216 :     HCCL_INFO("[CcuComponent][%s] loop channel use tp handle[%llu] psn[%u].", __func__, tpHandle, psn);
     427              : 
     428          216 :     JettyImportCfg cfg = {};
     429          216 :     cfg.localTpHandle = tpHandle;
     430          216 :     cfg.remoteTpHandle = tpHandle;
     431          216 :     cfg.localPsn = psn;
     432          216 :     cfg.remotePsn = psn;
     433          216 :     cfg.protocol = LOOP_JETTY_PROTOCOL;
     434          216 :     return cfg;
     435              : }
     436              : 
     437          216 : HcclResult CcuComponent::CreateAndImportLoopJettys(
     438              :     const uint8_t dieId, const CommAddr& commAddr, const std::vector<JettyInfo>& jettyInfos)
     439              : {
     440          216 :     Hccl::IpAddress ipAddr{};
     441          216 :     CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
     442              : 
     443          216 :     Hccl::CqCreateInfo cqInfo{};
     444          216 :     auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
     445          216 :     const auto ctxHandle = static_cast<CtxHandle>(rdmaHandleMgr.GetByIp(devPhyId_, ipAddr));
     446          216 :     const auto _jfcHandle = rdmaHandleMgr.GetJfcHandle(ctxHandle, cqInfo, Hccl::HrtUbJfcMode::CCU_POLL);
     447          216 :     const JfcHandle jfcHandle = reinterpret_cast<JfcHandle>(_jfcHandle);
     448              : 
     449          216 :     const auto& rmaBufferIter = ccuRmaBufferMap_.find(dieId);
     450          216 :     CHK_PRT_RET(
     451              :         rmaBufferIter == ccuRmaBufferMap_.end(),
     452              :         HCCL_RUN_WARNING(
     453              :             "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     454              :             "devLogicId[%d].",
     455              :             __func__, dieId, devLogicId_),
     456              :         HcclResult::HCCL_E_NOT_FOUND);
     457              : 
     458          216 :     const auto& ccuRmaBuffer = rmaBufferIter->second;
     459          216 :     const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
     460              : 
     461          216 :     auto& createdVec = createdOutParamMap_[dieId];
     462          216 :     auto& importedVec = importedOutParamMap_[dieId];
     463              : 
     464          216 :     TpInfo loopTpInfo{};
     465          216 :     CHK_RET(GetLoopTpInfo(dieId, commAddr, loopTpInfo));
     466          216 :     const uint32_t loopJettyQos
     467          216 :         = loopTpInfo.hasMappedJettyPriority ? (loopTpInfo.mappedJettyPriority & 0xFU) : EnvConfig::UB_QOS_DEFAULT;
     468              : 
     469          216 :     uint8_t errTimeout = 0;
     470          216 :     CHK_RET(GetLoopJettyTimeout(dieId, commAddr, errTimeout));
     471              : 
     472          432 :     for (const auto& jettyInfo : jettyInfos) {
     473          216 :         const auto jettyMode = jettyInfo.jettyType == CcuJettyType::CCUM_CACHED_JETTY ? HrtJettyMode::CCU_CCUM_CACHE :
     474          216 :                                                                                         HrtJettyMode::CCU_TA_CACHE;
     475              :         HrtRaUbCreateJettyParam req{jfcHandle,         jfcHandle,           ccuBufTokenValue,
     476          216 :                                     nullptr,           jettyMode,           jettyInfo.taJettyId,
     477          216 :                                     jettyInfo.sqBufVa, jettyInfo.sqBufSize, jettyInfo.wqeBBStartId,
     478          216 :                                     jettyInfo.sqDepth, errTimeout};
     479          216 :         req.qos = loopJettyQos;
     480              : 
     481          216 :         HrtRaUbJettyCreatedOutParam createdOutParam{};
     482          216 :         CHK_RET(HccpUbCreateJetty(ctxHandle, req, createdOutParam));
     483          216 :         createdVec.emplace_back(createdOutParam);
     484              : 
     485          216 :         const auto psn = GetNewPsn();
     486          216 :         const auto& jettyImportCfg = GetJettyImportCfg(loopTpInfo, psn);
     487              : 
     488          216 :         HrtRaUbJettyImportedOutParam importedOutParam{};
     489          216 :         CHK_RET(HccpUbTpImportJetty(
     490              :             ctxHandle, createdOutParam.key, createdOutParam.keySize, ccuBufTokenValue, jettyImportCfg,
     491              :             importedOutParam));
     492          216 :         importedVec.emplace_back(std::make_pair(ctxHandle, importedOutParam));
     493              :     }
     494              : 
     495          216 :     return HcclResult::HCCL_SUCCESS;
     496              : }
     497              : 
     498          429 : static GetTpInfoParam MakeLoopGetTpInfoParam(const CommAddr& commAddr)
     499              : {
     500          429 :     GetTpInfoParam param;
     501          429 :     param.locAddr = commAddr;
     502          429 :     param.rmtAddr = commAddr;
     503          429 :     param.tpProtocol = LOOP_JETTY_PROTOCOL;
     504          429 :     param.qos = 0U; // CCU 环回与通信域 hcclQos 解耦;SL 仅由 RaGetTpAttr.slBitmap + loopFirstTpLowestSl 决定
     505          429 :     param.slLevelCount = 0;
     506          429 :     param.loopFirstTpLowestSl = true;
     507          429 :     param.ccuLoopbackGetTpInfo = true;
     508          429 :     return param;
     509              : }
     510              : 
     511          215 : static HcclResult RequestNewLoopTpInfo(const uint32_t devPhyId, const CommAddr& commAddr, TpInfo& tpInfo)
     512              : {
     513          215 :     constexpr auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
     514          215 :     const auto startTime = std::chrono::steady_clock::now();
     515              : 
     516          215 :     auto& tpMgr = TpMgr::GetInstance(devPhyId);
     517          215 :     const GetTpInfoParam& tpParam = MakeLoopGetTpInfoParam(commAddr);
     518          215 :     HcclResult ret = HcclResult::HCCL_SUCCESS;
     519              :     do {
     520          639 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     521            0 :             HCCL_ERROR(
     522              :                 "[CcuComponent][%s] failed, get tp info "
     523              :                 "timeout[%d ms], devPhyId[%u].",
     524              :                 __func__, timeout, devPhyId);
     525            0 :             return HcclResult::HCCL_E_TIMEOUT;
     526              :         }
     527              : 
     528          639 :         ret = tpMgr.GetTpInfo(tpParam, tpInfo);
     529          639 :     } while (ret == HcclResult::HCCL_E_AGAIN);
     530              : 
     531          215 :     CHK_RET(ret); // 非重试属于异常情况
     532          215 :     return HcclResult::HCCL_SUCCESS;
     533              : }
     534              : 
     535          217 : HcclResult CcuComponent::GetLoopTpInfo(const uint8_t dieId, const CommAddr& commAddr, TpInfo& tpInfo)
     536              : {
     537          217 :     const auto& srcIter = tpInfoMap_.find(dieId);
     538              :     // 优先使用已经创建过的tpHandle
     539          217 :     if (srcIter == tpInfoMap_.end()) {
     540          215 :         TpInfo newTpInfo{};
     541          215 :         CHK_RET(RequestNewLoopTpInfo(devPhyId_, commAddr, newTpInfo));
     542          215 :         tpInfoMap_[dieId] = std::move(newTpInfo);
     543              :     }
     544              : 
     545          217 :     tpInfo = tpInfoMap_[dieId];
     546          217 :     return HcclResult::HCCL_SUCCESS;
     547              : }
     548              : 
     549              : static HcclResult
     550          214 : RequestNewLoopTpAttr(const uint32_t devPhyId, CtxHandle ctxHandle, const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     551              : {
     552          214 :     constexpr auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
     553          214 :     const auto startTime = std::chrono::steady_clock::now();
     554              : 
     555          214 :     auto& tpMgr = TpMgr::GetInstance(devPhyId);
     556          214 :     constexpr uint32_t kTpAttrRetryTimesInitBit = 0U;
     557          214 :     constexpr uint32_t kTpAttrAtBit = 1U;
     558          214 :     constexpr uint32_t TP_ATTR_BITMAP = (1U << kTpAttrRetryTimesInitBit) | (1U << kTpAttrAtBit);
     559          214 :     const GetTpAttrParam tpAttrParam = {tpHandle, TP_ATTR_BITMAP};
     560          214 :     HcclResult ret = HcclResult::HCCL_SUCCESS;
     561              :     do {
     562          320 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     563            0 :             HCCL_ERROR(
     564              :                 "[CcuComponent][%s] failed, get tp attr "
     565              :                 "timeout[%d ms], devPhyId[%d].",
     566              :                 __func__, timeout, devPhyId);
     567            0 :             return HcclResult::HCCL_E_TIMEOUT;
     568              :         }
     569              : 
     570          320 :         ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, ctxHandle);
     571          320 :     } while (ret == HcclResult::HCCL_E_AGAIN);
     572              : 
     573          214 :     CHK_RET(ret);
     574          214 :     return HcclResult::HCCL_SUCCESS;
     575              : }
     576              : 
     577          218 : HcclResult CcuComponent::GetLoopTpAttr(const uint8_t dieId, const CommAddr& commAddr, TpAttrInfo& tpAttrInfo)
     578              : {
     579          218 :     const auto& srcIter = tpAttrInfoMap_.find(dieId);
     580          218 :     if (srcIter == tpAttrInfoMap_.end()) {
     581          215 :         const auto& tpInfoIter = tpInfoMap_.find(dieId);
     582          215 :         CHK_PRT_RET(
     583              :             tpInfoIter == tpInfoMap_.end(),
     584              :             HCCL_ERROR(
     585              :                 "[CcuComponent][%s] failed, tpInfo not found for dieId[%u], "
     586              :                 "devLogicId[%d].",
     587              :                 __func__, dieId, devLogicId_),
     588              :             HcclResult::HCCL_E_NOT_FOUND);
     589              : 
     590          214 :         Hccl::IpAddress ipAddr{};
     591          214 :         CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
     592          214 :         auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
     593          214 :         const CtxHandle ctxHandle = static_cast<CtxHandle>(rdmaHandleMgr.GetByIp(devPhyId_, ipAddr));
     594              : 
     595          214 :         TpAttrInfo newTpAttrInfo{};
     596          214 :         CHK_RET(RequestNewLoopTpAttr(devPhyId_, ctxHandle, tpInfoIter->second.tpHandle, newTpAttrInfo));
     597          214 :         tpAttrInfoMap_[dieId] = std::move(newTpAttrInfo);
     598              :     }
     599              : 
     600          217 :     tpAttrInfo = tpAttrInfoMap_[dieId];
     601          217 :     return HcclResult::HCCL_SUCCESS;
     602              : }
     603              : 
     604          216 : HcclResult CcuComponent::GetLoopJettyTimeout(const uint8_t dieId, const CommAddr& commAddr, uint8_t& errTimeout)
     605              : {
     606          216 :     TpAttrInfo tpAttrInfo{};
     607          216 :     CHK_RET(GetLoopTpAttr(dieId, commAddr, tpAttrInfo));
     608              :     // CTP 协议不感知 TP 建链,跳过 GetTpTotalTimeout(对齐 DevUbConnection::GetTimeOut 的 CTP 分支),
     609              :     // tpTimeOutMs 保持 0,由 TpManager::CalcTaTimeout 内部按 CTP 规则直接使用 taTimeOut_
     610          216 :     uint32_t tpTimeOutMs = 0;
     611          216 :     if (LOOP_JETTY_PROTOCOL != TpProtocol::CTP) {
     612          216 :         CHK_RET(TpMgr::GetTpTotalTimeout(tpAttrInfo, tpTimeOutMs));
     613              :     }
     614          216 :     errTimeout = TpMgr::CalcTaTimeout(LOOP_JETTY_PROTOCOL, TpMgr::TA_TIMEOUT_NOT_SET, tpTimeOutMs);
     615          216 :     return HcclResult::HCCL_SUCCESS;
     616              : }
     617              : 
     618          216 : inline uint32_t GenerateRandomNum()
     619              : {
     620          216 :     uint32_t randNum = std::rand();
     621          216 :     return randNum;
     622              : }
     623              : 
     624          216 : uint32_t CcuComponent::GetNewPsn() const { return GenerateRandomNum(); }
     625              : 
     626              : HcclResult
     627          214 : CcuComponent::ConfigLoopChannel(const uint8_t dieId, const CommAddr& commAddr, const ChannelInfo& channelInfo)
     628              : {
     629          214 :     const uint32_t dstDieId = 1 - dieId; // 当前仅存在最多两个die
     630              :     // 当前环回复用支持die内die间,当两个die均启用时应配置对die,否则为本die
     631          214 :     auto rmaBufferIter = ccuRmaBufferMap_.find(dstDieId);
     632          214 :     if (rmaBufferIter == ccuRmaBufferMap_.end()) {
     633            0 :         rmaBufferIter = ccuRmaBufferMap_.find(dieId);
     634              :     }
     635              : 
     636          214 :     CHK_PRT_RET(
     637              :         rmaBufferIter == ccuRmaBufferMap_.end(),
     638              :         HCCL_WARNING(
     639              :             "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     640              :             "devLogicId[%d].",
     641              :             __func__, dieId, devLogicId_),
     642              :         HcclResult::HCCL_E_NOT_FOUND);
     643              : 
     644          214 :     const auto& ccuRmaBuffer = rmaBufferIter->second;
     645          214 :     const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
     646              : 
     647          214 :     Hccl::IpAddress ipAddr{};
     648          214 :     CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
     649              : 
     650          214 :     ChannelCfg cfg{};
     651          214 :     cfg.channelId = channelInfo.channelId;
     652          214 :     CHK_RET(IpAddressToReverseHcclEid(ipAddr, cfg.remoteEid));
     653          214 :     cfg.tpn = importedOutParamMap_[dieId][0].second.tpn; // 环回仅1个对端
     654          214 :     cfg.remoteCcuVa = ccuRmaBuffer->GetBuf()->GetAddr();
     655          214 :     cfg.memTokenId = ccuRmaBuffer->GetTokenId();
     656          214 :     cfg.memTokenValue = ccuBufTokenValue;
     657              : 
     658          214 :     const auto& jettyInfos = channelInfo.jettyInfos;
     659          214 :     const auto& createdVec = createdOutParamMap_[dieId];
     660          214 :     const uint32_t jettyNum = jettyInfos.size();
     661          428 :     for (uint32_t i = 0; i < jettyNum; i++) {
     662          214 :         cfg.jettyCfgs.emplace_back(
     663          214 :             JettyCfg{jettyInfos[i].jettyCtxId, createdVec[i].dbVa, createdVec[i].dbTokenId, ccuBufTokenValue});
     664              :     }
     665              : 
     666          214 :     return channelCtxMgrs_[dieId]->Config(cfg);
     667          214 : }
     668              : 
     669          107 : HcclResult CcuComponent::ConfigMsIdToken()
     670              : {
     671          107 :     const auto serveMode = CcuResSpecifications::GetInstance(devLogicId_).GetServeMode();
     672          107 :     CustomChannelInfoIn inBuff{};
     673          107 :     CustomChannelInfoOut outBuff{};
     674          321 :     for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
     675          214 :         const auto& dieIter = ccuRmaBufferMap_.find(dieId);
     676          214 :         if (dieIter == ccuRmaBufferMap_.end()) {
     677            0 :             HCCL_WARNING(
     678              :                 "[CcuComponent][%s] failed but passed, ccu rma buffer of die[%u] "
     679              :                 "is not existed, devLogicId[%d].",
     680              :                 __func__, dieId, devLogicId_);
     681            0 :             continue;
     682              :         }
     683          214 :         const auto& ccuRmaBuffer = dieIter->second;
     684          214 :         const uint32_t tokenId = ccuRmaBuffer->GetTokenId();
     685          214 :         const uint32_t tokenValue = ccuRmaBuffer->GetTokenValue();
     686          214 :         uint32_t msId = 0;
     687              :         // 非A+X, 非die 0,采用默认交织粒度
     688          214 :         if (serveMode == ServeMode::ARMX86 && dieId == 0) {
     689            0 :             msId = MSID_CONFIG_ARMX86_MAINBOARD;
     690              :         } else {
     691          214 :             CHK_RET(CcuResSpecifications::GetInstance(devLogicId_).GetMsId(dieId, msId));
     692              :         }
     693              : 
     694          214 :         inBuff.op = CcuOpcodeType::CCU_U_OP_SET_MSID_TOKEN;
     695          214 :         inBuff.offsetStartIdx = 0;
     696          214 :         inBuff.data.dataInfo.udieIdx = dieId;
     697          214 :         inBuff.data.dataInfo.dataArray[0].baseinfo.msId = msId;
     698          214 :         inBuff.data.dataInfo.dataArray[0].baseinfo.tokenId = tokenId;
     699          214 :         inBuff.data.dataInfo.dataArray[0].baseinfo.tokenValue = tokenValue;
     700              : 
     701          214 :         auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
     702          214 :         if (ret != HCCL_SUCCESS) {
     703            0 :             HCCL_ERROR(
     704              :                 "[CcuComponent][%s] failed to call ccu driver, "
     705              :                 "devLogicId[%d] dieId[%d] op[%s] ret[%d].",
     706              :                 __func__, devLogicId_, dieId, "SET_MSID_TOKEN", ret);
     707            0 :             return ret;
     708              :         }
     709              : 
     710          214 :         HCCL_INFO("[CcuComponent][%s] config MS ID token success, dieId[%u], msid[%u]", __func__, dieId, msId);
     711              :     }
     712              : 
     713          107 :     return HcclResult::HCCL_SUCCESS;
     714              : }
     715              : 
     716           15 : HcclResult CcuComponent::GetCcuResourceSpaceBufInfo(const uint8_t dieId, uint64_t& addr, uint64_t& size) const
     717              : {
     718           15 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     719              : 
     720           15 :     auto res = ccuRmaBufferMap_.find(dieId);
     721           15 :     CHK_PRT_RET(
     722              :         res == ccuRmaBufferMap_.end(),
     723              :         HCCL_WARNING(
     724              :             "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     725              :             "devLogicId[%d].",
     726              :             __func__, dieId, devLogicId_),
     727              :         HcclResult::HCCL_E_NOT_FOUND);
     728              : 
     729           15 :     const auto rawBuffer = res->second->GetBuf();
     730           15 :     addr = static_cast<uint64_t>(rawBuffer->GetAddr());
     731           15 :     size = static_cast<uint64_t>(rawBuffer->GetSize());
     732           15 :     return HcclResult::HCCL_SUCCESS;
     733              : }
     734              : 
     735              : HcclResult
     736          213 : CcuComponent::GetCcuResourceSpaceTokenInfo(const uint8_t dieId, uint64_t& tokenId, uint64_t& tokenValue) const
     737              : {
     738          213 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     739              : 
     740          213 :     auto res = ccuRmaBufferMap_.find(dieId);
     741          213 :     CHK_PRT_RET(
     742              :         res == ccuRmaBufferMap_.end(),
     743              :         HCCL_WARNING(
     744              :             "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     745              :             "devLogicId[%d].",
     746              :             __func__, dieId, devLogicId_),
     747              :         HcclResult::HCCL_E_NOT_FOUND);
     748              : 
     749          213 :     const auto& ccuRmaBuffer = res->second;
     750          213 :     tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
     751          213 :     tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
     752          213 :     return HcclResult::HCCL_SUCCESS;
     753              : }
     754              : 
     755              : HcclResult
     756           15 : CcuComponent::AllocChannels(const uint8_t dieId, const ChannelPara& channelPara, std::vector<ChannelInfo>& channelInfos)
     757              : {
     758           15 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     759              : 
     760           15 :     CHK_PTR_NULL(channelCtxMgrs_[dieId]);
     761           15 :     auto ret = channelCtxMgrs_[dieId]->Alloc(channelPara, channelInfos);
     762           15 :     CHK_PRT_RET(
     763              :         ret != HcclResult::HCCL_SUCCESS,
     764              :         HCCL_WARNING(
     765              :             "[CcuComponent][%s] failed, feId[%u], devLogicId[%d], dieId[%u].", __func__, channelPara.feId, devLogicId_,
     766              :             dieId),
     767              :         ret);
     768              : 
     769           15 :     return HcclResult::HCCL_SUCCESS;
     770              : }
     771              : 
     772            0 : HcclResult CcuComponent::ConfigChannel(const uint8_t dieId, const ChannelCfg& cfg)
     773              : {
     774            0 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     775              : 
     776            0 :     uint32_t channelId = cfg.channelId;
     777            0 :     CHK_PRT_RET(
     778              :         channelId == loopChannelIds_[dieId],
     779              :         HCCL_WARNING(
     780              :             "[CcuComponent][%s] failed, refused to config loop channel[%u], "
     781              :             "devLogicId[%d], dieId[%u].",
     782              :             __func__, channelId, devLogicId_, dieId),
     783              :         HcclResult::HCCL_E_PARA);
     784              : 
     785            0 :     CHK_PTR_NULL(channelCtxMgrs_[dieId]);
     786            0 :     auto ret = channelCtxMgrs_[dieId]->Config(cfg);
     787            0 :     CHK_PRT_RET(
     788              :         ret != HcclResult::HCCL_SUCCESS,
     789              :         HCCL_WARNING(
     790              :             "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId_,
     791              :             dieId),
     792              :         ret);
     793              : 
     794            0 :     return HcclResult::HCCL_SUCCESS;
     795              : }
     796              : 
     797           29 : HcclResult CcuComponent::ReleaseChannel(const uint8_t dieId, const uint32_t channelId)
     798              : {
     799           29 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     800           29 :     CHK_PRT_RET(
     801              :         channelId == loopChannelIds_[dieId],
     802              :         HCCL_WARNING(
     803              :             "[CcuComponent][%s] failed, refused to release loop channel[%u], "
     804              :             "devLogicId[%d], dieId[%u].",
     805              :             __func__, channelId, devLogicId_, dieId),
     806              :         HcclResult::HCCL_E_PARA);
     807              : 
     808           29 :     CHK_PTR_NULL(channelCtxMgrs_[dieId]);
     809           29 :     auto ret = channelCtxMgrs_[dieId]->Release(channelId);
     810           29 :     CHK_PRT_RET(
     811              :         ret != HcclResult::HCCL_SUCCESS,
     812              :         HCCL_WARNING(
     813              :             "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId_,
     814              :             dieId),
     815              :         ret);
     816              : 
     817           29 :     return HcclResult::HCCL_SUCCESS;
     818              : }
     819              : 
     820          396 : HcclResult CcuComponent::GetLoopChannelId(const uint8_t srcDieId, const uint8_t dstDieId, uint32_t& channelId) const
     821              : {
     822          396 :     channelId = INVAILD_LOOP_CHANNEL_ID; // 允许die未启用时查询环回channelId
     823              : 
     824          396 :     CHK_RET(CheckDieValid(__func__, devLogicId_, srcDieId, {true, true}));
     825          396 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dstDieId, {true, true}));
     826              : 
     827              :     // 特殊处理die未启用场景
     828          396 :     CHK_PRT_RET(
     829              :         !dieEnableFlags_[srcDieId] || !dieEnableFlags_[dstDieId],
     830              :         HCCL_WARNING(
     831              :             "[CcuComponent][%s] passed, srcDie[%u] or dstDie[%u] is not enable,"
     832              :             "devLogicId[%d].",
     833              :             __func__, srcDieId, dstDieId, devLogicId_),
     834              :         HcclResult::HCCL_SUCCESS);
     835              : 
     836              :     // 当前环回channel每个die占用1个,不区分die内die间
     837          396 :     CHK_PRT_RET(
     838              :         loopChannelIds_[srcDieId] == INVAILD_LOOP_CHANNEL_ID,
     839              :         HCCL_ERROR(
     840              :             "[CcuComponent][%s] failed, invalid loop channel id, "
     841              :             "devLogicId[%d], srcDieId[%u].",
     842              :             __func__, devLogicId_, srcDieId),
     843              :         HcclResult::HCCL_E_INTERNAL);
     844              : 
     845          396 :     channelId = loopChannelIds_[srcDieId];
     846          396 :     return HcclResult::HCCL_SUCCESS;
     847              : }
     848              : 
     849         1754 : HcclResult CcuComponent::AllocRes(
     850              :     const uint8_t dieId, const ResType resType, const uint32_t num, const bool consecutive,
     851              :     std::vector<ResInfo>& resInfos)
     852              : {
     853         1754 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     854              : 
     855         1754 :     CHK_PTR_NULL(resAllocators_[dieId]);
     856         1754 :     auto ret = resAllocators_[dieId]->Alloc(resType, num, consecutive, resInfos);
     857         1754 :     CHK_PRT_RET(
     858              :         ret != HcclResult::HCCL_SUCCESS,
     859              :         HCCL_WARNING(
     860              :             "[CcuComponent][%s] failed, resType[%s], num[%u], devLogicId[%d], dieId[%u].", __func__,
     861              :             resType.Describe().c_str(), num, devLogicId_, dieId),
     862              :         ret);
     863              : 
     864         1754 :     return HcclResult::HCCL_SUCCESS;
     865              : }
     866              : 
     867              : HcclResult
     868            0 : CcuComponent::ReleaseRes(const uint8_t dieId, const ResType resType, const uint32_t startId, const uint32_t num)
     869              : {
     870            0 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     871              : 
     872            0 :     CHK_PTR_NULL(resAllocators_[dieId]);
     873            0 :     auto ret = resAllocators_[dieId]->Release(resType, startId, num);
     874            0 :     CHK_PRT_RET(
     875              :         ret != HcclResult::HCCL_SUCCESS,
     876              :         HCCL_WARNING(
     877              :             "[CcuComponent][%s] failed, resType[%s], startId[%u], num[%u], "
     878              :             "devLogicId[%d], dieId[%u].",
     879              :             __func__, resType.Describe().c_str(), startId, num, devLogicId_, dieId),
     880              :         ret);
     881              : 
     882            0 :     return HcclResult::HCCL_SUCCESS;
     883              : }
     884              : 
     885            0 : uint32_t CcuComponent::GetInsConsecutiveRemainSize(const uint8_t dieId) const
     886              : {
     887            0 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     888            0 :     if (resAllocators_[dieId] == nullptr)
     889            0 :         return 0;
     890            0 :     return resAllocators_[dieId]->GetConsecutiveRemainSize(ResType::INS);
     891              : }
     892              : 
     893           47 : HcclResult CcuComponent::AllocIns(const uint8_t dieId, const uint32_t num, ResInfo& insInfo)
     894              : {
     895           47 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     896              : 
     897           47 :     CHK_PTR_NULL(resAllocators_[dieId]);
     898           47 :     std::vector<ResInfo> resInfos;
     899           47 :     auto ret = resAllocators_[dieId]->Alloc(ResType::INS, num, true, resInfos);
     900           47 :     CHK_PRT_RET(
     901              :         ret != HcclResult::HCCL_SUCCESS,
     902              :         HCCL_WARNING(
     903              :             "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId_, dieId),
     904              :         ret);
     905              : 
     906           47 :     insInfo = resInfos[0]; // 申请连续资源只会有一份
     907           47 :     return HcclResult::HCCL_SUCCESS;
     908           47 : }
     909              : 
     910           47 : HcclResult CcuComponent::ReleaseIns(const uint8_t dieId, const ResInfo& insInfo)
     911              : {
     912           47 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     913              : 
     914           47 :     CHK_PTR_NULL(resAllocators_[dieId]);
     915           47 :     auto ret = resAllocators_[dieId]->Release(ResType::INS, insInfo.startId, insInfo.num);
     916           47 :     CHK_PRT_RET(
     917              :         ret != HcclResult::HCCL_SUCCESS,
     918              :         HCCL_WARNING(
     919              :             "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__, insInfo.Describe().c_str(),
     920              :             devLogicId_, dieId),
     921              :         ret);
     922              : 
     923           47 :     return HcclResult::HCCL_SUCCESS;
     924              : }
     925              : 
     926           15 : HcclResult CcuComponent::AllocCke(const uint8_t dieId, const uint32_t num, std::vector<ResInfo>& ckeInfos)
     927              : {
     928           15 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     929              : 
     930           15 :     CHK_PTR_NULL(resAllocators_[dieId]);
     931           15 :     auto ret = resAllocators_[dieId]->Alloc(ResType::CKE, num, false, ckeInfos);
     932           15 :     CHK_PRT_RET(
     933              :         ret != HcclResult::HCCL_SUCCESS,
     934              :         HCCL_WARNING(
     935              :             "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId_, dieId),
     936              :         ret);
     937              : 
     938           15 :     return HcclResult::HCCL_SUCCESS;
     939              : }
     940              : 
     941           15 : HcclResult CcuComponent::ReleaseCke(const uint8_t dieId, const std::vector<ResInfo>& ckeInfos)
     942              : {
     943           15 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     944              : 
     945           15 :     CHK_PTR_NULL(resAllocators_[dieId]);
     946           30 :     for (auto& ckeInfo : ckeInfos) {
     947           15 :         auto ret = resAllocators_[dieId]->Release(ResType::CKE, ckeInfo.startId, ckeInfo.num);
     948           15 :         CHK_PRT_RET(
     949              :             ret != HcclResult::HCCL_SUCCESS,
     950              :             HCCL_WARNING(
     951              :                 "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
     952              :                 ckeInfo.Describe().c_str(), devLogicId_, dieId),
     953              :             ret);
     954              :     }
     955              : 
     956           15 :     return HcclResult::HCCL_SUCCESS;
     957              : }
     958              : 
     959           15 : HcclResult CcuComponent::AllocXn(const uint8_t dieId, const uint32_t num, std::vector<ResInfo>& xnInfos)
     960              : {
     961           15 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     962              : 
     963           15 :     CHK_PTR_NULL(resAllocators_[dieId]);
     964           15 :     auto ret = resAllocators_[dieId]->Alloc(ResType::XN, num, false, xnInfos);
     965           15 :     CHK_PRT_RET(
     966              :         ret != HcclResult::HCCL_SUCCESS,
     967              :         HCCL_WARNING(
     968              :             "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId_, dieId),
     969              :         ret);
     970              : 
     971           15 :     return HcclResult::HCCL_SUCCESS;
     972              : }
     973              : 
     974           15 : HcclResult CcuComponent::ReleaseXn(const uint8_t dieId, const std::vector<ResInfo>& xnInfos)
     975              : {
     976           15 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
     977              : 
     978           15 :     CHK_PTR_NULL(resAllocators_[dieId]);
     979           30 :     for (auto& xnInfo : xnInfos) {
     980           15 :         auto ret = resAllocators_[dieId]->Release(ResType::XN, xnInfo.startId, xnInfo.num);
     981           15 :         CHK_PRT_RET(
     982              :             ret != HcclResult::HCCL_SUCCESS,
     983              :             HCCL_WARNING(
     984              :                 "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
     985              :                 xnInfo.Describe().c_str(), devLogicId_, dieId),
     986              :             ret);
     987              :     }
     988              : 
     989           15 :     return HcclResult::HCCL_SUCCESS;
     990              : }
     991              : 
     992              : constexpr u32 WISH_COUNT_XN_NUM = 511;
     993              : constexpr u32 TOTAL_COUNT_XN_NUM = 1;
     994              : 
     995            0 : HcclResult CcuComponent::SetSplitUnit(uint8_t dieId, uint32_t splitPktUnit) const
     996              : {
     997            0 :     CHK_PRT_RET(
     998              :         dieId >= MAX_CCU_IODIE_NUM,
     999              :         HCCL_ERROR(
    1000              :             "[CcuComponent][%s] failed, dieId[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, dieId,
    1001              :             MAX_CCU_IODIE_NUM, devLogicId_),
    1002              :         HcclResult::HCCL_E_PARA);
    1003              : 
    1004            0 :     CustomChannelInfoIn inBuff{};
    1005            0 :     CustomChannelInfoOut outBuff{};
    1006              : 
    1007            0 :     inBuff.op = CcuOpcodeType::CCU_U_OP_SET_TIF_SPLIT_SIZE;
    1008            0 :     inBuff.data.dataInfo.udieIdx = dieId;
    1009            0 :     inBuff.data.dataInfo.dataArraySize = 1;
    1010            0 :     inBuff.data.dataInfo.dataLen = sizeof(CcuDataTypeUnion) * inBuff.data.dataInfo.dataArraySize;
    1011              : 
    1012            0 :     inBuff.data.dataInfo.dataArray[0].tifSplitSize.splitPktUnit = splitPktUnit & 0b1;
    1013            0 :     inBuff.data.dataInfo.dataArray[0].tifSplitSize.tpSplitSize = 0x2;  // 0x2:TP模式的拆包size为4KB
    1014            0 :     inBuff.data.dataInfo.dataArray[0].tifSplitSize.ctpSplitSize = 0x1; // 0x1:CTP模式的拆包size为4KB
    1015              : 
    1016            0 :     auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
    1017            0 :     if (ret != 0) {
    1018            0 :         HCCL_ERROR(
    1019              :             "[CcuComponent][%s] failed to call ccu driver, "
    1020              :             "devPhyId[%u] dieId[%d] op[%s].",
    1021              :             __func__, devPhyId_, dieId, "CCU_U_OP_SET_TIF_SPLIT_SIZE");
    1022            0 :         return HcclResult::HCCL_E_NETWORK;
    1023              :     }
    1024            0 :     return HcclResult::HCCL_SUCCESS;
    1025              : }
    1026              : 
    1027            0 : HcclResult CcuComponent::GetAvailableTotalCntXnIndex(uint32_t& index) const
    1028              : {
    1029            0 :     for (uint32_t i = 0; i < CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM; ++i) {
    1030            0 :         if (!usedTotalCntXnFlags_[i]) {
    1031            0 :             index = i;
    1032            0 :             return HcclResult::HCCL_SUCCESS;
    1033              :         }
    1034              :     }
    1035              : 
    1036            0 :     HCCL_ERROR("[CcuComponent][%s] failed, no available TotalCnt Xns.", __func__);
    1037            0 :     return HcclResult::HCCL_E_UNAVAIL;
    1038              : }
    1039              : 
    1040            0 : HcclResult CcuComponent::SetTotalCntXn(uint8_t dieId, uint32_t fromId, uint32_t toId, uint32_t totalId, uint32_t index)
    1041              : {
    1042            0 :     CHK_PRT_RET(
    1043              :         fromId > toId,
    1044              :         HCCL_ERROR("[CcuComponent][%s] failed, fromId or toId invalid, fromId[%u] > toId[%u].", __func__, fromId, toId),
    1045              :         HcclResult::HCCL_E_PARA);
    1046              : 
    1047            0 :     CHK_PRT_RET(
    1048              :         fromId <= totalId && totalId <= toId,
    1049              :         HCCL_ERROR(
    1050              :             "[CcuComponent][%s] failed, totalId[%u] invalid, should not be in [fromId[%u], toId[%u]].", __func__,
    1051              :             totalId, fromId, toId),
    1052              :         HcclResult::HCCL_E_PARA);
    1053              : 
    1054            0 :     HcclResult ret = SetTotalCntXnProcess(dieId, index, fromId, toId, totalId);
    1055            0 :     CHK_PRT_RET(
    1056              :         ret != HcclResult::HCCL_SUCCESS,
    1057              :         HCCL_ERROR(
    1058              :             "[CcuComponent][%s] failed, dieId[%u], index[%u], devLogicId[%d].", __func__, dieId, index, devLogicId_),
    1059              :         ret);
    1060              : 
    1061            0 :     usedTotalCntXnFlags_[index] = true;
    1062            0 :     return HcclResult::HCCL_SUCCESS;
    1063              : }
    1064              : 
    1065            0 : HcclResult CcuComponent::ResetTotalCntXn(uint8_t dieId, uint32_t index)
    1066              : {
    1067            0 :     if (index >= CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM || !usedTotalCntXnFlags_[index]) {
    1068            0 :         return HcclResult::HCCL_SUCCESS;
    1069              :     }
    1070              : 
    1071              :     static constexpr uint32_t fromIdDefault = 0xFFFF; // from默认值
    1072              :     static constexpr uint32_t toIdDefault = 0x0000;   // to默认值
    1073              :     static constexpr uint32_t totalIdDefault[CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM]{
    1074              :         0x3FFC, 0x3FFD, 0x3FFE, 0x3FFF}; // total默认值
    1075              : 
    1076            0 :     auto ret = SetTotalCntXnProcess(dieId, index, fromIdDefault, toIdDefault, totalIdDefault[index]);
    1077            0 :     CHK_PRT_RET(
    1078              :         ret != HcclResult::HCCL_SUCCESS,
    1079              :         HCCL_ERROR(
    1080              :             "[CcuComponent][%s] failed, dieId[%u], index[%u], devLogicId[%d].", __func__, dieId, index, devLogicId_),
    1081              :         ret);
    1082              : 
    1083            0 :     usedTotalCntXnFlags_[index] = false;
    1084            0 :     return HcclResult::HCCL_SUCCESS;
    1085              : }
    1086              : 
    1087            0 : HcclResult CcuComponent::SetTotalCntXnProcess(
    1088              :     uint8_t dieId, uint32_t index, uint32_t fromId, uint32_t toId, uint32_t totalId) const
    1089              : {
    1090            0 :     CHK_PRT_RET(
    1091              :         dieId >= MAX_CCU_IODIE_NUM,
    1092              :         HCCL_ERROR(
    1093              :             "[CcuComponent][%s] failed, dieId[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, dieId,
    1094              :             MAX_CCU_IODIE_NUM, devLogicId_),
    1095              :         HcclResult::HCCL_E_PARA);
    1096              : 
    1097            0 :     CHK_PRT_RET(
    1098              :         index >= CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM,
    1099              :         HCCL_ERROR(
    1100              :             "[CcuComponent][%s] failed, index[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, index,
    1101              :             CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM, devLogicId_),
    1102              :         HcclResult::HCCL_E_PARA);
    1103              : 
    1104            0 :     CustomChannelInfoIn inBuff{};
    1105            0 :     CustomChannelInfoOut outBuff{};
    1106              : 
    1107            0 :     inBuff.op = CcuOpcodeType::CCU_U_OP_SET_XN_TOTAL_CNT;
    1108            0 :     inBuff.data.dataInfo.udieIdx = dieId;
    1109            0 :     inBuff.data.dataInfo.dataArraySize = 1;
    1110            0 :     inBuff.data.dataInfo.dataLen = sizeof(CcuDataTypeUnion) * inBuff.data.dataInfo.dataArraySize;
    1111              : 
    1112            0 :     inBuff.data.dataInfo.dataArray[0].xnTotalCnt.cntIndex = index & 0b11; // range: [0, 3]
    1113            0 :     inBuff.data.dataInfo.dataArray[0].xnTotalCnt.flagFromAddr = fromId;
    1114            0 :     inBuff.data.dataInfo.dataArray[0].xnTotalCnt.flagToAddr = toId;
    1115            0 :     inBuff.data.dataInfo.dataArray[0].xnTotalCnt.totalAddr = totalId;
    1116            0 :     auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
    1117            0 :     if (ret != 0) {
    1118            0 :         HCCL_ERROR(
    1119              :             "[CcuComponent][%s] failed to call ccu driver, "
    1120              :             "devPhyId[%u] dieId[%d] op[%s].",
    1121              :             __func__, devPhyId_, dieId, "CCU_U_OP_SET_XN_TOTAL_CNT");
    1122            0 :         return HcclResult::HCCL_E_NETWORK;
    1123              :     }
    1124              : 
    1125            0 :     return HcclResult::HCCL_SUCCESS;
    1126              : }
    1127              : 
    1128            0 : HcclResult CcuComponent::ConfirmCntXns(const uint8_t dieId, const std::string& resGroupTag, const ResInfo& cntXnInfos)
    1129              : {
    1130            0 :     struct CntXnBlock cntXnBlock;
    1131            0 :     uint32_t totalCntXnId = cntXnInfos.startId + cntXnInfos.num - TOTAL_COUNT_XN_NUM;
    1132            0 :     uint32_t wishCntXnIdBegin = cntXnInfos.startId;
    1133            0 :     uint32_t wishCntXnIdEnd = totalCntXnId - 1;
    1134            0 :     uint32_t blockIdx = CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM; // invalid value
    1135              : 
    1136            0 :     HCCL_INFO(
    1137              :         "Set TotalCntXn, wishCntXnIdBegin[%u] wishCntXnIdEnd[%u] totalCntXnId[%u]", wishCntXnIdBegin, wishCntXnIdEnd,
    1138              :         totalCntXnId);
    1139              : 
    1140            0 :     auto ret = GetAvailableTotalCntXnIndex(blockIdx);
    1141            0 :     CHK_PRT_RET(
    1142              :         ret != HcclResult::HCCL_SUCCESS,
    1143              :         HCCL_ERROR(
    1144              :             "[CcuComponent][%s] failed, no available TotalCnt Xns, dieId[%u], devLogicId[%d].", __func__, dieId,
    1145              :             devLogicId_),
    1146              :         ret);
    1147            0 :     CHK_RET(SetTotalCntXn(dieId, wishCntXnIdBegin, wishCntXnIdEnd, totalCntXnId, blockIdx));
    1148            0 :     HCCL_INFO("Set TotalCntXn success, index[%u]", blockIdx);
    1149              : 
    1150            0 :     ret = SetSplitUnit(dieId, 0); // 0表示stomic store add value的单位是byte。1表示以包为单位
    1151            0 :     if (ret != HcclResult::HCCL_SUCCESS) {
    1152            0 :         HCCL_ERROR("[CcuComponent][%s] SetSplitUnit failed, dieId[%u], devLogicId[%d].", __func__, dieId, devLogicId_);
    1153            0 :         CHK_RET(ResetTotalCntXn(dieId, blockIdx));
    1154            0 :         return ret;
    1155              :     }
    1156              : 
    1157            0 :     for (u32 idx = wishCntXnIdBegin; idx <= wishCntXnIdEnd; idx++) {
    1158            0 :         cntXnBlock.wishCntXns.push(idx);
    1159              :     }
    1160            0 :     cntXnBlock.resInfo = cntXnInfos;
    1161            0 :     cntXnBlock.totalCntXn = totalCntXnId;
    1162            0 :     cntXnBlock.blockIdx = blockIdx;
    1163            0 :     cntXnBlocks_[dieId].insert(std::make_pair(resGroupTag, cntXnBlock));
    1164            0 :     return HcclResult::HCCL_SUCCESS;
    1165            0 : }
    1166              : 
    1167            0 : HcclResult CcuComponent::AllocWishCntXn(const uint8_t dieId, const std::string& resGroupTag, uint32_t& wishCntXn)
    1168              : {
    1169            0 :     CHK_PRT_RET(
    1170              :         (ccuVersion_ != CcuVersion::CCU_V2),
    1171              :         HCCL_ERROR("[CcuComponent][%s] failed, ccuVersion[%d] does not support this interface.", __func__, ccuVersion_),
    1172              :         HCCL_E_NOT_SUPPORT);
    1173            0 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
    1174              : 
    1175            0 :     std::unique_lock<std::mutex> lock(cntXnBlockMutex_);
    1176            0 :     auto& cntXnBlocks = cntXnBlocks_[dieId];
    1177            0 :     auto iter = cntXnBlocks.find(resGroupTag);
    1178            0 :     if (iter != cntXnBlocks.end()) {
    1179            0 :         CHK_PRT_RET(
    1180              :             (iter->second.wishCntXns.size() == 0),
    1181              :             HCCL_ERROR(
    1182              :                 "[CcuComponent][%s] failed, wishCntXn is not enough, resGroupTag[%s], devLogicId[%d], "
    1183              :                 "dieId[%u].",
    1184              :                 __func__, resGroupTag.c_str(), devLogicId_, dieId),
    1185              :             HCCL_E_UNAVAIL);
    1186              :     } else {
    1187            0 :         CHK_PRT_RET(
    1188              :             (cntXnBlocks.size() == CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM),
    1189              :             HCCL_ERROR(
    1190              :                 "[CcuComponent][%s] failed, cntXnBlock is not enough, resGroupTag[%s], "
    1191              :                 "devLogicId[%d], dieId[%u].",
    1192              :                 __func__, resGroupTag.c_str(), devLogicId_, dieId),
    1193              :             HCCL_E_UNAVAIL);
    1194            0 :         ResInfo countXnInfo;
    1195              :         // 申请511 + 1个cntXn,前511个为wishCntXn,最后一个为totalCntXn
    1196            0 :         auto ret = resAllocators_[dieId]->AllocCountXn(WISH_COUNT_XN_NUM + TOTAL_COUNT_XN_NUM, countXnInfo);
    1197            0 :         CHK_PRT_RET(
    1198              :             ret != HcclResult::HCCL_SUCCESS,
    1199              :             HCCL_ERROR(
    1200              :                 "[CcuComponent][%s] failed, num[%u], resGroupTag[%s], devLogicId[%d], dieId[%u].", __func__,
    1201              :                 (WISH_COUNT_XN_NUM + TOTAL_COUNT_XN_NUM), resGroupTag.c_str(), devLogicId_, dieId),
    1202              :             ret);
    1203              :         // 配置cntXn
    1204            0 :         ret = ConfirmCntXns(dieId, resGroupTag, countXnInfo);
    1205            0 :         if (ret != HcclResult::HCCL_SUCCESS) {
    1206            0 :             HCCL_ERROR(
    1207              :                 "[CcuComponent][%s] failed[%d] to confirm cnt xns, "
    1208              :                 "try to release new allocated cnt xns, dieId[%u] resGroupTag[%s].",
    1209              :                 __func__, ret, dieId, resGroupTag.c_str());
    1210            0 :             CHK_RET(resAllocators_[dieId]->ReleaseCountXn(countXnInfo.startId, countXnInfo.num));
    1211            0 :             return ret;
    1212              :         }
    1213              :     }
    1214            0 :     auto& xnBlock = cntXnBlocks_[dieId][resGroupTag];
    1215            0 :     HCCL_INFO("resGroupTag[%s] stack size[%u]", resGroupTag.c_str(), xnBlock.wishCntXns.size());
    1216            0 :     wishCntXn = xnBlock.wishCntXns.top();
    1217            0 :     xnBlock.wishCntXns.pop();
    1218            0 :     uint32_t totalCntXn = xnBlock.totalCntXn;
    1219            0 :     HCCL_INFO(
    1220              :         "[CcuComponent][%s] success, resGroupTag[%s], devLogicId[%d], dieId[%u], wishCntXn[%u], totalCntXn[%u].",
    1221              :         __func__, resGroupTag.c_str(), devLogicId_, dieId, wishCntXn, totalCntXn);
    1222              : 
    1223            0 :     return HcclResult::HCCL_SUCCESS;
    1224            0 : }
    1225              : 
    1226            0 : HcclResult CcuComponent::ReleaseWishCntXn(const uint8_t dieId, const std::string& resGroupTag, uint32_t wishCntXn)
    1227              : {
    1228            0 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
    1229              : 
    1230            0 :     std::unique_lock<std::mutex> lock(cntXnBlockMutex_);
    1231            0 :     if (cntXnBlocks_[dieId].find(resGroupTag) == cntXnBlocks_[dieId].end()) {
    1232            0 :         HCCL_ERROR(
    1233              :             "[CcuComponent][%s] failed, resGroupTag[%s] is not found, devLogicId[%d], dieId[%u].", __func__,
    1234              :             resGroupTag.c_str(), devLogicId_, dieId);
    1235            0 :         return HCCL_E_NOT_FOUND;
    1236              :     }
    1237              : 
    1238            0 :     auto& xnBlock = cntXnBlocks_[dieId][resGroupTag];
    1239            0 :     xnBlock.wishCntXns.push(wishCntXn);
    1240            0 :     if (xnBlock.wishCntXns.size() != WISH_COUNT_XN_NUM) {
    1241            0 :         HCCL_INFO(
    1242              :             "[CcuComponent][%s] success, resGroupTag[%s], devLogicId[%d], dieId[%u], wishCntXn[%u], available "
    1243              :             "wishCntXn num[%u].",
    1244              :             __func__, resGroupTag.c_str(), devLogicId_, dieId, wishCntXn, xnBlock.wishCntXns.size());
    1245            0 :         return HCCL_SUCCESS;
    1246              :     }
    1247              : 
    1248              :     // 所有wishCnt都已经release,释放资源
    1249            0 :     CHK_RET(ResetTotalCntXn(dieId, xnBlock.blockIdx));
    1250              : 
    1251            0 :     auto ret = resAllocators_[dieId]->ReleaseCountXn(xnBlock.resInfo.startId, xnBlock.resInfo.num);
    1252            0 :     CHK_PRT_RET(
    1253              :         ret != HcclResult::HCCL_SUCCESS,
    1254              :         HCCL_ERROR(
    1255              :             "[CcuComponent][%s] failed, resGroupTag[%s], resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
    1256              :             resGroupTag.c_str(), xnBlock.resInfo.Describe().c_str(), devLogicId_, dieId),
    1257              :         ret);
    1258            0 :     cntXnBlocks_[dieId].erase(resGroupTag);
    1259              : 
    1260            0 :     return HcclResult::HCCL_SUCCESS;
    1261            0 : }
    1262              : 
    1263            0 : HcclResult CcuComponent::GetCntXnBlock(
    1264              :     const uint8_t dieId, const std::string& resGroupTag, std::pair<uint32_t, uint32_t>& cntXnPair)
    1265              : {
    1266            0 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
    1267              : 
    1268            0 :     std::unique_lock<std::mutex> lock(cntXnBlockMutex_);
    1269            0 :     auto iter = cntXnBlocks_[dieId].find(resGroupTag);
    1270            0 :     if (iter == cntXnBlocks_[dieId].end()) {
    1271            0 :         HCCL_ERROR(
    1272              :             "[CcuComponent][%s] failed, resGroupTag[%s] is not found, devLogicId[%d], dieId[%u].", __func__,
    1273              :             resGroupTag.c_str(), devLogicId_, dieId);
    1274            0 :         return HCCL_E_NOT_FOUND;
    1275              :     }
    1276              : 
    1277            0 :     cntXnPair = std::make_pair(iter->second.resInfo.startId, iter->second.totalCntXn);
    1278              : 
    1279            0 :     return HcclResult::HCCL_SUCCESS;
    1280            0 : }
    1281              : 
    1282            0 : HcclResult CcuComponent::GetTotalCntXn(const uint8_t dieId, const std::string& resGroupTag, uint32_t& totalCntXn)
    1283              : {
    1284            0 :     CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
    1285              : 
    1286            0 :     std::unique_lock<std::mutex> lock(cntXnBlockMutex_);
    1287            0 :     auto iter = cntXnBlocks_[dieId].find(resGroupTag);
    1288            0 :     if (iter == cntXnBlocks_[dieId].end()) {
    1289            0 :         HCCL_ERROR(
    1290              :             "[CcuComponent][%s] failed, resGroupTag[%s] is not found, devLogicId[%d], dieId[%u].", __func__,
    1291              :             resGroupTag.c_str(), devLogicId_, dieId);
    1292            0 :         return HCCL_E_NOT_FOUND;
    1293              :     }
    1294              : 
    1295            0 :     totalCntXn = iter->second.totalCntXn;
    1296              : 
    1297            0 :     return HcclResult::HCCL_SUCCESS;
    1298            0 : }
    1299              : 
    1300         3679 : const std::array<bool, CCU_MAX_IODIE_NUM>& CcuComponent::GetDieEnableFlags() const { return dieEnableFlags_; }
    1301              : 
    1302          393 : HcclResult CcuComponent::ReleaseJettyRes()
    1303              : {
    1304          393 :     CHK_RET(UnimportAllJettys());
    1305          393 :     CHK_RET(ReleaseAllTpInfos());
    1306          390 :     CHK_RET(DestroyAllJettys());
    1307              :     // HrtRaUbLocalMemReg 跟随 LocalUbRmaBuffer 析构时释放
    1308              :     // 环回channel不需要手动释放,channelCtxMgr跟随CcuComponent释放
    1309          390 :     return HcclResult::HCCL_SUCCESS;
    1310              : }
    1311              : 
    1312          393 : HcclResult CcuComponent::UnimportAllJettys()
    1313              : {
    1314          609 :     for (auto& importedVec : importedOutParamMap_) {
    1315          432 :         for (auto& paramPair : importedVec.second) {
    1316          216 :             const auto ctxHandle = paramPair.first;
    1317          216 :             const auto remoteJettyHandle = paramPair.second.handle;
    1318          216 :             if (!ctxHandle || !remoteJettyHandle) {
    1319          216 :                 continue;
    1320              :             }
    1321            0 :             if (!Hccl::RdmaHandleManager::GetInstance().IsHandleValid(ctxHandle)) {
    1322            0 :                 HCCL_WARNING(
    1323              :                     "[CcuComponent][%s] skip RaCtxQpUnimport, ctxHandle=%p invalid, "
    1324              :                     "remoteJettyHandle=%p, devLogicId[%d].",
    1325              :                     __func__, ctxHandle, remoteJettyHandle, devLogicId_);
    1326            0 :                 paramPair.second.handle = nullptr;
    1327            0 :                 continue;
    1328              :             }
    1329            0 :             int32_t ret = RaCtxQpUnimport(ctxHandle, remoteJettyHandle);
    1330            0 :             if (ret != 0) {
    1331            0 :                 HCCL_ERROR(
    1332              :                     "[CcuComponent][%s] failed, ctxHandle[%p] "
    1333              :                     "remoteJettyHandle[%p], devLogicId[%d].",
    1334              :                     __func__, ctxHandle, remoteJettyHandle, devLogicId_);
    1335              :             }
    1336            0 :             paramPair.second.handle = nullptr; // 清理handle,避免重复释放
    1337              :         }
    1338              :     }
    1339          393 :     importedOutParamMap_.clear();
    1340          393 :     return HcclResult::HCCL_SUCCESS;
    1341              : }
    1342              : 
    1343          393 : HcclResult CcuComponent::ReleaseAllTpInfos()
    1344              : {
    1345          610 :     for (auto& item : tpAttrInfoMap_) {
    1346          217 :         const auto& dieId = item.first;
    1347          217 :         const auto& tpAttrInfo = item.second;
    1348          217 :         const auto& tpInfoIter = tpInfoMap_.find(dieId);
    1349          217 :         if (tpInfoIter != tpInfoMap_.end() && tpInfoIter->second.tpHandle != 0) {
    1350          216 :             (void)TpMgr::GetInstance(devPhyId_).ReleaseTpAttr(tpInfoIter->second.tpHandle, tpAttrInfo);
    1351              :         }
    1352              :     }
    1353          393 :     tpAttrInfoMap_.clear();
    1354          607 :     for (auto& item : tpInfoMap_) {
    1355          217 :         const auto& dieId = item.first;
    1356          217 :         const auto& tpInfo = item.second;
    1357          217 :         if (tpInfo.tpHandle == 0) {
    1358            0 :             continue;
    1359              :         }
    1360              : 
    1361          217 :         const auto& dieIdIter = loopFeCommAddrMap_.find(dieId);
    1362          217 :         if (dieIdIter == loopFeCommAddrMap_.end()) {
    1363            3 :             HCCL_ERROR(
    1364              :                 "[CcuComponent][%s] failed, dieId[%u] loop comm address"
    1365              :                 " is not found, devLogicId[%d].",
    1366              :                 __func__, static_cast<uint32_t>(dieId), devLogicId_);
    1367            3 :             return HcclResult::HCCL_E_NOT_FOUND;
    1368              :         }
    1369          214 :         const auto& commAddr = dieIdIter->second.second;
    1370          214 :         const GetTpInfoParam& tpParam = MakeLoopGetTpInfoParam(commAddr);
    1371          214 :         (void)TpMgr::GetInstance(devPhyId_).ReleaseTpInfo(tpParam, tpInfo);
    1372          214 :         item.second.tpHandle = 0; // 清理handle,避免重复释放
    1373              :     }
    1374          390 :     tpInfoMap_.clear();
    1375          390 :     return HcclResult::HCCL_SUCCESS;
    1376              : }
    1377              : 
    1378          390 : HcclResult CcuComponent::DestroyAllJettys()
    1379              : {
    1380          604 :     for (auto& createdVec : createdOutParamMap_) {
    1381          428 :         for (auto& param : createdVec.second) {
    1382          214 :             const auto jettyHandle = param.handle;
    1383          214 :             if (!jettyHandle) {
    1384          214 :                 continue;
    1385              :             }
    1386            0 :             int32_t ret = RaCtxQpDestroy(jettyHandle);
    1387            0 :             if (ret != 0) {
    1388            0 :                 HCCL_ERROR(
    1389              :                     "[CcuComponent][%s] failed, jettyHandle[%p], "
    1390              :                     "devLogicId[%d].",
    1391              :                     __func__, jettyHandle, devLogicId_);
    1392              :             }
    1393            0 :             param.handle = 0; // 清理handle,避免重复释放
    1394              :         }
    1395              :     }
    1396          390 :     createdOutParamMap_.clear();
    1397          390 :     return HcclResult::HCCL_SUCCESS;
    1398              : }
    1399              : 
    1400            3 : HcclResult CcuComponent::SetProcess(CcuOpcodeType opCode) const
    1401              : {
    1402            3 :     CustomChannelInfoIn inBuff;
    1403            3 :     CustomChannelInfoOut outBuff;
    1404              : 
    1405            3 :     inBuff.op = opCode;
    1406            9 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
    1407            6 :         if (!dieEnableFlags_[dieId]) {
    1408            6 :             HCCL_WARNING("[%s] devLogicId[%d], dieId[%u] is not enable, skip.", __func__, devLogicId_, dieId);
    1409            6 :             continue;
    1410              :         }
    1411            0 :         HCCL_INFO("[%s] devLogicId[%d], dieId[%u] start.", __func__, devLogicId_, dieId);
    1412            0 :         inBuff.data.dataInfo.udieIdx = dieId;
    1413            0 :         auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
    1414            0 :         CHK_PRT_RET(
    1415              :             ret != HCCL_SUCCESS,
    1416              :             HCCL_ERROR(
    1417              :                 "[%s] failed to call ccu driver, devLogicId[%d] dieId[%u] op[%u] ret[%d].", __func__, devLogicId_,
    1418              :                 dieId, static_cast<uint32_t>(opCode), ret),
    1419              :             ret);
    1420              :     }
    1421            3 :     return HcclResult::HCCL_SUCCESS;
    1422              : }
    1423              : 
    1424            1 : HcclResult CcuComponent::CleanTaskKillState() const
    1425              : {
    1426            1 :     CHK_RET(SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE));
    1427            1 :     return HcclResult::HCCL_SUCCESS;
    1428              : }
    1429              : 
    1430            2 : HcclResult CcuComponent::SetTaskKill()
    1431              : {
    1432            2 :     std::lock_guard<std::mutex> _lock(taskKillMutex_); // 加锁,确保线程安全
    1433              : 
    1434              :     // 初始化状态下,设置任务kill状态
    1435            2 :     if (status == CcuTaskKillStatus::INVALID) {
    1436            1 :         status = CcuTaskKillStatus::INIT;
    1437              :     }
    1438              : 
    1439            2 :     if (status == CcuTaskKillStatus::TASK_KILL) {
    1440            1 :         HCCL_INFO("No need to set task kill, state = %u, devLogicId = %u", status, devLogicId_);
    1441            1 :         return HcclResult::HCCL_SUCCESS;
    1442              :     }
    1443              : 
    1444            1 :     if (status != CcuTaskKillStatus::INIT) {
    1445            0 :         HCCL_ERROR(
    1446              :             "[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1447              :             "state = %u, devLogicId = %d.",
    1448              :             __func__, status, devLogicId_);
    1449            0 :         return HcclResult::HCCL_E_INTERNAL;
    1450              :     }
    1451              : 
    1452            1 :     CHK_RET(SetProcess(CcuOpcodeType::CCU_U_OP_SET_TASKKILL));
    1453            1 :     status = CcuTaskKillStatus::TASK_KILL;
    1454            1 :     HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d.", __func__, status, devLogicId_);
    1455            1 :     return HcclResult::HCCL_SUCCESS;
    1456            2 : }
    1457              : 
    1458            1 : HcclResult CcuComponent::SetTaskKillDone()
    1459              : {
    1460            1 :     std::lock_guard<std::mutex> _lock(taskKillMutex_); // 加锁,确保线程安全
    1461            1 :     if (status == CcuTaskKillStatus::INVALID) {
    1462            0 :         HCCL_ERROR(
    1463              :             "[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1464              :             "state = %u, devLogicId = %d.",
    1465              :             __func__, status, devLogicId_);
    1466            0 :         return HcclResult::HCCL_E_INTERNAL;
    1467              :     }
    1468              : 
    1469            1 :     if (status == CcuTaskKillStatus::INIT) {
    1470            0 :         HCCL_INFO("No need to set task kill done, state = %u, devLogicId = %u", status, devLogicId_);
    1471            0 :         return HcclResult::HCCL_SUCCESS;
    1472              :     }
    1473              : 
    1474            1 :     if (status != CcuTaskKillStatus::TASK_KILL) {
    1475            0 :         HCCL_ERROR(
    1476              :             "[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1477              :             "state = %u, devLogicId = %d.",
    1478              :             __func__, status, devLogicId_);
    1479            0 :         return HcclResult::HCCL_E_INTERNAL;
    1480              :     }
    1481              : 
    1482            1 :     CHK_RET(SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE));
    1483            1 :     status = CcuTaskKillStatus::INIT;
    1484            1 :     HCCL_INFO(
    1485              :         "[CcuComponent][%s] success, state = INIT(%u), devLogicId = %d", __func__, static_cast<uint8_t>(status),
    1486              :         devLogicId_);
    1487            1 :     return HcclResult::HCCL_SUCCESS;
    1488            1 : }
    1489              : 
    1490            0 : HcclResult CcuComponent::CcuSetTaskKillDone(const int32_t deviceLogicId) const
    1491              : {
    1492            0 :     HCCL_INFO("[CcuSetTaskKillDone] Input params: deviceLogicId[%d]", deviceLogicId);
    1493              :     // 入参校验拦截
    1494            0 :     CHK_PRT_RET(
    1495              :         (deviceLogicId < 0 || static_cast<u32>(deviceLogicId) >= MAX_MODULE_DEVICE_NUM),
    1496              :         HCCL_ERROR(
    1497              :             "[CcuSetTaskKillDone] deviceLogicId[%d] error, MAX_MODULE_DEVICE_NUM[%u]", deviceLogicId,
    1498              :             MAX_MODULE_DEVICE_NUM),
    1499              :         HcclResult::HCCL_E_PARA);
    1500            0 :     return CcuComponent::GetInstance(deviceLogicId).SetTaskKillDone();
    1501              : }
    1502              : 
    1503            0 : HcclResult CcuComponent::CcuCleanTaskKillState(const int32_t deviceLogicId) const
    1504              : {
    1505            0 :     HCCL_INFO("[CcuCleanTaskKillState] Input params: deviceLogicId[%d]", deviceLogicId);
    1506              :     // 入参校验拦截
    1507            0 :     CHK_PRT_RET(
    1508              :         (deviceLogicId < 0 || static_cast<u32>(deviceLogicId) >= MAX_MODULE_DEVICE_NUM),
    1509              :         HCCL_ERROR(
    1510              :             "[CcuCleanTaskKillState] deviceLogicId[%d] error, MAX_MODULE_DEVICE_NUM[%u]", deviceLogicId,
    1511              :             MAX_MODULE_DEVICE_NUM),
    1512              :         HcclResult::HCCL_E_PARA);
    1513            0 :     return CcuComponent::GetInstance(deviceLogicId).CleanTaskKillState();
    1514              : }
    1515              : 
    1516              : // 以下接口用于n秒快恢与TaskException
    1517          216 : HcclResult CcuComponent::CleanDieCkes(const uint8_t dieId) const
    1518              : {
    1519          216 :     CHK_PRT_RET(
    1520              :         dieId >= MAX_CCU_IODIE_NUM,
    1521              :         HCCL_WARNING(
    1522              :             "[%s] failed, dieId[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, dieId,
    1523              :             MAX_CCU_IODIE_NUM, devLogicId_),
    1524              :         HcclResult::HCCL_E_PARA);
    1525              : 
    1526          215 :     if (!dieEnableFlags_[dieId]) {
    1527            1 :         HCCL_INFO("[%s] dieId[%u] is not enable, skip", __func__, dieId);
    1528            1 :         return HcclResult::HCCL_SUCCESS;
    1529              :     }
    1530              : 
    1531          214 :     CustomChannelInfoIn inBuff{};
    1532          214 :     CustomChannelInfoOut outBuff{};
    1533              : 
    1534              :     // 设置操作码和数据
    1535          214 :     uint32_t ckeNum = 0;
    1536          214 :     CHK_RET(CcuResSpecifications::GetInstance(devLogicId_).GetCkeNum(dieId, ckeNum));
    1537          214 :     HCCL_INFO(
    1538              :         "[CcuComponent][CleanAllCke]NS recovery devLogicId[%d], dieId[%u], ckeNum[%u].", devLogicId_, dieId, ckeNum);
    1539              : 
    1540          214 :     inBuff.op = CcuOpcodeType::CCU_U_OP_SET_CKE;
    1541          214 :     inBuff.data.dataInfo.udieIdx = dieId;
    1542              :     // 接口限制,目前方案每次最多清理8个cke,超过8个时分多次清理
    1543        27606 :     for (uint32_t startIdx = 0; startIdx < ckeNum; startIdx += MAX_CKE_DATA_ARRAY_SIZE) {
    1544        27392 :         inBuff.data.dataInfo.dataArraySize = std::min(ckeNum - startIdx, MAX_CKE_DATA_ARRAY_SIZE);
    1545        27392 :         inBuff.data.dataInfo.dataLen = sizeof(CcuDataByte8) * inBuff.data.dataInfo.dataArraySize;
    1546        27392 :         inBuff.offsetStartIdx = startIdx;
    1547        27392 :         auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
    1548        27392 :         CHK_PRT_RET(
    1549              :             ret != HCCL_SUCCESS,
    1550              :             HCCL_ERROR(
    1551              :                 "[%s] failed to call ccu driver, devLogicId[%d] dieId[%u] op[%s] ret[%d].", __func__, devLogicId_,
    1552              :                 dieId, "SET_CKE", ret),
    1553              :             ret);
    1554              :     }
    1555              : 
    1556          214 :     return HcclResult::HCCL_SUCCESS;
    1557              : }
    1558              : 
    1559              : }; // namespace hcomm
        

Generated by: LCOV version 2.0-1