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