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 1904 : 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 717 : static HcclResult IsPcieStdMainboardByPhyId(uint32_t devPhyId, bool& isPcieStd)
44 : {
45 717 : isPcieStd = false;
46 717 : u32 devLogicId = 0U;
47 717 : CHK_RET(hrtGetDeviceIndexByPhyId(devPhyId, devLogicId));
48 717 : Hccl::HcclMainboardId mainboardId = Hccl::HcclMainboardId::MAINBOARD_OTHERS;
49 717 : CHK_RET(Hccl::HrtGetMainboardId(devLogicId, mainboardId));
50 717 : isPcieStd = (mainboardId == Hccl::HcclMainboardId::MAINBOARD_PCIE_STD);
51 717 : return HcclResult::HCCL_SUCCESS;
52 : }
53 :
54 : struct TpInfoAddrKey {
55 : Hccl::IpAddress locAddr{};
56 : Hccl::IpAddress rmtAddr{};
57 : QosKey qosKey{0};
58 : };
59 :
60 1665 : static HcclResult ResolveTpInfoAddrKey(const GetTpInfoParam& param, TpInfoAddrKey& out)
61 : {
62 1665 : CHK_RET(CommAddrToIpAddress(param.locAddr, out.locAddr));
63 1665 : CHK_RET(CommAddrToIpAddress(param.rmtAddr, out.rmtAddr));
64 1665 : out.qosKey = QosMapKey(param.qos);
65 1665 : return HcclResult::HCCL_SUCCESS;
66 : }
67 :
68 478 : static uint32_t CalSlAvailableCnt(uint32_t mask)
69 : {
70 478 : uint32_t c = 0;
71 8126 : for (uint32_t i = 0; i < 16U; ++i) {
72 7648 : if ((mask & (1U << i)) != 0U) {
73 1426 : ++c;
74 : }
75 : }
76 478 : return c;
77 : }
78 :
79 239 : static uint32_t SlValueAtRankInMask16(uint32_t mask, uint32_t rank)
80 : {
81 239 : uint32_t seen = 0;
82 304 : for (uint32_t bit = 0; bit < 16U; ++bit) {
83 304 : if ((mask & (1U << bit)) != 0U) {
84 269 : if (seen == rank) {
85 239 : return bit;
86 : }
87 30 : ++seen;
88 : }
89 : }
90 0 : return 0;
91 : }
92 :
93 246 : static uint16_t ReadSlAvailableMask16(const struct TpAttr& attr) { return static_cast<uint16_t>(attr.slBitmap); }
94 :
95 239 : static uint32_t ResolveSlAvailableCntForPolicy(uint16_t slMask, uint32_t slLevelCount)
96 : {
97 239 : uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
98 239 : if (slLevelCount != 0U) {
99 1 : slAvailableCnt = std::min(slLevelCount, slAvailableCnt);
100 : }
101 239 : return slAvailableCnt;
102 : }
103 :
104 : static bool
105 239 : ApplyQosTpSlPolicy(const GetTpInfoParam& param, uint16_t slMask, uint32_t& tpListIndexOut, uint32_t& mappedSlOut)
106 : {
107 239 : const uint32_t slAvailableCnt = ResolveSlAvailableCntForPolicy(slMask, param.slLevelCount);
108 239 : if (slAvailableCnt == 0U) {
109 0 : return false;
110 : }
111 239 : if (param.loopFirstTpLowestSl) {
112 214 : tpListIndexOut = 0U;
113 214 : mappedSlOut = SlValueAtRankInMask16(slMask, 0U);
114 214 : 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 242 : static HcclResult SetTpAttrAsync(
147 : const Hccl::RdmaHandle rdmaHandle, uint64_t tpHandle, uint32_t attrBitmap, struct TpAttr& attr,
148 : const char* logTag)
149 : {
150 242 : Hccl::RequestHandle reqHandle = 0;
151 : try {
152 242 : const HcclResult hret = Hccl::HrtRaSetTpAttrAsync(rdmaHandle, tpHandle, attrBitmap, attr, reqHandle);
153 242 : 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 242 : 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 235 : CommitMappedSlToTpAttr(const uint32_t devPhyId, const CommAddr& locCommAddr, uint64_t tpHandle, uint32_t mappedSl)
169 : {
170 235 : if (tpHandle == 0U) {
171 0 : HCCL_ERROR("[TpMgr][CommitMappedSlToTpAttr] tpHandle is 0");
172 0 : return HcclResult::HCCL_E_INTERNAL;
173 : }
174 235 : Hccl::IpAddress locAddr{};
175 235 : CHK_RET(CommAddrToIpAddress(locCommAddr, locAddr));
176 235 : const Hccl::RdmaHandle rdmaHandle = Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId, locAddr);
177 235 : CHK_PTR_NULL(rdmaHandle);
178 :
179 235 : struct TpAttr tpSlAttr {};
180 235 : tpSlAttr.sl = static_cast<uint8_t>(mappedSl & 0xFU);
181 : const HcclResult hret
182 235 : = SetTpAttrAsync(rdmaHandle, tpHandle, kTpAttrBitmapSl, tpSlAttr, "CommitMappedSlToTpAttr");
183 235 : if (hret == HcclResult::HCCL_SUCCESS) {
184 235 : HCCL_INFO(
185 : "[TpMgr][CommitMappedSlToTpAttr] ok tpHandle[%llu] sl[%u].", static_cast<unsigned long long>(tpHandle),
186 : static_cast<unsigned>(mappedSl & 0xFU));
187 : }
188 235 : 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 903 : TpMgr& TpMgr::GetInstance(const uint32_t devicePhyId)
218 : {
219 1035 : static TpMgr tpMgr[MAX_MODULE_DEVICE_NUM + 1];
220 :
221 903 : uint32_t devPhyId = devicePhyId;
222 903 : 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 903 : tpMgr[devPhyId].devPhyId_ = devPhyId;
231 :
232 903 : return tpMgr[devPhyId];
233 : }
234 :
235 585 : static HcclResult CheckRequestResult(RequestHandle& reqHandle)
236 : {
237 585 : if (reqHandle == 0) {
238 0 : return HcclResult::HCCL_SUCCESS;
239 : }
240 :
241 585 : RequestResult result = HccpGetAsyncReqResult(reqHandle);
242 585 : if (result == RequestResult::NOT_COMPLETED) {
243 0 : return HcclResult::HCCL_E_AGAIN;
244 : }
245 :
246 585 : 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 585 : return HcclResult::HCCL_SUCCESS;
252 : }
253 :
254 722 : HcclResult CheckTpProtocol(const TpProtocol tpProtocol)
255 : {
256 722 : 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 721 : return HcclResult::HCCL_SUCCESS;
262 : }
263 :
264 948 : 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 948 : lit = infoMap.find(locAddr);
269 948 : if (lit == infoMap.end()) {
270 720 : return HcclResult::HCCL_E_NOT_FOUND;
271 : }
272 228 : rit = lit->second.find(rmtAddr);
273 228 : if (rit == lit->second.end()) {
274 0 : return HcclResult::HCCL_E_NOT_FOUND;
275 : }
276 228 : qosIt = rit->second.find(qosKey);
277 228 : if (qosIt == rit->second.end()) {
278 4 : return HcclResult::HCCL_E_NOT_FOUND;
279 : }
280 224 : return HcclResult::HCCL_SUCCESS;
281 : }
282 :
283 721 : HcclResult TpMgr::FindAndGetTpInfo(const GetTpInfoParam& param, TpInfo& tpInfo)
284 : {
285 721 : TpInfoAddrKey key{};
286 721 : CHK_RET(ResolveTpInfoAddrKey(param, key));
287 721 : std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
288 721 : auto& infoMap = GetInfoCtxMap(param.tpProtocol);
289 721 : InfoCtxMap::iterator lit;
290 721 : InfoRmtMap::iterator rit;
291 721 : InfoQosMap::iterator qosIt;
292 721 : const auto lookupRet = LookupInfoCtxEntry(infoMap, key.locAddr, key.rmtAddr, key.qosKey, lit, rit, qosIt);
293 721 : if (lookupRet != HcclResult::HCCL_SUCCESS) {
294 717 : 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 721 : }
301 :
302 239 : HcclResult TpMgr::BeginGetTpInfoListRequest(const GetTpInfoParam& param, ReqQosMap& qosMap, const QosKey qosKey)
303 : {
304 239 : RequestCtx& reqCtx = qosMap[qosKey];
305 239 : CHK_RET(StartGetTpInfoListRequest(param, reqCtx));
306 239 : 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 239 : return HcclResult::HCCL_E_AGAIN;
311 : }
312 :
313 239 : 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 239 : 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 239 : bool isPcieStd = false;
325 239 : CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
326 239 : 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 239 : const struct HccpTpInfo* list = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
340 239 : 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 239 : CHK_RET(StartGetTpAttrForFirstTp(param, reqCtx));
345 0 : } catch (...) {
346 0 : qosMap.erase(it);
347 0 : throw;
348 0 : }
349 239 : 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 239 : return HcclResult::HCCL_E_AGAIN;
354 : }
355 :
356 : HcclResult
357 717 : TpMgr::PollGetTpInfoReqCtx(std::unique_lock<std::mutex>& reqCtxLock, const GetTpInfoParam& param, TpInfo& tpInfo)
358 : {
359 717 : auto& reqCtxMap = GetReqCtxMap(param.tpProtocol);
360 717 : TpInfoAddrKey key{};
361 717 : CHK_RET(ResolveTpInfoAddrKey(param, key));
362 717 : auto& qosMap = reqCtxMap[key.locAddr][key.rmtAddr];
363 717 : auto it = qosMap.find(key.qosKey);
364 717 : if (it == qosMap.end()) {
365 239 : return BeginGetTpInfoListRequest(param, qosMap, key.qosKey);
366 : }
367 :
368 478 : RequestCtx& reqCtx = it->second;
369 478 : const auto ret = CheckRequestResult(reqCtx.handle);
370 478 : if (ret == HcclResult::HCCL_E_AGAIN) {
371 0 : return ret;
372 : }
373 478 : CHK_RET(ret);
374 :
375 478 : if (reqCtx.phase == ReqPhase::WAIT_LIST) {
376 239 : return AdvanceGetTpInfoWaitList(param, reqCtx, qosMap, it, reqCtxLock, tpInfo);
377 : }
378 :
379 : // 先 move 出槽位再 erase,避免 erase 析构槽内对象后再 move(UB / double free)
380 239 : RequestCtx completedReqCtx = std::move(it->second);
381 239 : qosMap.erase(it);
382 239 : reqCtxLock.unlock();
383 239 : CHK_RET(HandleCompletedRequest(std::move(completedReqCtx), param, tpInfo));
384 239 : return HcclResult::HCCL_SUCCESS;
385 239 : }
386 :
387 722 : HcclResult TpMgr::GetTpInfo(const GetTpInfoParam& param, TpInfo& tpInfo)
388 : {
389 722 : CHK_RET(CheckTpProtocol(param.tpProtocol));
390 721 : if (FindAndGetTpInfo(param, tpInfo) == HcclResult::HCCL_SUCCESS) {
391 4 : return HcclResult::HCCL_SUCCESS;
392 : }
393 :
394 717 : std::unique_lock<std::mutex> reqCtxLock(GetReqCtxMutex(param.tpProtocol));
395 717 : return PollGetTpInfoReqCtx(reqCtxLock, param, tpInfo);
396 717 : }
397 :
398 227 : HcclResult TpMgr::ReleaseTpInfo(const GetTpInfoParam& param, const TpInfo& tpInfo)
399 : {
400 227 : TpInfoAddrKey key{};
401 227 : CHK_RET(ResolveTpInfoAddrKey(param, key));
402 227 : std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
403 227 : auto& infoMap = GetInfoCtxMap(param.tpProtocol);
404 227 : InfoCtxMap::iterator lit;
405 227 : InfoRmtMap::iterator rmtIt;
406 227 : InfoQosMap::iterator qosIt;
407 227 : const auto lookupRet = LookupInfoCtxEntry(infoMap, key.locAddr, key.rmtAddr, key.qosKey, lit, rmtIt, qosIt);
408 227 : 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 220 : if (tpInfo.tpHandle != qosIt->second.tpInfo.tpHandle) {
423 1 : return HcclResult::HCCL_SUCCESS;
424 : }
425 :
426 219 : if (qosIt->second.useCnt > 1) {
427 3 : qosIt->second.useCnt -= 1;
428 3 : return HcclResult::HCCL_SUCCESS;
429 : }
430 :
431 216 : rmtIt->second.erase(qosIt);
432 216 : if (rmtIt->second.empty()) {
433 216 : lit->second.erase(rmtIt);
434 : }
435 216 : if (lit->second.empty()) {
436 216 : infoMap.erase(lit);
437 : }
438 216 : return HcclResult::HCCL_SUCCESS;
439 227 : }
440 :
441 239 : static HcclResult GetTpInfoListAsync(
442 : const CtxHandle ctxHandle, const GetTpInfoParam& param, std::vector<char>& out, uint32_t& num,
443 : RequestHandle& reqHandle)
444 : {
445 239 : Hccl::IpAddress locAddr{};
446 239 : Hccl::IpAddress rmtAddr{};
447 239 : CHK_RET(CommAddrToIpAddress(param.locAddr, locAddr));
448 239 : CHK_RET(CommAddrToIpAddress(param.rmtAddr, rmtAddr));
449 239 : const auto& tpProtocol = param.tpProtocol;
450 :
451 239 : struct GetTpCfg cfg {};
452 239 : cfg.flag.bs.rtp = tpProtocol == TpProtocol::RTP ? 1 : 0;
453 239 : cfg.flag.bs.ctp = tpProtocol == TpProtocol::CTP ? 1 : 0;
454 239 : cfg.flag.bs.uboe = tpProtocol == TpProtocol::UBOE ? 1 : 0;
455 239 : cfg.transMode = TransportModeT::CONN_RM;
456 239 : CHK_RET(IpAddressToHccpEid(locAddr, cfg.localEid));
457 239 : HCCL_INFO(
458 : "[TpMgr][GetTpInfoListAsync] 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 239 : CHK_RET(IpAddressToHccpEid(rmtAddr, cfg.peerEid));
462 239 : HCCL_INFO(
463 : "[TpMgr][GetTpInfoListAsync] 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 239 : out.resize(static_cast<size_t>(Hccl::TP_HANDLE_REQUEST_NUM) * sizeof(struct HccpTpInfo));
469 239 : struct HccpTpInfo* info = reinterpret_cast<struct HccpTpInfo*>(out.data());
470 :
471 239 : void* raReqHandle = nullptr;
472 239 : num = Hccl::TP_HANDLE_REQUEST_NUM; // 指定需要从管控面申请 tp handle 的上限;完成后 num 为实际个数
473 239 : const s32 ret = RaGetTpInfoListAsync(ctxHandle, &cfg, info, &num, &raReqHandle);
474 239 : if (ret != 0 || !raReqHandle) {
475 0 : HCCL_ERROR(
476 : "[TpMgr][%s] failed, call interface error[%d] raReqHandle[%p], ctxHandle[%p] locAddr[%s] rmtAddr[%s].",
477 : __func__, ret, raReqHandle, ctxHandle, locAddr.Describe().c_str(), rmtAddr.Describe().c_str());
478 0 : return HcclResult::HCCL_E_NETWORK;
479 : }
480 :
481 239 : reqHandle = reinterpret_cast<RequestHandle>(raReqHandle);
482 239 : HCCL_INFO("[TpMgr][%s] get request handle[%llu].", __func__, static_cast<unsigned long long>(reqHandle));
483 239 : return HcclResult::HCCL_SUCCESS;
484 : }
485 :
486 239 : HcclResult TpMgr::StartGetTpInfoListRequest(const GetTpInfoParam& param, RequestCtx& reqCtx) const
487 : {
488 : EXCEPTION_HANDLE_BEGIN
489 239 : reqCtx.phase = ReqPhase::WAIT_LIST;
490 239 : reqCtx.tpAttrBitmap = 0;
491 239 : (void)memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
492 :
493 239 : Hccl::IpAddress ipAddr{};
494 239 : CHK_RET(CommAddrToIpAddress(param.locAddr, ipAddr));
495 : const CtxHandle ctxHandle
496 239 : = static_cast<CtxHandle>(Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId_, ipAddr));
497 239 : CHK_PTR_NULL(ctxHandle);
498 :
499 239 : CHK_RET(GetTpInfoListAsync(ctxHandle, param, reqCtx.dataBuffer, reqCtx.tpInfoNum, reqCtx.handle));
500 0 : EXCEPTION_HANDLE_END
501 239 : return HcclResult::HCCL_SUCCESS;
502 : }
503 :
504 239 : HcclResult TpMgr::StartGetTpAttrForFirstTp(const GetTpInfoParam& param, RequestCtx& reqCtx) const
505 : {
506 239 : EXCEPTION_HANDLE_BEGIN(void) memset_s(&reqCtx.tpAttr, sizeof(reqCtx.tpAttr), 0, sizeof(reqCtx.tpAttr));
507 239 : reqCtx.tpAttrBitmap = (1U << kTpAttrSlAvailableBit) | kTpAttrBitmapSl;
508 239 : if (param.tpProtocol == TpProtocol::UBOE) {
509 10 : reqCtx.tpAttrBitmap |= kTpAttrBitmapDscp | (1U << kTpAttrDscpConfigModeBit);
510 : }
511 :
512 239 : const struct HccpTpInfo* list = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
513 239 : const uint64_t firstTpHandle = list[0].tpHandle;
514 :
515 239 : Hccl::IpAddress ipAddr{};
516 239 : CHK_RET(CommAddrToIpAddress(param.locAddr, ipAddr));
517 : const CtxHandle ctxHandle
518 239 : = static_cast<CtxHandle>(Hccl::RdmaHandleManager::GetInstance().GetByIp(devPhyId_, ipAddr));
519 239 : CHK_PTR_NULL(ctxHandle);
520 :
521 239 : void* raReqHandle = nullptr;
522 239 : const s32 ret = RaGetTpAttrAsync(ctxHandle, firstTpHandle, &reqCtx.tpAttrBitmap, &reqCtx.tpAttr, &raReqHandle);
523 239 : 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 239 : reqCtx.handle = reinterpret_cast<RequestHandle>(raReqHandle);
530 239 : reqCtx.phase = ReqPhase::WAIT_TP_ATTR;
531 0 : EXCEPTION_HANDLE_END
532 239 : return HcclResult::HCCL_SUCCESS;
533 : }
534 :
535 325 : HcclResult TpMgr::FindAndGetTpAttr(const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
536 : {
537 325 : std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
538 325 : auto attrIter = tpAttrCtxMap_.find(tpHandle);
539 325 : if (attrIter != tpAttrCtxMap_.end()) {
540 111 : attrIter->second.useCnt += 1;
541 111 : tpAttrInfo = attrIter->second.tpAttrInfo;
542 111 : return HcclResult::HCCL_SUCCESS;
543 : }
544 :
545 214 : return HcclResult::HCCL_E_NOT_FOUND;
546 325 : }
547 :
548 325 : HcclResult TpMgr::GetTpAttr(const GetTpAttrParam& param, TpAttrInfo& tpAttrInfo, CtxHandle ctxHandle)
549 : {
550 325 : const TpHandle tpHandle = param.tpHandle;
551 325 : if (FindAndGetTpAttr(tpHandle, tpAttrInfo) == HcclResult::HCCL_SUCCESS) {
552 111 : return HcclResult::HCCL_SUCCESS;
553 : }
554 :
555 214 : std::unique_lock<std::mutex> reqCtxLock(tpAttrReqMutex_);
556 214 : auto reqCtxIter = tpAttrReqCtxMap_.find(tpHandle);
557 214 : if (reqCtxIter == tpAttrReqCtxMap_.end()) {
558 107 : HCCL_INFO("[TpMgr][%s] get new tpAttr, param[%s].", __func__, param.Describe().c_str());
559 :
560 107 : TpAttrRequestCtx& reqCtx = tpAttrReqCtxMap_[tpHandle];
561 107 : CHK_RET(StartGetTpAttrRequest(param, reqCtx, ctxHandle));
562 107 : return HcclResult::HCCL_E_AGAIN;
563 : }
564 :
565 107 : auto& reqCtx = reqCtxIter->second;
566 107 : auto ret = CheckRequestResult(reqCtx.handle);
567 107 : if (ret == HcclResult::HCCL_E_AGAIN) {
568 0 : return ret;
569 : }
570 107 : CHK_RET(ret);
571 :
572 107 : TpAttrRequestCtx completedReqCtx = reqCtxIter->second;
573 107 : tpAttrReqCtxMap_.erase(reqCtxIter);
574 107 : reqCtxLock.unlock();
575 107 : CHK_RET(HandleCompletedTpAttrRequest(std::move(completedReqCtx), tpHandle, tpAttrInfo));
576 107 : return HcclResult::HCCL_SUCCESS;
577 214 : }
578 :
579 : HcclResult
580 107 : TpMgr::StartGetTpAttrRequest(const GetTpAttrParam& param, TpMgr::TpAttrRequestCtx& reqCtx, CtxHandle ctxHandle) const
581 : {
582 107 : void* raReqHandle = nullptr;
583 214 : s32 ret = RaGetTpAttrAsync(
584 107 : ctxHandle, param.tpHandle, const_cast<uint32_t*>(¶m.attrBitmap), &reqCtx.tpAttr, &raReqHandle);
585 107 : 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 107 : reqCtx.handle = reinterpret_cast<RequestHandle>(raReqHandle);
594 107 : 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 107 : return HcclResult::HCCL_SUCCESS;
598 : }
599 :
600 107 : HcclResult TpMgr::HandleCompletedTpAttrRequest(
601 : const TpMgr::TpAttrRequestCtx reqCtx, const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
602 : {
603 107 : TpAttrInfo tmpTpAttrInfo(reqCtx.tpAttr);
604 :
605 107 : std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
606 107 : tpAttrCtxMap_[tpHandle] = {std::move(tmpTpAttrInfo), 1};
607 :
608 107 : tpAttrInfo = tpAttrCtxMap_[tpHandle].tpAttrInfo;
609 107 : return HcclResult::HCCL_SUCCESS;
610 107 : }
611 :
612 224 : HcclResult TpMgr::ReleaseTpAttr(const TpHandle tpHandle, [[maybe_unused]] const TpAttrInfo& tpAttrInfo)
613 : {
614 224 : std::lock_guard<std::mutex> lock(tpAttrCtxMutex_);
615 224 : auto attrIter = tpAttrCtxMap_.find(tpHandle);
616 224 : 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 217 : if (attrIter->second.useCnt > 1) {
625 111 : attrIter->second.useCnt -= 1;
626 111 : return HcclResult::HCCL_SUCCESS;
627 : }
628 :
629 106 : tpAttrCtxMap_.erase(attrIter);
630 106 : return HcclResult::HCCL_SUCCESS;
631 224 : }
632 :
633 221 : HcclResult TpMgr::GetTpTotalTimeout(const TpAttrInfo& tpAttrInfo, uint32_t& tpTimeOutMs)
634 : {
635 221 : uint8_t rawAtGear = tpAttrInfo.tpAttr.at;
636 221 : uint8_t rawRetryTimes = tpAttrInfo.tpAttr.retryTimesInit;
637 :
638 221 : uint8_t finalAtGear = rawAtGear;
639 221 : if (rawAtGear > AT_GEAR_MAX) {
640 1 : finalAtGear = AT_GEAR_DEFAULT;
641 1 : HCCL_WARNING(
642 : "[TpMgr][%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 221 : uint32_t singleAtTimeoutMs = AT_TIMEOUT_MAP[finalAtGear];
648 221 : tpTimeOutMs = singleAtTimeoutMs * static_cast<uint32_t>(rawRetryTimes + 1);
649 :
650 221 : HCCL_INFO(
651 : "[TpMgr][%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 221 : return HcclResult::HCCL_SUCCESS;
657 : }
658 :
659 219 : static uint32_t TaHwValueToMs(uint8_t hwValue)
660 : {
661 219 : uint8_t gear = hwValue / 8;
662 219 : switch (gear) {
663 1 : case TA_GEAR_INDEX_0:
664 1 : return TA_TIMEOUT_MS_GEAR0;
665 0 : case TA_GEAR_INDEX_1:
666 0 : return TA_TIMEOUT_MS_GEAR1;
667 217 : case TA_GEAR_INDEX_2:
668 217 : 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 218 : uint8_t TpMgr::CalcTaTimeout(TpProtocol tpProtocol, uint8_t taTimeOut, uint32_t tpTimeOutMs)
691 : {
692 : // 未传入时回退到协议默认值(CTP=8,其他=16)
693 218 : uint8_t envValue = (taTimeOut != TA_TIMEOUT_NOT_SET) ? taTimeOut : ((tpProtocol == TpProtocol::CTP) ? 8 : 16);
694 218 : uint32_t envTimeOutMs = TaHwValueToMs(envValue);
695 :
696 : // CTP 协议直接使用 envValue,不与 TP 总超时比较
697 218 : if (tpProtocol == TpProtocol::CTP) {
698 0 : HCCL_INFO("[TpMgr][%s] [UbCtp] Env Value [%u] (%ums).", __func__, envValue, envTimeOutMs);
699 0 : return envValue;
700 : }
701 :
702 : // 其他协议:需要与 TP 总超时比较决定是否自动升挡
703 218 : uint8_t jettyTimeOut = envValue;
704 218 : if (envTimeOutMs <= tpTimeOutMs) {
705 1 : jettyTimeOut = FindMinTaHwValue(tpTimeOutMs);
706 1 : HCCL_WARNING(
707 : "[TpMgr][%s] Env timeout [%ums] <= TP timeout [%ums]. Auto upgrade TA to hw_val[%u] (%ums).", __func__,
708 : envTimeOutMs, tpTimeOutMs, jettyTimeOut, TaHwValueToMs(jettyTimeOut));
709 : } else {
710 217 : HCCL_INFO(
711 : "[TpMgr][%s] Env timeout [%ums] > TP timeout [%ums]. Use env gear base hw_val[%u] (%ums).", __func__,
712 : envTimeOutMs, tpTimeOutMs, envValue, envTimeOutMs);
713 : }
714 :
715 218 : return jettyTimeOut;
716 : }
717 :
718 239 : HcclResult TpMgr::BuildTpInfoAndCommitQosAttr(
719 : const GetTpInfoParam& param, const RequestCtx& reqCtx, const struct HccpTpInfo* baseInfoPtr,
720 : const uint32_t tpListIndex, const uint32_t mappedSl, TpInfo& tpInfo)
721 : {
722 239 : tpInfo = TpInfo{};
723 239 : tpInfo.tpHandle = baseInfoPtr[tpListIndex].tpHandle;
724 239 : tpInfo.mappedJettyPriority = mappedSl & 0xFU;
725 239 : tpInfo.hasMappedJettyPriority = true;
726 :
727 239 : bool isPcieStd = false;
728 239 : CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
729 239 : if (isPcieStd) {
730 0 : HCCL_INFO(
731 : "[TpMgr][%s] pcie std mainboard: skip SetTpAttr, devPhyId[%u] tpProtocol[%s] tpHandle[%llu] "
732 : "param[%s].",
733 : __func__, devPhyId_, param.tpProtocol.Describe().c_str(), static_cast<unsigned long long>(tpInfo.tpHandle),
734 : param.Describe().c_str());
735 239 : } else if (param.tpProtocol == TpProtocol::RTP || param.tpProtocol == TpProtocol::UBOE) {
736 235 : CHK_RET(CommitMappedSlToTpAttr(devPhyId_, param.locAddr, tpInfo.tpHandle, mappedSl));
737 : }
738 239 : if (!isPcieStd && param.tpProtocol == TpProtocol::UBOE && reqCtx.tpAttr.dscpConfigMode == 0) {
739 7 : const uint8_t dscpBefore = static_cast<uint8_t>(reqCtx.tpAttr.dscp & 0x3FU);
740 7 : const uint8_t requestQos = static_cast<uint8_t>(param.qos & 0xFFU);
741 7 : const uint16_t slMask = ReadSlAvailableMask16(reqCtx.tpAttr);
742 7 : const uint8_t dscpLookupQos = ResolveUboeDscpLookupQos(param, reqCtx.tpInfoNum, slMask);
743 7 : uint8_t dscp = Hccl::kUboeDefaultDscp;
744 7 : (void)Hccl::TpQosGetDscpByQosFromHccnCfg(devPhyId_, dscpLookupQos, dscp);
745 7 : CHK_RET(CommitUboeDscpToTpAttr(devPhyId_, param.locAddr, tpInfo.tpHandle, dscp));
746 7 : HCCL_INFO(
747 : "[TpMgr][%s] UBOE dscp updated: tpHandle[%llu] requestQos[%u] dscpLookupQos[%u] dscpBefore[%u] "
748 : "dscpAfter[%u].",
749 : __func__, static_cast<unsigned long long>(tpInfo.tpHandle), static_cast<unsigned>(requestQos),
750 : static_cast<unsigned>(dscpLookupQos), static_cast<unsigned>(dscpBefore), static_cast<unsigned>(dscp));
751 : }
752 239 : HCCL_INFO(
753 : "[TpMgr][%s] tp qos mapping ok: tpHandle[%llu] tpListIndex[%u] mappedSl[%u] jettyPriority[%u] qos[%u] "
754 : "param[%s].",
755 : __func__, static_cast<unsigned long long>(tpInfo.tpHandle), tpListIndex, static_cast<unsigned>(mappedSl & 0xFU),
756 : tpInfo.mappedJettyPriority, param.qos & 0xFFU, param.Describe().c_str());
757 239 : return HcclResult::HCCL_SUCCESS;
758 : }
759 :
760 : // GetTpInfo 完成后写入缓存。useCnt 仅在 FindAndGetTpInfo 命中时 +1,此处不做引用计数。
761 : // 并发首次 GetTpInfo 时,先完成者写入缓存;后完成者若 tpHandle 不同则跳过写入,直接使用本地结果。
762 239 : HcclResult TpMgr::CommitTpInfoToCache(const GetTpInfoParam& param, TpInfo& tpInfo)
763 : {
764 239 : Hccl::IpAddress locAddr{};
765 239 : Hccl::IpAddress rmtAddr{};
766 239 : CHK_RET(CommAddrToIpAddress(param.locAddr, locAddr));
767 239 : CHK_RET(CommAddrToIpAddress(param.rmtAddr, rmtAddr));
768 239 : const QosKey qosKey = QosMapKey(param.qos);
769 :
770 239 : std::lock_guard<std::mutex> lock(GetInfoCtxMutex(param.tpProtocol));
771 239 : auto& infoMap = GetInfoCtxMap(param.tpProtocol);
772 239 : auto& rmtMap = infoMap[locAddr][rmtAddr];
773 239 : const auto qIt = rmtMap.find(qosKey);
774 239 : if (qIt == rmtMap.end()) {
775 239 : rmtMap[qosKey] = TpInfoCtx{tpInfo, 1U};
776 239 : return HcclResult::HCCL_SUCCESS;
777 : }
778 :
779 : // 缓存已存在:不再覆盖(避免并发后写覆盖先写的 tpHandle);tpInfo 保持 GetTpInfo 本地结果。
780 0 : if (qIt->second.tpInfo.tpHandle != tpInfo.tpHandle) {
781 0 : HCCL_WARNING(
782 : "[TpMgr][%s] skip cache store, cached tpHandle[%llu] != local tpHandle[%llu] param[%s].", __func__,
783 : static_cast<unsigned long long>(qIt->second.tpInfo.tpHandle),
784 : static_cast<unsigned long long>(tpInfo.tpHandle), param.Describe().c_str());
785 : }
786 0 : return HcclResult::HCCL_SUCCESS;
787 239 : }
788 :
789 239 : HcclResult TpMgr::HandleCompletedRequest(RequestCtx reqCtx, const GetTpInfoParam& param, TpInfo& tpInfo)
790 : {
791 239 : const uint32_t tpInfoNum = reqCtx.tpInfoNum;
792 239 : if (tpInfoNum == 0U) {
793 0 : HCCL_WARNING(
794 : "[TpMgr][%s] failed to find tp info, tpInfoNum is 0, param[%s].", __func__, param.Describe().c_str());
795 0 : return HcclResult::HCCL_E_NOT_FOUND;
796 : }
797 :
798 239 : tpInfo = TpInfo{};
799 :
800 239 : const struct HccpTpInfo* baseInfoPtr = reinterpret_cast<const struct HccpTpInfo*>(reqCtx.dataBuffer.data());
801 239 : bool isPcieStd = false;
802 239 : CHK_RET(IsPcieStdMainboardByPhyId(devPhyId_, isPcieStd));
803 239 : if (isPcieStd) {
804 0 : tpInfo.tpHandle = baseInfoPtr[0].tpHandle;
805 0 : tpInfo.mappedJettyPriority = kPcieStdMappedSl;
806 0 : tpInfo.hasMappedJettyPriority = true;
807 0 : HCCL_INFO(
808 : "[TpMgr][%s] pcie std mainboard: skip GetTpAttr/SetTpAttr, devPhyId[%u] tpInfoNum[%u] "
809 : "mappedSl[%u] tpHandle[%llu] param[%s].",
810 : __func__, devPhyId_, tpInfoNum, kPcieStdMappedSl, static_cast<unsigned long long>(tpInfo.tpHandle),
811 : param.Describe().c_str());
812 0 : return CommitTpInfoToCache(param, tpInfo);
813 : }
814 :
815 239 : const uint16_t slMask = ReadSlAvailableMask16(reqCtx.tpAttr);
816 239 : const uint32_t slAvailableCnt = CalSlAvailableCnt(slMask);
817 239 : HCCL_INFO(
818 : "[TpMgr][%s] after get_tp_attr: slMask[0x%04x] slAvailableCnt[%u] slBitmap[0x%x] dscp[%u] dscpConfigMode[%u] "
819 : "tpAttrBitmap[0x%x] param[%s].",
820 : __func__, static_cast<unsigned>(slMask), slAvailableCnt, static_cast<unsigned>(reqCtx.tpAttr.slBitmap),
821 : static_cast<unsigned>(reqCtx.tpAttr.dscp & 0x3FU), static_cast<unsigned>(reqCtx.tpAttr.dscpConfigMode & 1U),
822 : reqCtx.tpAttrBitmap, param.Describe().c_str());
823 239 : if (slAvailableCnt == 0U) {
824 0 : HCCL_ERROR(
825 : "[TpMgr][%s] sl_available mask empty after get_tp_attr, param[%s].", __func__, param.Describe().c_str());
826 0 : return HcclResult::HCCL_E_INTERNAL;
827 : }
828 239 : uint32_t tpListIndex = 0;
829 239 : uint32_t mappedSl = 0;
830 239 : if (!ApplyQosTpSlPolicy(param, slMask, tpListIndex, mappedSl)) {
831 0 : HCCL_ERROR(
832 : "[TpMgr][%s] ApplyQosTpSlPolicy failed, param[%s] nTp[%u] slAvailableCnt[%u] mask[%u].", __func__,
833 : param.Describe().c_str(), tpInfoNum, slAvailableCnt, static_cast<unsigned>(slMask));
834 0 : return HcclResult::HCCL_E_INTERNAL;
835 : }
836 239 : if (tpListIndex >= tpInfoNum) {
837 0 : HCCL_ERROR(
838 : "[TpMgr][%s] tpListIndex out of range: tpListIndex[%u] tpInfoNum[%u] mappedSl[%u] param[%s].", __func__,
839 : tpListIndex, tpInfoNum, static_cast<unsigned>(mappedSl & 0xFU), param.Describe().c_str());
840 0 : return HcclResult::HCCL_E_INTERNAL;
841 : }
842 :
843 239 : CHK_RET(BuildTpInfoAndCommitQosAttr(param, reqCtx, baseInfoPtr, tpListIndex, mappedSl, tpInfo));
844 239 : return CommitTpInfoToCache(param, tpInfo);
845 : }
846 :
847 1187 : TpMgr::InfoCtxMap& TpMgr::GetInfoCtxMap(const TpProtocol tpProtocol)
848 : {
849 1187 : switch (tpProtocol) {
850 16 : case TpProtocol::CTP:
851 16 : return ctpInfoMap_;
852 1131 : case TpProtocol::RTP:
853 1131 : return rtpInfoMap_;
854 40 : case TpProtocol::UBOE:
855 40 : return uboeInfoMap_;
856 0 : default:
857 0 : return rtpInfoMap_;
858 : }
859 : }
860 :
861 717 : TpMgr::ReqCtxMap& TpMgr::GetReqCtxMap(const TpProtocol tpProtocol)
862 : {
863 717 : switch (tpProtocol) {
864 12 : case TpProtocol::CTP:
865 12 : return ctpReqMap_;
866 675 : case TpProtocol::RTP:
867 675 : return rtpReqMap_;
868 30 : case TpProtocol::UBOE:
869 30 : return uboeReqMap_;
870 0 : default:
871 0 : return rtpReqMap_;
872 : }
873 : }
874 :
875 1187 : std::mutex& TpMgr::GetInfoCtxMutex(const TpProtocol tpProtocol)
876 : {
877 1187 : switch (tpProtocol) {
878 16 : case TpProtocol::CTP:
879 16 : return ctpInfoMutex_;
880 1131 : case TpProtocol::RTP:
881 1131 : return rtpInfoMutex_;
882 40 : case TpProtocol::UBOE:
883 40 : return uboeInfoMutex_;
884 0 : default:
885 0 : return rtpInfoMutex_;
886 : }
887 : }
888 :
889 717 : std::mutex& TpMgr::GetReqCtxMutex(const TpProtocol tpProtocol)
890 : {
891 717 : switch (tpProtocol) {
892 12 : case TpProtocol::CTP:
893 12 : return ctpReqMutex_;
894 675 : case TpProtocol::RTP:
895 675 : return rtpReqMutex_;
896 30 : case TpProtocol::UBOE:
897 30 : return uboeReqMutex_;
898 0 : default:
899 0 : return rtpReqMutex_;
900 : }
901 : }
902 :
903 : } // namespace hcomm
|