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.7 % 571 432
Test Date: 2026-07-28 12:11:00 Functions: 92.0 % 50 46

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

Generated by: LCOV version 2.0-1