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