LCOV - code coverage report
Current view: top level - base_comm/common - tp_mgr.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.1 % 502 427
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 41 41

            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_mgr.h"
      12              : 
      13              : #include <algorithm>
      14              : #include <vector>
      15              : 
      16              : #include "hccp_ctx.h"
      17              : #include "hccp_async_ctx.h"
      18              : 
      19              : #include "hccl_common.h"
      20              : #include "exception_handler.h"
      21              : #include "network_api_exception.h"
      22              : #include "orion_adapter_hccp.h"
      23              : #include "rdma_handle_manager.h"
      24              : #include "dev_type.h"
      25              : #include "orion_adapter_rts.h"
      26              : #include "env_config/env_config_v2.h"
      27              : #include "tp_qos.h"
      28              : 
      29              : namespace hcomm {
      30              : 
      31              : namespace {
      32              :     constexpr uint32_t kTpAttrSlAvailableBit = 17U;
      33              :     static constexpr uint32_t kTpAttrBitmapSl = (1U << 10U);
      34              :     static constexpr uint32_t kTpAttrBitmapDscp = (1U << 8U);
      35              :     static constexpr uint32_t kTpAttrDscpConfigModeBit = 18U;
      36              : 
      37         1822 :     static constexpr QosKey QosMapKey(uint32_t qos) noexcept { return static_cast<QosKey>(qos & 0xFFU); }
      38              : 
      39              :     // MAINBOARD_PCIE_STD(PCIE 标卡):跳过 GetTpAttr/SL 策略,固定使用 TP 列表首个 TP;
      40              :     // jetty priority(SL)取 2,为标卡 UB 互通方案约定档位,与现网标卡环境对齐。
      41              :     static constexpr uint32_t kPcieStdMappedSl = 2U;
      42              : 
      43          677 :     static HcclResult IsPcieStdMainboardByPhyId(uint32_t devPhyId, bool& isPcieStd)
      44              :     {
      45          677 :         isPcieStd = false;
      46          677 :         u32 devLogicId = 0U;
      47          677 :         CHK_RET(hrtGetDeviceIndexByPhyId(devPhyId, devLogicId));
      48          677 :         Hccl::HcclMainboardId mainboardId = Hccl::HcclMainboardId::MAINBOARD_OTHERS;
      49          677 :         CHK_RET(Hccl::HrtGetMainboardId(devLogicId, mainboardId));
      50          677 :         isPcieStd = (mainboardId == Hccl::HcclMainboardId::MAINBOARD_PCIE_STD);
      51          677 :         return HcclResult::HCCL_SUCCESS;
      52              :     }
      53              : 
      54              :     struct TpInfoAddrKey {
      55              :         Hccl::IpAddress locAddr{};
      56              :         Hccl::IpAddress rmtAddr{};
      57              :         QosKey qosKey{0};
      58              :     };
      59              : 
      60         1597 :     static HcclResult ResolveTpInfoAddrKey(const GetTpInfoParam& param, TpInfoAddrKey& out)
      61              :     {
      62         1597 :         CHK_RET(CommAddrToIpAddress(param.locAddr, out.locAddr));
      63         1597 :         CHK_RET(CommAddrToIpAddress(param.rmtAddr, out.rmtAddr));
      64         1597 :         out.qosKey = QosMapKey(param.qos);
      65         1597 :         return HcclResult::HCCL_SUCCESS;
      66              :     }
      67              : 
      68          450 :     static uint32_t CalSlAvailableCnt(uint32_t mask)
      69              :     {
      70          450 :         uint32_t c = 0;
      71         7650 :         for (uint32_t i = 0; i < 16U; ++i) {
      72         7200 :             if ((mask & (1U << i)) != 0U) {
      73         1342 :                 ++c;
      74              :             }
      75              :         }
      76          450 :         return c;
      77              :     }
      78              : 
      79          225 :     static uint32_t SlValueAtRankInMask16(uint32_t mask, uint32_t rank)
      80              :     {
      81          225 :         uint32_t seen = 0;
      82          290 :         for (uint32_t bit = 0; bit < 16U; ++bit) {
      83          290 :             if ((mask & (1U << bit)) != 0U) {
      84          255 :                 if (seen == rank) {
      85          225 :                     return bit;
      86              :                 }
      87           30 :                 ++seen;
      88              :             }
      89              :         }
      90            0 :         return 0;
      91              :     }
      92              : 
      93          232 :     static uint16_t ReadSlAvailableMask16(const struct TpAttr& attr) { return static_cast<uint16_t>(attr.slBitmap); }
      94              : 
      95          225 :     static uint32_t ResolveSlAvailableCntForPolicy(uint16_t slMask, uint32_t slLevelCount)
      96              :     {
      97          225 :         uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
      98          225 :         if (slLevelCount != 0U) {
      99            1 :             slAvailableCnt = std::min(slLevelCount, slAvailableCnt);
     100              :         }
     101          225 :         return slAvailableCnt;
     102              :     }
     103              : 
     104              :     static bool
     105          225 :     ApplyQosTpSlPolicy(const GetTpInfoParam& param, uint16_t slMask, uint32_t& tpListIndexOut, uint32_t& mappedSlOut)
     106              :     {
     107          225 :         const uint32_t slAvailableCnt = ResolveSlAvailableCntForPolicy(slMask, param.slLevelCount);
     108          225 :         if (slAvailableCnt == 0U) {
     109            0 :             return false;
     110              :         }
     111          225 :         if (param.loopFirstTpLowestSl) {
     112          200 :             tpListIndexOut = 0U;
     113          200 :             mappedSlOut = SlValueAtRankInMask16(slMask, 0U);
     114          200 :             return true;
     115              :         }
     116              : 
     117           25 :         const uint32_t qos = param.qos;
     118           25 :         const uint32_t numGroups = slAvailableCnt;
     119           25 :         const uint32_t groupIdx = Hccl::TpQosResolveQosSlGroupIdx(qos, numGroups);
     120           25 :         if (groupIdx >= numGroups) {
     121            0 :             HCCL_ERROR(
     122              :                 "[TpMgr][%s] groupIdx out of range: groupIdx[%u] numGroups[%u] qos[%u] slAvailableCnt[%u].", __func__,
     123              :                 groupIdx, numGroups, qos, slAvailableCnt);
     124            0 :             return false;
     125              :         }
     126              : 
     127           25 :         tpListIndexOut = 0U;
     128           25 :         const uint32_t slRank = (slAvailableCnt - 1U) - groupIdx;
     129           25 :         mappedSlOut = SlValueAtRankInMask16(slMask, slRank);
     130           25 :         return true;
     131              :     }
     132              : 
     133            7 :     static uint8_t ResolveUboeDscpLookupQos(const GetTpInfoParam& param, uint32_t nTp, uint16_t slMask)
     134              :     {
     135              :         (void)nTp;
     136              :         (void)slMask;
     137            7 :         if (param.loopFirstTpLowestSl) {
     138            1 :             return 0U;
     139              :         }
     140            6 :         return static_cast<uint8_t>(param.qos & 0xFFU);
     141              :     }
     142              : 
     143              :     /// isSync=false(异步 GetTpInfo 写回 SL/DSCP):HrtRaSetTpAttrAsync。
     144              :     /// 阻塞等待在 adapter 内(RaSetTpAttrAsync + WaitRequestResult),本函数返回时 Set 已生效。
     145              :     /// 不用 RaCtxSetTpAttr,避免 Rs 路径 phyId 无效(与 TpManager::SetTpAttrAsync 一致)。
     146          228 :     static HcclResult SetTpAttrAsync(
     147              :         const Hccl::RdmaHandle rdmaHandle, uint64_t tpHandle, uint32_t attrBitmap, struct TpAttr& attr,
     148              :         const char* logTag)
     149              :     {
     150          228 :         Hccl::RequestHandle reqHandle = 0;
     151              :         try {
     152          228 :             const HcclResult hret = Hccl::HrtRaSetTpAttrAsync(rdmaHandle, tpHandle, attrBitmap, attr, reqHandle);
     153          228 :             if (hret != HcclResult::HCCL_SUCCESS) {
     154            0 :                 HCCL_ERROR(
     155              :                     "[TpMgr][%s] HrtRaSetTpAttrAsync failed hcclRet[%d] tpHandle[%llu].", logTag,
     156              :                     static_cast<int>(hret), static_cast<unsigned long long>(tpHandle));
     157              :             }
     158          228 :             return hret;
     159            0 :         } catch (const Hccl::NetworkApiException& ex) {
     160            0 :             HCCL_ERROR(
     161              :                 "[TpMgr][%s] HrtRaSetTpAttrAsync exception: %s tpHandle[%llu].", logTag, ex.what(),
     162              :                 static_cast<unsigned long long>(tpHandle));
     163            0 :             return HcclResult::HCCL_E_NETWORK;
     164            0 :         }
     165              :     }
     166              : 
     167              :     static HcclResult
     168          221 :     CommitMappedSlToTpAttr(const uint32_t devPhyId, const CommAddr& locCommAddr, uint64_t tpHandle, uint32_t mappedSl)
     169              :     {
     170          221 :         if (tpHandle == 0U) {
     171            0 :             HCCL_ERROR("[TpMgr][CommitMappedSlToTpAttr] tpHandle is 0");
     172            0 :             return HcclResult::HCCL_E_INTERNAL;
     173              :         }
     174          221 :         Hccl::IpAddress locAddr{};
     175          221 :         CHK_RET(CommAddrToIpAddress(locCommAddr, locAddr));
     176          221 :         const Hccl::RdmaHandle rdmaHandle = Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId, locAddr);
     177          221 :         CHK_PTR_NULL(rdmaHandle);
     178              : 
     179          221 :         struct TpAttr tpSlAttr {};
     180          221 :         tpSlAttr.sl = static_cast<uint8_t>(mappedSl & 0xFU);
     181              :         const HcclResult hret
     182          221 :             = SetTpAttrAsync(rdmaHandle, tpHandle, kTpAttrBitmapSl, tpSlAttr, "CommitMappedSlToTpAttr");
     183          221 :         if (hret == HcclResult::HCCL_SUCCESS) {
     184          221 :             HCCL_INFO(
     185              :                 "[TpMgr][CommitMappedSlToTpAttr] ok tpHandle[%llu] sl[%u].", static_cast<unsigned long long>(tpHandle),
     186              :                 static_cast<unsigned>(mappedSl & 0xFU));
     187              :         }
     188          221 :         return hret;
     189              :     }
     190              : 
     191              :     static HcclResult
     192            7 :     CommitUboeDscpToTpAttr(const uint32_t devPhyId, const CommAddr& locCommAddr, uint64_t tpHandle, uint8_t dscp)
     193              :     {
     194            7 :         if (tpHandle == 0U) {
     195            0 :             HCCL_ERROR("[TpMgr][CommitUboeDscpToTpAttr] tpHandle is 0");
     196            0 :             return HcclResult::HCCL_E_INTERNAL;
     197              :         }
     198            7 :         Hccl::IpAddress locAddr{};
     199            7 :         CHK_RET(CommAddrToIpAddress(locCommAddr, locAddr));
     200            7 :         const Hccl::RdmaHandle rdmaHandle = Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId, locAddr);
     201            7 :         CHK_PTR_NULL(rdmaHandle);
     202              : 
     203            7 :         struct TpAttr tpDscpAttr {};
     204            7 :         tpDscpAttr.dscp = static_cast<uint8_t>(dscp & 0x3FU);
     205              :         const HcclResult hret
     206            7 :             = SetTpAttrAsync(rdmaHandle, tpHandle, kTpAttrBitmapDscp, tpDscpAttr, "CommitUboeDscpToTpAttr");
     207            7 :         if (hret == HcclResult::HCCL_SUCCESS) {
     208            7 :             HCCL_INFO(
     209              :                 "[TpMgr][CommitUboeDscpToTpAttr] ok tpHandle[%llu] dscp[%u].",
     210              :                 static_cast<unsigned long long>(tpHandle), static_cast<unsigned>(tpDscpAttr.dscp));
     211              :         }
     212            7 :         return hret;
     213              :     }
     214              : 
     215              : } // namespace
     216              : 
     217          862 : TpMgr& TpMgr::GetInstance(const uint32_t devicePhyId)
     218              : {
     219          994 :     static TpMgr tpMgr[MAX_MODULE_DEVICE_NUM + 1];
     220              : 
     221          862 :     uint32_t devPhyId = devicePhyId;
     222          862 :     if (devPhyId >= MAX_MODULE_DEVICE_NUM) {
     223            1 :         HCCL_WARNING(
     224              :             "[TpMgr][%s] use the backup device, devPhyId[%u] should be "
     225              :             "less than %u.",
     226              :             __func__, devPhyId, MAX_MODULE_DEVICE_NUM);
     227            1 :         devPhyId = MAX_MODULE_DEVICE_NUM;
     228              :     }
     229              : 
     230          862 :     tpMgr[devPhyId].devPhyId_ = devPhyId;
     231              : 
     232          862 :     return tpMgr[devPhyId];
     233              : }
     234              : 
     235          552 : static HcclResult CheckRequestResult(RequestHandle& reqHandle)
     236              : {
     237          552 :     if (reqHandle == 0) {
     238            0 :         return HcclResult::HCCL_SUCCESS;
     239              :     }
     240              : 
     241          552 :     RequestResult result = HccpGetAsyncReqResult(reqHandle);
     242          552 :     if (result == RequestResult::NOT_COMPLETED) {
     243            0 :         return HcclResult::HCCL_E_AGAIN;
     244              :     }
     245              : 
     246          552 :     if (result != RequestResult::COMPLETED) {
     247            0 :         HCCL_ERROR("[TpMgr][%s] failed, result[%s] is unexpected.", __func__, result.Describe().c_str());
     248            0 :         return HcclResult::HCCL_E_NETWORK;
     249              :     }
     250              : 
     251          552 :     return HcclResult::HCCL_SUCCESS;
     252              : }
     253              : 
     254          695 : HcclResult CheckTpProtocol(const TpProtocol tpProtocol)
     255              : {
     256          695 :     if (tpProtocol != TpProtocol::CTP && tpProtocol != TpProtocol::RTP && tpProtocol != TpProtocol::UBOE) {
     257            1 :         HCCL_ERROR("[TpMgr][%s] failed, tpProtocol[%s] is not supported.", __func__, tpProtocol.Describe().c_str());
     258            1 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     259              :     }
     260              : 
     261          694 :     return HcclResult::HCCL_SUCCESS;
     262              : }
     263              : 
     264          907 : HcclResult TpMgr::LookupInfoCtxEntry(
     265              :     InfoCtxMap& infoMap, const Hccl::IpAddress& locAddr, const Hccl::IpAddress& rmtAddr, const QosKey qosKey,
     266              :     InfoCtxMap::iterator& lit, InfoRmtMap::iterator& rit, InfoQosMap::iterator& qosIt) const
     267              : {
     268          907 :     lit = infoMap.find(locAddr);
     269          907 :     if (lit == infoMap.end()) {
     270          693 :         return HcclResult::HCCL_E_NOT_FOUND;
     271              :     }
     272          214 :     rit = lit->second.find(rmtAddr);
     273          214 :     if (rit == lit->second.end()) {
     274            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     275              :     }
     276          214 :     qosIt = rit->second.find(qosKey);
     277          214 :     if (qosIt == rit->second.end()) {
     278            4 :         return HcclResult::HCCL_E_NOT_FOUND;
     279              :     }
     280          210 :     return HcclResult::HCCL_SUCCESS;
     281              : }
     282              : 
     283          694 : HcclResult TpMgr::FindAndGetTpInfo(const GetTpInfoParam& param, TpInfo& tpInfo)
     284              : {
     285          694 :     TpInfoAddrKey key{};
     286          694 :     CHK_RET(ResolveTpInfoAddrKey(param, key));
     287          694 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     288          694 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     289          694 :     InfoCtxMap::iterator lit;
     290          694 :     InfoRmtMap::iterator rit;
     291          694 :     InfoQosMap::iterator qosIt;
     292          694 :     const auto lookupRet = LookupInfoCtxEntry(infoMap, key.locAddr, key.rmtAddr, key.qosKey, lit, rit, qosIt);
     293          694 :     if (lookupRet != HcclResult::HCCL_SUCCESS) {
     294          690 :         return lookupRet;
     295              :     }
     296              :     // 复用缓存:useCnt 仅在此处(命中)递增,与 CommitTpInfoToCache 写入路径分离。
     297            4 :     qosIt->second.useCnt += 1;
     298            4 :     tpInfo = qosIt->second.tpInfo;
     299            4 :     return HcclResult::HCCL_SUCCESS;
     300          694 : }
     301              : 
     302          238 : HcclResult TpMgr::BeginGetTpInfoListRequest(const GetTpInfoParam& param, ReqQosMap& qosMap, const QosKey qosKey)
     303              : {
     304          238 :     RequestCtx& reqCtx = qosMap[qosKey];
     305          238 :     CHK_RET(StartGetTpInfoListRequest(param, reqCtx));
     306          238 :     HCCL_INFO(
     307              :         "[TpMgr][GetTpInfo] RaGetTpInfoListAsync submitted, devPhyId[%u] reqHandle[%llu] phase[WAIT_LIST] "
     308              :         "param[%s].",
     309              :         devPhyId_, static_cast<unsigned long long>(reqCtx.handle), param.Describe().c_str());
     310          238 :     return HcclResult::HCCL_E_AGAIN;
     311              : }
     312              : 
     313          227 : HcclResult TpMgr::AdvanceGetTpInfoWaitList(
     314              :     const GetTpInfoParam& param, RequestCtx& reqCtx, ReqQosMap& qosMap, const ReqQosMap::iterator it,
     315              :     std::unique_lock<std::mutex>& reqCtxLock, TpInfo& tpInfo)
     316              : {
     317          227 :     if (reqCtx.tpInfoNum == 0U) {
     318            0 :         qosMap.erase(it);
     319            0 :         reqCtxLock.unlock();
     320            0 :         HCCL_WARNING(
     321              :             "[TpMgr][%s] failed to find tp info, tpInfoNum is 0, param[%s].", __func__, param.Describe().c_str());
     322            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     323              :     }
     324          227 :     bool isPcieStd = false;
     325          227 :     CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
     326          227 :     if (isPcieStd) {
     327            0 :         const struct HccpTpInfo* list = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
     328            0 :         HCCL_INFO(
     329              :             "[TpMgr][%s] pcie std mainboard: skip GetTpAttr, devPhyId[%u] tpInfoNum[%u] mappedSl[%u] "
     330              :             "tpHandle[%llu] param[%s].",
     331              :             __func__, devPhyId_, reqCtx.tpInfoNum, kPcieStdMappedSl, static_cast<unsigned long long>(list[0].tpHandle),
     332              :             param.Describe().c_str());
     333            0 :         RequestCtx completedReqCtx = std::move(it->second);
     334            0 :         qosMap.erase(it);
     335            0 :         reqCtxLock.unlock();
     336            0 :         CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo));
     337            0 :         return HcclResult::HCCL_SUCCESS;
     338            0 :     }
     339          227 :     const struct HccpTpInfo* list = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
     340          227 :     HCCL_INFO(
     341              :         "[TpMgr][GetTpInfo] list stage ok, devPhyId[%u] tpInfoNum[%u] firstTpHandle[%llu] param[%s].", devPhyId_,
     342              :         reqCtx.tpInfoNum, static_cast<unsigned long long>(list[0].tpHandle), param.Describe().c_str());
     343              :     try {
     344          227 :         CHK_RET(StartGetTpAttrForFirstTp(param, reqCtx));
     345            0 :     } catch (...) {
     346            0 :         qosMap.erase(it);
     347            0 :         throw;
     348            0 :     }
     349          227 :     HCCL_INFO(
     350              :         "[TpMgr][GetTpInfo] RaGetTpAttrAsync submitted, devPhyId[%u] reqHandle[%llu] phase[WAIT_TP_ATTR] "
     351              :         "tpAttrBitmap[0x%x] param[%s].",
     352              :         devPhyId_, static_cast<unsigned long long>(reqCtx.handle), reqCtx.tpAttrBitmap, param.Describe().c_str());
     353          227 :     return HcclResult::HCCL_E_AGAIN;
     354              : }
     355              : 
     356              : HcclResult
     357          690 : TpMgr::PollGetTpInfoReqCtx(std::unique_lock<std::mutex>& reqCtxLock, const GetTpInfoParam& param, TpInfo& tpInfo)
     358              : {
     359          690 :     auto& reqCtxMap = GetReqCtxMap(param.tpProtocol);
     360          690 :     TpInfoAddrKey key{};
     361          690 :     CHK_RET(ResolveTpInfoAddrKey(param, key));
     362          690 :     auto& qosMap = reqCtxMap[key.locAddr][key.rmtAddr];
     363          690 :     auto it = qosMap.find(key.qosKey);
     364          690 :     if (it == qosMap.end()) {
     365          238 :         return BeginGetTpInfoListRequest(param, qosMap, key.qosKey);
     366              :     }
     367              : 
     368          452 :     RequestCtx& reqCtx = it->second;
     369          452 :     const auto ret = CheckRequestResult(reqCtx.handle);
     370          452 :     if (ret == HcclResult::HCCL_E_AGAIN) {
     371            0 :         return ret;
     372              :     }
     373          452 :     CHK_RET(ret);
     374              : 
     375          452 :     if (reqCtx.phase == ReqPhase::WAIT_LIST) {
     376          227 :         return AdvanceGetTpInfoWaitList(param, reqCtx, qosMap, it, reqCtxLock, tpInfo);
     377              :     }
     378              : 
     379              :     // 先 move 出槽位再 erase,避免 erase 析构槽内对象后再 move(UB / double free)
     380          225 :     RequestCtx completedReqCtx = std::move(it->second);
     381          225 :     qosMap.erase(it);
     382          225 :     reqCtxLock.unlock();
     383          225 :     CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo));
     384          225 :     return HcclResult::HCCL_SUCCESS;
     385          225 : }
     386              : 
     387          695 : HcclResult TpMgr::GetTpInfo(const GetTpInfoParam& param, TpInfo& tpInfo)
     388              : {
     389          695 :     CHK_RET(CheckTpProtocol(param.tpProtocol));
     390          694 :     if (FindAndGetTpInfo(param, tpInfo) == HcclResult::HCCL_SUCCESS) {
     391            4 :         return HcclResult::HCCL_SUCCESS;
     392              :     }
     393              : 
     394          690 :     std::unique_lock<std::mutex> reqCtxLock(GetReqCtxMutex(param.tpProtocol));
     395          690 :     return PollGetTpInfoReqCtx(reqCtxLock, param, tpInfo);
     396          690 : }
     397              : 
     398          213 : HcclResult TpMgr::ReleaseTpInfo(const GetTpInfoParam& param, const TpInfo& tpInfo)
     399              : {
     400          213 :     TpInfoAddrKey key{};
     401          213 :     CHK_RET(ResolveTpInfoAddrKey(param, key));
     402          213 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     403          213 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     404          213 :     InfoCtxMap::iterator lit;
     405          213 :     InfoRmtMap::iterator rmtIt;
     406          213 :     InfoQosMap::iterator qosIt;
     407          213 :     const auto lookupRet = LookupInfoCtxEntry(infoMap, key.locAddr, key.rmtAddr, key.qosKey, lit, rmtIt, qosIt);
     408          213 :     if (lookupRet != HcclResult::HCCL_SUCCESS) {
     409            7 :         if (lit == infoMap.end()) {
     410            6 :             HCCL_ERROR("[TpMgr][%s] failed, tp info is not found, param[%s].", __func__, param.Describe().c_str());
     411            1 :         } else if (rmtIt == lit->second.end()) {
     412            0 :             HCCL_ERROR("[TpMgr][%s] failed, tp info is not found, param[%s].", __func__, param.Describe().c_str());
     413              :         } else {
     414            1 :             HCCL_ERROR(
     415              :                 "[TpMgr][%s] failed, tp info is not found for qosKey[%u], param[%s].", __func__,
     416              :                 static_cast<unsigned>(key.qosKey), param.Describe().c_str());
     417              :         }
     418            7 :         return HcclResult::HCCL_E_NOT_FOUND;
     419              :     }
     420              : 
     421              :     // 未入缓存的并发 GetTpInfo 结果:与缓存 tpHandle 不一致,无需操作缓存。
     422          206 :     if (tpInfo.tpHandle != qosIt->second.tpInfo.tpHandle) {
     423            1 :         return HcclResult::HCCL_SUCCESS;
     424              :     }
     425              : 
     426          205 :     if (qosIt->second.useCnt > 1) {
     427            3 :         qosIt->second.useCnt -= 1;
     428            3 :         return HcclResult::HCCL_SUCCESS;
     429              :     }
     430              : 
     431          202 :     rmtIt->second.erase(qosIt);
     432          202 :     if (rmtIt->second.empty()) {
     433          202 :         lit->second.erase(rmtIt);
     434              :     }
     435          202 :     if (lit->second.empty()) {
     436          202 :         infoMap.erase(lit);
     437              :     }
     438          202 :     return HcclResult::HCCL_SUCCESS;
     439          213 : }
     440              : 
     441          238 : static HcclResult GetTpInfoListAsync(
     442              :     const CtxHandle ctxHandle, const GetTpInfoParam& param, std::vector<char>& out, uint32_t& num,
     443              :     RequestHandle& reqHandle)
     444              : {
     445          238 :     Hccl::IpAddress locAddr{};
     446          238 :     Hccl::IpAddress rmtAddr{};
     447          238 :     CHK_RET(CommAddrToIpAddress(param.locAddr, locAddr));
     448          238 :     CHK_RET(CommAddrToIpAddress(param.rmtAddr, rmtAddr));
     449          238 :     const auto& tpProtocol = param.tpProtocol;
     450              : 
     451          238 :     struct GetTpCfg cfg {};
     452          238 :     cfg.flag.bs.rtp = tpProtocol == TpProtocol::RTP ? 1 : 0;
     453          238 :     cfg.flag.bs.ctp = tpProtocol == TpProtocol::CTP ? 1 : 0;
     454          238 :     cfg.flag.bs.uboe = tpProtocol == TpProtocol::UBOE ? 1 : 0;
     455          238 :     cfg.transMode = TransportModeT::CONN_RM;
     456          238 :     CHK_RET(IpAddressToHccpEid(locAddr, cfg.localEid));
     457          238 :     HCCL_INFO(
     458              :         "RaUbGetTpInfoAsync cfg.local_eid[subnetPrefix[%016llx], interfaceId[%016llx]]",
     459              :         static_cast<unsigned long long>(cfg.localEid.in6.subnetPrefix),
     460              :         static_cast<unsigned long long>(cfg.localEid.in6.interfaceId));
     461          238 :     CHK_RET(IpAddressToHccpEid(rmtAddr, cfg.peerEid));
     462          238 :     HCCL_INFO(
     463              :         "RaUbGetTpInfoAsync cfg.peer_eid[subnetPrefix[%016llx], interfaceId[%016llx]]",
     464              :         static_cast<unsigned long long>(cfg.peerEid.in6.subnetPrefix),
     465              :         static_cast<unsigned long long>(cfg.peerEid.in6.interfaceId));
     466              : 
     467              :     // buffer 须至少容纳本次请求的个数,避免 RS 按 num 写多条 HccpTpInfo 时越界破坏堆
     468          238 :     out.resize(static_cast<size_t>(Hccl::TP_HANDLE_REQUEST_NUM) * sizeof(struct HccpTpInfo));
     469          238 :     struct HccpTpInfo* info = reinterpret_cast<struct HccpTpInfo*>(out.data());
     470              : 
     471          238 :     void* raReqHandle = nullptr;
     472          238 :     num = Hccl::TP_HANDLE_REQUEST_NUM; // 指定需要从管控面申请 tp handle 的上限;完成后 num 为实际个数
     473          238 :     const s32 ret = RaGetTpInfoListAsync(ctxHandle, &cfg, info, &num, &raReqHandle);
     474          238 :     if (ret != 0 || !raReqHandle) {
     475            0 :         HCCL_ERROR(
     476              :             "[%s] failed, call interface error[%d] raReqHandle[%p], ctxHandle[%p] locAddr[%s] rmtAddr[%s].", __func__,
     477              :             ret, raReqHandle, ctxHandle, locAddr.Describe().c_str(), rmtAddr.Describe().c_str());
     478            0 :         return HcclResult::HCCL_E_NETWORK;
     479              :     }
     480              : 
     481          238 :     reqHandle = reinterpret_cast<RequestHandle>(raReqHandle);
     482          238 :     HCCL_INFO("[%s] get request handle[%llu].", __func__, static_cast<unsigned long long>(reqHandle));
     483          238 :     return HcclResult::HCCL_SUCCESS;
     484              : }
     485              : 
     486          238 : HcclResult TpMgr::StartGetTpInfoListRequest(const GetTpInfoParam& param, RequestCtx& reqCtx) const
     487              : {
     488              :     EXCEPTION_HANDLE_BEGIN
     489          238 :     reqCtx.phase = ReqPhase::WAIT_LIST;
     490          238 :     reqCtx.tpAttrBitmap = 0;
     491          238 :     (void)memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
     492              : 
     493          238 :     Hccl::IpAddress ipAddr{};
     494          238 :     CHK_RET(CommAddrToIpAddress(param.locAddr, ipAddr));
     495              :     const CtxHandle ctxHandle
     496          238 :         = static_cast<CtxHandle>(Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId_, ipAddr));
     497          238 :     CHK_PTR_NULL(ctxHandle);
     498              : 
     499          238 :     CHK_RET(GetTpInfoListAsync(ctxHandle, param, reqCtx.dataBuffer, reqCtx.tpInfoNum, reqCtx.handle));
     500            0 :     EXCEPTION_HANDLE_END
     501          238 :     return HcclResult::HCCL_SUCCESS;
     502              : }
     503              : 
     504          227 : HcclResult TpMgr::StartGetTpAttrForFirstTp(const GetTpInfoParam& param, RequestCtx& reqCtx) const
     505              : {
     506          227 :     EXCEPTION_HANDLE_BEGIN(void) memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
     507          227 :     reqCtx.tpAttrBitmap = (1U << kTpAttrSlAvailableBit) | kTpAttrBitmapSl;
     508          227 :     if (param.tpProtocol == TpProtocol::UBOE) {
     509           10 :         reqCtx.tpAttrBitmap |= kTpAttrBitmapDscp | (1U << kTpAttrDscpConfigModeBit);
     510              :     }
     511              : 
     512          227 :     const struct HccpTpInfo* list = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
     513          227 :     const uint64_t firstTpHandle = list[0].tpHandle;
     514              : 
     515          227 :     Hccl::IpAddress ipAddr{};
     516          227 :     CHK_RET(CommAddrToIpAddress(param.locAddr, ipAddr));
     517              :     const CtxHandle ctxHandle
     518          227 :         = static_cast<CtxHandle>(Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId_, ipAddr));
     519          227 :     CHK_PTR_NULL(ctxHandle);
     520              : 
     521          227 :     void* raReqHandle = nullptr;
     522          227 :     const s32 ret = RaGetTpAttrAsync(ctxHandle, firstTpHandle, &reqCtx.tpAttrBitmap, &reqCtx.tpAttr, &raReqHandle);
     523          227 :     if (ret != 0 || !raReqHandle) {
     524            0 :         HCCL_ERROR(
     525              :             "[TpMgr][%s] RaGetTpAttrAsync failed ret[%d] raReqHandle[%p] ctx[%p] tpHandle[%llu].", __func__, ret,
     526              :             raReqHandle, ctxHandle, static_cast<unsigned long long>(firstTpHandle));
     527            0 :         return HcclResult::HCCL_E_NETWORK;
     528              :     }
     529          227 :     reqCtx.handle = reinterpret_cast<RequestHandle>(raReqHandle);
     530          227 :     reqCtx.phase = ReqPhase::WAIT_TP_ATTR;
     531            0 :     EXCEPTION_HANDLE_END
     532          227 :     return HcclResult::HCCL_SUCCESS;
     533              : }
     534              : 
     535          304 : HcclResult TpMgr::FindAndGetTpAttr(const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     536              : {
     537          304 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
     538          304 :     auto attrIter = tpAttrCtxMap_.find(tpHandle);
     539          304 :     if (attrIter != tpAttrCtxMap_.end()) {
     540          104 :         attrIter->second.useCnt += 1;
     541          104 :         tpAttrInfo = attrIter->second.tpAttrInfo;
     542          104 :         return HcclResult::HCCL_SUCCESS;
     543              :     }
     544              : 
     545          200 :     return HcclResult::HCCL_E_NOT_FOUND;
     546          304 : }
     547              : 
     548          304 : HcclResult TpMgr::GetTpAttr(const GetTpAttrParam& param, TpAttrInfo& tpAttrInfo, CtxHandle ctxHandle)
     549              : {
     550          304 :     const TpHandle tpHandle = param.tpHandle;
     551          304 :     if (FindAndGetTpAttr(tpHandle, tpAttrInfo) == HcclResult::HCCL_SUCCESS) {
     552          104 :         return HcclResult::HCCL_SUCCESS;
     553              :     }
     554              : 
     555          200 :     std::unique_lock<std::mutex> reqCtxLock(tpAttrReqMutex_);
     556          200 :     auto reqCtxIter = tpAttrReqCtxMap_.find(tpHandle);
     557          200 :     if (reqCtxIter == tpAttrReqCtxMap_.end()) {
     558          100 :         HCCL_INFO("[TpMgr][%s] get new tpAttr, param[%s].", __func__, param.Describe().c_str());
     559              : 
     560          100 :         TpAttrRequestCtx& reqCtx = tpAttrReqCtxMap_[tpHandle];
     561          100 :         CHK_RET(StartGetTpAttrRequest(param, reqCtx, ctxHandle));
     562          100 :         return HcclResult::HCCL_E_AGAIN;
     563              :     }
     564              : 
     565          100 :     auto& reqCtx = reqCtxIter->second;
     566          100 :     auto ret = CheckRequestResult(reqCtx.handle);
     567          100 :     if (ret == HcclResult::HCCL_E_AGAIN) {
     568            0 :         return ret;
     569              :     }
     570          100 :     CHK_RET(ret);
     571              : 
     572          100 :     TpAttrRequestCtx completedReqCtx = reqCtxIter->second;
     573          100 :     tpAttrReqCtxMap_.erase(reqCtxIter);
     574          100 :     reqCtxLock.unlock();
     575          100 :     CHK_RET(HandleCompletedTpAttrRequest(std::move(completedReqCtx), tpHandle, tpAttrInfo));
     576          100 :     return HcclResult::HCCL_SUCCESS;
     577          200 : }
     578              : 
     579              : HcclResult
     580          100 : TpMgr::StartGetTpAttrRequest(const GetTpAttrParam& param, TpMgr::TpAttrRequestCtx& reqCtx, CtxHandle ctxHandle) const
     581              : {
     582          100 :     void* raReqHandle = nullptr;
     583          200 :     s32 ret = RaGetTpAttrAsync(
     584          100 :         ctxHandle, param.tpHandle, const_cast<uint32_t*>(&param.attrBitmap), &reqCtx.tpAttr, &raReqHandle);
     585          100 :     if (ret != 0 || !raReqHandle) {
     586            0 :         HCCL_ERROR(
     587              :             "[TpMgr][%s] failed, call RaGetTpAttrAsync error[%d] raReqHandle[%p], "
     588              :             "tpHandle[0x%llx] attrBitmap[0x%x].",
     589              :             __func__, ret, raReqHandle, static_cast<unsigned long long>(param.tpHandle), param.attrBitmap);
     590            0 :         return HcclResult::HCCL_E_NETWORK;
     591              :     }
     592              : 
     593          100 :     reqCtx.handle = reinterpret_cast<RequestHandle>(raReqHandle);
     594          100 :     HCCL_INFO(
     595              :         "[TpMgr][%s] success, tpHandle[0x%llx] reqHandle[%llu].", __func__,
     596              :         static_cast<unsigned long long>(param.tpHandle), static_cast<unsigned long long>(reqCtx.handle));
     597          100 :     return HcclResult::HCCL_SUCCESS;
     598              : }
     599              : 
     600          100 : HcclResult TpMgr::HandleCompletedTpAttrRequest(
     601              :     const TpMgr::TpAttrRequestCtx reqCtx, const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     602              : {
     603          100 :     TpAttrInfo tmpTpAttrInfo(reqCtx.tpAttr);
     604              : 
     605          100 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
     606          100 :     tpAttrCtxMap_[tpHandle] = {std::move(tmpTpAttrInfo), 1};
     607              : 
     608          100 :     tpAttrInfo = tpAttrCtxMap_[tpHandle].tpAttrInfo;
     609          100 :     return HcclResult::HCCL_SUCCESS;
     610          100 : }
     611              : 
     612          210 : HcclResult TpMgr::ReleaseTpAttr(const TpHandle tpHandle, [[maybe_unused]] const TpAttrInfo& tpAttrInfo)
     613              : {
     614          210 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
     615          210 :     auto attrIter = tpAttrCtxMap_.find(tpHandle);
     616          210 :     if (attrIter == tpAttrCtxMap_.end()) {
     617            7 :         HCCL_ERROR(
     618              :             "[TpMgr][%s] failed, tp attr is not found, "
     619              :             "tpHandle[0x%llx].",
     620              :             __func__, static_cast<unsigned long long>(tpHandle));
     621            7 :         return HcclResult::HCCL_E_NOT_FOUND;
     622              :     }
     623              : 
     624          203 :     if (attrIter->second.useCnt > 1) {
     625          104 :         attrIter->second.useCnt -= 1;
     626          104 :         return HcclResult::HCCL_SUCCESS;
     627              :     }
     628              : 
     629           99 :     tpAttrCtxMap_.erase(attrIter);
     630           99 :     return HcclResult::HCCL_SUCCESS;
     631          210 : }
     632              : 
     633          207 : HcclResult TpMgr::GetTpTotalTimeout(const TpAttrInfo& tpAttrInfo, uint32_t& tpTimeOutMs)
     634              : {
     635          207 :     uint8_t rawAtGear = tpAttrInfo.tpAttr.at;
     636          207 :     uint8_t rawRetryTimes = tpAttrInfo.tpAttr.retryTimesInit;
     637              : 
     638          207 :     uint8_t finalAtGear = rawAtGear;
     639          207 :     if (rawAtGear > AT_GEAR_MAX) {
     640            1 :         finalAtGear = AT_GEAR_DEFAULT;
     641            1 :         HCCL_WARNING(
     642              :             "%s Invalid at gear[%u], expect [%u, %u], use default gear[%u].", __func__,
     643              :             static_cast<unsigned>(rawAtGear), static_cast<unsigned>(AT_GEAR_MIN), static_cast<unsigned>(AT_GEAR_MAX),
     644              :             static_cast<unsigned>(finalAtGear));
     645              :     }
     646              : 
     647          207 :     uint32_t singleAtTimeoutMs = AT_TIMEOUT_MAP[finalAtGear];
     648          207 :     tpTimeOutMs = singleAtTimeoutMs * static_cast<uint32_t>(rawRetryTimes + 1);
     649              : 
     650          207 :     HCCL_INFO(
     651              :         "%s TP timeout calc success: raw_at_gear[%u], final_at_gear[%u], "
     652              :         "single_timeout[%ums], retry_times[%u], total_timeout[%ums].",
     653              :         __func__, static_cast<unsigned>(rawAtGear), static_cast<unsigned>(finalAtGear), singleAtTimeoutMs,
     654              :         static_cast<unsigned>(rawRetryTimes), tpTimeOutMs);
     655              : 
     656          207 :     return HcclResult::HCCL_SUCCESS;
     657              : }
     658              : 
     659          205 : static uint32_t TaHwValueToMs(uint8_t hwValue)
     660              : {
     661          205 :     uint8_t gear = hwValue / 8;
     662          205 :     switch (gear) {
     663            1 :         case TA_GEAR_INDEX_0:
     664            1 :             return TA_TIMEOUT_MS_GEAR0;
     665          202 :         case TA_GEAR_INDEX_1:
     666          202 :             return TA_TIMEOUT_MS_GEAR1;
     667            1 :         case TA_GEAR_INDEX_2:
     668            1 :             return TA_TIMEOUT_MS_GEAR2;
     669            1 :         case TA_GEAR_INDEX_3:
     670            1 :             return TA_TIMEOUT_MS_GEAR3;
     671            0 :         default:
     672            0 :             return TA_TIMEOUT_MS_GEAR2;
     673              :     }
     674              : }
     675              : 
     676            1 : static uint8_t FindMinTaHwValue(uint32_t tpTotalTimeoutMs)
     677              : {
     678            1 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR0) {
     679            0 :         return TA_HW_GEAR0_BASE;
     680              :     }
     681            1 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR1) {
     682            0 :         return TA_HW_GEAR1_BASE;
     683              :     }
     684            1 :     if (tpTotalTimeoutMs < TA_TIMEOUT_MS_GEAR2) {
     685            1 :         return TA_HW_GEAR2_BASE;
     686              :     }
     687            0 :     return TA_HW_GEAR3_BASE;
     688              : }
     689              : 
     690          204 : uint8_t TpMgr::CalcTaTimeout(const TpAttrInfo& tpAttrInfo)
     691              : {
     692          204 :     constexpr uint8_t UB_TIMEOUT_DEFAULT = 8; // 默认 UB_CTP 和 UBC_TP 超时配置为8
     693          204 :     uint8_t envValue = static_cast<uint8_t>(Hccl::EnvConfig::GetInstance().GetRdmaConfig().GetUbTimeOut());
     694          204 :     uint32_t envTimeoutMs = TaHwValueToMs(envValue);
     695              : 
     696          204 :     uint32_t tpTimeOutMs = 0;
     697          204 :     (void)GetTpTotalTimeout(tpAttrInfo, tpTimeOutMs);
     698              : 
     699          204 :     uint8_t errTimeout = UB_TIMEOUT_DEFAULT;
     700          204 :     if (envTimeoutMs < tpTimeOutMs) {
     701            1 :         errTimeout = FindMinTaHwValue(tpTimeOutMs);
     702            1 :         HCCL_WARNING(
     703              :             "[TpMgr][%s] Env timeout [%ums] < TP timeout [%ums]. Auto upgrade TA to hw_val[%u] (%ums).", __func__,
     704              :             envTimeoutMs, tpTimeOutMs, static_cast<unsigned>(errTimeout), TaHwValueToMs(errTimeout));
     705              :     } else {
     706          203 :         errTimeout = envValue;
     707          203 :         HCCL_INFO(
     708              :             "[TpMgr][%s] Env timeout [%ums] >= TP timeout [%ums]. Use env gear base hw_val[%u] (%ums).", __func__,
     709              :             envTimeoutMs, tpTimeOutMs, static_cast<unsigned>(envValue), envTimeoutMs);
     710              :     }
     711              : 
     712          204 :     return errTimeout;
     713              : }
     714              : 
     715          225 : HcclResult TpMgr::BuildTpInfoAndCommitQosAttr(
     716              :     const GetTpInfoParam& param, const RequestCtx& reqCtx, const struct HccpTpInfo* baseInfoPtr,
     717              :     const uint32_t tpListIndex, const uint32_t mappedSl, TpInfo& tpInfo)
     718              : {
     719          225 :     tpInfo = TpInfo{};
     720          225 :     tpInfo.tpHandle = baseInfoPtr[tpListIndex].tpHandle;
     721          225 :     tpInfo.mappedJettyPriority = mappedSl & 0xFU;
     722          225 :     tpInfo.hasMappedJettyPriority = true;
     723              : 
     724          225 :     bool isPcieStd = false;
     725          225 :     CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
     726          225 :     if (isPcieStd) {
     727            0 :         HCCL_INFO(
     728              :             "[TpMgr][%s] pcie std mainboard: skip SetTpAttr, devPhyId[%u] tpProtocol[%s] tpHandle[%llu] "
     729              :             "param[%s].",
     730              :             __func__, devPhyId_, param.tpProtocol.Describe().c_str(), static_cast<unsigned long long>(tpInfo.tpHandle),
     731              :             param.Describe().c_str());
     732          225 :     } else if (param.tpProtocol == TpProtocol::RTP || param.tpProtocol == TpProtocol::UBOE) {
     733          221 :         CHK_RET(CommitMappedSlToTpAttr(devPhyId_, param.locAddr, tpInfo.tpHandle, mappedSl));
     734              :     }
     735          225 :     if (!isPcieStd && param.tpProtocol == TpProtocol::UBOE && reqCtx.tpAttr.dscpConfigMode == 0) {
     736            7 :         const uint8_t dscpBefore = static_cast<uint8_t>(reqCtx.tpAttr.dscp & 0x3FU);
     737            7 :         const uint8_t requestQos = static_cast<uint8_t>(param.qos & 0xFFU);
     738            7 :         const uint16_t slMask = ReadSlAvailableMask16(reqCtx.tpAttr);
     739            7 :         const uint8_t dscpLookupQos = ResolveUboeDscpLookupQos(param, reqCtx.tpInfoNum, slMask);
     740            7 :         uint8_t dscp = Hccl::kUboeDefaultDscp;
     741            7 :         (void)Hccl::TpQosGetDscpByQosFromHccnCfg(devPhyId_, dscpLookupQos, dscp);
     742            7 :         CHK_RET(CommitUboeDscpToTpAttr(devPhyId_, param.locAddr, tpInfo.tpHandle, dscp));
     743            7 :         HCCL_INFO(
     744              :             "[TpMgr][%s] UBOE dscp updated: tpHandle[%llu] requestQos[%u] dscpLookupQos[%u] dscpBefore[%u] "
     745              :             "dscpAfter[%u].",
     746              :             __func__, static_cast<unsigned long long>(tpInfo.tpHandle), static_cast<unsigned>(requestQos),
     747              :             static_cast<unsigned>(dscpLookupQos), static_cast<unsigned>(dscpBefore), static_cast<unsigned>(dscp));
     748              :     }
     749          225 :     HCCL_INFO(
     750              :         "[TpMgr][%s] tp qos mapping ok: tpHandle[%llu] tpListIndex[%u] mappedSl[%u] jettyPriority[%u] qos[%u] "
     751              :         "param[%s].",
     752              :         __func__, static_cast<unsigned long long>(tpInfo.tpHandle), tpListIndex, static_cast<unsigned>(mappedSl & 0xFU),
     753              :         tpInfo.mappedJettyPriority, param.qos & 0xFFU, param.Describe().c_str());
     754          225 :     return HcclResult::HCCL_SUCCESS;
     755              : }
     756              : 
     757              : // GetTpInfo 完成后写入缓存。useCnt 仅在 FindAndGetTpInfo 命中时 +1,此处不做引用计数。
     758              : // 并发首次 GetTpInfo 时,先完成者写入缓存;后完成者若 tpHandle 不同则跳过写入,直接使用本地结果。
     759          225 : HcclResult TpMgr::CommitTpInfoToCache(const GetTpInfoParam& param, TpInfo& tpInfo)
     760              : {
     761          225 :     Hccl::IpAddress locAddr{};
     762          225 :     Hccl::IpAddress rmtAddr{};
     763          225 :     CHK_RET(CommAddrToIpAddress(param.locAddr, locAddr));
     764          225 :     CHK_RET(CommAddrToIpAddress(param.rmtAddr, rmtAddr));
     765          225 :     const QosKey qosKey = QosMapKey(param.qos);
     766              : 
     767          225 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     768          225 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     769          225 :     auto& rmtMap = infoMap[locAddr][rmtAddr];
     770          225 :     const auto qIt = rmtMap.find(qosKey);
     771          225 :     if (qIt == rmtMap.end()) {
     772          225 :         rmtMap[qosKey] = TpInfoCtx{tpInfo, 1U};
     773          225 :         return HcclResult::HCCL_SUCCESS;
     774              :     }
     775              : 
     776              :     // 缓存已存在:不再覆盖(避免并发后写覆盖先写的 tpHandle);tpInfo 保持 GetTpInfo 本地结果。
     777            0 :     if (qIt->second.tpInfo.tpHandle != tpInfo.tpHandle) {
     778            0 :         HCCL_WARNING(
     779              :             "[TpMgr][%s] skip cache store, cached tpHandle[%llu] != local tpHandle[%llu] param[%s].", __func__,
     780              :             static_cast<unsigned long long>(qIt->second.tpInfo.tpHandle),
     781              :             static_cast<unsigned long long>(tpInfo.tpHandle), param.Describe().c_str());
     782              :     }
     783            0 :     return HcclResult::HCCL_SUCCESS;
     784          225 : }
     785              : 
     786          225 : HcclResult TpMgr::HandleCompletedRequest(RequestCtx reqCtx, const GetTpInfoParam& param, TpInfo& tpInfo)
     787              : {
     788          225 :     const uint32_t tpInfoNum = reqCtx.tpInfoNum;
     789          225 :     if (tpInfoNum == 0U) {
     790            0 :         HCCL_WARNING(
     791              :             "[TpMgr][%s] failed to find tp info, tpInfoNum is 0, param[%s].", __func__, param.Describe().c_str());
     792            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     793              :     }
     794              : 
     795          225 :     tpInfo = TpInfo{};
     796              : 
     797          225 :     const struct HccpTpInfo* baseInfoPtr = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
     798          225 :     bool isPcieStd = false;
     799          225 :     CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
     800          225 :     if (isPcieStd) {
     801            0 :         tpInfo.tpHandle = baseInfoPtr[0].tpHandle;
     802            0 :         tpInfo.mappedJettyPriority = kPcieStdMappedSl;
     803            0 :         tpInfo.hasMappedJettyPriority = true;
     804            0 :         HCCL_INFO(
     805              :             "[TpMgr][%s] pcie std mainboard: skip GetTpAttr/SetTpAttr, devPhyId[%u] tpInfoNum[%u] "
     806              :             "mappedSl[%u] tpHandle[%llu] param[%s].",
     807              :             __func__, devPhyId_, tpInfoNum, kPcieStdMappedSl, static_cast<unsigned long long>(tpInfo.tpHandle),
     808              :             param.Describe().c_str());
     809            0 :         return CommitTpInfoToCache(param, tpInfo);
     810              :     }
     811              : 
     812          225 :     const uint16_t slMask = ReadSlAvailableMask16(reqCtx.tpAttr);
     813          225 :     const uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
     814          225 :     HCCL_INFO(
     815              :         "[TpMgr][%s] after get_tp_attr: slMask[0x%04x] slAvailableCnt[%u] slBitmap[0x%x] dscp[%u] dscpConfigMode[%u] "
     816              :         "tpAttrBitmap[0x%x] param[%s].",
     817              :         __func__, static_cast<unsigned>(slMask), slAvailableCnt, static_cast<unsigned>(reqCtx.tpAttr.slBitmap),
     818              :         static_cast<unsigned>(reqCtx.tpAttr.dscp & 0x3FU), static_cast<unsigned>(reqCtx.tpAttr.dscpConfigMode & 1U),
     819              :         reqCtx.tpAttrBitmap, param.Describe().c_str());
     820          225 :     if (slAvailableCnt == 0U) {
     821            0 :         HCCL_ERROR(
     822              :             "[TpMgr][%s] sl_available mask empty after get_tp_attr, param[%s].", __func__, param.Describe().c_str());
     823            0 :         return HcclResult::HCCL_E_INTERNAL;
     824              :     }
     825          225 :     uint32_t tpListIndex = 0;
     826          225 :     uint32_t mappedSl = 0;
     827          225 :     if (!ApplyQosTpSlPolicy(param, slMask, tpListIndex, mappedSl)) {
     828            0 :         HCCL_ERROR(
     829              :             "[TpMgr][%s] ApplyQosTpSlPolicy failed, param[%s] nTp[%u] slAvailableCnt[%u] mask[%u].", __func__,
     830              :             param.Describe().c_str(), tpInfoNum, slAvailableCnt, static_cast<unsigned>(slMask));
     831            0 :         return HcclResult::HCCL_E_INTERNAL;
     832              :     }
     833          225 :     if (tpListIndex >= tpInfoNum) {
     834            0 :         HCCL_ERROR(
     835              :             "[TpMgr][%s] tpListIndex out of range: tpListIndex[%u] tpInfoNum[%u] mappedSl[%u] param[%s].", __func__,
     836              :             tpListIndex, tpInfoNum, static_cast<unsigned>(mappedSl & 0xFU), param.Describe().c_str());
     837            0 :         return HcclResult::HCCL_E_INTERNAL;
     838              :     }
     839              : 
     840          225 :     CHK_RET(BuildTpInfoAndCommitQosAttr(param, reqCtx, baseInfoPtr, tpListIndex, mappedSl, tpInfo));
     841          225 :     return CommitTpInfoToCache(param, tpInfo);
     842              : }
     843              : 
     844         1132 : TpMgr::InfoCtxMap& TpMgr::GetInfoCtxMap(const TpProtocol tpProtocol)
     845              : {
     846         1132 :     switch (tpProtocol) {
     847           31 :         case TpProtocol::CTP:
     848           31 :             return ctpInfoMap_;
     849         1061 :         case TpProtocol::RTP:
     850         1061 :             return rtpInfoMap_;
     851           40 :         case TpProtocol::UBOE:
     852           40 :             return uboeInfoMap_;
     853            0 :         default:
     854            0 :             return rtpInfoMap_;
     855              :     }
     856              : }
     857              : 
     858          690 : TpMgr::ReqCtxMap& TpMgr::GetReqCtxMap(const TpProtocol tpProtocol)
     859              : {
     860          690 :     switch (tpProtocol) {
     861           27 :         case TpProtocol::CTP:
     862           27 :             return ctpReqMap_;
     863          633 :         case TpProtocol::RTP:
     864          633 :             return rtpReqMap_;
     865           30 :         case TpProtocol::UBOE:
     866           30 :             return uboeReqMap_;
     867            0 :         default:
     868            0 :             return rtpReqMap_;
     869              :     }
     870              : }
     871              : 
     872         1132 : std::mutex& TpMgr::GetInfoCtxMutex(const TpProtocol tpProtocol)
     873              : {
     874         1132 :     switch (tpProtocol) {
     875           31 :         case TpProtocol::CTP:
     876           31 :             return ctpInfoMutex_;
     877         1061 :         case TpProtocol::RTP:
     878         1061 :             return rtpInfoMutex_;
     879           40 :         case TpProtocol::UBOE:
     880           40 :             return uboeInfoMutex_;
     881            0 :         default:
     882            0 :             return rtpInfoMutex_;
     883              :     }
     884              : }
     885              : 
     886          690 : std::mutex& TpMgr::GetReqCtxMutex(const TpProtocol tpProtocol)
     887              : {
     888          690 :     switch (tpProtocol) {
     889           27 :         case TpProtocol::CTP:
     890           27 :             return ctpReqMutex_;
     891          633 :         case TpProtocol::RTP:
     892          633 :             return rtpReqMutex_;
     893           30 :         case TpProtocol::UBOE:
     894           30 :             return uboeReqMutex_;
     895            0 :         default:
     896            0 :             return rtpReqMutex_;
     897              :     }
     898              : }
     899              : 
     900              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1