LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/common - tp_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 75.0 % 568 426
Test Date: 2026-08-17 10:19:35 Functions: 89.8 % 49 44

            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 "tp_manager.h"
      12              : 
      13              : #include <algorithm>
      14              : #include <arpa/inet.h>
      15              : #include <string>
      16              : 
      17              : #include "exception_util.h"
      18              : #include "hccl_common_v2.h"
      19              : #include "invalid_params_exception.h"
      20              : #include "env_config/env_config_v2.h"
      21              : #include "network_api_exception.h"
      22              : #include "tp_qos.h"
      23              : 
      24              : #include "dev_type.h"
      25              : #include "orion_adapter_rts.h"
      26              : #include "rdma_handle_manager.h"
      27              : #include "securec.h"
      28              : 
      29              : namespace Hccl {
      30              : 
      31              : // GetTpAttr 属性位图常量;匿名命名空间内工具与 TpManager 成员函数共用
      32              : constexpr uint32_t kTpAttrSlAvailableBit = 17U;
      33              : constexpr uint32_t kTpAttrBitmapSl = (1U << 10U);
      34              : constexpr uint32_t kTpAttrBitmapDscp = (1U << 8U);
      35              : constexpr uint32_t kTpAttrDscpConfigModeBit = 18U;
      36              : /// UBOE SetTpAttr 网络属性位图:bit2~8(0x1FC,sip/dip/smac/dmac/vlan + dscp,不含 sl);HCCP 自动
      37              : /// urma_get_smac/get_dmac
      38              : constexpr uint32_t kTpAttrBitmapUboeNetWithDscp = 0x1FCU;
      39              : 
      40              : namespace {
      41              : 
      42          133 :     static constexpr QosKey QosMapKey(uint32_t qos) noexcept { return static_cast<QosKey>(qos & 0xFFU); }
      43              : 
      44              :     // MAINBOARD_PCIE_STD(PCIE 标卡):跳过 GetTpAttr/SL 策略,固定使用 TP 列表首个 TP;
      45              :     // jetty priority(SL)取 2,为标卡 UB 互通方案约定档位,与现网标卡环境对齐。
      46              :     static constexpr uint32_t kPcieStdMappedSl = 2U;
      47              :     // TpAttr::sip/dip 为 16 字节;IPv4 映射时前 12 字节填 0,后 4 字节填 IPv4 四段地址(网络字节序)。
      48              :     static constexpr size_t kMappedIpArrayLen = 16U;
      49              :     static constexpr size_t kIpv4OctetCount = 4U;
      50              :     static constexpr size_t kIpv4MappedOffset = kMappedIpArrayLen - kIpv4OctetCount;
      51              : 
      52           40 :     static HcclResult IsPcieStdMainboard(uint32_t devLogicId, bool& isPcieStd)
      53              :     {
      54           40 :         isPcieStd = false;
      55           40 :         HcclMainboardId mainboardId = HcclMainboardId::MAINBOARD_OTHERS;
      56           40 :         CHK_RET(HrtGetMainboardId(devLogicId, mainboardId));
      57           40 :         isPcieStd = (mainboardId == HcclMainboardId::MAINBOARD_PCIE_STD);
      58           40 :         return HcclResult::HCCL_SUCCESS;
      59              :     }
      60              : 
      61           18 :     static uint32_t CalSlAvailableCnt(uint32_t mask)
      62              :     {
      63           18 :         uint32_t c = 0;
      64          306 :         for (uint32_t i = 0; i < 16U; ++i) {
      65          288 :             if ((mask & (1U << i)) != 0U) {
      66           51 :                 ++c;
      67              :             }
      68              :         }
      69           18 :         return c;
      70              :     }
      71              : 
      72            6 :     static uint32_t SlValueAtRankInMask16(uint32_t mask, uint32_t rank)
      73              :     {
      74            6 :         uint32_t seen = 0;
      75           29 :         for (uint32_t bit = 0; bit < 16U; ++bit) {
      76           29 :             if ((mask & (1U << bit)) != 0U) {
      77            8 :                 if (seen == rank) {
      78            6 :                     return bit;
      79              :                 }
      80            2 :                 ++seen;
      81              :             }
      82              :         }
      83            0 :         return 0;
      84              :     }
      85              : 
      86            6 :     static uint16_t ReadSlAvailableMask16(const struct TpAttr& attr) { return static_cast<uint16_t>(attr.slBitmap); }
      87              : 
      88            6 :     static uint32_t ResolveSlAvailableCntForPolicy(uint16_t slMask, uint32_t slLevelCount)
      89              :     {
      90            6 :         uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
      91            6 :         if (slLevelCount != 0U) {
      92            0 :             slAvailableCnt = std::min(slLevelCount, slAvailableCnt);
      93              :         }
      94            6 :         return slAvailableCnt;
      95              :     }
      96              : 
      97            2 :     static bool ApplyLoopFirstTpLowestSl(
      98              :         const RaUbGetTpInfoParam& param, const uint16_t slMask, const uint32_t slRawCnt, const uint32_t slAvailableCnt,
      99              :         uint32_t& tpListIndexOut, uint32_t& mappedSlOut)
     100              :     {
     101              :         (void)param;
     102            2 :         tpListIndexOut = 0U;
     103            2 :         mappedSlOut = SlValueAtRankInMask16(slMask, 0U);
     104            6 :         HCCL_INFO(
     105              :             "[TpManager][ApplyQosTpSlPolicy] loopFirstTpLowestSl: slRawCnt[%u] slAvailableCnt[%u(after cap)] "
     106              :             "slMask[0x%x] tpListIdx[0] mappedSl[%u] param[%s].",
     107              :             slRawCnt, slAvailableCnt, static_cast<unsigned>(slMask), static_cast<unsigned>(mappedSlOut & 0xFU),
     108              :             param.Describe().c_str());
     109            2 :         return true;
     110              :     }
     111              : 
     112            6 :     static bool ApplyQosTpSlPolicy(
     113              :         const RaUbGetTpInfoParam& param, uint16_t slMask, uint32_t& tpListIndexOut, uint32_t& mappedSlOut)
     114              :     {
     115            6 :         const uint32_t slRawCnt = CalSlAvailableCnt(slMask);
     116            6 :         const uint32_t slAvailableCnt = ResolveSlAvailableCntForPolicy(slMask, param.slLevelCount);
     117            6 :         if (slAvailableCnt == 0U) {
     118            0 :             return false;
     119              :         }
     120            6 :         if (param.loopFirstTpLowestSl) {
     121            2 :             return ApplyLoopFirstTpLowestSl(param, slMask, slRawCnt, slAvailableCnt, tpListIndexOut, mappedSlOut);
     122              :         }
     123              : 
     124            4 :         const uint32_t qos = param.qos;
     125            4 :         const uint32_t numGroups = slAvailableCnt;
     126            4 :         const uint32_t groupIdx = TpQosResolveQosSlGroupIdx(qos, numGroups);
     127            4 :         if (groupIdx >= numGroups) {
     128            0 :             HCCL_ERROR(
     129              :                 "[TpManager][%s] groupIdx out of range: groupIdx[%u] numGroups[%u] qos[%u] slAvailableCnt[%u].",
     130              :                 __func__, groupIdx, numGroups, qos, slAvailableCnt);
     131            0 :             return false;
     132              :         }
     133              : 
     134            4 :         tpListIndexOut = 0U;
     135              :         // groupIdx 越大 SL 越低:slRank = (numGroups - 1) - groupIdx,从 slMask 中取对应 jetty priority。
     136            4 :         const uint32_t slRank = (slAvailableCnt - 1U) - groupIdx;
     137            4 :         mappedSlOut = SlValueAtRankInMask16(slMask, slRank);
     138            4 :         return true;
     139              :     }
     140              : 
     141            6 :     static uint32_t BuildGetTpAttrBitmapForSlPolicy(TpProtocol tpProtocol)
     142              :     {
     143            6 :         uint32_t bitmap = (1U << kTpAttrSlAvailableBit) | kTpAttrBitmapSl;
     144            6 :         if (tpProtocol == TpProtocol::UBOE || tpProtocol == TpProtocol::UBG) {
     145            3 :             bitmap |= kTpAttrBitmapDscp | (1U << kTpAttrDscpConfigModeBit);
     146              :         }
     147            6 :         return bitmap;
     148              :     }
     149              : 
     150              :     /// isSync=false(异步 GetTpInfo 写回 SL/DSCP):HrtRaSetTpAttrAsync。
     151              :     /// 阻塞等待在 adapter 内,本函数返回时 Set 已生效。
     152              :     /// 不用同步 HrtRaSetTpAttr,避免 Rs 路径 phyId 无效。
     153            9 :     static HcclResult SetTpAttrAsync(
     154              :         RdmaHandle ctxHandle, uint64_t tpHandle, uint32_t attrBitmap, struct TpAttr& attr, const char* logTag)
     155              :     {
     156            9 :         RequestHandle reqHandle = 0;
     157            9 :         HcclResult hret = HcclResult::HCCL_SUCCESS;
     158            9 :         TRY_CATCH_RETURN(hret = HrtRaSetTpAttrAsync(ctxHandle, tpHandle, attrBitmap, attr, reqHandle););
     159            9 :         if (hret != HcclResult::HCCL_SUCCESS) {
     160            0 :             HCCL_ERROR(
     161              :                 "[TpManager][%s] HrtRaSetTpAttrAsync failed hcclRet[%d] tpHandle[%llu].", logTag,
     162              :                 static_cast<int>(hret), tpHandle);
     163              :         }
     164            9 :         return hret;
     165              :     }
     166              : 
     167              :     /// isSync=true(同步 GetTpInfo 写回 SL/DSCP):HrtRaSetTpAttr,与 HrtRaGetTpAttr / RaUbGetTpInfo 成对。
     168              :     static HcclResult
     169            0 :     SetTpAttrSync(RdmaHandle ctxHandle, uint64_t tpHandle, uint32_t attrBitmap, struct TpAttr& attr, const char* logTag)
     170              :     {
     171            0 :         const HcclResult hret = HrtRaSetTpAttr(ctxHandle, tpHandle, attrBitmap, attr);
     172            0 :         if (hret != HcclResult::HCCL_SUCCESS) {
     173            0 :             HCCL_ERROR(
     174              :                 "[TpManager][%s] HrtRaSetTpAttr failed hcclRet[%d] tpHandle[%llu] attrBitmap[0x%x].", logTag,
     175              :                 static_cast<int>(hret), tpHandle, attrBitmap);
     176              :         }
     177            0 :         return hret;
     178              :     }
     179              : 
     180              :     /// 按 GetTpInfo 的 isSync 选择 SetTpAttr:true → SetTpAttrSync;false → SetTpAttrAsync。
     181            9 :     static HcclResult SetTpAttrByPath(
     182              :         const bool isSync, RdmaHandle ctxHandle, uint64_t tpHandle, uint32_t attrBitmap, struct TpAttr& attr,
     183              :         const char* logTag)
     184              :     {
     185            9 :         if (isSync) {
     186            0 :             return SetTpAttrSync(ctxHandle, tpHandle, attrBitmap, attr, logTag);
     187              :         }
     188            9 :         return SetTpAttrAsync(ctxHandle, tpHandle, attrBitmap, attr, logTag);
     189              :     }
     190              : 
     191              :     static HcclResult
     192            6 :     CommitMappedSlToTpAttr(const bool isSync, RdmaHandle ctxHandle, uint64_t tpHandle, uint32_t mappedSl)
     193              :     {
     194            6 :         if (tpHandle == 0U) {
     195            0 :             HCCL_ERROR("[TpManager][CommitMappedSlToTpAttr] tpHandle is 0");
     196            0 :             return HcclResult::HCCL_E_INTERNAL;
     197              :         }
     198            6 :         if (!ctxHandle) {
     199            0 :             HCCL_ERROR("[TpManager][CommitMappedSlToTpAttr] ctxHandle is null tpHandle[%llu]", tpHandle);
     200            0 :             return HcclResult::HCCL_E_INTERNAL;
     201              :         }
     202            6 :         struct TpAttr tpSlAttr {};
     203            6 :         tpSlAttr.sl = static_cast<uint8_t>(mappedSl & 0xFU);
     204            6 :         return SetTpAttrByPath(isSync, ctxHandle, tpHandle, kTpAttrBitmapSl, tpSlAttr, "CommitMappedSlToTpAttr");
     205              :     }
     206              : 
     207           32 :     static RdmaHandle ResolveUbRdmaHandle(const bool isSync, const uint32_t devPhyId, const IpAddress& locAddr)
     208              :     {
     209           32 :         if (isSync) {
     210            0 :             Hccl::IpAddress addr = locAddr;
     211            0 :             return RdmaHandleManager::GetInstance().GetByAddr(
     212            0 :                 devPhyId, LinkProtoType::UB, addr, Hccl::PortDeploymentType::HOST_NET);
     213              :         }
     214           32 :         return RdmaHandleManager::GetInstance().GetByIp(devPhyId, locAddr);
     215              :     }
     216              : 
     217              :     // 将 IPv4 点分十进制字符串解析为 TpAttr::sip/dip 所需的 16 字节映射格式:
     218              :     // 前 12 字节填 0,后 4 字节为 inet_pton 得到的网络字节序 IPv4 地址。
     219            6 :     static HcclResult Ipv4ToIpArray(const char* ipv4Str, uint8_t ipArr[kMappedIpArrayLen])
     220              :     {
     221            6 :         if (ipv4Str == nullptr || ipArr == nullptr) {
     222            0 :             return HcclResult::HCCL_E_PARA;
     223              :         }
     224            6 :         struct in_addr addr {};
     225            6 :         if (inet_pton(AF_INET, ipv4Str, &addr) != 1) {
     226            0 :             return HcclResult::HCCL_E_PARA;
     227              :         }
     228            6 :         const errno_t memsetRet = memset_s(ipArr, kMappedIpArrayLen, 0, kMappedIpArrayLen);
     229            6 :         if (memsetRet != EOK) {
     230            0 :             return HcclResult::HCCL_E_INTERNAL;
     231              :         }
     232            6 :         const errno_t cpyRet = memcpy_s(ipArr + kIpv4MappedOffset, kIpv4OctetCount, &addr.s_addr, kIpv4OctetCount);
     233            6 :         if (cpyRet != EOK) {
     234            0 :             return HcclResult::HCCL_E_INTERNAL;
     235              :         }
     236            6 :         return HcclResult::HCCL_SUCCESS;
     237              :     }
     238              : 
     239            3 :     static HcclResult CommitUboeNetAttrsToTpAttr(
     240              :         const bool isSync, RdmaHandle ctxHandle, uint64_t tpHandle, const TpAttr& tpAttr, const IpAddress& locIpv4Addr,
     241              :         const IpAddress& rmtIpv4Addr, bool setDscp, uint8_t dscp)
     242              :     {
     243            3 :         if (tpHandle == 0U || !ctxHandle) {
     244            0 :             return HcclResult::HCCL_E_INTERNAL;
     245              :         }
     246            3 :         struct TpAttr netAttr = tpAttr;
     247            3 :         const std::string localIp = locIpv4Addr.GetIpStr();
     248            3 :         const std::string rmtIp = rmtIpv4Addr.GetIpStr();
     249            3 :         CHK_RET(Ipv4ToIpArray(localIp.c_str(), netAttr.sip));
     250            3 :         CHK_RET(Ipv4ToIpArray(rmtIp.c_str(), netAttr.dip));
     251            3 :         if (setDscp) {
     252            3 :             netAttr.dscp = static_cast<uint8_t>(dscp & 0x3FU);
     253              :         }
     254            9 :         HCCL_INFO(
     255              :             "[TpManager][CommitUboeNetAttrsToTpAttr] tpHandle[%llu] localIpv4[%s] rmtIpv4[%s] setDscp[%d] "
     256              :             "dscp[%u] attrBitmap[0x%x].",
     257              :             tpHandle, localIp.c_str(), rmtIp.c_str(), static_cast<int>(setDscp),
     258              :             static_cast<unsigned>(netAttr.dscp & 0x3FU), kTpAttrBitmapUboeNetWithDscp);
     259            3 :         return SetTpAttrByPath(
     260            3 :             isSync, ctxHandle, tpHandle, kTpAttrBitmapUboeNetWithDscp, netAttr, "CommitUboeNetAttrsToTpAttr");
     261            3 :     }
     262              : 
     263            0 :     static HcclResult CommitUbgDscpToTpAttr(const bool isSync, RdmaHandle ctxHandle, uint64_t tpHandle, uint8_t dscp)
     264              :     {
     265            0 :         if (tpHandle == 0U || !ctxHandle) {
     266            0 :             return HcclResult::HCCL_E_INTERNAL;
     267              :         }
     268              : 
     269            0 :         struct TpAttr dscpAttr {};
     270            0 :         dscpAttr.dscp = dscp;
     271            0 :         HCCL_INFO(
     272              :             "[TpManager][%s] tpHandle[%llu] dscp[%u] attrBitmap[0x%x].", __func__, tpHandle,
     273              :             static_cast<unsigned>(dscpAttr.dscp), kTpAttrBitmapDscp);
     274            0 :         return SetTpAttrByPath(isSync, ctxHandle, tpHandle, kTpAttrBitmapDscp, dscpAttr, "CommitUbgDscpToTpAttr");
     275              :     }
     276              : 
     277            6 :     static HcclResult CommitTpAttrsAfterSlMapping(
     278              :         const uint32_t devLogicId, const uint32_t devPhyId, const bool isSync, const RaUbGetTpInfoParam& param,
     279              :         const TpAttr& tpAttr, uint64_t tpHandle, uint32_t mappedSl, uint32_t nTp, uint16_t slMask)
     280              :     {
     281            6 :         bool isPcieStd = false;
     282            6 :         CHK_RET(IsPcieStdMainboard(devLogicId, isPcieStd));
     283            6 :         if (isPcieStd) {
     284            0 :             HCCL_INFO(
     285              :                 "[TpManager][%s] pcie std mainboard: skip SetTpAttr, devPhyId[%u] tpProtocol[%s] tpHandle[%llu] "
     286              :                 "param[%s].",
     287              :                 __func__, devPhyId, param.tpProtocol.Describe().c_str(), tpHandle, param.Describe().c_str());
     288            0 :             return HcclResult::HCCL_SUCCESS;
     289              :         }
     290            6 :         const RdmaHandle ctxHandle = ResolveUbRdmaHandle(isSync, devPhyId, param.locAddr);
     291            6 :         if (!ctxHandle) {
     292            0 :             HCCL_ERROR(
     293              :                 "[TpManager][%s] ctxHandle null devPhyId[%u] isSync[%d] loc[%s].", __func__, devPhyId,
     294              :                 static_cast<int>(isSync), param.locAddr.Describe().c_str());
     295            0 :             return HcclResult::HCCL_E_INTERNAL;
     296              :         }
     297              :         // TP / UBOE / UBG:将 TP QoS/SL 策略得到的 mapped SL 写回 TP;CTP 不向 TP 写 SL(与 Next TpMgr 一致)
     298            9 :         if (param.tpProtocol == TpProtocol::TP || param.tpProtocol == TpProtocol::UBOE
     299            9 :             || param.tpProtocol == TpProtocol::UBG) {
     300            6 :             CHK_RET(CommitMappedSlToTpAttr(isSync, ctxHandle, tpHandle, mappedSl));
     301              :         }
     302            6 :         if (param.tpProtocol != TpProtocol::UBOE && param.tpProtocol != TpProtocol::UBG) {
     303            3 :             return HcclResult::HCCL_SUCCESS;
     304              :         }
     305            3 :         if (param.tpProtocol == TpProtocol::UBG) {
     306              :             // UBG:仅当 dscp mode == 0 时下发 DSCP。
     307            0 :             if (tpAttr.dscpConfigMode != 0) {
     308            0 :                 return HcclResult::HCCL_SUCCESS;
     309              :             }
     310              : 
     311            0 :             uint8_t dscp = kUboeDefaultDscp;
     312            0 :             (void)TpQosGetDscpByQosFromHccnCfg(devPhyId, param.qos, dscp);
     313            0 :             CHK_RET(CommitUbgDscpToTpAttr(isSync, ctxHandle, tpHandle, dscp));
     314            0 :             HCCL_INFO(
     315              :                 "[TpManager][%s] UBG dscp committed: tpHandle[%llu] dscpAfter[%u].", __func__, tpHandle,
     316              :                 static_cast<unsigned>(dscp));
     317            0 :             return HcclResult::HCCL_SUCCESS;
     318              :         }
     319            3 :         if (tpAttr.dscpConfigMode == 1) {
     320            0 :             CHK_RET(CommitUboeNetAttrsToTpAttr(
     321              :                 isSync, ctxHandle, tpHandle, tpAttr, param.locIpv4Addr, param.rmtIpv4Addr, false, 0U));
     322            0 :             return HcclResult::HCCL_SUCCESS;
     323              :         }
     324              : 
     325            3 :         uint8_t dscp = kUboeDefaultDscp;
     326            3 :         (void)TpQosGetDscpByQosFromHccnCfg(devPhyId, param.qos, dscp);
     327            3 :         CHK_RET(CommitUboeNetAttrsToTpAttr(
     328              :             isSync, ctxHandle, tpHandle, tpAttr, param.locIpv4Addr, param.rmtIpv4Addr, true, dscp));
     329            9 :         HCCL_INFO(
     330              :             "[TpManager][%s] UBOE net attrs updated: tpHandle[%llu] dscpAfter[%u].", __func__, tpHandle,
     331              :             static_cast<unsigned>(dscp));
     332            3 :         return HcclResult::HCCL_SUCCESS;
     333              :     }
     334              : 
     335              : } // namespace
     336              : 
     337          166 : TpManager& TpManager::GetInstance(const int32_t deviceLogicId)
     338              : {
     339          232 :     static TpManager tpManager[MAX_MODULE_DEVICE_NUM + 1];
     340              : 
     341          166 :     if (deviceLogicId < 0 || static_cast<uint32_t>(deviceLogicId) > MAX_MODULE_DEVICE_NUM) {
     342            0 :         THROW<InvalidParamsException>(
     343              :             "[TpManager][%s] failed to get instance, "
     344              :             "devLogicId[%d] should be less than %u.",
     345              :             __func__, deviceLogicId, MAX_MODULE_DEVICE_NUM);
     346              :     }
     347              : 
     348          166 :     tpManager[deviceLogicId].devLogicId = deviceLogicId;
     349              : 
     350          166 :     return tpManager[deviceLogicId];
     351              : }
     352              : 
     353           28 : void TpManager::Init()
     354              : {
     355           28 :     if (initFlag) {
     356           27 :         return;
     357              :     }
     358              : 
     359            1 :     devPhyId = HrtGetDevicePhyIdByIndex(devLogicId);
     360            1 :     initFlag = true;
     361              : }
     362              : 
     363           30 : bool TpManager::CheckRequestResult(RequestHandle& reqHandle) const
     364              : {
     365           30 :     if (reqHandle == 0) {
     366            0 :         return true;
     367              :     }
     368              : 
     369           30 :     ReqHandleResult result = HrtRaGetAsyncReqResult(reqHandle);
     370           30 :     if (result == ReqHandleResult::NOT_COMPLETED) {
     371            0 :         return false;
     372              :     }
     373              : 
     374           30 :     if (result != ReqHandleResult::COMPLETED) {
     375            1 :         THROW<InternalException>(
     376            3 :             "[TpManager][%s] failed, result[%s] is unexpected.", __func__, result.Describe().c_str());
     377              :     }
     378              : 
     379           29 :     return true;
     380              : }
     381              : 
     382           58 : HcclResult CheckTpProtocol(const TpProtocol tpProtocol)
     383              : {
     384          114 :     if (tpProtocol != TpProtocol::CTP && tpProtocol != TpProtocol::TP && tpProtocol != TpProtocol::UBOE
     385          114 :         && tpProtocol != TpProtocol::UBG) {
     386            0 :         HCCL_WARNING("[TpManager][%s] failed, tpProtocol[%d] is not supported.", __func__, tpProtocol);
     387            0 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     388              :     }
     389              : 
     390           58 :     return HcclResult::HCCL_SUCCESS;
     391              : }
     392              : 
     393           19 : HcclResult TpManager::AdvanceDeviceWaitListPhase(
     394              :     const RaUbGetTpInfoParam& param, RequestCtx& reqCtx, ReqQosMap& qosReqMap, ReqQosMap::iterator it,
     395              :     std::unique_lock<std::mutex>& reqCtxLock, TpInfo& tpInfo)
     396              : {
     397           19 :     if (reqCtx.tpInfoNum == 0U) {
     398            2 :         qosReqMap.erase(it);
     399            6 :         HCCL_ERROR(
     400              :             "[TpManager][%s] failed to find tp info, tpInfoNum is 0, param[%s].", __func__, param.Describe().c_str());
     401            2 :         return HcclResult::HCCL_E_NOT_FOUND;
     402              :     }
     403           17 :     bool isPcieStd = false;
     404           17 :     CHK_RET(IsPcieStdMainboard(devLogicId, isPcieStd));
     405           17 :     if (isPcieStd) {
     406              :         const struct HccpTpInfo* list
     407            0 :             = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     408            0 :         HCCL_INFO(
     409              :             "[TpManager][%s] pcie std mainboard: skip GetTpAttr, devPhyId[%u] tpInfoNum[%u] mappedSl[%u] "
     410              :             "tpHandle[%llu] param[%s].",
     411              :             __func__, devPhyId, reqCtx.tpInfoNum, kPcieStdMappedSl, static_cast<unsigned long long>(list[0].tpHandle),
     412              :             param.Describe().c_str());
     413            0 :         RequestCtx completedReqCtx = std::move(it->second);
     414            0 :         qosReqMap.erase(it);
     415            0 :         reqCtxLock.unlock();
     416            0 :         CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo, false));
     417            0 :         return HcclResult::HCCL_SUCCESS;
     418            0 :     }
     419           17 :     if (HrtRaSupportsGetTpAttr(devPhyId)) {
     420              :         const struct HccpTpInfo* list
     421            6 :             = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     422           18 :         HCCL_INFO(
     423              :             "[TpManager][GetTpInfo] list stage ok, devPhyId[%u] tpInfoNum[%u] firstTpHandle[%llu] param[%s].", devPhyId,
     424              :             reqCtx.tpInfoNum, static_cast<unsigned long long>(list[0].tpHandle), param.Describe().c_str());
     425            6 :         TRY_CATCH_PROCESS_THROW(
     426              :             NetworkApiException, StartGetTpAttrForFirstTpDevice(param, reqCtx),
     427              :             "[TpManager][AdvanceDeviceWaitListPhase] StartGetTpAttrForFirstTpDevice failed", qosReqMap.erase(it));
     428            6 :         return HcclResult::HCCL_E_AGAIN;
     429              :     }
     430           11 :     RequestCtx completedReqCtx = std::move(it->second);
     431           11 :     qosReqMap.erase(it);
     432           11 :     reqCtxLock.unlock();
     433           11 :     CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo, false));
     434           11 :     return HcclResult::HCCL_SUCCESS;
     435           11 : }
     436              : 
     437              : // GetTpInfo 完成后写入缓存。useCnt 仅在 FindAndGetTpInfo 命中时 +1,此处不做引用计数。
     438              : // 并发首次 GetTpInfo 时,先完成者写入缓存;后完成者若 tpHandle 不同则跳过写入,直接使用本地结果。
     439           17 : HcclResult TpManager::StoreTpInfoResult(const RaUbGetTpInfoParam& param, TpInfo& tpInfo)
     440              : {
     441           17 :     const QosKey qosKey = QosMapKey(param.qos);
     442           17 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     443           17 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     444           17 :     auto& qosMap = infoMap[param.locAddr][param.rmtAddr];
     445           17 :     const auto qIt = qosMap.find(qosKey);
     446           17 :     if (qIt == qosMap.end()) {
     447           17 :         qosMap[qosKey] = TpInfoCtx{tpInfo, 1U};
     448           17 :         return HcclResult::HCCL_SUCCESS;
     449              :     }
     450              : 
     451              :     // 缓存已存在:不再覆盖(避免并发后写覆盖先写的 tpHandle);tpInfo 保持 GetTpInfo 本地结果。
     452            0 :     if (qIt->second.tpInfo.tpHandle != tpInfo.tpHandle) {
     453            0 :         HCCL_WARNING(
     454              :             "[TpManager][%s] skip cache store, cached tpHandle[%llu] != local tpHandle[%llu] param[%s].", __func__,
     455              :             qIt->second.tpInfo.tpHandle, tpInfo.tpHandle, param.Describe().c_str());
     456              :     }
     457            0 :     return HcclResult::HCCL_SUCCESS;
     458           17 : }
     459              : 
     460            0 : HcclResult TpManager::SyncGetFirstTpAttrForSlPolicy(
     461              :     const RaUbGetTpInfoParam& param, uint64_t firstTpHandle, TpAttr& tpAttr, uint32_t& attrBitmap) const
     462              : {
     463            0 :     (void)memset_s(&tpAttr, sizeof(tpAttr), 0, sizeof(tpAttr));
     464            0 :     attrBitmap = BuildGetTpAttrBitmapForSlPolicy(param.tpProtocol);
     465            0 :     const RdmaHandle rdmaHandle = ResolveUbRdmaHandle(true, devPhyId, param.locAddr);
     466            0 :     if (!rdmaHandle) {
     467            0 :         HCCL_ERROR(
     468              :             "[TpManager][%s] can not find host rdmaHandle, devPhyId[%u] locAddr[%s].", __func__, devPhyId,
     469              :             param.locAddr.Describe().c_str());
     470            0 :         return HcclResult::HCCL_E_INTERNAL;
     471              :     }
     472            0 :     CHK_RET(HrtRaGetTpAttr(rdmaHandle, firstTpHandle, attrBitmap, tpAttr));
     473            0 :     HCCL_INFO(
     474              :         "[TpManager][%s] HrtRaGetTpAttr ok, tpHandle[%llu] attrBitmap[0x%x] param[%s].", __func__, firstTpHandle,
     475              :         attrBitmap, param.Describe().c_str());
     476            0 :     return HcclResult::HCCL_SUCCESS;
     477              : }
     478              : 
     479            0 : HcclResult TpManager::RunSyncGetTpInfo(const RaUbGetTpInfoParam& param, TpInfo& tpInfo)
     480              : {
     481            0 :     RequestCtx reqCtx{};
     482            0 :     StartGetTpInfoListRequest(param, reqCtx, true);
     483              : 
     484            0 :     if (reqCtx.tpInfoNum == 0U) {
     485            0 :         HCCL_ERROR(
     486              :             "[TpManager][%s] failed to find tp info, tpInfoNum is 0, param[%s].", __func__, param.Describe().c_str());
     487            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     488              :     }
     489              : 
     490              :     const struct HccpTpInfo* list
     491            0 :         = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     492            0 :     HCCL_INFO(
     493              :         "[TpManager][%s] sync GetTpList ok, devPhyId[%u] tpInfoNum[%u] firstTpHandle[%llu] param[%s].", __func__,
     494              :         devPhyId, reqCtx.tpInfoNum, static_cast<unsigned long long>(list[0].tpHandle), param.Describe().c_str());
     495              : 
     496            0 :     tpInfo = TpInfo{};
     497            0 :     bool isPcieStd = false;
     498            0 :     CHK_RET(IsPcieStdMainboard(devLogicId, isPcieStd));
     499            0 :     if (isPcieStd) {
     500            0 :         tpInfo.tpHandle = list[0].tpHandle;
     501            0 :         tpInfo.mappedJettyPriority = kPcieStdMappedSl;
     502            0 :         tpInfo.hasMappedJettyPriority = true;
     503            0 :         HCCL_INFO(
     504              :             "[TpManager][%s] pcie std mainboard: skip GetTpAttr/SetTpAttr, mappedSl[%u] tpHandle[%llu] "
     505              :             "param[%s].",
     506              :             __func__, kPcieStdMappedSl, tpInfo.tpHandle, param.Describe().c_str());
     507              :     } else {
     508            0 :         CHK_RET(SyncGetFirstTpAttrForSlPolicy(param, list[0].tpHandle, reqCtx.tpAttr, reqCtx.tpAttrBitmap));
     509            0 :         CHK_RET(MapTpInfoFromTpAttr(param, reqCtx, tpInfo, true));
     510              :     }
     511              : 
     512            0 :     return StoreTpInfoResult(param, tpInfo);
     513            0 : }
     514              : 
     515           46 : HcclResult TpManager::RunAsyncGetTpInfo(const RaUbGetTpInfoParam& param, TpInfo& tpInfo)
     516              : {
     517           46 :     RequestCtx completedReqCtx{};
     518           46 :     bool withSlPolicy = false;
     519              : 
     520              :     {
     521           46 :         std::unique_lock<std::mutex> reqCtxLock(GetReqCtxMutex(param.tpProtocol));
     522           46 :         auto& reqCtxMap = GetReqCtxMap(param.tpProtocol);
     523           46 :         const auto& locAddr = param.locAddr;
     524           46 :         const auto& rmtAddr = param.rmtAddr;
     525           46 :         const QosKey qosKey = QosMapKey(param.qos);
     526              : 
     527           46 :         auto& rmtReqMap = reqCtxMap[locAddr];
     528           46 :         auto& qosReqMap = rmtReqMap[rmtAddr];
     529           46 :         auto it = qosReqMap.find(qosKey);
     530           46 :         if (it == qosReqMap.end()) {
     531           60 :             HCCL_INFO("[TpManager][%s] get new tpInfo, param[%s].", __func__, param.Describe().c_str());
     532              : 
     533           20 :             RequestCtx& reqCtx = qosReqMap[qosKey];
     534           20 :             StartGetTpInfoListRequest(param, reqCtx, false);
     535           20 :             return HcclResult::HCCL_E_AGAIN;
     536              :         }
     537              : 
     538           26 :         RequestCtx& reqCtx = it->second;
     539              : 
     540           26 :         if (reqCtx.handle != 0U && !CheckRequestResult(reqCtx.handle)) {
     541            0 :             return HcclResult::HCCL_E_AGAIN;
     542              :         }
     543              : 
     544           25 :         switch (reqCtx.phase) {
     545           19 :             case RequestCtx::ReqPhase::WAIT_LIST:
     546           19 :                 return AdvanceDeviceWaitListPhase(param, reqCtx, qosReqMap, it, reqCtxLock, tpInfo);
     547            6 :             case RequestCtx::ReqPhase::WAIT_TP_ATTR:
     548            6 :                 completedReqCtx = std::move(it->second);
     549            6 :                 qosReqMap.erase(it);
     550            6 :                 withSlPolicy = true;
     551            6 :                 break;
     552            0 :             default:
     553            0 :                 completedReqCtx = std::move(it->second);
     554            0 :                 qosReqMap.erase(it);
     555            0 :                 withSlPolicy = false;
     556            0 :                 break;
     557              :         }
     558           46 :     }
     559              : 
     560            6 :     CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo, withSlPolicy));
     561            6 :     return HcclResult::HCCL_SUCCESS;
     562           46 : }
     563              : 
     564           58 : HcclResult TpManager::GetTpInfo(const RaUbGetTpInfoParam& param, TpInfo& tpInfo, bool isSync)
     565              : {
     566           58 :     CHK_RET(CheckTpProtocol(param.tpProtocol));
     567           58 :     if (FindAndGetTpInfo(param, tpInfo) == HcclResult::HCCL_SUCCESS) {
     568           12 :         return HcclResult::HCCL_SUCCESS;
     569              :     }
     570              : 
     571           46 :     if (isSync) {
     572            0 :         return RunSyncGetTpInfo(param, tpInfo);
     573              :     }
     574           46 :     return RunAsyncGetTpInfo(param, tpInfo);
     575              : }
     576              : 
     577           19 : HcclResult TpManager::FindAndGetTpAttr(const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     578              : {
     579           19 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex);
     580           19 :     auto attrIter = tpAttrCtxMap.find(tpHandle);
     581           19 :     if (attrIter != tpAttrCtxMap.end()) {
     582           11 :         attrIter->second.useCnt += 1;
     583           11 :         tpAttrInfo = attrIter->second.tpAttrInfo;
     584           33 :         HCCL_INFO(
     585              :             "[TpManager][%s] cache hit, tpHandle[0x%llx] useCnt[%u].", __func__,
     586              :             static_cast<unsigned long long>(tpHandle), attrIter->second.useCnt);
     587           11 :         return HcclResult::HCCL_SUCCESS;
     588              :     }
     589              : 
     590            8 :     return HcclResult::HCCL_E_NOT_FOUND;
     591           19 : }
     592              : 
     593           19 : HcclResult TpManager::GetTpAttr(const GetTpAttrParam& param, TpAttrInfo& tpAttrInfo, RdmaHandle rdmaHandle)
     594              : {
     595           19 :     const TpHandle tpHandle = param.tpHandle;
     596           19 :     if (FindAndGetTpAttr(tpHandle, tpAttrInfo) == HcclResult::HCCL_SUCCESS) {
     597           11 :         return HcclResult::HCCL_SUCCESS;
     598              :     }
     599              : 
     600            8 :     std::unique_lock<std::mutex> reqCtxLock(tpAttrReqMutex);
     601            8 :     auto reqCtxIter = tpAttrReqCtxMap.find(tpHandle);
     602            8 :     if (reqCtxIter == tpAttrReqCtxMap.end()) {
     603           12 :         HCCL_INFO("[TpManager][%s] get new tpAttr, param[%s].", __func__, param.Describe().c_str());
     604              : 
     605            4 :         TpAttrRequestCtx& reqCtx = tpAttrReqCtxMap[tpHandle];
     606            4 :         CHK_RET(StartGetTpAttrRequest(param, reqCtx, rdmaHandle));
     607            4 :         return HcclResult::HCCL_E_AGAIN;
     608              :     }
     609              : 
     610            4 :     auto& reqCtx = reqCtxIter->second;
     611            4 :     if (!CheckRequestResult(reqCtx.handle)) {
     612            0 :         return HcclResult::HCCL_E_AGAIN;
     613              :     }
     614              : 
     615            4 :     TpAttrRequestCtx completedReqCtx = reqCtxIter->second;
     616            4 :     tpAttrReqCtxMap.erase(reqCtxIter);
     617            4 :     reqCtxLock.unlock();
     618            4 :     CHK_RET(HandleCompletedTpAttrRequest(std::move(completedReqCtx), tpHandle, tpAttrInfo));
     619            4 :     return HcclResult::HCCL_SUCCESS;
     620            8 : }
     621              : 
     622            4 : HcclResult TpManager::StartGetTpAttrRequest(
     623              :     const GetTpAttrParam& param, TpManager::TpAttrRequestCtx& reqCtx, RdmaHandle rdmaHandle) const
     624              : {
     625            4 :     reqCtx.attrBitmap = param.attrBitmap;
     626            4 :     CHK_RET(HrtRaStartGetTpAttrAsync(rdmaHandle, param.tpHandle, reqCtx.attrBitmap, reqCtx.tpAttr, reqCtx.handle));
     627           12 :     HCCL_INFO("[TpManager][%s] success, tpHandle[0x%llx] reqHandle[%llu].", __func__, param.tpHandle, reqCtx.handle);
     628            4 :     return HcclResult::HCCL_SUCCESS;
     629              : }
     630              : 
     631            4 : HcclResult TpManager::HandleCompletedTpAttrRequest(
     632              :     const TpManager::TpAttrRequestCtx reqCtx, const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     633              : {
     634            4 :     TpAttrInfo tmpTpAttrInfo(reqCtx.tpAttr);
     635              : 
     636            4 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex);
     637            4 :     tpAttrCtxMap[tpHandle] = {std::move(tmpTpAttrInfo), 1};
     638              : 
     639            4 :     tpAttrInfo = tpAttrCtxMap[tpHandle].tpAttrInfo;
     640            4 :     return HcclResult::HCCL_SUCCESS;
     641            4 : }
     642              : 
     643           12 : HcclResult TpManager::ReleaseTpInfo(const RaUbGetTpInfoParam& param, const TpInfo& tpInfo)
     644              : {
     645           12 :     const QosKey qosKey = QosMapKey(param.qos);
     646           12 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     647           12 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     648           12 :     auto lit = infoMap.find(param.locAddr);
     649           12 :     if (lit == infoMap.end()) {
     650           15 :         HCCL_ERROR("[TpManager][%s] failed, tp info is not found, param[%s].", __func__, param.Describe().c_str());
     651            5 :         return HcclResult::HCCL_E_NOT_FOUND;
     652              :     }
     653            7 :     auto rit = lit->second.find(param.rmtAddr);
     654            7 :     if (rit == lit->second.end()) {
     655            0 :         HCCL_ERROR("[TpManager][%s] failed, tp info is not found, param[%s].", __func__, param.Describe().c_str());
     656            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     657              :     }
     658            7 :     auto qit = rit->second.find(qosKey);
     659            7 :     if (qit == rit->second.end()) {
     660            3 :         HCCL_ERROR(
     661              :             "[TpManager][%s] failed, tp info is not found for qosKey[%u], param[%s].", __func__,
     662              :             static_cast<unsigned>(qosKey), param.Describe().c_str());
     663            1 :         return HcclResult::HCCL_E_NOT_FOUND;
     664              :     }
     665              : 
     666              :     // 未入缓存的并发 GetTpInfo 结果:与缓存 tpHandle 不一致,无需操作缓存。
     667            6 :     if (tpInfo.tpHandle != qit->second.tpInfo.tpHandle) {
     668            3 :         HCCL_INFO(
     669              :             "[TpManager][%s] skip, tpHandle mismatch, local[%llu] cached[%llu] locAddr[%s] rmtAddr[%s].", __func__,
     670              :             static_cast<unsigned long long>(tpInfo.tpHandle),
     671              :             static_cast<unsigned long long>(qit->second.tpInfo.tpHandle), param.locAddr.Describe().c_str(),
     672              :             param.rmtAddr.Describe().c_str());
     673            1 :         return HcclResult::HCCL_SUCCESS;
     674              :     }
     675              : 
     676            5 :     if (qit->second.useCnt > 1) {
     677            2 :         qit->second.useCnt -= 1;
     678            6 :         HCCL_INFO(
     679              :             "[TpManager][%s] ref decrement, useCnt[%u -> %u] tpHandle[%llu] locAddr[%s] rmtAddr[%s].", __func__,
     680              :             qit->second.useCnt + 1U, qit->second.useCnt, static_cast<unsigned long long>(tpInfo.tpHandle),
     681              :             param.locAddr.Describe().c_str(), param.rmtAddr.Describe().c_str());
     682            2 :         return HcclResult::HCCL_SUCCESS;
     683              :     }
     684              : 
     685            9 :     HCCL_INFO(
     686              :         "[TpManager][%s] last ref, erase cache entry, useCnt[%u] tpHandle[%llu] locAddr[%s] rmtAddr[%s].", __func__,
     687              :         qit->second.useCnt, static_cast<unsigned long long>(tpInfo.tpHandle), param.locAddr.Describe().c_str(),
     688              :         param.rmtAddr.Describe().c_str());
     689            3 :     rit->second.erase(qit);
     690            3 :     if (rit->second.empty()) {
     691            3 :         lit->second.erase(rit);
     692              :     }
     693            3 :     if (lit->second.empty()) {
     694            3 :         infoMap.erase(lit);
     695              :     }
     696            3 :     return HcclResult::HCCL_SUCCESS;
     697           12 : }
     698              : 
     699            1 : HcclResult TpManager::ReleaseTpAttr(const TpHandle tpHandle, const TpAttrInfo& tpAttrInfo)
     700              : {
     701              :     (void)tpAttrInfo;
     702            1 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex);
     703            1 :     auto attrIter = tpAttrCtxMap.find(tpHandle);
     704            1 :     if (attrIter == tpAttrCtxMap.end()) {
     705            0 :         HCCL_ERROR(
     706              :             "[TpManager][%s] failed, tp attr is not found, "
     707              :             "tpHandle[0x%llx].",
     708              :             __func__, tpHandle);
     709            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     710              :     }
     711              : 
     712            1 :     if (attrIter->second.useCnt > 1) {
     713            1 :         attrIter->second.useCnt -= 1;
     714            3 :         HCCL_INFO(
     715              :             "[TpManager][%s] ref decrement, useCnt[%u -> %u] tpHandle[0x%llx].", __func__, attrIter->second.useCnt + 1U,
     716              :             attrIter->second.useCnt, static_cast<unsigned long long>(tpHandle));
     717            1 :         return HcclResult::HCCL_SUCCESS;
     718              :     }
     719              : 
     720            0 :     HCCL_INFO(
     721              :         "[TpManager][%s] last ref, erase cache entry, useCnt[%u] tpHandle[0x%llx].", __func__, attrIter->second.useCnt,
     722              :         static_cast<unsigned long long>(tpHandle));
     723            0 :     tpAttrCtxMap.erase(attrIter);
     724            0 :     return HcclResult::HCCL_SUCCESS;
     725            1 : }
     726              : 
     727           35 : HcclResult TpManager::GetTpTotalTimeout(const TpAttrInfo& tpAttrInfo, uint32_t& tpTimeOutMs)
     728              : {
     729           35 :     uint8_t rawAtGear = tpAttrInfo.tpAttr.at;
     730           35 :     uint8_t rawRetryTimes = tpAttrInfo.tpAttr.retryTimesInit;
     731              : 
     732           35 :     uint8_t finalAtGear = rawAtGear;
     733           35 :     if (rawAtGear > AT_GEAR_MAX) {
     734            1 :         finalAtGear = AT_GEAR_DEFAULT;
     735            3 :         HCCL_WARNING(
     736              :             "%s Invalid at gear[%u], expect [%u, %u], use default gear[%u].", __func__, rawAtGear, AT_GEAR_MIN,
     737              :             AT_GEAR_MAX, finalAtGear);
     738              :     }
     739              : 
     740           35 :     uint32_t singleAtTimeoutMs = AT_TIMEOUT_MAP[finalAtGear];
     741           35 :     tpTimeOutMs = singleAtTimeoutMs * static_cast<uint32_t>(rawRetryTimes + 1);
     742              : 
     743          105 :     HCCL_INFO(
     744              :         "%s TP timeout calc success: raw_at_gear[%u], final_at_gear[%u], "
     745              :         "single_timeout[%ums], retry_times[%u], total_timeout[%ums].",
     746              :         __func__, rawAtGear, finalAtGear, singleAtTimeoutMs, rawRetryTimes, tpTimeOutMs);
     747              : 
     748           35 :     return HcclResult::HCCL_SUCCESS;
     749              : }
     750              : 
     751           45 : uint32_t TpManager::TaHwValueToMs(uint8_t hwValue)
     752              : {
     753           45 :     uint8_t gear = hwValue / 8;
     754           45 :     switch (gear) {
     755            3 :         case TA_GEAR_INDEX_0:
     756            3 :             return TA_TIMEOUT_MS_GEAR0;
     757           34 :         case TA_GEAR_INDEX_1:
     758           34 :             return TA_TIMEOUT_MS_GEAR1;
     759            3 :         case TA_GEAR_INDEX_2:
     760            3 :             return TA_TIMEOUT_MS_GEAR2;
     761            3 :         case TA_GEAR_INDEX_3:
     762            3 :             return TA_TIMEOUT_MS_GEAR3;
     763            2 :         default:
     764            2 :             return TA_TIMEOUT_MS_GEAR2;
     765              :     }
     766              : }
     767              : 
     768            8 : uint8_t TpManager::FindMinTaHwValue(uint32_t tpTotalTimeoutMs)
     769              : {
     770            8 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR0) {
     771            1 :         return TA_HW_GEAR0_BASE;
     772              :     }
     773            7 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR1) {
     774            2 :         return TA_HW_GEAR1_BASE;
     775              :     }
     776            5 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR2) {
     777            3 :         return TA_HW_GEAR2_BASE;
     778              :     }
     779            2 :     return TA_HW_GEAR3_BASE;
     780              : }
     781              : 
     782           28 : uint8_t TpManager::CalcTaTimeout(const TpAttrInfo& tpAttrInfo)
     783              : {
     784           28 :     constexpr uint8_t UB_TIMEOUT_DEFAULT = 8;
     785           28 :     uint8_t envValue = static_cast<uint8_t>(EnvConfig::GetInstance().GetRdmaConfig().GetUbTimeOut());
     786           28 :     uint32_t envTimeoutMs = TaHwValueToMs(envValue);
     787              : 
     788           28 :     uint32_t tpTimeOutMs = 0;
     789           28 :     (void)GetTpTotalTimeout(tpAttrInfo, tpTimeOutMs);
     790              : 
     791           28 :     uint8_t errTimeout = UB_TIMEOUT_DEFAULT;
     792           28 :     if (envTimeoutMs < tpTimeOutMs) {
     793            1 :         errTimeout = FindMinTaHwValue(tpTimeOutMs);
     794            3 :         HCCL_WARNING(
     795              :             "[TpManager][%s] Env timeout [%ums] < TP timeout [%ums]. Auto upgrade TA to hw_val[%u] (%ums).", __func__,
     796              :             envTimeoutMs, tpTimeOutMs, errTimeout, TaHwValueToMs(errTimeout));
     797              :     } else {
     798           27 :         errTimeout = envValue;
     799           81 :         HCCL_INFO(
     800              :             "[TpManager][%s] Env timeout [%ums] >= TP timeout [%ums]. Use env gear base hw_val[%u] (%ums).", __func__,
     801              :             envTimeoutMs, tpTimeOutMs, envValue, envTimeoutMs);
     802              :     }
     803              : 
     804           28 :     return errTimeout;
     805              : }
     806              : 
     807           58 : HcclResult TpManager::FindAndGetTpInfo(const RaUbGetTpInfoParam& param, TpInfo& tpInfo)
     808              : {
     809           58 :     const QosKey qosKey = QosMapKey(param.qos);
     810           58 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     811           58 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     812           58 :     auto lit = infoMap.find(param.locAddr);
     813           58 :     if (lit == infoMap.end()) {
     814           44 :         return HcclResult::HCCL_E_NOT_FOUND;
     815              :     }
     816           14 :     auto rit = lit->second.find(param.rmtAddr);
     817           14 :     if (rit == lit->second.end()) {
     818            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     819              :     }
     820           14 :     auto qit = rit->second.find(qosKey);
     821           14 :     if (qit == rit->second.end()) {
     822            2 :         return HcclResult::HCCL_E_NOT_FOUND;
     823              :     }
     824              :     // 复用缓存:useCnt 仅在此处(命中)递增,与 StoreTpInfoResult 写入路径分离。
     825           12 :     qit->second.useCnt += 1;
     826           12 :     tpInfo = qit->second.tpInfo;
     827           36 :     HCCL_INFO(
     828              :         "[TpManager][%s] cache hit, tpHandle[%llu] mappedJettyPriority[%u] hasMappedJettyPriority[%d] "
     829              :         "useCnt[%u] param[%s].",
     830              :         __func__, static_cast<unsigned long long>(tpInfo.tpHandle), tpInfo.mappedJettyPriority,
     831              :         static_cast<int>(tpInfo.hasMappedJettyPriority), qit->second.useCnt, param.Describe().c_str());
     832           12 :     return HcclResult::HCCL_SUCCESS;
     833           58 : }
     834              : 
     835           20 : void TpManager::StartGetTpInfoListRequest(
     836              :     const RaUbGetTpInfoParam& param, TpManager::RequestCtx& reqCtx, bool isSync) const
     837              : {
     838           20 :     reqCtx.phase = RequestCtx::ReqPhase::WAIT_LIST;
     839           20 :     (void)memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
     840           20 :     reqCtx.tpAttrBitmap = 0;
     841              : 
     842           20 :     Hccl::IpAddress localIp = param.locAddr;
     843           20 :     const RdmaHandle rdmaHandle = ResolveUbRdmaHandle(isSync, devPhyId, localIp);
     844           20 :     if (!rdmaHandle) {
     845            0 :         THROW<InternalException>(
     846              :             "[TpManager][%s] can not find rdmaHandle, "
     847              :             "devPhyId[%u] locAddr[%s].",
     848            0 :             __func__, devPhyId, param.locAddr.Describe().c_str());
     849              :     }
     850           20 :     if (isSync) {
     851            0 :         RaUbGetTpInfo(rdmaHandle, param, reqCtx.dataBuffer, reqCtx.tpInfoNum);
     852            0 :         return;
     853              :     }
     854           20 :     reqCtx.handle = RaUbGetTpInfoAsync(rdmaHandle, param, reqCtx.dataBuffer, reqCtx.tpInfoNum);
     855              : }
     856              : 
     857            6 : void TpManager::StartGetTpAttrForFirstTpDevice(const RaUbGetTpInfoParam& param, RequestCtx& reqCtx) const
     858              : {
     859            6 :     (void)memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
     860            6 :     reqCtx.tpAttrBitmap = BuildGetTpAttrBitmapForSlPolicy(param.tpProtocol);
     861              :     const struct HccpTpInfo* list
     862            6 :         = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     863            6 :     const uint64_t firstTpHandle = list[0].tpHandle;
     864            6 :     const RdmaHandle rdmaHandle = ResolveUbRdmaHandle(false, devPhyId, param.locAddr);
     865            6 :     if (!rdmaHandle) {
     866            0 :         THROW<InternalException>(
     867            0 :             "[TpManager][%s] can not find rdmaHandle for GetTpAttrAsync, devPhyId[%u].", __func__, devPhyId);
     868              :     }
     869              :     const HcclResult hret
     870            6 :         = HrtRaStartGetTpAttrAsync(rdmaHandle, firstTpHandle, reqCtx.tpAttrBitmap, reqCtx.tpAttr, reqCtx.handle);
     871            6 :     if (hret != HcclResult::HCCL_SUCCESS) {
     872            0 :         THROW<NetworkApiException>(StringFormat(
     873              :             "[TpManager][StartGetTpAttrForFirstTpDevice] HrtRaStartGetTpAttrAsync "
     874              :             "failed hcclRet[%d] tpHandle[%llu].",
     875              :             static_cast<int>(hret), firstTpHandle));
     876              :     }
     877            6 :     reqCtx.phase = RequestCtx::ReqPhase::WAIT_TP_ATTR;
     878            6 : }
     879              : 
     880            6 : HcclResult TpManager::MapTpInfoFromTpAttr(
     881              :     const RaUbGetTpInfoParam& param, const RequestCtx& reqCtx, TpInfo& outTpInfo, bool isSync)
     882              : {
     883            6 :     const uint32_t tpInfoNum = reqCtx.tpInfoNum;
     884              :     const struct HccpTpInfo* baseInfoPtr
     885            6 :         = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     886            6 :     const uint16_t slMask = ReadSlAvailableMask16(reqCtx.tpAttr);
     887            6 :     const uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
     888           18 :     HCCL_INFO(
     889              :         "[TpManager][%s] after get_tp_attr: slMask[0x%04x] slAvailableCnt[%u] slBitmap[0x%x] dscp[%u] "
     890              :         "dscpConfigMode[%u] tpAttrBitmap[0x%x] param[%s].",
     891              :         __func__, static_cast<unsigned>(slMask), slAvailableCnt, static_cast<unsigned>(reqCtx.tpAttr.slBitmap),
     892              :         static_cast<unsigned>(reqCtx.tpAttr.dscp & 0x3FU), static_cast<unsigned>(reqCtx.tpAttr.dscpConfigMode & 1U),
     893              :         reqCtx.tpAttrBitmap, param.Describe().c_str());
     894            6 :     if (slAvailableCnt == 0U) {
     895            0 :         HCCL_ERROR(
     896              :             "[TpManager][%s] sl_available mask empty after get_tp_attr, param[%s].", __func__,
     897              :             param.Describe().c_str());
     898            0 :         return HcclResult::HCCL_E_INTERNAL;
     899              :     }
     900            6 :     uint32_t tpListIndex = 0;
     901            6 :     uint32_t mappedSl = 0;
     902            6 :     if (!ApplyQosTpSlPolicy(param, slMask, tpListIndex, mappedSl)) {
     903            0 :         HCCL_ERROR(
     904              :             "[TpManager][%s] ApplyQosTpSlPolicy failed, param[%s] nTp[%u] slAvailableCnt[%u] mask[%u].", __func__,
     905              :             param.Describe().c_str(), tpInfoNum, slAvailableCnt, static_cast<unsigned>(slMask));
     906            0 :         return HcclResult::HCCL_E_INTERNAL;
     907              :     }
     908            6 :     if (tpListIndex >= tpInfoNum) {
     909            0 :         HCCL_ERROR(
     910              :             "[TpManager][%s] tpListIndex out of range: tpListIndex[%u] tpInfoNum[%u] mappedSl[%u] param[%s].", __func__,
     911              :             tpListIndex, tpInfoNum, static_cast<unsigned>(mappedSl & 0xFU), param.Describe().c_str());
     912            0 :         return HcclResult::HCCL_E_INTERNAL;
     913              :     }
     914              : 
     915            6 :     outTpInfo.tpHandle = baseInfoPtr[tpListIndex].tpHandle;
     916            6 :     outTpInfo.mappedJettyPriority = mappedSl & 0xFU;
     917            6 :     outTpInfo.hasMappedJettyPriority = true;
     918              : 
     919            6 :     CHK_RET(CommitTpAttrsAfterSlMapping(
     920              :         devLogicId, devPhyId, isSync, param, reqCtx.tpAttr, outTpInfo.tpHandle, mappedSl, tpInfoNum, slMask));
     921              : 
     922           18 :     HCCL_INFO(
     923              :         "[TpManager][%s] tp qos mapping ok: tpInfoNum[%u] tpHandle[%llu] tpListIndex[%u] "
     924              :         "mappedJettyPriority[%u] qos[%u] param[%s].",
     925              :         __func__, tpInfoNum, outTpInfo.tpHandle, tpListIndex, outTpInfo.mappedJettyPriority, param.qos & 0xFFU,
     926              :         param.Describe().c_str());
     927            6 :     return HcclResult::HCCL_SUCCESS;
     928              : }
     929              : 
     930           17 : HcclResult TpManager::HandleCompletedRequest(
     931              :     const TpManager::RequestCtx reqCtx, const RaUbGetTpInfoParam& param, TpInfo& tpInfo, bool withSlPolicy)
     932              : {
     933           17 :     const uint32_t tpInfoNum = reqCtx.tpInfoNum;
     934           17 :     if (tpInfoNum == 0) {
     935            0 :         HCCL_ERROR(
     936              :             "[TpManager][%s] failed to find tp info, tpInfoNum is 0, "
     937              :             "param[%s].",
     938              :             __func__, param.Describe().c_str());
     939            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     940              :     }
     941              : 
     942           17 :     tpInfo = TpInfo{};
     943              : 
     944           51 :     HCCL_INFO(
     945              :         "[TpManager][%s] RaGetTpInfoList completed: tpInfoNum[%u] withSlPolicy[%d] devPhyId[%u] param[%s].", __func__,
     946              :         tpInfoNum, static_cast<int>(withSlPolicy), devPhyId, param.Describe().c_str());
     947              : 
     948           17 :     bool isPcieStd = false;
     949           17 :     CHK_RET(IsPcieStdMainboard(devLogicId, isPcieStd));
     950           17 :     if (isPcieStd) {
     951              :         const struct HccpTpInfo* baseInfoPtr
     952            0 :             = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     953            0 :         tpInfo.tpHandle = baseInfoPtr[0].tpHandle;
     954            0 :         tpInfo.mappedJettyPriority = kPcieStdMappedSl;
     955            0 :         tpInfo.hasMappedJettyPriority = true;
     956            0 :         HCCL_INFO(
     957              :             "[TpManager][%s] pcie std mainboard: skip GetTpAttr/SetTpAttr, devPhyId[%u] tpInfoNum[%u] "
     958              :             "mappedSl[%u] tpHandle[%llu] param[%s].",
     959              :             __func__, devPhyId, tpInfoNum, kPcieStdMappedSl, tpInfo.tpHandle, param.Describe().c_str());
     960           17 :     } else if (withSlPolicy) {
     961            6 :         CHK_RET(MapTpInfoFromTpAttr(param, reqCtx, tpInfo, false));
     962              :     } else {
     963              :         const struct HccpTpInfo* baseInfoPtr
     964           11 :             = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     965           11 :         tpInfo.tpHandle = baseInfoPtr[0].tpHandle;
     966           11 :         tpInfo.hasMappedJettyPriority = false;
     967              :     }
     968              : 
     969           17 :     return StoreTpInfoResult(param, tpInfo);
     970              : }
     971              : 
     972           87 : TpManager::InfoCtxMap& TpManager::GetInfoCtxMap(const TpProtocol tpProtocol)
     973              : {
     974           87 :     switch (tpProtocol) {
     975            6 :         case TpProtocol::CTP:
     976            6 :             return ctpInfoMap;
     977           69 :         case TpProtocol::TP:
     978           69 :             return tpInfoMap;
     979           12 :         case TpProtocol::UBOE:
     980           12 :             return uboeInfoMap;
     981            0 :         case TpProtocol::UBG:
     982            0 :             return ubgInfoMap;
     983            0 :         default:
     984            0 :             return tpInfoMap;
     985              :     }
     986              : }
     987              : 
     988           46 : TpManager::ReqCtxMap& TpManager::GetReqCtxMap(const TpProtocol tpProtocol)
     989              : {
     990           46 :     switch (tpProtocol) {
     991            2 :         case TpProtocol::CTP:
     992            2 :             return ctpReqMap;
     993           35 :         case TpProtocol::TP:
     994           35 :             return tpReqMap;
     995            9 :         case TpProtocol::UBOE:
     996            9 :             return uboeReqMap;
     997            0 :         case TpProtocol::UBG:
     998            0 :             return ubgReqMap;
     999            0 :         default:
    1000            0 :             return tpReqMap;
    1001              :     }
    1002              : }
    1003              : 
    1004           87 : std::mutex& TpManager::GetInfoCtxMutex(const TpProtocol tpProtocol)
    1005              : {
    1006           87 :     switch (tpProtocol) {
    1007            6 :         case TpProtocol::CTP:
    1008            6 :             return ctpInfoMutex;
    1009           69 :         case TpProtocol::TP:
    1010           69 :             return tpInfoMutex;
    1011           12 :         case TpProtocol::UBOE:
    1012           12 :             return uboeInfoMutex;
    1013            0 :         case TpProtocol::UBG:
    1014            0 :             return ubgInfoMutex;
    1015            0 :         default:
    1016            0 :             return tpInfoMutex;
    1017              :     }
    1018              : }
    1019              : 
    1020           46 : std::mutex& TpManager::GetReqCtxMutex(const TpProtocol tpProtocol)
    1021              : {
    1022           46 :     switch (tpProtocol) {
    1023            2 :         case TpProtocol::CTP:
    1024            2 :             return ctpReqMutex;
    1025           35 :         case TpProtocol::TP:
    1026           35 :             return tpReqMutex;
    1027            9 :         case TpProtocol::UBOE:
    1028            9 :             return uboeReqMutex;
    1029            0 :         case TpProtocol::UBG:
    1030            0 :             return ubgReqMutex;
    1031            0 :         default:
    1032            0 :             return tpReqMutex;
    1033              :     }
    1034              : }
    1035              : 
    1036          112 : void ReleaseUbConnectionTp(
    1037              :     int32_t devLogicId, const IpAddress& locAddr, const IpAddress& rmtAddr, TpProtocol tpProtocol, TpInfo& tpInfo,
    1038              :     uint32_t requestQos)
    1039              : {
    1040          112 :     if (tpInfo.tpHandle == 0) {
    1041          327 :         HCCL_WARNING(
    1042              :             "[TpManager][%s] skip release, tpHandle is 0, devLogicId[%d] loc[%s] rmt[%s] tpProtocol[%s] "
    1043              :             "qos[%u].",
    1044              :             __func__, devLogicId, locAddr.Describe().c_str(), rmtAddr.Describe().c_str(), tpProtocol.Describe().c_str(),
    1045              :             requestQos);
    1046          109 :         return;
    1047              :     }
    1048            3 :     RaUbGetTpInfoParam relParam(locAddr, rmtAddr, tpProtocol);
    1049            3 :     relParam.qos = requestQos;
    1050            3 :     (void)TpManager::GetInstance(devLogicId).ReleaseTpInfo(relParam, tpInfo);
    1051            3 :     tpInfo.tpHandle = 0;
    1052              : }
    1053              : 
    1054              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1