LCOV - code coverage report
Current view: top level - base_comm/common - tp_mgr.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.2 % 501 422
Test Date: 2026-08-25 19:18:03 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         1824 :     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          687 :     static HcclResult IsPcieStdMainboardByPhyId(uint32_t devPhyId, bool& isPcieStd)
      44              :     {
      45          687 :         isPcieStd = false;
      46          687 :         u32 devLogicId = 0U;
      47          687 :         CHK_RET(hrtGetDeviceIndexByPhyId(devPhyId, devLogicId));
      48          687 :         Hccl::HcclMainboardId mainboardId = Hccl::HcclMainboardId::MAINBOARD_OTHERS;
      49          687 :         CHK_RET(Hccl::HrtGetMainboardId(devLogicId, mainboardId));
      50          687 :         isPcieStd = (mainboardId == Hccl::HcclMainboardId::MAINBOARD_PCIE_STD);
      51          687 :         return HcclResult::HCCL_SUCCESS;
      52              :     }
      53              : 
      54              :     struct TpInfoAddrKey {
      55              :         Hccl::IpAddress locAddr{};
      56              :         Hccl::IpAddress rmtAddr{};
      57              :         QosKey qosKey{0};
      58              :     };
      59              : 
      60         1595 :     static HcclResult ResolveTpInfoAddrKey(const GetTpInfoParam& param, TpInfoAddrKey& out)
      61              :     {
      62         1595 :         CHK_RET(CommAddrToIpAddress(param.locAddr, out.locAddr));
      63         1595 :         CHK_RET(CommAddrToIpAddress(param.rmtAddr, out.rmtAddr));
      64         1595 :         out.qosKey = QosMapKey(param.qos);
      65         1595 :         return HcclResult::HCCL_SUCCESS;
      66              :     }
      67              : 
      68          458 :     static uint32_t CalSlAvailableCnt(uint32_t mask)
      69              :     {
      70          458 :         uint32_t c = 0;
      71         7786 :         for (uint32_t i = 0; i < 16U; ++i) {
      72         7328 :             if ((mask & (1U << i)) != 0U) {
      73         1366 :                 ++c;
      74              :             }
      75              :         }
      76          458 :         return c;
      77              :     }
      78              : 
      79          229 :     static uint32_t SlValueAtRankInMask16(uint32_t mask, uint32_t rank)
      80              :     {
      81          229 :         uint32_t seen = 0;
      82          294 :         for (uint32_t bit = 0; bit < 16U; ++bit) {
      83          294 :             if ((mask & (1U << bit)) != 0U) {
      84          259 :                 if (seen == rank) {
      85          229 :                     return bit;
      86              :                 }
      87           30 :                 ++seen;
      88              :             }
      89              :         }
      90            0 :         return 0;
      91              :     }
      92              : 
      93          236 :     static uint16_t ReadSlAvailableMask16(const struct TpAttr& attr) { return static_cast<uint16_t>(attr.slBitmap); }
      94              : 
      95          229 :     static uint32_t ResolveSlAvailableCntForPolicy(uint16_t slMask, uint32_t slLevelCount)
      96              :     {
      97          229 :         uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
      98          229 :         if (slLevelCount != 0U) {
      99            1 :             slAvailableCnt = std::min(slLevelCount, slAvailableCnt);
     100              :         }
     101          229 :         return slAvailableCnt;
     102              :     }
     103              : 
     104              :     static bool
     105          229 :     ApplyQosTpSlPolicy(const GetTpInfoParam& param, uint16_t slMask, uint32_t& tpListIndexOut, uint32_t& mappedSlOut)
     106              :     {
     107          229 :         const uint32_t slAvailableCnt = ResolveSlAvailableCntForPolicy(slMask, param.slLevelCount);
     108          229 :         if (slAvailableCnt == 0U) {
     109            0 :             return false;
     110              :         }
     111          229 :         if (param.loopFirstTpLowestSl) {
     112          204 :             tpListIndexOut = 0U;
     113          204 :             mappedSlOut = SlValueAtRankInMask16(slMask, 0U);
     114          204 :             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          232 :     static HcclResult SetTpAttrAsync(
     147              :         const Hccl::RdmaHandle rdmaHandle, uint64_t tpHandle, uint32_t attrBitmap, struct TpAttr& attr,
     148              :         const char* logTag)
     149              :     {
     150          232 :         Hccl::RequestHandle reqHandle = 0;
     151              :         try {
     152          232 :             const HcclResult hret = Hccl::HrtRaSetTpAttrAsync(rdmaHandle, tpHandle, attrBitmap, attr, reqHandle);
     153          232 :             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          232 :             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          225 :     CommitMappedSlToTpAttr(const uint32_t devPhyId, const CommAddr& locCommAddr, uint64_t tpHandle, uint32_t mappedSl)
     169              :     {
     170          225 :         if (tpHandle == 0U) {
     171            0 :             HCCL_ERROR("[TpMgr][CommitMappedSlToTpAttr] tpHandle is 0");
     172            0 :             return HcclResult::HCCL_E_INTERNAL;
     173              :         }
     174          225 :         Hccl::IpAddress locAddr{};
     175          225 :         CHK_RET(CommAddrToIpAddress(locCommAddr, locAddr));
     176          225 :         const Hccl::RdmaHandle rdmaHandle = Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId, locAddr);
     177          225 :         CHK_PTR_NULL(rdmaHandle);
     178              : 
     179          225 :         struct TpAttr tpSlAttr {};
     180          225 :         tpSlAttr.sl = static_cast<uint8_t>(mappedSl & 0xFU);
     181              :         const HcclResult hret
     182          225 :             = SetTpAttrAsync(rdmaHandle, tpHandle, kTpAttrBitmapSl, tpSlAttr, "CommitMappedSlToTpAttr");
     183          225 :         if (hret == HcclResult::HCCL_SUCCESS) {
     184          225 :             HCCL_INFO(
     185              :                 "[TpMgr][CommitMappedSlToTpAttr] ok tpHandle[%llu] sl[%u].", static_cast<unsigned long long>(tpHandle),
     186              :                 static_cast<unsigned>(mappedSl & 0xFU));
     187              :         }
     188          225 :         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          863 : TpMgr& TpMgr::GetInstance(const uint32_t devicePhyId)
     218              : {
     219          995 :     static TpMgr tpMgr[MAX_MODULE_DEVICE_NUM + 1];
     220              : 
     221          863 :     uint32_t devPhyId = devicePhyId;
     222          863 :     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          863 :     tpMgr[devPhyId].devPhyId_ = devPhyId;
     231              : 
     232          863 :     return tpMgr[devPhyId];
     233              : }
     234              : 
     235          560 : static HcclResult CheckRequestResult(RequestHandle& reqHandle)
     236              : {
     237          560 :     if (reqHandle == 0) {
     238            0 :         return HcclResult::HCCL_SUCCESS;
     239              :     }
     240              : 
     241          560 :     RequestResult result = HccpGetAsyncReqResult(reqHandle);
     242          560 :     if (result == RequestResult::NOT_COMPLETED) {
     243            0 :         return HcclResult::HCCL_E_AGAIN;
     244              :     }
     245              : 
     246          560 :     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          560 :     return HcclResult::HCCL_SUCCESS;
     252              : }
     253              : 
     254          692 : HcclResult CheckTpProtocol(const TpProtocol tpProtocol)
     255              : {
     256          692 :     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          691 :     return HcclResult::HCCL_SUCCESS;
     262              : }
     263              : 
     264          908 : 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          908 :     lit = infoMap.find(locAddr);
     269          908 :     if (lit == infoMap.end()) {
     270          690 :         return HcclResult::HCCL_E_NOT_FOUND;
     271              :     }
     272          218 :     rit = lit->second.find(rmtAddr);
     273          218 :     if (rit == lit->second.end()) {
     274            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     275              :     }
     276          218 :     qosIt = rit->second.find(qosKey);
     277          218 :     if (qosIt == rit->second.end()) {
     278            4 :         return HcclResult::HCCL_E_NOT_FOUND;
     279              :     }
     280          214 :     return HcclResult::HCCL_SUCCESS;
     281              : }
     282              : 
     283          691 : HcclResult TpMgr::FindAndGetTpInfo(const GetTpInfoParam& param, TpInfo& tpInfo)
     284              : {
     285          691 :     TpInfoAddrKey key{};
     286          691 :     CHK_RET(ResolveTpInfoAddrKey(param, key));
     287          691 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     288          691 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     289          691 :     InfoCtxMap::iterator lit;
     290          691 :     InfoRmtMap::iterator rit;
     291          691 :     InfoQosMap::iterator qosIt;
     292          691 :     const auto lookupRet = LookupInfoCtxEntry(infoMap, key.locAddr, key.rmtAddr, key.qosKey, lit, rit, qosIt);
     293          691 :     if (lookupRet != HcclResult::HCCL_SUCCESS) {
     294          687 :         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          691 : }
     301              : 
     302          229 : HcclResult TpMgr::BeginGetTpInfoListRequest(const GetTpInfoParam& param, ReqQosMap& qosMap, const QosKey qosKey)
     303              : {
     304          229 :     RequestCtx& reqCtx = qosMap[qosKey];
     305          229 :     CHK_RET(StartGetTpInfoListRequest(param, reqCtx));
     306          229 :     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          229 :     return HcclResult::HCCL_E_AGAIN;
     311              : }
     312              : 
     313          229 : 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          229 :     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          229 :     bool isPcieStd = false;
     325          229 :     CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
     326          229 :     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          229 :     const struct HccpTpInfo* list = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
     340          229 :     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          229 :         CHK_RET(StartGetTpAttrForFirstTp(param, reqCtx));
     345            0 :     } catch (...) {
     346            0 :         qosMap.erase(it);
     347            0 :         throw;
     348            0 :     }
     349          229 :     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          229 :     return HcclResult::HCCL_E_AGAIN;
     354              : }
     355              : 
     356              : HcclResult
     357          687 : TpMgr::PollGetTpInfoReqCtx(std::unique_lock<std::mutex>& reqCtxLock, const GetTpInfoParam& param, TpInfo& tpInfo)
     358              : {
     359          687 :     auto& reqCtxMap = GetReqCtxMap(param.tpProtocol);
     360          687 :     TpInfoAddrKey key{};
     361          687 :     CHK_RET(ResolveTpInfoAddrKey(param, key));
     362          687 :     auto& qosMap = reqCtxMap[key.locAddr][key.rmtAddr];
     363          687 :     auto it = qosMap.find(key.qosKey);
     364          687 :     if (it == qosMap.end()) {
     365          229 :         return BeginGetTpInfoListRequest(param, qosMap, key.qosKey);
     366              :     }
     367              : 
     368          458 :     RequestCtx& reqCtx = it->second;
     369          458 :     const auto ret = CheckRequestResult(reqCtx.handle);
     370          458 :     if (ret == HcclResult::HCCL_E_AGAIN) {
     371            0 :         return ret;
     372              :     }
     373          458 :     CHK_RET(ret);
     374              : 
     375          458 :     if (reqCtx.phase == ReqPhase::WAIT_LIST) {
     376          229 :         return AdvanceGetTpInfoWaitList(param, reqCtx, qosMap, it, reqCtxLock, tpInfo);
     377              :     }
     378              : 
     379              :     // 先 move 出槽位再 erase,避免 erase 析构槽内对象后再 move(UB / double free)
     380          229 :     RequestCtx completedReqCtx = std::move(it->second);
     381          229 :     qosMap.erase(it);
     382          229 :     reqCtxLock.unlock();
     383          229 :     CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo));
     384          229 :     return HcclResult::HCCL_SUCCESS;
     385          229 : }
     386              : 
     387          692 : HcclResult TpMgr::GetTpInfo(const GetTpInfoParam& param, TpInfo& tpInfo)
     388              : {
     389          692 :     CHK_RET(CheckTpProtocol(param.tpProtocol));
     390          691 :     if (FindAndGetTpInfo(param, tpInfo) == HcclResult::HCCL_SUCCESS) {
     391            4 :         return HcclResult::HCCL_SUCCESS;
     392              :     }
     393              : 
     394          687 :     std::unique_lock<std::mutex> reqCtxLock(GetReqCtxMutex(param.tpProtocol));
     395          687 :     return PollGetTpInfoReqCtx(reqCtxLock, param, tpInfo);
     396          687 : }
     397              : 
     398          217 : HcclResult TpMgr::ReleaseTpInfo(const GetTpInfoParam& param, const TpInfo& tpInfo)
     399              : {
     400          217 :     TpInfoAddrKey key{};
     401          217 :     CHK_RET(ResolveTpInfoAddrKey(param, key));
     402          217 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     403          217 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     404          217 :     InfoCtxMap::iterator lit;
     405          217 :     InfoRmtMap::iterator rmtIt;
     406          217 :     InfoQosMap::iterator qosIt;
     407          217 :     const auto lookupRet = LookupInfoCtxEntry(infoMap, key.locAddr, key.rmtAddr, key.qosKey, lit, rmtIt, qosIt);
     408          217 :     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          210 :     if (tpInfo.tpHandle != qosIt->second.tpInfo.tpHandle) {
     423            1 :         return HcclResult::HCCL_SUCCESS;
     424              :     }
     425              : 
     426          209 :     if (qosIt->second.useCnt > 1) {
     427            3 :         qosIt->second.useCnt -= 1;
     428            3 :         return HcclResult::HCCL_SUCCESS;
     429              :     }
     430              : 
     431          206 :     rmtIt->second.erase(qosIt);
     432          206 :     if (rmtIt->second.empty()) {
     433          206 :         lit->second.erase(rmtIt);
     434              :     }
     435          206 :     if (lit->second.empty()) {
     436          206 :         infoMap.erase(lit);
     437              :     }
     438          206 :     return HcclResult::HCCL_SUCCESS;
     439          217 : }
     440              : 
     441          229 : static HcclResult GetTpInfoListAsync(
     442              :     const CtxHandle ctxHandle, const GetTpInfoParam& param, std::vector<char>& out, uint32_t& num,
     443              :     RequestHandle& reqHandle)
     444              : {
     445          229 :     Hccl::IpAddress locAddr{};
     446          229 :     Hccl::IpAddress rmtAddr{};
     447          229 :     CHK_RET(CommAddrToIpAddress(param.locAddr, locAddr));
     448          229 :     CHK_RET(CommAddrToIpAddress(param.rmtAddr, rmtAddr));
     449          229 :     const auto& tpProtocol = param.tpProtocol;
     450              : 
     451          229 :     struct GetTpCfg cfg {};
     452          229 :     cfg.flag.bs.rtp = tpProtocol == TpProtocol::RTP ? 1 : 0;
     453          229 :     cfg.flag.bs.ctp = tpProtocol == TpProtocol::CTP ? 1 : 0;
     454          229 :     cfg.flag.bs.uboe = tpProtocol == TpProtocol::UBOE ? 1 : 0;
     455          229 :     cfg.transMode = TransportModeT::CONN_RM;
     456          229 :     CHK_RET(IpAddressToHccpEid(locAddr, cfg.localEid));
     457          229 :     HCCL_INFO(
     458              :         "[TpMgr][GetTpInfoListAsync] 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          229 :     CHK_RET(IpAddressToHccpEid(rmtAddr, cfg.peerEid));
     462          229 :     HCCL_INFO(
     463              :         "[TpMgr][GetTpInfoListAsync] 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          229 :     out.resize(static_cast<size_t>(Hccl::TP_HANDLE_REQUEST_NUM) * sizeof(struct HccpTpInfo));
     469          229 :     struct HccpTpInfo* info = reinterpret_cast<struct HccpTpInfo*>(out.data());
     470              : 
     471          229 :     void* raReqHandle = nullptr;
     472          229 :     num = Hccl::TP_HANDLE_REQUEST_NUM; // 指定需要从管控面申请 tp handle 的上限;完成后 num 为实际个数
     473          229 :     const s32 ret = RaGetTpInfoListAsync(ctxHandle, &cfg, info, &num, &raReqHandle);
     474          229 :     if (ret != 0 || !raReqHandle) {
     475            0 :         HCCL_ERROR(
     476              :             "[TpMgr][%s] failed, call interface error[%d] raReqHandle[%p], ctxHandle[%p] locAddr[%s] rmtAddr[%s].",
     477              :             __func__, ret, raReqHandle, ctxHandle, locAddr.Describe().c_str(), rmtAddr.Describe().c_str());
     478            0 :         return HcclResult::HCCL_E_NETWORK;
     479              :     }
     480              : 
     481          229 :     reqHandle = reinterpret_cast<RequestHandle>(raReqHandle);
     482          229 :     HCCL_INFO("[TpMgr][%s] get request handle[%llu].", __func__, static_cast<unsigned long long>(reqHandle));
     483          229 :     return HcclResult::HCCL_SUCCESS;
     484              : }
     485              : 
     486          229 : HcclResult TpMgr::StartGetTpInfoListRequest(const GetTpInfoParam& param, RequestCtx& reqCtx) const
     487              : {
     488              :     EXCEPTION_HANDLE_BEGIN
     489          229 :     reqCtx.phase = ReqPhase::WAIT_LIST;
     490          229 :     reqCtx.tpAttrBitmap = 0;
     491          229 :     (void)memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
     492              : 
     493          229 :     Hccl::IpAddress ipAddr{};
     494          229 :     CHK_RET(CommAddrToIpAddress(param.locAddr, ipAddr));
     495              :     const CtxHandle ctxHandle
     496          229 :         = static_cast<CtxHandle>(Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId_, ipAddr));
     497          229 :     CHK_PTR_NULL(ctxHandle);
     498              : 
     499          229 :     CHK_RET(GetTpInfoListAsync(ctxHandle, param, reqCtx.dataBuffer, reqCtx.tpInfoNum, reqCtx.handle));
     500            0 :     EXCEPTION_HANDLE_END
     501          229 :     return HcclResult::HCCL_SUCCESS;
     502              : }
     503              : 
     504          229 : HcclResult TpMgr::StartGetTpAttrForFirstTp(const GetTpInfoParam& param, RequestCtx& reqCtx) const
     505              : {
     506          229 :     EXCEPTION_HANDLE_BEGIN(void) memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
     507          229 :     reqCtx.tpAttrBitmap = (1U << kTpAttrSlAvailableBit) | kTpAttrBitmapSl;
     508          229 :     if (param.tpProtocol == TpProtocol::UBOE) {
     509           10 :         reqCtx.tpAttrBitmap |= kTpAttrBitmapDscp | (1U << kTpAttrDscpConfigModeBit);
     510              :     }
     511              : 
     512          229 :     const struct HccpTpInfo* list = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
     513          229 :     const uint64_t firstTpHandle = list[0].tpHandle;
     514              : 
     515          229 :     Hccl::IpAddress ipAddr{};
     516          229 :     CHK_RET(CommAddrToIpAddress(param.locAddr, ipAddr));
     517              :     const CtxHandle ctxHandle
     518          229 :         = static_cast<CtxHandle>(Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId_, ipAddr));
     519          229 :     CHK_PTR_NULL(ctxHandle);
     520              : 
     521          229 :     void* raReqHandle = nullptr;
     522          229 :     const s32 ret = RaGetTpAttrAsync(ctxHandle, firstTpHandle, &reqCtx.tpAttrBitmap, &reqCtx.tpAttr, &raReqHandle);
     523          229 :     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          229 :     reqCtx.handle = reinterpret_cast<RequestHandle>(raReqHandle);
     530          229 :     reqCtx.phase = ReqPhase::WAIT_TP_ATTR;
     531            0 :     EXCEPTION_HANDLE_END
     532          229 :     return HcclResult::HCCL_SUCCESS;
     533              : }
     534              : 
     535          310 : HcclResult TpMgr::FindAndGetTpAttr(const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     536              : {
     537          310 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
     538          310 :     auto attrIter = tpAttrCtxMap_.find(tpHandle);
     539          310 :     if (attrIter != tpAttrCtxMap_.end()) {
     540          106 :         attrIter->second.useCnt += 1;
     541          106 :         tpAttrInfo = attrIter->second.tpAttrInfo;
     542          106 :         return HcclResult::HCCL_SUCCESS;
     543              :     }
     544              : 
     545          204 :     return HcclResult::HCCL_E_NOT_FOUND;
     546          310 : }
     547              : 
     548          310 : HcclResult TpMgr::GetTpAttr(const GetTpAttrParam& param, TpAttrInfo& tpAttrInfo, CtxHandle ctxHandle)
     549              : {
     550          310 :     const TpHandle tpHandle = param.tpHandle;
     551          310 :     if (FindAndGetTpAttr(tpHandle, tpAttrInfo) == HcclResult::HCCL_SUCCESS) {
     552          106 :         return HcclResult::HCCL_SUCCESS;
     553              :     }
     554              : 
     555          204 :     std::unique_lock<std::mutex> reqCtxLock(tpAttrReqMutex_);
     556          204 :     auto reqCtxIter = tpAttrReqCtxMap_.find(tpHandle);
     557          204 :     if (reqCtxIter == tpAttrReqCtxMap_.end()) {
     558          102 :         HCCL_INFO("[TpMgr][%s] get new tpAttr, param[%s].", __func__, param.Describe().c_str());
     559              : 
     560          102 :         TpAttrRequestCtx& reqCtx = tpAttrReqCtxMap_[tpHandle];
     561          102 :         CHK_RET(StartGetTpAttrRequest(param, reqCtx, ctxHandle));
     562          102 :         return HcclResult::HCCL_E_AGAIN;
     563              :     }
     564              : 
     565          102 :     auto& reqCtx = reqCtxIter->second;
     566          102 :     auto ret = CheckRequestResult(reqCtx.handle);
     567          102 :     if (ret == HcclResult::HCCL_E_AGAIN) {
     568            0 :         return ret;
     569              :     }
     570          102 :     CHK_RET(ret);
     571              : 
     572          102 :     TpAttrRequestCtx completedReqCtx = reqCtxIter->second;
     573          102 :     tpAttrReqCtxMap_.erase(reqCtxIter);
     574          102 :     reqCtxLock.unlock();
     575          102 :     CHK_RET(HandleCompletedTpAttrRequest(std::move(completedReqCtx), tpHandle, tpAttrInfo));
     576          102 :     return HcclResult::HCCL_SUCCESS;
     577          204 : }
     578              : 
     579              : HcclResult
     580          102 : TpMgr::StartGetTpAttrRequest(const GetTpAttrParam& param, TpMgr::TpAttrRequestCtx& reqCtx, CtxHandle ctxHandle) const
     581              : {
     582          102 :     void* raReqHandle = nullptr;
     583          204 :     s32 ret = RaGetTpAttrAsync(
     584          102 :         ctxHandle, param.tpHandle, const_cast<uint32_t*>(&param.attrBitmap), &reqCtx.tpAttr, &raReqHandle);
     585          102 :     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          102 :     reqCtx.handle = reinterpret_cast<RequestHandle>(raReqHandle);
     594          102 :     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          102 :     return HcclResult::HCCL_SUCCESS;
     598              : }
     599              : 
     600          102 : HcclResult TpMgr::HandleCompletedTpAttrRequest(
     601              :     const TpMgr::TpAttrRequestCtx reqCtx, const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
     602              : {
     603          102 :     TpAttrInfo tmpTpAttrInfo(reqCtx.tpAttr);
     604              : 
     605          102 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
     606          102 :     tpAttrCtxMap_[tpHandle] = {std::move(tmpTpAttrInfo), 1};
     607              : 
     608          102 :     tpAttrInfo = tpAttrCtxMap_[tpHandle].tpAttrInfo;
     609          102 :     return HcclResult::HCCL_SUCCESS;
     610          102 : }
     611              : 
     612          214 : HcclResult TpMgr::ReleaseTpAttr(const TpHandle tpHandle, [[maybe_unused]] const TpAttrInfo& tpAttrInfo)
     613              : {
     614          214 :     std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
     615          214 :     auto attrIter = tpAttrCtxMap_.find(tpHandle);
     616          214 :     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          207 :     if (attrIter->second.useCnt > 1) {
     625          106 :         attrIter->second.useCnt -= 1;
     626          106 :         return HcclResult::HCCL_SUCCESS;
     627              :     }
     628              : 
     629          101 :     tpAttrCtxMap_.erase(attrIter);
     630          101 :     return HcclResult::HCCL_SUCCESS;
     631          214 : }
     632              : 
     633          211 : HcclResult TpMgr::GetTpTotalTimeout(const TpAttrInfo& tpAttrInfo, uint32_t& tpTimeOutMs)
     634              : {
     635          211 :     uint8_t rawAtGear = tpAttrInfo.tpAttr.at;
     636          211 :     uint8_t rawRetryTimes = tpAttrInfo.tpAttr.retryTimesInit;
     637              : 
     638          211 :     uint8_t finalAtGear = rawAtGear;
     639          211 :     if (rawAtGear > AT_GEAR_MAX) {
     640            1 :         finalAtGear = AT_GEAR_DEFAULT;
     641            1 :         HCCL_WARNING(
     642              :             "[TpMgr][%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          211 :     uint32_t singleAtTimeoutMs = AT_TIMEOUT_MAP[finalAtGear];
     648          211 :     tpTimeOutMs = singleAtTimeoutMs * static_cast<uint32_t>(rawRetryTimes + 1);
     649              : 
     650          211 :     HCCL_INFO(
     651              :         "[TpMgr][%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          211 :     return HcclResult::HCCL_SUCCESS;
     657              : }
     658              : 
     659          209 : static uint32_t TaHwValueToMs(uint8_t hwValue)
     660              : {
     661          209 :     uint8_t gear = hwValue / 8;
     662          209 :     switch (gear) {
     663            1 :         case TA_GEAR_INDEX_0:
     664            1 :             return TA_TIMEOUT_MS_GEAR0;
     665            0 :         case TA_GEAR_INDEX_1:
     666            0 :             return TA_TIMEOUT_MS_GEAR1;
     667          207 :         case TA_GEAR_INDEX_2:
     668          207 :             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          208 : uint8_t TpMgr::CalcTaTimeout(TpProtocol tpProtocol, uint8_t taTimeOut, uint32_t tpTimeOutMs)
     691              : {
     692              :     // 未传入时回退到协议默认值(CTP=8,其他=16)
     693          208 :     uint8_t envValue = (taTimeOut != TA_TIMEOUT_NOT_SET) ? taTimeOut : ((tpProtocol == TpProtocol::CTP) ? 8 : 16);
     694          208 :     uint32_t envTimeOutMs = TaHwValueToMs(envValue);
     695              : 
     696              :     // CTP 协议直接使用 envValue,不与 TP 总超时比较
     697          208 :     if (tpProtocol == TpProtocol::CTP) {
     698            0 :         HCCL_INFO("[TpMgr][%s] [UbCtp] Env Value [%u] (%ums).", __func__, envValue, envTimeOutMs);
     699            0 :         return envValue;
     700              :     }
     701              : 
     702              :     // 其他协议:需要与 TP 总超时比较决定是否自动升挡
     703          208 :     uint8_t jettyTimeOut = envValue;
     704          208 :     if (envTimeOutMs <= tpTimeOutMs) {
     705            1 :         jettyTimeOut = FindMinTaHwValue(tpTimeOutMs);
     706            1 :         HCCL_WARNING(
     707              :             "[TpMgr][%s] Env timeout [%ums] <= TP timeout [%ums]. Auto upgrade TA to hw_val[%u] (%ums).", __func__,
     708              :             envTimeOutMs, tpTimeOutMs, jettyTimeOut, TaHwValueToMs(jettyTimeOut));
     709              :     } else {
     710          207 :         HCCL_INFO(
     711              :             "[TpMgr][%s] Env timeout [%ums] > TP timeout [%ums]. Use env gear base hw_val[%u] (%ums).", __func__,
     712              :             envTimeOutMs, tpTimeOutMs, envValue, envTimeOutMs);
     713              :     }
     714              : 
     715          208 :     return jettyTimeOut;
     716              : }
     717              : 
     718          229 : HcclResult TpMgr::BuildTpInfoAndCommitQosAttr(
     719              :     const GetTpInfoParam& param, const RequestCtx& reqCtx, const struct HccpTpInfo* baseInfoPtr,
     720              :     const uint32_t tpListIndex, const uint32_t mappedSl, TpInfo& tpInfo)
     721              : {
     722          229 :     tpInfo = TpInfo{};
     723          229 :     tpInfo.tpHandle = baseInfoPtr[tpListIndex].tpHandle;
     724          229 :     tpInfo.mappedJettyPriority = mappedSl & 0xFU;
     725          229 :     tpInfo.hasMappedJettyPriority = true;
     726              : 
     727          229 :     bool isPcieStd = false;
     728          229 :     CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
     729          229 :     if (isPcieStd) {
     730            0 :         HCCL_INFO(
     731              :             "[TpMgr][%s] pcie std mainboard: skip SetTpAttr, devPhyId[%u] tpProtocol[%s] tpHandle[%llu] "
     732              :             "param[%s].",
     733              :             __func__, devPhyId_, param.tpProtocol.Describe().c_str(), static_cast<unsigned long long>(tpInfo.tpHandle),
     734              :             param.Describe().c_str());
     735          229 :     } else if (param.tpProtocol == TpProtocol::RTP || param.tpProtocol == TpProtocol::UBOE) {
     736          225 :         CHK_RET(CommitMappedSlToTpAttr(devPhyId_, param.locAddr, tpInfo.tpHandle, mappedSl));
     737              :     }
     738          229 :     if (!isPcieStd && param.tpProtocol == TpProtocol::UBOE && reqCtx.tpAttr.dscpConfigMode == 0) {
     739            7 :         const uint8_t dscpBefore = static_cast<uint8_t>(reqCtx.tpAttr.dscp & 0x3FU);
     740            7 :         const uint8_t requestQos = static_cast<uint8_t>(param.qos & 0xFFU);
     741            7 :         const uint16_t slMask = ReadSlAvailableMask16(reqCtx.tpAttr);
     742            7 :         const uint8_t dscpLookupQos = ResolveUboeDscpLookupQos(param, reqCtx.tpInfoNum, slMask);
     743            7 :         uint8_t dscp = Hccl::kUboeDefaultDscp;
     744            7 :         (void)Hccl::TpQosGetDscpByQosFromHccnCfg(devPhyId_, dscpLookupQos, dscp);
     745            7 :         CHK_RET(CommitUboeDscpToTpAttr(devPhyId_, param.locAddr, tpInfo.tpHandle, dscp));
     746            7 :         HCCL_INFO(
     747              :             "[TpMgr][%s] UBOE dscp updated: tpHandle[%llu] requestQos[%u] dscpLookupQos[%u] dscpBefore[%u] "
     748              :             "dscpAfter[%u].",
     749              :             __func__, static_cast<unsigned long long>(tpInfo.tpHandle), static_cast<unsigned>(requestQos),
     750              :             static_cast<unsigned>(dscpLookupQos), static_cast<unsigned>(dscpBefore), static_cast<unsigned>(dscp));
     751              :     }
     752          229 :     HCCL_INFO(
     753              :         "[TpMgr][%s] tp qos mapping ok: tpHandle[%llu] tpListIndex[%u] mappedSl[%u] jettyPriority[%u] qos[%u] "
     754              :         "param[%s].",
     755              :         __func__, static_cast<unsigned long long>(tpInfo.tpHandle), tpListIndex, static_cast<unsigned>(mappedSl & 0xFU),
     756              :         tpInfo.mappedJettyPriority, param.qos & 0xFFU, param.Describe().c_str());
     757          229 :     return HcclResult::HCCL_SUCCESS;
     758              : }
     759              : 
     760              : // GetTpInfo 完成后写入缓存。useCnt 仅在 FindAndGetTpInfo 命中时 +1,此处不做引用计数。
     761              : // 并发首次 GetTpInfo 时,先完成者写入缓存;后完成者若 tpHandle 不同则跳过写入,直接使用本地结果。
     762          229 : HcclResult TpMgr::CommitTpInfoToCache(const GetTpInfoParam& param, TpInfo& tpInfo)
     763              : {
     764          229 :     Hccl::IpAddress locAddr{};
     765          229 :     Hccl::IpAddress rmtAddr{};
     766          229 :     CHK_RET(CommAddrToIpAddress(param.locAddr, locAddr));
     767          229 :     CHK_RET(CommAddrToIpAddress(param.rmtAddr, rmtAddr));
     768          229 :     const QosKey qosKey = QosMapKey(param.qos);
     769              : 
     770          229 :     std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
     771          229 :     auto& infoMap = GetInfoCtxMap(param.tpProtocol);
     772          229 :     auto& rmtMap = infoMap[locAddr][rmtAddr];
     773          229 :     const auto qIt = rmtMap.find(qosKey);
     774          229 :     if (qIt == rmtMap.end()) {
     775          229 :         rmtMap[qosKey] = TpInfoCtx{tpInfo, 1U};
     776          229 :         return HcclResult::HCCL_SUCCESS;
     777              :     }
     778              : 
     779              :     // 缓存已存在:不再覆盖(避免并发后写覆盖先写的 tpHandle);tpInfo 保持 GetTpInfo 本地结果。
     780            0 :     if (qIt->second.tpInfo.tpHandle != tpInfo.tpHandle) {
     781            0 :         HCCL_WARNING(
     782              :             "[TpMgr][%s] skip cache store, cached tpHandle[%llu] != local tpHandle[%llu] param[%s].", __func__,
     783              :             static_cast<unsigned long long>(qIt->second.tpInfo.tpHandle),
     784              :             static_cast<unsigned long long>(tpInfo.tpHandle), param.Describe().c_str());
     785              :     }
     786            0 :     return HcclResult::HCCL_SUCCESS;
     787          229 : }
     788              : 
     789          229 : HcclResult TpMgr::HandleCompletedRequest(RequestCtx reqCtx, const GetTpInfoParam& param, TpInfo& tpInfo)
     790              : {
     791          229 :     const uint32_t tpInfoNum = reqCtx.tpInfoNum;
     792          229 :     if (tpInfoNum == 0U) {
     793            0 :         HCCL_WARNING(
     794              :             "[TpMgr][%s] failed to find tp info, tpInfoNum is 0, param[%s].", __func__, param.Describe().c_str());
     795            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     796              :     }
     797              : 
     798          229 :     tpInfo = TpInfo{};
     799              : 
     800          229 :     const struct HccpTpInfo* baseInfoPtr = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
     801          229 :     bool isPcieStd = false;
     802          229 :     CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
     803          229 :     if (isPcieStd) {
     804            0 :         tpInfo.tpHandle = baseInfoPtr[0].tpHandle;
     805            0 :         tpInfo.mappedJettyPriority = kPcieStdMappedSl;
     806            0 :         tpInfo.hasMappedJettyPriority = true;
     807            0 :         HCCL_INFO(
     808              :             "[TpMgr][%s] pcie std mainboard: skip GetTpAttr/SetTpAttr, devPhyId[%u] tpInfoNum[%u] "
     809              :             "mappedSl[%u] tpHandle[%llu] param[%s].",
     810              :             __func__, devPhyId_, tpInfoNum, kPcieStdMappedSl, static_cast<unsigned long long>(tpInfo.tpHandle),
     811              :             param.Describe().c_str());
     812            0 :         return CommitTpInfoToCache(param, tpInfo);
     813              :     }
     814              : 
     815          229 :     const uint16_t slMask = ReadSlAvailableMask16(reqCtx.tpAttr);
     816          229 :     const uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
     817          229 :     HCCL_INFO(
     818              :         "[TpMgr][%s] after get_tp_attr: slMask[0x%04x] slAvailableCnt[%u] slBitmap[0x%x] dscp[%u] dscpConfigMode[%u] "
     819              :         "tpAttrBitmap[0x%x] param[%s].",
     820              :         __func__, static_cast<unsigned>(slMask), slAvailableCnt, static_cast<unsigned>(reqCtx.tpAttr.slBitmap),
     821              :         static_cast<unsigned>(reqCtx.tpAttr.dscp & 0x3FU), static_cast<unsigned>(reqCtx.tpAttr.dscpConfigMode & 1U),
     822              :         reqCtx.tpAttrBitmap, param.Describe().c_str());
     823          229 :     if (slAvailableCnt == 0U) {
     824            0 :         HCCL_ERROR(
     825              :             "[TpMgr][%s] sl_available mask empty after get_tp_attr, param[%s].", __func__, param.Describe().c_str());
     826            0 :         return HcclResult::HCCL_E_INTERNAL;
     827              :     }
     828          229 :     uint32_t tpListIndex = 0;
     829          229 :     uint32_t mappedSl = 0;
     830          229 :     if (!ApplyQosTpSlPolicy(param, slMask, tpListIndex, mappedSl)) {
     831            0 :         HCCL_ERROR(
     832              :             "[TpMgr][%s] ApplyQosTpSlPolicy failed, param[%s] nTp[%u] slAvailableCnt[%u] mask[%u].", __func__,
     833              :             param.Describe().c_str(), tpInfoNum, slAvailableCnt, static_cast<unsigned>(slMask));
     834            0 :         return HcclResult::HCCL_E_INTERNAL;
     835              :     }
     836          229 :     if (tpListIndex >= tpInfoNum) {
     837            0 :         HCCL_ERROR(
     838              :             "[TpMgr][%s] tpListIndex out of range: tpListIndex[%u] tpInfoNum[%u] mappedSl[%u] param[%s].", __func__,
     839              :             tpListIndex, tpInfoNum, static_cast<unsigned>(mappedSl & 0xFU), param.Describe().c_str());
     840            0 :         return HcclResult::HCCL_E_INTERNAL;
     841              :     }
     842              : 
     843          229 :     CHK_RET(BuildTpInfoAndCommitQosAttr(param, reqCtx, baseInfoPtr, tpListIndex, mappedSl, tpInfo));
     844          229 :     return CommitTpInfoToCache(param, tpInfo);
     845              : }
     846              : 
     847         1137 : TpMgr::InfoCtxMap& TpMgr::GetInfoCtxMap(const TpProtocol tpProtocol)
     848              : {
     849         1137 :     switch (tpProtocol) {
     850           16 :         case TpProtocol::CTP:
     851           16 :             return ctpInfoMap_;
     852         1081 :         case TpProtocol::RTP:
     853         1081 :             return rtpInfoMap_;
     854           40 :         case TpProtocol::UBOE:
     855           40 :             return uboeInfoMap_;
     856            0 :         default:
     857            0 :             return rtpInfoMap_;
     858              :     }
     859              : }
     860              : 
     861          687 : TpMgr::ReqCtxMap& TpMgr::GetReqCtxMap(const TpProtocol tpProtocol)
     862              : {
     863          687 :     switch (tpProtocol) {
     864           12 :         case TpProtocol::CTP:
     865           12 :             return ctpReqMap_;
     866          645 :         case TpProtocol::RTP:
     867          645 :             return rtpReqMap_;
     868           30 :         case TpProtocol::UBOE:
     869           30 :             return uboeReqMap_;
     870            0 :         default:
     871            0 :             return rtpReqMap_;
     872              :     }
     873              : }
     874              : 
     875         1137 : std::mutex& TpMgr::GetInfoCtxMutex(const TpProtocol tpProtocol)
     876              : {
     877         1137 :     switch (tpProtocol) {
     878           16 :         case TpProtocol::CTP:
     879           16 :             return ctpInfoMutex_;
     880         1081 :         case TpProtocol::RTP:
     881         1081 :             return rtpInfoMutex_;
     882           40 :         case TpProtocol::UBOE:
     883           40 :             return uboeInfoMutex_;
     884            0 :         default:
     885            0 :             return rtpInfoMutex_;
     886              :     }
     887              : }
     888              : 
     889          687 : std::mutex& TpMgr::GetReqCtxMutex(const TpProtocol tpProtocol)
     890              : {
     891          687 :     switch (tpProtocol) {
     892           12 :         case TpProtocol::CTP:
     893           12 :             return ctpReqMutex_;
     894          645 :         case TpProtocol::RTP:
     895          645 :             return rtpReqMutex_;
     896           30 :         case TpProtocol::UBOE:
     897           30 :             return uboeReqMutex_;
     898            0 :         default:
     899            0 :             return rtpReqMutex_;
     900              :     }
     901              : }
     902              : 
     903              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1