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