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