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

Generated by: LCOV version 2.0-1