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-18 17:47:01 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::UB_RTP) {
     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 CommitUbRtpDscpToTpAttr(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, "CommitUbRtpDscpToTpAttr");
     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, [[maybe_unused]] uint32_t nTp,
     280              :         [[maybe_unused]] uint16_t slMask)
     281              :     {
     282            6 :         bool isPcieStd = false;
     283            6 :         CHK_RET(IsPcieStdMainboard(devLogicId, isPcieStd));
     284            6 :         if (isPcieStd) {
     285            0 :             HCCL_INFO(
     286              :                 "[TpManager][%s] pcie std mainboard: skip SetTpAttr, devPhyId[%u] tpProtocol[%s] tpHandle[%llu] "
     287              :                 "param[%s].",
     288              :                 __func__, devPhyId, param.tpProtocol.Describe().c_str(), tpHandle, param.Describe().c_str());
     289            0 :             return HcclResult::HCCL_SUCCESS;
     290              :         }
     291            6 :         const RdmaHandle ctxHandle = ResolveUbRdmaHandle(isSync, devPhyId, param.locAddr);
     292            6 :         if (!ctxHandle) {
     293            0 :             HCCL_ERROR(
     294              :                 "[TpManager][%s] ctxHandle null devPhyId[%u] isSync[%d] loc[%s].", __func__, devPhyId,
     295              :                 static_cast<int>(isSync), param.locAddr.Describe().c_str());
     296            0 :             return HcclResult::HCCL_E_INTERNAL;
     297              :         }
     298              :         // TP / UBOE / UB_RTP:将 TP QoS/SL 策略得到的 mapped SL 写回 TP;CTP 不向 TP 写 SL(与 Next TpMgr 一致)
     299            9 :         if (param.tpProtocol == TpProtocol::TP || param.tpProtocol == TpProtocol::UBOE
     300            9 :             || param.tpProtocol == TpProtocol::UB_RTP) {
     301            6 :             CHK_RET(CommitMappedSlToTpAttr(isSync, ctxHandle, tpHandle, mappedSl));
     302              :         }
     303            6 :         if (param.tpProtocol != TpProtocol::UBOE && param.tpProtocol != TpProtocol::UB_RTP) {
     304            3 :             return HcclResult::HCCL_SUCCESS;
     305              :         }
     306            3 :         if (param.tpProtocol == TpProtocol::UB_RTP) {
     307              :             // UB_RTP:仅当 dscp mode == 0 时下发 DSCP。
     308            0 :             if (tpAttr.dscpConfigMode != 0) {
     309            0 :                 return HcclResult::HCCL_SUCCESS;
     310              :             }
     311              : 
     312            0 :             uint8_t dscp = kUboeDefaultDscp;
     313            0 :             (void)TpQosGetDscpByQosFromHccnCfg(devPhyId, param.qos, dscp);
     314            0 :             CHK_RET(CommitUbRtpDscpToTpAttr(isSync, ctxHandle, tpHandle, dscp));
     315            0 :             HCCL_INFO(
     316              :                 "[TpManager][%s] UB_RTP dscp committed: tpHandle[%llu] dscpAfter[%u].", __func__, tpHandle,
     317              :                 static_cast<unsigned>(dscp));
     318            0 :             return HcclResult::HCCL_SUCCESS;
     319              :         }
     320            3 :         if (tpAttr.dscpConfigMode == 1) {
     321            0 :             CHK_RET(CommitUboeNetAttrsToTpAttr(
     322              :                 isSync, ctxHandle, tpHandle, tpAttr, param.locIpv4Addr, param.rmtIpv4Addr, false, 0U));
     323            0 :             return HcclResult::HCCL_SUCCESS;
     324              :         }
     325              : 
     326            3 :         uint8_t dscp = kUboeDefaultDscp;
     327            3 :         (void)TpQosGetDscpByQosFromHccnCfg(devPhyId, param.qos, dscp);
     328            3 :         CHK_RET(CommitUboeNetAttrsToTpAttr(
     329              :             isSync, ctxHandle, tpHandle, tpAttr, param.locIpv4Addr, param.rmtIpv4Addr, true, dscp));
     330            9 :         HCCL_INFO(
     331              :             "[TpManager][%s] UBOE net attrs updated: tpHandle[%llu] dscpAfter[%u].", __func__, tpHandle,
     332              :             static_cast<unsigned>(dscp));
     333            3 :         return HcclResult::HCCL_SUCCESS;
     334              :     }
     335              : 
     336              : } // namespace
     337              : 
     338          166 : TpManager& TpManager::GetInstance(const int32_t deviceLogicId)
     339              : {
     340          232 :     static TpManager tpManager[MAX_MODULE_DEVICE_NUM + 1];
     341              : 
     342          166 :     if (deviceLogicId < 0 || static_cast<uint32_t>(deviceLogicId) > MAX_MODULE_DEVICE_NUM) {
     343            0 :         THROW<InvalidParamsException>(
     344              :             "[TpManager][%s] failed to get instance, "
     345              :             "devLogicId[%d] should be less than %u.",
     346              :             __func__, deviceLogicId, MAX_MODULE_DEVICE_NUM);
     347              :     }
     348              : 
     349          166 :     tpManager[deviceLogicId].devLogicId = deviceLogicId;
     350              : 
     351          166 :     return tpManager[deviceLogicId];
     352              : }
     353              : 
     354           28 : void TpManager::Init()
     355              : {
     356           28 :     if (initFlag) {
     357           27 :         return;
     358              :     }
     359              : 
     360            1 :     devPhyId = HrtGetDevicePhyIdByIndex(devLogicId);
     361            1 :     initFlag = true;
     362              : }
     363              : 
     364           30 : bool TpManager::CheckRequestResult(RequestHandle& reqHandle) const
     365              : {
     366           30 :     if (reqHandle == 0) {
     367            0 :         return true;
     368              :     }
     369              : 
     370           30 :     ReqHandleResult result = HrtRaGetAsyncReqResult(reqHandle);
     371           30 :     if (result == ReqHandleResult::NOT_COMPLETED) {
     372            0 :         return false;
     373              :     }
     374              : 
     375           30 :     if (result != ReqHandleResult::COMPLETED) {
     376            1 :         THROW<InternalException>(
     377            3 :             "[TpManager][%s] failed, result[%s] is unexpected.", __func__, result.Describe().c_str());
     378              :     }
     379              : 
     380           29 :     return true;
     381              : }
     382              : 
     383           58 : HcclResult CheckTpProtocol(const TpProtocol tpProtocol)
     384              : {
     385          114 :     if (tpProtocol != TpProtocol::CTP && tpProtocol != TpProtocol::TP && tpProtocol != TpProtocol::UBOE
     386          114 :         && tpProtocol != TpProtocol::UB_RTP) {
     387            0 :         HCCL_WARNING("[TpManager][%s] failed, tpProtocol[%d] is not supported.", __func__, tpProtocol);
     388            0 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     389              :     }
     390              : 
     391           58 :     return HcclResult::HCCL_SUCCESS;
     392              : }
     393              : 
     394           19 : HcclResult TpManager::AdvanceDeviceWaitListPhase(
     395              :     const RaUbGetTpInfoParam& param, RequestCtx& reqCtx, ReqQosMap& qosReqMap, ReqQosMap::iterator it,
     396              :     std::unique_lock<std::mutex>& reqCtxLock, TpInfo& tpInfo)
     397              : {
     398           19 :     if (reqCtx.tpInfoNum == 0U) {
     399            2 :         qosReqMap.erase(it);
     400            6 :         HCCL_ERROR(
     401              :             "[TpManager][%s] failed to find tp info, tpInfoNum is 0, param[%s].", __func__, param.Describe().c_str());
     402            2 :         return HcclResult::HCCL_E_NOT_FOUND;
     403              :     }
     404           17 :     bool isPcieStd = false;
     405           17 :     CHK_RET(IsPcieStdMainboard(devLogicId, isPcieStd));
     406           17 :     if (isPcieStd) {
     407              :         const struct HccpTpInfo* list
     408            0 :             = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     409            0 :         HCCL_INFO(
     410              :             "[TpManager][%s] pcie std mainboard: skip GetTpAttr, devPhyId[%u] tpInfoNum[%u] mappedSl[%u] "
     411              :             "tpHandle[%llu] param[%s].",
     412              :             __func__, devPhyId, reqCtx.tpInfoNum, kPcieStdMappedSl, static_cast<unsigned long long>(list[0].tpHandle),
     413              :             param.Describe().c_str());
     414            0 :         RequestCtx completedReqCtx = std::move(it->second);
     415            0 :         qosReqMap.erase(it);
     416            0 :         reqCtxLock.unlock();
     417            0 :         CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo, false));
     418            0 :         return HcclResult::HCCL_SUCCESS;
     419            0 :     }
     420           17 :     if (HrtRaSupportsGetTpAttr(devPhyId)) {
     421              :         const struct HccpTpInfo* list
     422            6 :             = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     423           18 :         HCCL_INFO(
     424              :             "[TpManager][GetTpInfo] list stage ok, devPhyId[%u] tpInfoNum[%u] firstTpHandle[%llu] param[%s].", devPhyId,
     425              :             reqCtx.tpInfoNum, static_cast<unsigned long long>(list[0].tpHandle), param.Describe().c_str());
     426            6 :         TRY_CATCH_PROCESS_THROW(
     427              :             NetworkApiException, StartGetTpAttrForFirstTpDevice(param, reqCtx),
     428              :             "[TpManager][AdvanceDeviceWaitListPhase] StartGetTpAttrForFirstTpDevice failed", qosReqMap.erase(it));
     429            6 :         return HcclResult::HCCL_E_AGAIN;
     430              :     }
     431           11 :     RequestCtx completedReqCtx = std::move(it->second);
     432           11 :     qosReqMap.erase(it);
     433           11 :     reqCtxLock.unlock();
     434           11 :     CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo, false));
     435           11 :     return HcclResult::HCCL_SUCCESS;
     436           11 : }
     437              : 
     438              : // GetTpInfo 完成后写入缓存。useCnt 仅在 FindAndGetTpInfo 命中时 +1,此处不做引用计数。
     439              : // 并发首次 GetTpInfo 时,先完成者写入缓存;后完成者若 tpHandle 不同则跳过写入,直接使用本地结果。
     440           17 : HcclResult TpManager::StoreTpInfoResult(const RaUbGetTpInfoParam& param, TpInfo& tpInfo)
     441              : {
     442           17 :     const QosKey qosKey = QosMapKey(param.qos);
     443           17 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     444           17 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     445           17 :     auto& qosMap = infoMap[param.locAddr][param.rmtAddr];
     446           17 :     const auto qIt = qosMap.find(qosKey);
     447           17 :     if (qIt == qosMap.end()) {
     448           17 :         qosMap[qosKey] = TpInfoCtx{tpInfo, 1U};
     449           17 :         return HcclResult::HCCL_SUCCESS;
     450              :     }
     451              : 
     452              :     // 缓存已存在:不再覆盖(避免并发后写覆盖先写的 tpHandle);tpInfo 保持 GetTpInfo 本地结果。
     453            0 :     if (qIt->second.tpInfo.tpHandle != tpInfo.tpHandle) {
     454            0 :         HCCL_WARNING(
     455              :             "[TpManager][%s] skip cache store, cached tpHandle[%llu] != local tpHandle[%llu] param[%s].", __func__,
     456              :             qIt->second.tpInfo.tpHandle, tpInfo.tpHandle, param.Describe().c_str());
     457              :     }
     458            0 :     return HcclResult::HCCL_SUCCESS;
     459           17 : }
     460              : 
     461            0 : HcclResult TpManager::SyncGetFirstTpAttrForSlPolicy(
     462              :     const RaUbGetTpInfoParam& param, uint64_t firstTpHandle, TpAttr& tpAttr, uint32_t& attrBitmap) const
     463              : {
     464            0 :     (void)memset_s(&tpAttr, sizeof(tpAttr), 0, sizeof(tpAttr));
     465            0 :     attrBitmap = BuildGetTpAttrBitmapForSlPolicy(param.tpProtocol);
     466            0 :     const RdmaHandle rdmaHandle = ResolveUbRdmaHandle(true, devPhyId, param.locAddr);
     467            0 :     if (!rdmaHandle) {
     468            0 :         HCCL_ERROR(
     469              :             "[TpManager][%s] can not find host rdmaHandle, devPhyId[%u] locAddr[%s].", __func__, devPhyId,
     470              :             param.locAddr.Describe().c_str());
     471            0 :         return HcclResult::HCCL_E_INTERNAL;
     472              :     }
     473            0 :     CHK_RET(HrtRaGetTpAttr(rdmaHandle, firstTpHandle, attrBitmap, tpAttr));
     474            0 :     HCCL_INFO(
     475              :         "[TpManager][%s] HrtRaGetTpAttr ok, tpHandle[%llu] attrBitmap[0x%x] param[%s].", __func__, firstTpHandle,
     476              :         attrBitmap, param.Describe().c_str());
     477            0 :     return HcclResult::HCCL_SUCCESS;
     478              : }
     479              : 
     480            0 : HcclResult TpManager::RunSyncGetTpInfo(const RaUbGetTpInfoParam& param, TpInfo& tpInfo)
     481              : {
     482            0 :     RequestCtx reqCtx{};
     483            0 :     StartGetTpInfoListRequest(param, reqCtx, true);
     484              : 
     485            0 :     if (reqCtx.tpInfoNum == 0U) {
     486            0 :         HCCL_ERROR(
     487              :             "[TpManager][%s] failed to find tp info, tpInfoNum is 0, param[%s].", __func__, param.Describe().c_str());
     488            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     489              :     }
     490              : 
     491              :     const struct HccpTpInfo* list
     492            0 :         = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     493            0 :     HCCL_INFO(
     494              :         "[TpManager][%s] sync GetTpList ok, devPhyId[%u] tpInfoNum[%u] firstTpHandle[%llu] param[%s].", __func__,
     495              :         devPhyId, reqCtx.tpInfoNum, static_cast<unsigned long long>(list[0].tpHandle), param.Describe().c_str());
     496              : 
     497            0 :     tpInfo = TpInfo{};
     498            0 :     bool isPcieStd = false;
     499            0 :     CHK_RET(IsPcieStdMainboard(devLogicId, isPcieStd));
     500            0 :     if (isPcieStd) {
     501            0 :         tpInfo.tpHandle = list[0].tpHandle;
     502            0 :         tpInfo.mappedJettyPriority = kPcieStdMappedSl;
     503            0 :         tpInfo.hasMappedJettyPriority = true;
     504            0 :         HCCL_INFO(
     505              :             "[TpManager][%s] pcie std mainboard: skip GetTpAttr/SetTpAttr, mappedSl[%u] tpHandle[%llu] "
     506              :             "param[%s].",
     507              :             __func__, kPcieStdMappedSl, tpInfo.tpHandle, param.Describe().c_str());
     508              :     } else {
     509            0 :         CHK_RET(SyncGetFirstTpAttrForSlPolicy(param, list[0].tpHandle, reqCtx.tpAttr, reqCtx.tpAttrBitmap));
     510            0 :         CHK_RET(MapTpInfoFromTpAttr(param, reqCtx, tpInfo, true));
     511              :     }
     512              : 
     513            0 :     return StoreTpInfoResult(param, tpInfo);
     514            0 : }
     515              : 
     516           46 : HcclResult TpManager::RunAsyncGetTpInfo(const RaUbGetTpInfoParam& param, TpInfo& tpInfo)
     517              : {
     518           46 :     RequestCtx completedReqCtx{};
     519           46 :     bool withSlPolicy = false;
     520              : 
     521              :     {
     522           46 :         std::unique_lock<std::mutex> reqCtxLock(GetReqCtxMutex(param.tpProtocol));
     523           46 :         auto& reqCtxMap = GetReqCtxMap(param.tpProtocol);
     524           46 :         const auto& locAddr = param.locAddr;
     525           46 :         const auto& rmtAddr = param.rmtAddr;
     526           46 :         const QosKey qosKey = QosMapKey(param.qos);
     527              : 
     528           46 :         auto& rmtReqMap = reqCtxMap[locAddr];
     529           46 :         auto& qosReqMap = rmtReqMap[rmtAddr];
     530           46 :         auto it = qosReqMap.find(qosKey);
     531           46 :         if (it == qosReqMap.end()) {
     532           60 :             HCCL_INFO("[TpManager][%s] get new tpInfo, param[%s].", __func__, param.Describe().c_str());
     533              : 
     534           20 :             RequestCtx& reqCtx = qosReqMap[qosKey];
     535           20 :             StartGetTpInfoListRequest(param, reqCtx, false);
     536           20 :             return HcclResult::HCCL_E_AGAIN;
     537              :         }
     538              : 
     539           26 :         RequestCtx& reqCtx = it->second;
     540              : 
     541           26 :         if (reqCtx.handle != 0U && !CheckRequestResult(reqCtx.handle)) {
     542            0 :             return HcclResult::HCCL_E_AGAIN;
     543              :         }
     544              : 
     545           25 :         switch (reqCtx.phase) {
     546           19 :             case RequestCtx::ReqPhase::WAIT_LIST:
     547           19 :                 return AdvanceDeviceWaitListPhase(param, reqCtx, qosReqMap, it, reqCtxLock, tpInfo);
     548            6 :             case RequestCtx::ReqPhase::WAIT_TP_ATTR:
     549            6 :                 completedReqCtx = std::move(it->second);
     550            6 :                 qosReqMap.erase(it);
     551            6 :                 withSlPolicy = true;
     552            6 :                 break;
     553            0 :             default:
     554            0 :                 completedReqCtx = std::move(it->second);
     555            0 :                 qosReqMap.erase(it);
     556            0 :                 withSlPolicy = false;
     557            0 :                 break;
     558              :         }
     559           46 :     }
     560              : 
     561            6 :     CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo, withSlPolicy));
     562            6 :     return HcclResult::HCCL_SUCCESS;
     563           46 : }
     564              : 
     565           58 : HcclResult TpManager::GetTpInfo(const RaUbGetTpInfoParam& param, TpInfo& tpInfo, bool isSync)
     566              : {
     567           58 :     CHK_RET(CheckTpProtocol(param.tpProtocol));
     568           58 :     if (FindAndGetTpInfo(param, tpInfo) == HcclResult::HCCL_SUCCESS) {
     569           12 :         return HcclResult::HCCL_SUCCESS;
     570              :     }
     571              : 
     572           46 :     if (isSync) {
     573            0 :         return RunSyncGetTpInfo(param, tpInfo);
     574              :     }
     575           46 :     return RunAsyncGetTpInfo(param, tpInfo);
     576              : }
     577              : 
     578           19 : HcclResult TpManager::FindAndGetTpAttr(const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     579              : {
     580           19 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex);
     581           19 :     auto attrIter = tpAttrCtxMap.find(tpHandle);
     582           19 :     if (attrIter != tpAttrCtxMap.end()) {
     583           11 :         attrIter->second.useCnt += 1;
     584           11 :         tpAttrInfo = attrIter->second.tpAttrInfo;
     585           33 :         HCCL_INFO(
     586              :             "[TpManager][%s] cache hit, tpHandle[0x%llx] useCnt[%u].", __func__,
     587              :             static_cast<unsigned long long>(tpHandle), attrIter->second.useCnt);
     588           11 :         return HcclResult::HCCL_SUCCESS;
     589              :     }
     590              : 
     591            8 :     return HcclResult::HCCL_E_NOT_FOUND;
     592           19 : }
     593              : 
     594           19 : HcclResult TpManager::GetTpAttr(const GetTpAttrParam& param, TpAttrInfo& tpAttrInfo, RdmaHandle rdmaHandle)
     595              : {
     596           19 :     const TpHandle tpHandle = param.tpHandle;
     597           19 :     if (FindAndGetTpAttr(tpHandle, tpAttrInfo) == HcclResult::HCCL_SUCCESS) {
     598           11 :         return HcclResult::HCCL_SUCCESS;
     599              :     }
     600              : 
     601            8 :     std::unique_lock<std::mutex> reqCtxLock(tpAttrReqMutex);
     602            8 :     auto reqCtxIter = tpAttrReqCtxMap.find(tpHandle);
     603            8 :     if (reqCtxIter == tpAttrReqCtxMap.end()) {
     604           12 :         HCCL_INFO("[TpManager][%s] get new tpAttr, param[%s].", __func__, param.Describe().c_str());
     605              : 
     606            4 :         TpAttrRequestCtx& reqCtx = tpAttrReqCtxMap[tpHandle];
     607            4 :         CHK_RET(StartGetTpAttrRequest(param, reqCtx, rdmaHandle));
     608            4 :         return HcclResult::HCCL_E_AGAIN;
     609              :     }
     610              : 
     611            4 :     auto& reqCtx = reqCtxIter->second;
     612            4 :     if (!CheckRequestResult(reqCtx.handle)) {
     613            0 :         return HcclResult::HCCL_E_AGAIN;
     614              :     }
     615              : 
     616            4 :     TpAttrRequestCtx completedReqCtx = reqCtxIter->second;
     617            4 :     tpAttrReqCtxMap.erase(reqCtxIter);
     618            4 :     reqCtxLock.unlock();
     619            4 :     CHK_RET(HandleCompletedTpAttrRequest(std::move(completedReqCtx), tpHandle, tpAttrInfo));
     620            4 :     return HcclResult::HCCL_SUCCESS;
     621            8 : }
     622              : 
     623            4 : HcclResult TpManager::StartGetTpAttrRequest(
     624              :     const GetTpAttrParam& param, TpManager::TpAttrRequestCtx& reqCtx, RdmaHandle rdmaHandle) const
     625              : {
     626            4 :     reqCtx.attrBitmap = param.attrBitmap;
     627            4 :     CHK_RET(HrtRaStartGetTpAttrAsync(rdmaHandle, param.tpHandle, reqCtx.attrBitmap, reqCtx.tpAttr, reqCtx.handle));
     628           12 :     HCCL_INFO("[TpManager][%s] success, tpHandle[0x%llx] reqHandle[%llu].", __func__, param.tpHandle, reqCtx.handle);
     629            4 :     return HcclResult::HCCL_SUCCESS;
     630              : }
     631              : 
     632            4 : HcclResult TpManager::HandleCompletedTpAttrRequest(
     633              :     const TpManager::TpAttrRequestCtx reqCtx, const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     634              : {
     635            4 :     TpAttrInfo tmpTpAttrInfo(reqCtx.tpAttr);
     636              : 
     637            4 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex);
     638            4 :     tpAttrCtxMap[tpHandle] = {std::move(tmpTpAttrInfo), 1};
     639              : 
     640            4 :     tpAttrInfo = tpAttrCtxMap[tpHandle].tpAttrInfo;
     641            4 :     return HcclResult::HCCL_SUCCESS;
     642            4 : }
     643              : 
     644           12 : HcclResult TpManager::ReleaseTpInfo(const RaUbGetTpInfoParam& param, const TpInfo& tpInfo)
     645              : {
     646           12 :     const QosKey qosKey = QosMapKey(param.qos);
     647           12 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     648           12 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     649           12 :     auto lit = infoMap.find(param.locAddr);
     650           12 :     if (lit == infoMap.end()) {
     651           15 :         HCCL_ERROR("[TpManager][%s] failed, tp info is not found, param[%s].", __func__, param.Describe().c_str());
     652            5 :         return HcclResult::HCCL_E_NOT_FOUND;
     653              :     }
     654            7 :     auto rit = lit->second.find(param.rmtAddr);
     655            7 :     if (rit == lit->second.end()) {
     656            0 :         HCCL_ERROR("[TpManager][%s] failed, tp info is not found, param[%s].", __func__, param.Describe().c_str());
     657            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     658              :     }
     659            7 :     auto qit = rit->second.find(qosKey);
     660            7 :     if (qit == rit->second.end()) {
     661            3 :         HCCL_ERROR(
     662              :             "[TpManager][%s] failed, tp info is not found for qosKey[%u], param[%s].", __func__,
     663              :             static_cast<unsigned>(qosKey), param.Describe().c_str());
     664            1 :         return HcclResult::HCCL_E_NOT_FOUND;
     665              :     }
     666              : 
     667              :     // 未入缓存的并发 GetTpInfo 结果:与缓存 tpHandle 不一致,无需操作缓存。
     668            6 :     if (tpInfo.tpHandle != qit->second.tpInfo.tpHandle) {
     669            3 :         HCCL_INFO(
     670              :             "[TpManager][%s] skip, tpHandle mismatch, local[%llu] cached[%llu] locAddr[%s] rmtAddr[%s].", __func__,
     671              :             static_cast<unsigned long long>(tpInfo.tpHandle),
     672              :             static_cast<unsigned long long>(qit->second.tpInfo.tpHandle), param.locAddr.Describe().c_str(),
     673              :             param.rmtAddr.Describe().c_str());
     674            1 :         return HcclResult::HCCL_SUCCESS;
     675              :     }
     676              : 
     677            5 :     if (qit->second.useCnt > 1) {
     678            2 :         qit->second.useCnt -= 1;
     679            6 :         HCCL_INFO(
     680              :             "[TpManager][%s] ref decrement, useCnt[%u -> %u] tpHandle[%llu] locAddr[%s] rmtAddr[%s].", __func__,
     681              :             qit->second.useCnt + 1U, qit->second.useCnt, static_cast<unsigned long long>(tpInfo.tpHandle),
     682              :             param.locAddr.Describe().c_str(), param.rmtAddr.Describe().c_str());
     683            2 :         return HcclResult::HCCL_SUCCESS;
     684              :     }
     685              : 
     686            9 :     HCCL_INFO(
     687              :         "[TpManager][%s] last ref, erase cache entry, useCnt[%u] tpHandle[%llu] locAddr[%s] rmtAddr[%s].", __func__,
     688              :         qit->second.useCnt, static_cast<unsigned long long>(tpInfo.tpHandle), param.locAddr.Describe().c_str(),
     689              :         param.rmtAddr.Describe().c_str());
     690            3 :     rit->second.erase(qit);
     691            3 :     if (rit->second.empty()) {
     692            3 :         lit->second.erase(rit);
     693              :     }
     694            3 :     if (lit->second.empty()) {
     695            3 :         infoMap.erase(lit);
     696              :     }
     697            3 :     return HcclResult::HCCL_SUCCESS;
     698           12 : }
     699              : 
     700            1 : HcclResult TpManager::ReleaseTpAttr(const TpHandle tpHandle, const TpAttrInfo& tpAttrInfo)
     701              : {
     702              :     (void)tpAttrInfo;
     703            1 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex);
     704            1 :     auto attrIter = tpAttrCtxMap.find(tpHandle);
     705            1 :     if (attrIter == tpAttrCtxMap.end()) {
     706            0 :         HCCL_ERROR(
     707              :             "[TpManager][%s] failed, tp attr is not found, "
     708              :             "tpHandle[0x%llx].",
     709              :             __func__, tpHandle);
     710            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     711              :     }
     712              : 
     713            1 :     if (attrIter->second.useCnt > 1) {
     714            1 :         attrIter->second.useCnt -= 1;
     715            3 :         HCCL_INFO(
     716              :             "[TpManager][%s] ref decrement, useCnt[%u -> %u] tpHandle[0x%llx].", __func__, attrIter->second.useCnt + 1U,
     717              :             attrIter->second.useCnt, static_cast<unsigned long long>(tpHandle));
     718            1 :         return HcclResult::HCCL_SUCCESS;
     719              :     }
     720              : 
     721            0 :     HCCL_INFO(
     722              :         "[TpManager][%s] last ref, erase cache entry, useCnt[%u] tpHandle[0x%llx].", __func__, attrIter->second.useCnt,
     723              :         static_cast<unsigned long long>(tpHandle));
     724            0 :     tpAttrCtxMap.erase(attrIter);
     725            0 :     return HcclResult::HCCL_SUCCESS;
     726            1 : }
     727              : 
     728           35 : HcclResult TpManager::GetTpTotalTimeout(const TpAttrInfo& tpAttrInfo, uint32_t& tpTimeOutMs)
     729              : {
     730           35 :     uint8_t rawAtGear = tpAttrInfo.tpAttr.at;
     731           35 :     uint8_t rawRetryTimes = tpAttrInfo.tpAttr.retryTimesInit;
     732              : 
     733           35 :     uint8_t finalAtGear = rawAtGear;
     734           35 :     if (rawAtGear > AT_GEAR_MAX) {
     735            1 :         finalAtGear = AT_GEAR_DEFAULT;
     736            3 :         HCCL_WARNING(
     737              :             "%s Invalid at gear[%u], expect [%u, %u], use default gear[%u].", __func__, rawAtGear, AT_GEAR_MIN,
     738              :             AT_GEAR_MAX, finalAtGear);
     739              :     }
     740              : 
     741           35 :     uint32_t singleAtTimeoutMs = AT_TIMEOUT_MAP[finalAtGear];
     742           35 :     tpTimeOutMs = singleAtTimeoutMs * static_cast<uint32_t>(rawRetryTimes + 1);
     743              : 
     744          105 :     HCCL_INFO(
     745              :         "%s TP timeout calc success: raw_at_gear[%u], final_at_gear[%u], "
     746              :         "single_timeout[%ums], retry_times[%u], total_timeout[%ums].",
     747              :         __func__, rawAtGear, finalAtGear, singleAtTimeoutMs, rawRetryTimes, tpTimeOutMs);
     748              : 
     749           35 :     return HcclResult::HCCL_SUCCESS;
     750              : }
     751              : 
     752           45 : uint32_t TpManager::TaHwValueToMs(uint8_t hwValue)
     753              : {
     754           45 :     uint8_t gear = hwValue / 8;
     755           45 :     switch (gear) {
     756            3 :         case TA_GEAR_INDEX_0:
     757            3 :             return TA_TIMEOUT_MS_GEAR0;
     758           34 :         case TA_GEAR_INDEX_1:
     759           34 :             return TA_TIMEOUT_MS_GEAR1;
     760            3 :         case TA_GEAR_INDEX_2:
     761            3 :             return TA_TIMEOUT_MS_GEAR2;
     762            3 :         case TA_GEAR_INDEX_3:
     763            3 :             return TA_TIMEOUT_MS_GEAR3;
     764            2 :         default:
     765            2 :             return TA_TIMEOUT_MS_GEAR2;
     766              :     }
     767              : }
     768              : 
     769            8 : uint8_t TpManager::FindMinTaHwValue(uint32_t tpTotalTimeoutMs)
     770              : {
     771            8 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR0) {
     772            1 :         return TA_HW_GEAR0_BASE;
     773              :     }
     774            7 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR1) {
     775            2 :         return TA_HW_GEAR1_BASE;
     776              :     }
     777            5 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR2) {
     778            3 :         return TA_HW_GEAR2_BASE;
     779              :     }
     780            2 :     return TA_HW_GEAR3_BASE;
     781              : }
     782              : 
     783           28 : uint8_t TpManager::CalcTaTimeout(const TpAttrInfo& tpAttrInfo)
     784              : {
     785           28 :     constexpr uint8_t UB_TIMEOUT_DEFAULT = 8;
     786           28 :     uint8_t envValue = static_cast<uint8_t>(EnvConfig::GetInstance().GetRdmaConfig().GetUbTimeOut());
     787           28 :     uint32_t envTimeoutMs = TaHwValueToMs(envValue);
     788              : 
     789           28 :     uint32_t tpTimeOutMs = 0;
     790           28 :     (void)GetTpTotalTimeout(tpAttrInfo, tpTimeOutMs);
     791              : 
     792           28 :     uint8_t errTimeout = UB_TIMEOUT_DEFAULT;
     793           28 :     if (envTimeoutMs < tpTimeOutMs) {
     794            1 :         errTimeout = FindMinTaHwValue(tpTimeOutMs);
     795            3 :         HCCL_WARNING(
     796              :             "[TpManager][%s] Env timeout [%ums] < TP timeout [%ums]. Auto upgrade TA to hw_val[%u] (%ums).", __func__,
     797              :             envTimeoutMs, tpTimeOutMs, errTimeout, TaHwValueToMs(errTimeout));
     798              :     } else {
     799           27 :         errTimeout = envValue;
     800           81 :         HCCL_INFO(
     801              :             "[TpManager][%s] Env timeout [%ums] >= TP timeout [%ums]. Use env gear base hw_val[%u] (%ums).", __func__,
     802              :             envTimeoutMs, tpTimeOutMs, envValue, envTimeoutMs);
     803              :     }
     804              : 
     805           28 :     return errTimeout;
     806              : }
     807              : 
     808           58 : HcclResult TpManager::FindAndGetTpInfo(const RaUbGetTpInfoParam& param, TpInfo& tpInfo)
     809              : {
     810           58 :     const QosKey qosKey = QosMapKey(param.qos);
     811           58 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     812           58 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     813           58 :     auto lit = infoMap.find(param.locAddr);
     814           58 :     if (lit == infoMap.end()) {
     815           44 :         return HcclResult::HCCL_E_NOT_FOUND;
     816              :     }
     817           14 :     auto rit = lit->second.find(param.rmtAddr);
     818           14 :     if (rit == lit->second.end()) {
     819            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     820              :     }
     821           14 :     auto qit = rit->second.find(qosKey);
     822           14 :     if (qit == rit->second.end()) {
     823            2 :         return HcclResult::HCCL_E_NOT_FOUND;
     824              :     }
     825              :     // 复用缓存:useCnt 仅在此处(命中)递增,与 StoreTpInfoResult 写入路径分离。
     826           12 :     qit->second.useCnt += 1;
     827           12 :     tpInfo = qit->second.tpInfo;
     828           36 :     HCCL_INFO(
     829              :         "[TpManager][%s] cache hit, tpHandle[%llu] mappedJettyPriority[%u] hasMappedJettyPriority[%d] "
     830              :         "useCnt[%u] param[%s].",
     831              :         __func__, static_cast<unsigned long long>(tpInfo.tpHandle), tpInfo.mappedJettyPriority,
     832              :         static_cast<int>(tpInfo.hasMappedJettyPriority), qit->second.useCnt, param.Describe().c_str());
     833           12 :     return HcclResult::HCCL_SUCCESS;
     834           58 : }
     835              : 
     836           20 : void TpManager::StartGetTpInfoListRequest(
     837              :     const RaUbGetTpInfoParam& param, TpManager::RequestCtx& reqCtx, bool isSync) const
     838              : {
     839           20 :     reqCtx.phase = RequestCtx::ReqPhase::WAIT_LIST;
     840           20 :     (void)memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
     841           20 :     reqCtx.tpAttrBitmap = 0;
     842              : 
     843           20 :     Hccl::IpAddress localIp = param.locAddr;
     844           20 :     const RdmaHandle rdmaHandle = ResolveUbRdmaHandle(isSync, devPhyId, localIp);
     845           20 :     if (!rdmaHandle) {
     846            0 :         THROW<InternalException>(
     847              :             "[TpManager][%s] can not find rdmaHandle, "
     848              :             "devPhyId[%u] locAddr[%s].",
     849            0 :             __func__, devPhyId, param.locAddr.Describe().c_str());
     850              :     }
     851           20 :     if (isSync) {
     852            0 :         RaUbGetTpInfo(rdmaHandle, param, reqCtx.dataBuffer, reqCtx.tpInfoNum);
     853            0 :         return;
     854              :     }
     855           20 :     reqCtx.handle = RaUbGetTpInfoAsync(rdmaHandle, param, reqCtx.dataBuffer, reqCtx.tpInfoNum);
     856              : }
     857              : 
     858            6 : void TpManager::StartGetTpAttrForFirstTpDevice(const RaUbGetTpInfoParam& param, RequestCtx& reqCtx) const
     859              : {
     860            6 :     (void)memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
     861            6 :     reqCtx.tpAttrBitmap = BuildGetTpAttrBitmapForSlPolicy(param.tpProtocol);
     862              :     const struct HccpTpInfo* list
     863            6 :         = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     864            6 :     const uint64_t firstTpHandle = list[0].tpHandle;
     865            6 :     const RdmaHandle rdmaHandle = ResolveUbRdmaHandle(false, devPhyId, param.locAddr);
     866            6 :     if (!rdmaHandle) {
     867            0 :         THROW<InternalException>(
     868            0 :             "[TpManager][%s] can not find rdmaHandle for GetTpAttrAsync, devPhyId[%u].", __func__, devPhyId);
     869              :     }
     870              :     const HcclResult hret
     871            6 :         = HrtRaStartGetTpAttrAsync(rdmaHandle, firstTpHandle, reqCtx.tpAttrBitmap, reqCtx.tpAttr, reqCtx.handle);
     872            6 :     if (hret != HcclResult::HCCL_SUCCESS) {
     873            0 :         THROW<NetworkApiException>(StringFormat(
     874              :             "[TpManager][StartGetTpAttrForFirstTpDevice] HrtRaStartGetTpAttrAsync "
     875              :             "failed hcclRet[%d] tpHandle[%llu].",
     876              :             static_cast<int>(hret), firstTpHandle));
     877              :     }
     878            6 :     reqCtx.phase = RequestCtx::ReqPhase::WAIT_TP_ATTR;
     879            6 : }
     880              : 
     881            6 : HcclResult TpManager::MapTpInfoFromTpAttr(
     882              :     const RaUbGetTpInfoParam& param, const RequestCtx& reqCtx, TpInfo& outTpInfo, bool isSync)
     883              : {
     884            6 :     const uint32_t tpInfoNum = reqCtx.tpInfoNum;
     885              :     const struct HccpTpInfo* baseInfoPtr
     886            6 :         = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     887            6 :     const uint16_t slMask = ReadSlAvailableMask16(reqCtx.tpAttr);
     888            6 :     const uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
     889           18 :     HCCL_INFO(
     890              :         "[TpManager][%s] after get_tp_attr: slMask[0x%04x] slAvailableCnt[%u] slBitmap[0x%x] dscp[%u] "
     891              :         "dscpConfigMode[%u] tpAttrBitmap[0x%x] param[%s].",
     892              :         __func__, static_cast<unsigned>(slMask), slAvailableCnt, static_cast<unsigned>(reqCtx.tpAttr.slBitmap),
     893              :         static_cast<unsigned>(reqCtx.tpAttr.dscp & 0x3FU), static_cast<unsigned>(reqCtx.tpAttr.dscpConfigMode & 1U),
     894              :         reqCtx.tpAttrBitmap, param.Describe().c_str());
     895            6 :     if (slAvailableCnt == 0U) {
     896            0 :         HCCL_ERROR(
     897              :             "[TpManager][%s] sl_available mask empty after get_tp_attr, param[%s].", __func__,
     898              :             param.Describe().c_str());
     899            0 :         return HcclResult::HCCL_E_INTERNAL;
     900              :     }
     901            6 :     uint32_t tpListIndex = 0;
     902            6 :     uint32_t mappedSl = 0;
     903            6 :     if (!ApplyQosTpSlPolicy(param, slMask, tpListIndex, mappedSl)) {
     904            0 :         HCCL_ERROR(
     905              :             "[TpManager][%s] ApplyQosTpSlPolicy failed, param[%s] nTp[%u] slAvailableCnt[%u] mask[%u].", __func__,
     906              :             param.Describe().c_str(), tpInfoNum, slAvailableCnt, static_cast<unsigned>(slMask));
     907            0 :         return HcclResult::HCCL_E_INTERNAL;
     908              :     }
     909            6 :     if (tpListIndex >= tpInfoNum) {
     910            0 :         HCCL_ERROR(
     911              :             "[TpManager][%s] tpListIndex out of range: tpListIndex[%u] tpInfoNum[%u] mappedSl[%u] param[%s].", __func__,
     912              :             tpListIndex, tpInfoNum, static_cast<unsigned>(mappedSl & 0xFU), param.Describe().c_str());
     913            0 :         return HcclResult::HCCL_E_INTERNAL;
     914              :     }
     915              : 
     916            6 :     outTpInfo.tpHandle = baseInfoPtr[tpListIndex].tpHandle;
     917            6 :     outTpInfo.mappedJettyPriority = mappedSl & 0xFU;
     918            6 :     outTpInfo.hasMappedJettyPriority = true;
     919              : 
     920            6 :     CHK_RET(CommitTpAttrsAfterSlMapping(
     921              :         devLogicId, devPhyId, isSync, param, reqCtx.tpAttr, outTpInfo.tpHandle, mappedSl, tpInfoNum, slMask));
     922              : 
     923           18 :     HCCL_INFO(
     924              :         "[TpManager][%s] tp qos mapping ok: tpInfoNum[%u] tpHandle[%llu] tpListIndex[%u] "
     925              :         "mappedJettyPriority[%u] qos[%u] param[%s].",
     926              :         __func__, tpInfoNum, outTpInfo.tpHandle, tpListIndex, outTpInfo.mappedJettyPriority, param.qos & 0xFFU,
     927              :         param.Describe().c_str());
     928            6 :     return HcclResult::HCCL_SUCCESS;
     929              : }
     930              : 
     931           17 : HcclResult TpManager::HandleCompletedRequest(
     932              :     const TpManager::RequestCtx reqCtx, const RaUbGetTpInfoParam& param, TpInfo& tpInfo, bool withSlPolicy)
     933              : {
     934           17 :     const uint32_t tpInfoNum = reqCtx.tpInfoNum;
     935           17 :     if (tpInfoNum == 0) {
     936            0 :         HCCL_ERROR(
     937              :             "[TpManager][%s] failed to find tp info, tpInfoNum is 0, "
     938              :             "param[%s].",
     939              :             __func__, param.Describe().c_str());
     940            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     941              :     }
     942              : 
     943           17 :     tpInfo = TpInfo{};
     944              : 
     945           51 :     HCCL_INFO(
     946              :         "[TpManager][%s] RaGetTpInfoList completed: tpInfoNum[%u] withSlPolicy[%d] devPhyId[%u] param[%s].", __func__,
     947              :         tpInfoNum, static_cast<int>(withSlPolicy), devPhyId, param.Describe().c_str());
     948              : 
     949           17 :     bool isPcieStd = false;
     950           17 :     CHK_RET(IsPcieStdMainboard(devLogicId, isPcieStd));
     951           17 :     if (isPcieStd) {
     952              :         const struct HccpTpInfo* baseInfoPtr
     953            0 :             = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     954            0 :         tpInfo.tpHandle = baseInfoPtr[0].tpHandle;
     955            0 :         tpInfo.mappedJettyPriority = kPcieStdMappedSl;
     956            0 :         tpInfo.hasMappedJettyPriority = true;
     957            0 :         HCCL_INFO(
     958              :             "[TpManager][%s] pcie std mainboard: skip GetTpAttr/SetTpAttr, devPhyId[%u] tpInfoNum[%u] "
     959              :             "mappedSl[%u] tpHandle[%llu] param[%s].",
     960              :             __func__, devPhyId, tpInfoNum, kPcieStdMappedSl, tpInfo.tpHandle, param.Describe().c_str());
     961           17 :     } else if (withSlPolicy) {
     962            6 :         CHK_RET(MapTpInfoFromTpAttr(param, reqCtx, tpInfo, false));
     963              :     } else {
     964              :         const struct HccpTpInfo* baseInfoPtr
     965           11 :             = static_cast<const struct HccpTpInfo*>(static_cast<const void*>(reqCtx.dataBuffer.data()));
     966           11 :         tpInfo.tpHandle = baseInfoPtr[0].tpHandle;
     967           11 :         tpInfo.hasMappedJettyPriority = false;
     968              :     }
     969              : 
     970           17 :     return StoreTpInfoResult(param, tpInfo);
     971              : }
     972              : 
     973           87 : TpManager::InfoCtxMap& TpManager::GetInfoCtxMap(const TpProtocol tpProtocol)
     974              : {
     975           87 :     switch (tpProtocol) {
     976            6 :         case TpProtocol::CTP:
     977            6 :             return ctpInfoMap;
     978           69 :         case TpProtocol::TP:
     979           69 :             return tpInfoMap;
     980           12 :         case TpProtocol::UBOE:
     981           12 :             return uboeInfoMap;
     982            0 :         case TpProtocol::UB_RTP:
     983            0 :             return ubRtpInfoMap;
     984            0 :         default:
     985            0 :             return tpInfoMap;
     986              :     }
     987              : }
     988              : 
     989           46 : TpManager::ReqCtxMap& TpManager::GetReqCtxMap(const TpProtocol tpProtocol)
     990              : {
     991           46 :     switch (tpProtocol) {
     992            2 :         case TpProtocol::CTP:
     993            2 :             return ctpReqMap;
     994           35 :         case TpProtocol::TP:
     995           35 :             return tpReqMap;
     996            9 :         case TpProtocol::UBOE:
     997            9 :             return uboeReqMap;
     998            0 :         case TpProtocol::UB_RTP:
     999            0 :             return ubRtpReqMap;
    1000            0 :         default:
    1001            0 :             return tpReqMap;
    1002              :     }
    1003              : }
    1004              : 
    1005           87 : std::mutex& TpManager::GetInfoCtxMutex(const TpProtocol tpProtocol)
    1006              : {
    1007           87 :     switch (tpProtocol) {
    1008            6 :         case TpProtocol::CTP:
    1009            6 :             return ctpInfoMutex;
    1010           69 :         case TpProtocol::TP:
    1011           69 :             return tpInfoMutex;
    1012           12 :         case TpProtocol::UBOE:
    1013           12 :             return uboeInfoMutex;
    1014            0 :         case TpProtocol::UB_RTP:
    1015            0 :             return ubRtpInfoMutex;
    1016            0 :         default:
    1017            0 :             return tpInfoMutex;
    1018              :     }
    1019              : }
    1020              : 
    1021           46 : std::mutex& TpManager::GetReqCtxMutex(const TpProtocol tpProtocol)
    1022              : {
    1023           46 :     switch (tpProtocol) {
    1024            2 :         case TpProtocol::CTP:
    1025            2 :             return ctpReqMutex;
    1026           35 :         case TpProtocol::TP:
    1027           35 :             return tpReqMutex;
    1028            9 :         case TpProtocol::UBOE:
    1029            9 :             return uboeReqMutex;
    1030            0 :         case TpProtocol::UB_RTP:
    1031            0 :             return ubRtpReqMutex;
    1032            0 :         default:
    1033            0 :             return tpReqMutex;
    1034              :     }
    1035              : }
    1036              : 
    1037          112 : void ReleaseUbConnectionTp(
    1038              :     int32_t devLogicId, const IpAddress& locAddr, const IpAddress& rmtAddr, TpProtocol tpProtocol, TpInfo& tpInfo,
    1039              :     uint32_t requestQos)
    1040              : {
    1041          112 :     if (tpInfo.tpHandle == 0) {
    1042          327 :         HCCL_WARNING(
    1043              :             "[TpManager][%s] skip release, tpHandle is 0, devLogicId[%d] loc[%s] rmt[%s] tpProtocol[%s] "
    1044              :             "qos[%u].",
    1045              :             __func__, devLogicId, locAddr.Describe().c_str(), rmtAddr.Describe().c_str(), tpProtocol.Describe().c_str(),
    1046              :             requestQos);
    1047          109 :         return;
    1048              :     }
    1049            3 :     RaUbGetTpInfoParam relParam(locAddr, rmtAddr, tpProtocol);
    1050            3 :     relParam.qos = requestQos;
    1051            3 :     (void)TpManager::GetInstance(devLogicId).ReleaseTpInfo(relParam, tpInfo);
    1052            3 :     tpInfo.tpHandle = 0;
    1053              : }
    1054              : 
    1055              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1