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: 85.6 % 611 523
Test Date: 2026-08-29 17:38:31 Functions: 90.0 % 50 45

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include <cstdlib>
      12              : 
      13              : #include "ccu_component.h"
      14              : 
      15              : #include "exception_util.h"
      16              : #include "hccl_common_v2.h"
      17              : #include "ccu_api_exception.h"
      18              : #include "orion_adapter_rts.h"
      19              : #include "internal_exception.h"
      20              : #include "rdma_handle_manager.h"
      21              : 
      22              : #include "ccu_eid_info.h"
      23              : #include "ccu_res_specs_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          275 : CcuComponent& CcuComponent::GetInstance(const int32_t deviceLogicId)
      69              : {
      70          341 :     static CcuComponent ccuComponent[MAX_MODULE_DEVICE_NUM + 1];
      71              : 
      72          275 :     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          275 :     ccuComponent[deviceLogicId].devLogicId = deviceLogicId;
      80          275 :     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::unique_lock<std::shared_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::unique_lock<std::shared_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 enabled, skip. "
     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 :     uint8_t errTimeout = 0;
     486           26 :     CHK_RET(GetLoopJettyTimeout(ipAddr, tpInfo.tpHandle, errTimeout));
     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 kTpAttrRetryTimesInitBit = 0U;
     580           13 :     constexpr uint32_t kTpAttrAtBit = 1U;
     581           13 :     constexpr uint32_t TP_ATTR_BITMAP = (1U << kTpAttrRetryTimesInitBit) | (1U << kTpAttrAtBit);
     582           13 :     const GetTpAttrParam tpAttrParam = {tpHandle, TP_ATTR_BITMAP};
     583              : 
     584           13 :     TpAttrInfo tpAttrInfo{};
     585           13 :     auto& tpMgr = TpManager::GetInstance(devLogicId);
     586           13 :     const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
     587           13 :     const auto startTime = std::chrono::steady_clock::now();
     588              : 
     589           13 :     HcclResult ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
     590           16 :     while (ret == HcclResult::HCCL_E_AGAIN) {
     591            3 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     592            0 :             THROW<InternalException>(
     593              :                 "[CcuComponent][%s] failed, get tp attr "
     594              :                 "timeout[%d ms], devLogicId[%d].",
     595              :                 __func__, timeout, devLogicId);
     596              :         }
     597            3 :         ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
     598              :     }
     599              : 
     600           13 :     if (ret != HcclResult::HCCL_SUCCESS) {
     601            0 :         THROW<InternalException>(
     602              :             "[CcuComponent][%s] failed, ret[%u], "
     603              :             "devLogicId[%d].",
     604              :             __func__, ret, devLogicId);
     605              :     }
     606              : 
     607           13 :     tpAttrInfoMap[ipAddr] = tpAttrInfo;
     608           13 :     return tpAttrInfo;
     609              : }
     610              : 
     611           26 : HcclResult CcuComponent::GetLoopJettyTimeout(const IpAddress& ipAddr, const TpHandle tpHandle, uint8_t& errTimeout)
     612              : {
     613           26 :     const auto tpAttrInfo = GetLoopTpAttr(ipAddr, tpHandle);
     614              :     // CTP 协议不感知 TP 建链,跳过 GetTpTotalTimeout(对齐 DevUbConnection::GetTimeOut 的 CTP 分支),
     615              :     // tpTimeOutMs 保持 0,由 TpManager::CalcTaTimeout 内部按 CTP 规则直接使用 taTimeOut_
     616           26 :     uint32_t tpTimeOutMs = 0;
     617           26 :     if (LOOP_JETTY_PROTOCOL != TpProtocol::CTP) {
     618           26 :         CHK_RET(TpManager::GetTpTotalTimeout(tpAttrInfo, tpTimeOutMs));
     619              :     }
     620           26 :     errTimeout = TpManager::CalcTaTimeout(LOOP_JETTY_PROTOCOL, TpManager::TA_TIMEOUT_NOT_SET, tpTimeOutMs);
     621           26 :     return HcclResult::HCCL_SUCCESS;
     622              : }
     623              : 
     624            0 : inline uint32_t GetRandomNum()
     625              : {
     626            0 :     uint32_t randNum = std::rand();
     627            0 :     return randNum;
     628              : }
     629              : 
     630           26 : uint32_t CcuComponent::GetPsn(const IpAddress& ipAddr)
     631              : {
     632           26 :     const auto& srcIter = psnMap.find(ipAddr);
     633           26 :     if (srcIter == psnMap.end()) {
     634           14 :         const auto psn = GetRandomNum();
     635           14 :         psnMap[ipAddr] = psn;
     636           14 :         return psn;
     637              :     }
     638              : 
     639           12 :     return srcIter->second;
     640              : }
     641              : 
     642           24 : HcclResult CcuComponent::ConfigLoopChannel(const uint8_t dieId, const IpAddress& ipAddr, const ChannelInfo& channelInfo)
     643              : {
     644           72 :     HCCL_INFO("[CcuComponent][%s] Create loop channel with another die's address, my dieId[%u]", __func__, dieId);
     645           24 :     auto rmaBufferIter = ccuRmaBufferMap.find(1 - dieId); // 需要配置另一die的rma buffer
     646           24 :     if (rmaBufferIter == ccuRmaBufferMap.end()) {
     647            0 :         HCCL_WARNING(
     648              :             "[CcuComponent][%s] Another die is not enable, create loop channel with my die[%u]", __func__, dieId);
     649            0 :         rmaBufferIter = ccuRmaBufferMap.find(dieId);
     650              :     }
     651           24 :     CHK_PRT_RET(
     652              :         rmaBufferIter == ccuRmaBufferMap.end(),
     653              :         HCCL_WARNING(
     654              :             "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     655              :             "devLogicId[%d].",
     656              :             __func__, dieId, devLogicId),
     657              :         HcclResult::HCCL_E_NOT_FOUND);
     658              : 
     659           24 :     const auto& ccuRmaBuffer = rmaBufferIter->second;
     660           24 :     const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
     661              : 
     662           24 :     ChannelCfg cfg{};
     663           24 :     cfg.channelId = channelInfo.channelId;
     664           24 :     cfg.remoteEid = ipAddr.GetReverseEid();
     665           72 :     HCCL_INFO("[CcuComponent::ConfigLoopChannel] remoteEid=%s", cfg.remoteEid.Describe().c_str());
     666           24 :     cfg.tpn = importedOutParamMap[dieId][0].second.tpn;
     667              : 
     668           24 :     cfg.remoteCcuVa = ccuRmaBuffer->GetBuf()->GetAddr();
     669           24 :     cfg.memTokenId = ccuRmaBuffer->GetTokenId();
     670           24 :     cfg.memTokenValue = ccuBufTokenValue;
     671              : 
     672           24 :     const auto& jettyInfos = channelInfo.jettyInfos;
     673           24 :     const auto& createdVec = createdOutParamMap[dieId];
     674           24 :     const uint32_t jettyNum = jettyInfos.size();
     675           48 :     for (uint32_t i = 0; i < jettyNum; i++) {
     676           24 :         cfg.jettyCfgs.emplace_back(
     677           24 :             JettyCfg{jettyInfos[i].jettyCtxId, createdVec[i].dbVa, createdVec[i].dbTokenId, ccuBufTokenValue});
     678              :     }
     679              : 
     680           24 :     CHK_PTR_NULL(channelMgrs[dieId]);
     681           24 :     return channelMgrs[dieId]->Config(cfg);
     682           24 : }
     683              : 
     684           12 : void CcuComponent::ConfigMsIdToken()
     685              : {
     686           12 :     bool isAX = CcuResSpecifications::GetInstance(devLogicId).GetAXFlag();
     687           12 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
     688           12 :     CHECK_NULLPTR(
     689           24 :         tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
     690              : 
     691           12 :     struct CustomChannelInfoIn inBuff {};
     692           12 :     struct CustomChannelInfoOut outBuff {};
     693              : 
     694           36 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
     695           24 :         const auto& dieIter = localCcuRmaBufferMap.find(dieId);
     696           24 :         if (dieIter == localCcuRmaBufferMap.end()) {
     697            0 :             HCCL_WARNING(
     698              :                 "[CcuComponent][%s] failed but passed, ccu rma buffer of die[%u] "
     699              :                 "is not existed, devLogicId[%d].",
     700              :                 __func__, dieId, devLogicId);
     701            0 :             continue;
     702            0 :         }
     703           24 :         const auto& ccuRmaBuffer = dieIter->second;
     704           24 :         const uint32_t tokenId = ccuRmaBuffer->GetTokenId();
     705           24 :         const uint32_t tokenValue = ccuRmaBuffer->GetTokenValue();
     706           24 :         uint32_t msId = 0;
     707           24 :         CHK_RET_THROW(
     708              :             InternalException,
     709              :             StringFormat("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId),
     710              :             CcuResSpecifications::GetInstance(devLogicId).GetMsId(dieId, msId));
     711              : 
     712           24 :         inBuff.op = CcuOpcodeType::CCU_U_OP_SET_MSID_TOKEN;
     713           24 :         inBuff.offsetStartIdx = 0;
     714           24 :         inBuff.data.dataInfo.udieIdx = dieId;
     715              : 
     716           24 :         if (isAX && dieId == 0) { // A+X环境,给udie0配置新的交织粒度
     717            0 :             msId = MSID_CONFIG_AX_MAINBOARD;
     718              :         }
     719           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.msId = msId;
     720           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.tokenId = tokenId;
     721           24 :         inBuff.data.dataInfo.dataArray[0].baseinfo.tokenValue = tokenValue;
     722              : 
     723           24 :         HrtRaTlvRequestForCustomChannel(
     724              :             tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
     725              : 
     726           72 :         HCCL_INFO("[CcuComponent][%s] config MS ID token success, dieId[%u], msid[%u]", __func__, dieId, msId);
     727              :     }
     728           12 : }
     729              : 
     730            0 : HcclResult CcuComponent::GetCcuResourceSpaceBufInfo(const uint8_t dieId, uint64_t& addr, uint64_t& size) const
     731              : {
     732            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     733              : 
     734            0 :     auto res = ccuRmaBufferMap.find(dieId);
     735            0 :     CHK_PRT_RET(
     736              :         res == ccuRmaBufferMap.end(),
     737              :         HCCL_WARNING(
     738              :             "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     739              :             "devLogicId[%d].",
     740              :             __func__, dieId, devLogicId),
     741              :         HcclResult::HCCL_E_NOT_FOUND);
     742              : 
     743            0 :     const auto rawBuffer = res->second->GetBuf();
     744            0 :     addr = static_cast<uint64_t>(rawBuffer->GetAddr());
     745            0 :     size = static_cast<uint64_t>(rawBuffer->GetSize());
     746            0 :     return HcclResult::HCCL_SUCCESS;
     747              : }
     748              : 
     749              : HcclResult
     750            0 : CcuComponent::GetCcuResourceSpaceTokenInfoForLocal(const uint8_t dieId, uint64_t& tokenId, uint64_t& tokenValue) const
     751              : {
     752            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     753              : 
     754            0 :     auto res = localCcuRmaBufferMap.find(dieId);
     755            0 :     CHK_PRT_RET(
     756              :         res == localCcuRmaBufferMap.end(),
     757              :         HCCL_WARNING(
     758              :             "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     759              :             "devLogicId[%d].",
     760              :             __func__, dieId, devLogicId),
     761              :         HcclResult::HCCL_E_NOT_FOUND);
     762              : 
     763            0 :     const auto& ccuRmaBuffer = res->second;
     764            0 :     tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
     765            0 :     tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
     766            0 :     return HcclResult::HCCL_SUCCESS;
     767              : }
     768              : 
     769              : HcclResult
     770            0 : CcuComponent::GetCcuResourceSpaceTokenInfo(const uint8_t dieId, uint64_t& tokenId, uint64_t& tokenValue) const
     771              : {
     772            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     773              : 
     774            0 :     auto res = ccuRmaBufferMap.find(dieId);
     775            0 :     CHK_PRT_RET(
     776              :         res == ccuRmaBufferMap.end(),
     777              :         HCCL_WARNING(
     778              :             "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
     779              :             "devLogicId[%d].",
     780              :             __func__, dieId, devLogicId),
     781              :         HcclResult::HCCL_E_NOT_FOUND);
     782              : 
     783            0 :     const auto& ccuRmaBuffer = res->second;
     784            0 :     tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
     785            0 :     tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
     786            0 :     return HcclResult::HCCL_SUCCESS;
     787              : }
     788              : 
     789              : HcclResult
     790            5 : CcuComponent::AllocChannels(const uint8_t dieId, const ChannelPara& channelPara, std::vector<ChannelInfo>& channelInfos)
     791              : {
     792            5 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     793            8 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     794              : 
     795            4 :     CHK_PTR_NULL(channelMgrs[dieId]);
     796            4 :     auto ret = channelMgrs[dieId]->Alloc(channelPara, channelInfos);
     797            4 :     CHK_PRT_RET(
     798              :         ret != HcclResult::HCCL_SUCCESS,
     799              :         HCCL_WARNING(
     800              :             "[CcuComponent][%s] failed, feId[%u], devLogicId[%d], dieId[%u].", __func__, channelPara.feId, devLogicId,
     801              :             dieId),
     802              :         ret);
     803              : 
     804            4 :     return HcclResult::HCCL_SUCCESS;
     805            5 : }
     806              : 
     807            6 : HcclResult CcuComponent::ConfigChannel(const uint8_t dieId, const ChannelCfg& cfg)
     808              : {
     809            6 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     810            6 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     811              : 
     812            6 :     uint32_t channelId = cfg.channelId;
     813            9 :     CHK_PRT_RET(
     814              :         channelId == loopChannelIds[dieId],
     815              :         HCCL_WARNING(
     816              :             "[CcuComponent][%s] failed, refused to config loop channel[%u], "
     817              :             "devLogicId[%d], dieId[%u].",
     818              :             __func__, channelId, devLogicId, dieId),
     819              :         HcclResult::HCCL_E_PARA);
     820              : 
     821            5 :     CHK_PTR_NULL(channelMgrs[dieId]);
     822            5 :     auto ret = channelMgrs[dieId]->Config(cfg);
     823           14 :     CHK_PRT_RET(
     824              :         ret != HcclResult::HCCL_SUCCESS,
     825              :         HCCL_WARNING(
     826              :             "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId,
     827              :             dieId),
     828              :         ret);
     829              : 
     830            2 :     return HcclResult::HCCL_SUCCESS;
     831            6 : }
     832              : 
     833            4 : HcclResult CcuComponent::ReleaseChannel(const uint8_t dieId, const uint32_t channelId)
     834              : {
     835            4 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     836            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     837            7 :     CHK_PRT_RET(
     838              :         channelId == loopChannelIds[dieId],
     839              :         HCCL_WARNING(
     840              :             "[CcuComponent][%s] failed, refused to release loop channel[%u], "
     841              :             "devLogicId[%d], dieId[%u].",
     842              :             __func__, channelId, devLogicId, dieId),
     843              :         HcclResult::HCCL_E_PARA);
     844              : 
     845            3 :     CHK_PTR_NULL(channelMgrs[dieId]);
     846            3 :     auto ret = channelMgrs[dieId]->Release(channelId);
     847            6 :     CHK_PRT_RET(
     848              :         ret != HcclResult::HCCL_SUCCESS,
     849              :         HCCL_WARNING(
     850              :             "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId,
     851              :             dieId),
     852              :         ret);
     853              : 
     854            2 :     return HcclResult::HCCL_SUCCESS;
     855            4 : }
     856              : 
     857            4 : HcclResult CcuComponent::GetLoopChannelId(const uint8_t srcDieId, const uint8_t dstDieId, uint32_t& channelId) const
     858              : {
     859            4 :     channelId = INVAILD_LOOP_CHANNEL_ID; // 允许die未启用时查询环回channelId
     860            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, srcDieId, {true, true}));
     861            4 :     CHK_RET(CheckDieValid(__func__, devLogicId, dstDieId, {true, true}));
     862              : 
     863            4 :     CHK_PRT_RET(
     864              :         loopChannelIds[srcDieId] == INVAILD_LOOP_CHANNEL_ID, // 环回channel每个die共用1个
     865              :         HCCL_WARNING(
     866              :             "[CcuComponent][%s] failed, invalid loop channel id, "
     867              :             "devLogicId[%d], srcDieId[%u].",
     868              :             __func__, devLogicId, srcDieId),
     869              :         HcclResult::HCCL_E_INTERNAL);
     870              : 
     871            4 :     channelId = loopChannelIds[srcDieId];
     872            4 :     return HcclResult::HCCL_SUCCESS;
     873              : }
     874              : 
     875           34 : HcclResult CcuComponent::AllocRes(
     876              :     const uint8_t dieId, const ResType resType, const uint32_t num, const bool consecutive, vector<ResInfo>& resInfos)
     877              : {
     878           34 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     879           34 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     880              : 
     881           34 :     CHK_PTR_NULL(resAllocators[dieId]);
     882           34 :     auto ret = resAllocators[dieId]->Alloc(resType, num, consecutive, resInfos);
     883           37 :     CHK_PRT_RET(
     884              :         ret != HcclResult::HCCL_SUCCESS,
     885              :         HCCL_WARNING(
     886              :             "[CcuComponent][%s] failed, resType[%s], num[%u], devLogicId[%d], dieId[%u].", __func__,
     887              :             resType.Describe().c_str(), num, devLogicId, dieId),
     888              :         ret);
     889              : 
     890           33 :     return HcclResult::HCCL_SUCCESS;
     891           34 : }
     892              : 
     893              : HcclResult
     894            9 : CcuComponent::ReleaseRes(const uint8_t dieId, const ResType resType, const uint32_t startId, const uint32_t num)
     895              : {
     896            9 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     897            9 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     898              : 
     899            9 :     CHK_PTR_NULL(resAllocators[dieId]);
     900            9 :     auto ret = resAllocators[dieId]->Release(resType, startId, num);
     901            9 :     CHK_PRT_RET(
     902              :         ret != HcclResult::HCCL_SUCCESS,
     903              :         HCCL_WARNING(
     904              :             "[CcuComponent][%s] failed, resType[%s], startId[%u], num[%u], "
     905              :             "devLogicId[%d], dieId[%u].",
     906              :             __func__, resType.Describe().c_str(), startId, num, devLogicId, dieId),
     907              :         ret);
     908              : 
     909            9 :     return HcclResult::HCCL_SUCCESS;
     910            9 : }
     911              : 
     912            0 : uint32_t CcuComponent::GetInsConsecutiveRemainSize(const uint8_t dieId) const
     913              : {
     914            0 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     915            0 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     916            0 :     if (resAllocators[dieId] == nullptr)
     917            0 :         return 0;
     918            0 :     return resAllocators[dieId]->GetConsecutiveRemainSize(ResType::INS);
     919            0 : }
     920              : 
     921            7 : HcclResult CcuComponent::AllocIns(const uint8_t dieId, const uint32_t num, ResInfo& insInfo)
     922              : {
     923            7 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     924           10 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     925            6 :     CHK_PTR_NULL(resAllocators[dieId]);
     926              : 
     927            6 :     vector<ResInfo> resInfos;
     928            6 :     auto ret = resAllocators[dieId]->Alloc(ResType::INS, num, true, resInfos);
     929           15 :     CHK_PRT_RET(
     930              :         ret != HcclResult::HCCL_SUCCESS,
     931              :         HCCL_WARNING(
     932              :             "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
     933              :         ret);
     934              : 
     935            3 :     insInfo = resInfos[0]; // 申请连续资源只会有一份
     936            3 :     return HcclResult::HCCL_SUCCESS;
     937            7 : }
     938              : 
     939            4 : HcclResult CcuComponent::ReleaseIns(const uint8_t dieId, const ResInfo& insInfo)
     940              : {
     941            4 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     942            7 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     943            3 :     CHK_PTR_NULL(resAllocators[dieId]);
     944              : 
     945            3 :     auto ret = resAllocators[dieId]->Release(ResType::INS, insInfo.startId, insInfo.num);
     946            3 :     CHK_PRT_RET(
     947              :         ret != HcclResult::HCCL_SUCCESS,
     948              :         HCCL_WARNING(
     949              :             "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__, insInfo.Describe().c_str(),
     950              :             devLogicId, dieId),
     951              :         ret);
     952              : 
     953            3 :     return HcclResult::HCCL_SUCCESS;
     954            4 : }
     955              : 
     956          184 : HcclResult CcuComponent::AllocCke(const uint8_t dieId, const uint32_t num, vector<ResInfo>& ckeInfos)
     957              : {
     958          184 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     959          715 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     960            7 :     CHK_PTR_NULL(resAllocators[dieId]);
     961              : 
     962            7 :     auto ret = resAllocators[dieId]->Alloc(ResType::CKE, num, false, ckeInfos);
     963           16 :     CHK_PRT_RET(
     964              :         ret != HcclResult::HCCL_SUCCESS,
     965              :         HCCL_WARNING(
     966              :             "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
     967              :         ret);
     968              : 
     969            4 :     return HcclResult::HCCL_SUCCESS;
     970          184 : }
     971              : 
     972           30 : HcclResult CcuComponent::ReleaseCke(const uint8_t dieId, const vector<ResInfo>& ckeInfos)
     973              : {
     974           30 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     975           99 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     976            7 :     CHK_PTR_NULL(resAllocators[dieId]);
     977              : 
     978           12 :     for (auto& ckeInfo : ckeInfos) {
     979            7 :         auto ret = resAllocators[dieId]->Release(ResType::CKE, ckeInfo.startId, ckeInfo.num);
     980           13 :         CHK_PRT_RET(
     981              :             ret != HcclResult::HCCL_SUCCESS,
     982              :             HCCL_WARNING(
     983              :                 "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
     984              :                 ckeInfo.Describe().c_str(), devLogicId, dieId),
     985              :             ret);
     986              :     }
     987              : 
     988            5 :     return HcclResult::HCCL_SUCCESS;
     989           30 : }
     990              : 
     991            7 : HcclResult CcuComponent::AllocXn(const uint8_t dieId, const uint32_t num, vector<ResInfo>& xnInfos)
     992              : {
     993            7 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
     994           10 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     995            6 :     CHK_PTR_NULL(resAllocators[dieId]);
     996              : 
     997            6 :     auto ret = resAllocators[dieId]->Alloc(ResType::XN, num, false, xnInfos);
     998           15 :     CHK_PRT_RET(
     999              :         ret != HcclResult::HCCL_SUCCESS,
    1000              :         HCCL_WARNING(
    1001              :             "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
    1002              :         ret);
    1003              : 
    1004            3 :     return HcclResult::HCCL_SUCCESS;
    1005            7 : }
    1006              : 
    1007            4 : HcclResult CcuComponent::ReleaseXn(const uint8_t dieId, const vector<ResInfo>& xnInfos)
    1008              : {
    1009            4 :     std::shared_lock<std::shared_mutex> lock(innerMutex);
    1010            7 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
    1011            3 :     CHK_PTR_NULL(resAllocators[dieId]);
    1012              : 
    1013            6 :     for (auto& xnInfo : xnInfos) {
    1014            3 :         auto ret = resAllocators[dieId]->Release(ResType::XN, xnInfo.startId, xnInfo.num);
    1015            3 :         CHK_PRT_RET(
    1016              :             ret != HcclResult::HCCL_SUCCESS,
    1017              :             HCCL_WARNING(
    1018              :                 "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
    1019              :                 xnInfo.Describe().c_str(), devLogicId, dieId),
    1020              :             ret);
    1021              :     }
    1022              : 
    1023            3 :     return HcclResult::HCCL_SUCCESS;
    1024            4 : }
    1025              : 
    1026              : // 以下接口用于n秒快恢与TaskException
    1027           29 : HcclResult CcuComponent::CleanDieCkes(const uint8_t dieId) const
    1028              : {
    1029           29 :     CHK_PRT_RET(
    1030              :         dieId >= MAX_CCU_IODIE_NUM,
    1031              :         HCCL_WARNING(
    1032              :             "[CcuComponent][%s] failed, dieId[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, dieId,
    1033              :             MAX_CCU_IODIE_NUM, devLogicId),
    1034              :         HcclResult::HCCL_E_PARA);
    1035              : 
    1036           29 :     if (!dieEnableFlags[dieId]) {
    1037            4 :         return HcclResult::HCCL_SUCCESS;
    1038              :     }
    1039              : 
    1040           25 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
    1041           25 :     CHK_PTR_NULL(tlvHandle);
    1042           25 :     CustomChannelInfoIn inBuff{};
    1043           25 :     CustomChannelInfoOut outBuff{};
    1044              : 
    1045              :     // 设置操作码和数据
    1046           25 :     uint32_t ckeNum = 0;
    1047           25 :     CHK_RET(CcuResSpecifications::GetInstance(devLogicId).GetCkeNum(dieId, ckeNum));
    1048           75 :     HCCL_INFO("[CcuComponent][CleanAllCke]Nsrecovery devLogicId[%d], dieId[%u] ckeNum[%u].", devLogicId, dieId, ckeNum);
    1049              : 
    1050           25 :     inBuff.op = CcuOpcodeType::CCU_U_OP_SET_CKE;
    1051           25 :     inBuff.data.dataInfo.udieIdx = dieId;
    1052              :     // 接口限制,目前方案每次最多清理8个cke,超过8个时分多次清理
    1053         3225 :     for (uint32_t startIdx = 0; startIdx < ckeNum; startIdx += MAX_CKE_DATA_ARRAY_SIZE) {
    1054         3200 :         inBuff.data.dataInfo.dataArraySize = std::min(ckeNum - startIdx, MAX_CKE_DATA_ARRAY_SIZE);
    1055         3200 :         inBuff.data.dataInfo.dataLen = sizeof(CcuDataByte8) * inBuff.data.dataInfo.dataArraySize;
    1056         3200 :         inBuff.offsetStartIdx = startIdx;
    1057         3200 :         HrtRaTlvRequestForCustomChannel(
    1058              :             tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
    1059              :     }
    1060              : 
    1061           25 :     return HcclResult::HCCL_SUCCESS;
    1062              : }
    1063              : 
    1064           28 : void CcuComponent::SetProcess(CcuOpcodeType opCode) const
    1065              : {
    1066           28 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
    1067           28 :     CHECK_NULLPTR(
    1068           56 :         tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
    1069              : 
    1070           28 :     struct CustomChannelInfoIn inBuff;
    1071           28 :     struct CustomChannelInfoOut outBuff;
    1072              : 
    1073           28 :     inBuff.op = opCode;
    1074           84 :     for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
    1075           56 :         if (!dieEnableFlags[dieId]) {
    1076           12 :             HCCL_WARNING(
    1077              :                 "[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] is not enable,"
    1078              :                 "skip SetProcess.",
    1079              :                 devLogicId, dieId);
    1080            4 :             continue;
    1081            4 :         }
    1082          156 :         HCCL_INFO("[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] start.", devLogicId, dieId);
    1083           52 :         inBuff.data.dataInfo.udieIdx = dieId;
    1084           52 :         HrtRaTlvRequestForCustomChannel(
    1085              :             tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
    1086              :     }
    1087           28 : }
    1088              : 
    1089           13 : HcclResult CcuComponent::SetTaskKill()
    1090              : {
    1091           13 :     std::lock_guard<std::mutex> _lock(taskKillMutex_);
    1092              : 
    1093           13 :     if (status == CcuTaskKillStatus::INVALID) {
    1094           12 :         status = CcuTaskKillStatus::INIT;
    1095              :     }
    1096              : 
    1097           13 :     if (status == CcuTaskKillStatus::TASK_KILL) {
    1098            0 :         HCCL_INFO("No need to set task kill, state = %u, devLogicId = %u", status, devLogicId);
    1099            0 :         return HcclResult::HCCL_SUCCESS;
    1100              :     }
    1101              : 
    1102           13 :     if (status != CcuTaskKillStatus::INIT) {
    1103            0 :         HCCL_ERROR(
    1104              :             "[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1105              :             "state = %u, devLogicId = %d.",
    1106              :             __func__, status, devLogicId);
    1107            0 :         return HcclResult::HCCL_E_INTERNAL;
    1108              :     }
    1109              : 
    1110           13 :     SetProcess(CcuOpcodeType::CCU_U_OP_SET_TASKKILL);
    1111           13 :     status = CcuTaskKillStatus::TASK_KILL;
    1112           39 :     HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d.", __func__, status, devLogicId);
    1113           13 :     return HcclResult::HCCL_SUCCESS;
    1114           13 : }
    1115              : 
    1116           13 : HcclResult CcuComponent::SetTaskKillDone()
    1117              : {
    1118           13 :     std::lock_guard<std::mutex> _lock(taskKillMutex_);
    1119              : 
    1120           13 :     if (status == CcuTaskKillStatus::INVALID) {
    1121            0 :         HCCL_ERROR(
    1122              :             "[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1123              :             "state = %u, devLogicId = %d.",
    1124              :             __func__, status, devLogicId);
    1125            0 :         return HcclResult::HCCL_E_INTERNAL;
    1126              :     }
    1127              : 
    1128           13 :     if (status == CcuTaskKillStatus::INIT) {
    1129            0 :         HCCL_INFO("No need to set task kill done, state = %u, devLogicId = %u", status, devLogicId);
    1130            0 :         return HcclResult::HCCL_SUCCESS;
    1131              :     }
    1132              : 
    1133           13 :     if (status != CcuTaskKillStatus::TASK_KILL) {
    1134            0 :         HCCL_ERROR(
    1135              :             "[CcuComponent][%s] failed, cannot be invoked in the current state, "
    1136              :             "state = %u, devLogicId = %d.",
    1137              :             __func__, status, devLogicId);
    1138            0 :         return HcclResult::HCCL_E_INTERNAL;
    1139              :     }
    1140              : 
    1141           13 :     SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
    1142           13 :     status = CcuTaskKillStatus::INIT;
    1143           39 :     HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d", __func__, status, devLogicId);
    1144           13 :     return HcclResult::HCCL_SUCCESS;
    1145           13 : }
    1146              : 
    1147            2 : HcclResult CcuComponent::CleanTaskKillState() const
    1148              : {
    1149            2 :     SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
    1150            2 :     return HcclResult::HCCL_SUCCESS;
    1151              : }
    1152              : 
    1153            2 : const std::array<bool, MAX_CCU_IODIE_NUM>& CcuComponent::GetDieEnableFlags() const { return dieEnableFlags; }
    1154              : 
    1155           81 : CcuComponent::~CcuComponent() { DECTOR_TRY_CATCH("CcuComponent", ReleaseJettyRes()); }
    1156              : 
    1157           83 : void CcuComponent::ReleaseJettyRes()
    1158              : {
    1159           83 :     UnimportAllJetty();
    1160           83 :     DestroyAllJetty();
    1161              :     // HrtRaUbLocalMemReg 跟随 LocalUbRmaBuffer 析构时释放
    1162              :     // 环回channel不需要手动释放,channelMgr跟随CcuComponent释放
    1163           83 : }
    1164              : 
    1165           83 : void CcuComponent::UnimportAllJetty()
    1166              : {
    1167              :     // tpInfo不需要主动释放,因为CcuComponent生命周期与TpManager一致
    1168          109 :     for (auto& importedVec : importedOutParamMap) {
    1169           52 :         for (auto& paramPair : importedVec.second) {
    1170           26 :             const auto rdmaHandle = paramPair.first;
    1171           26 :             const auto remoteJettyHandle = paramPair.second.handle;
    1172           26 :             if (rdmaHandle != nullptr && remoteJettyHandle != 0) {
    1173            0 :                 paramPair.second.handle = 0;
    1174            0 :                 HrtRaUbUnimportJetty(rdmaHandle, remoteJettyHandle);
    1175              :             }
    1176              :         }
    1177              :     }
    1178              : 
    1179           83 :     importedOutParamMap.clear();
    1180           83 : }
    1181              : 
    1182           83 : void CcuComponent::DestroyAllJetty()
    1183              : {
    1184          109 :     for (auto& createdVec : createdOutParamMap) {
    1185           52 :         for (auto& param : createdVec.second) {
    1186           26 :             const auto jettyHandle = param.handle;
    1187           26 :             if (jettyHandle != 0) {
    1188            0 :                 param.handle = 0;
    1189            0 :                 HrtRaUbDestroyJetty(jettyHandle);
    1190              :             }
    1191              :         }
    1192              :     }
    1193           83 :     createdOutParamMap.clear();
    1194           83 : }
    1195              : 
    1196              : }; // namespace Hccl
        

Generated by: LCOV version 2.0-1