LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/ccu/ccu_device/ccu_component - ccu_component.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.1 % 579 487
Test Date: 2026-08-18 17:47:01 Functions: 87.8 % 49 43

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

Generated by: LCOV version 2.0-1