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 "ccu_comp.h"
12 :
13 : #include <random>
14 :
15 : #include "hccl_common.h"
16 : #include "rdma_handle_manager.h"
17 :
18 : #include "eid_info_mgr.h"
19 : #include "ccu_res_specs.h"
20 : #include "ccu_channel_ctx_mgr_v1.h"
21 : #include "ccu_channel_ctx_mgr_v2.h"
22 :
23 : #include "exception_handler.h"
24 : #include "adapter_rts_common.h"
25 : #include "env_config.h"
26 : #include "orion_adapter_hccp.h"
27 : #include "hcomm_adapter_hccp.h"
28 :
29 : namespace hcomm {
30 :
31 : constexpr TpProtocol LOOP_JETTY_PROTOCOL = TpProtocol::RTP; // 环回使用RTP避免被环境link down阻塞
32 : constexpr uint8_t CCU_MAX_MISSION_NUM = 16;
33 :
34 : // 设置为0,分配数量由channelCtxMgr决定,v1 默认1个
35 : constexpr uint32_t LOOP_CHANNEL_USE_JETTY = 0;
36 : constexpr uint32_t LOOP_CHANNEL_USE_SQSIZE_V1 = 16;
37 : constexpr uint32_t LOOP_CHANNEL_USE_SQSIZE_V2 = 32;
38 :
39 : // 环回获取TP信息超时等待10s
40 : constexpr uint32_t LOOP_CHANNEL_WAIT_TIMEOUT_MS = 10000;
41 :
42 : // 环境是ARM+X86时,配置 die0 的 MS 交织粒度为 1<<7 = 128
43 : constexpr uint32_t MSID_CONFIG_ARMX86_MAINBOARD = 7;
44 : // 设计支持的最大IOdie数量
45 : constexpr uint8_t MAX_CCU_IODIE_NUM = 2;
46 : // 清理CKE批量申请大小
47 : constexpr u32 MAX_CKE_DATA_ARRAY_SIZE = 8;
48 :
49 5782 : CcuComponent& CcuComponent::GetInstance(const int32_t deviceLogicId)
50 : {
51 5980 : static CcuComponent ccuComponent[MAX_MODULE_DEVICE_NUM + 1];
52 5782 : int32_t devLogicId = deviceLogicId;
53 5782 : if (devLogicId < 0 || static_cast<uint32_t>(devLogicId) >= MAX_MODULE_DEVICE_NUM) {
54 0 : HCCL_WARNING(
55 : "[CcuComponent][%s] use the backup device, devLogicId[%d] should be "
56 : "less than %u.",
57 : __func__, devLogicId, MAX_MODULE_DEVICE_NUM);
58 0 : devLogicId = MAX_MODULE_DEVICE_NUM; // 使用备份设备
59 : }
60 :
61 5782 : ccuComponent[devLogicId].devLogicId_ = devLogicId;
62 5782 : return ccuComponent[devLogicId];
63 : }
64 :
65 189 : HcclResult CcuComponent::Init()
66 : {
67 189 : std::lock_guard<std::mutex> _lock(innerMutex_);
68 :
69 189 : if (initFlag_) {
70 81 : return HcclResult::HCCL_SUCCESS;
71 : }
72 :
73 108 : CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<uint32_t>(devLogicId_), devPhyId_));
74 108 : CHK_RET(CheckDiesEnable());
75 :
76 : // 当前ccu驱动拉起时不清理资源,hcomm规避,后续需要清理cke及其他资源
77 321 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
78 214 : (void)CleanDieCkes(dieId);
79 : }
80 :
81 107 : CHK_RET(CreateCcuRmaBuffer());
82 107 : CHK_RET(CreateResourceManagers());
83 107 : CHK_RET(CreateLoopChannels());
84 107 : CHK_RET(ConfigMsIdToken());
85 107 : initFlag_ = true;
86 107 : return HcclResult::HCCL_SUCCESS;
87 189 : }
88 :
89 393 : HcclResult CcuComponent::Deinit()
90 : {
91 393 : std::lock_guard<std::mutex> _lock(innerMutex_);
92 393 : CHK_RET(ReleaseJettyRes());
93 :
94 390 : loopFeCommAddrMap_.clear();
95 390 : ccuRmaBufferMap_.clear();
96 :
97 1170 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
98 780 : channelCtxMgrs_[dieId] = nullptr;
99 780 : resAllocators_[dieId] = nullptr;
100 780 : loopChannelIds_[dieId] = INVAILD_LOOP_CHANNEL_ID;
101 : }
102 :
103 390 : initFlag_ = false;
104 390 : return HcclResult::HCCL_SUCCESS;
105 393 : }
106 :
107 207 : CcuComponent::~CcuComponent() { (void)Deinit(); }
108 :
109 108 : static std::array<bool, CCU_MAX_IODIE_NUM> GetDieDrvEnableFlags(const int32_t devLogicId)
110 : {
111 : // 根据资源规格的记录驱动可用的die
112 108 : std::array<bool, CCU_MAX_IODIE_NUM> dieDrvEnableFlags{false, false};
113 108 : const auto& ccuResSpecs = CcuResSpecifications::GetInstance(devLogicId);
114 324 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
115 216 : (void)ccuResSpecs.GetDieEnableFlag(dieId, dieDrvEnableFlags[dieId]);
116 216 : if (!dieDrvEnableFlags[dieId]) { // 调用接口失败时不会改变dieEnableFlags[i]
117 2 : HCCL_WARNING(
118 : "[CcuComponent][%s] devLogicId[%d], dieId[%u] driver is not usable.", __func__, devLogicId, dieId);
119 : }
120 : }
121 :
122 108 : return dieDrvEnableFlags;
123 : }
124 :
125 108 : HcclResult CcuComponent::CheckDiesEnable()
126 : {
127 108 : ccuVersion_ = CcuResSpecifications::GetInstance(devLogicId_).GetCcuVersion();
128 108 : HCCL_INFO(
129 : "[CcuComponent][%s] ccu version[%s], devLogicId[%d].", __func__, ccuVersion_.Describe().c_str(), devLogicId_);
130 :
131 108 : const auto& dieDrvEnableFlags = GetDieDrvEnableFlags(devLogicId_);
132 : // 内部检查驱动可用的die上是否配置eid,内部更新die是否可用的标记
133 108 : CHK_RET(ChooseLoopEids(dieDrvEnableFlags));
134 :
135 108 : bool allDieDisable = true;
136 324 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
137 216 : allDieDisable = allDieDisable && !dieEnableFlags_[dieId];
138 : }
139 :
140 108 : if (allDieDisable) {
141 1 : HCCL_ERROR(
142 : "[CcuComponent][%s] failed, because all dies are "
143 : "disabled, devLogicId[%d].",
144 : __func__, devLogicId_);
145 1 : return HcclResult::HCCL_E_UNAVAIL;
146 : }
147 :
148 107 : return HcclResult::HCCL_SUCCESS;
149 : }
150 :
151 214 : static HcclResult FindOneUsableEid(
152 : const int32_t devLogicId, const uint32_t devPhyId, const uint8_t dieId, uint32_t& feId, CommAddr& commAddr)
153 : {
154 : // 如果无法查询设备是否为uboe设备,报错退出
155 214 : CHK_RET(HccpGetUboeFlagEnable(devPhyId));
156 :
157 214 : std::vector<DevEidInfo> eidInfos;
158 214 : auto ret = EidInfoMgr::GetInstance(devPhyId).GetEidInfos(eidInfos);
159 214 : CHK_PRT_RET(
160 : ret != HCCL_SUCCESS,
161 : HCCL_WARNING("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId), ret);
162 :
163 214 : std::string name;
164 214 : bool findFlag = false;
165 : // 当前结论,除仅包含UBOE的FE外
166 : // 其他eid均支持源与目标eid一致时应用环回
167 : // 故当前版本选择首个可用eid即可
168 : EXCEPTION_HANDLE_BEGIN
169 214 : auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
170 856 : for (auto& eidInfo : eidInfos) {
171 : // 如果是UBOE设备或非本die,则跳过
172 642 : if (HccpCheckUboeSupported(eidInfo.devFeature) || (eidInfo.dieId != dieId)) {
173 423 : continue;
174 : }
175 :
176 321 : Hccl::IpAddress ipAddr{};
177 321 : CHK_RET(CommAddrToIpAddress(eidInfo.commAddr, ipAddr));
178 321 : const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
179 321 : CHK_PTR_NULL(rdmaHandle);
180 321 : const bool rtpEnable = rdmaHandleMgr.GetRtpEnable(rdmaHandle);
181 321 : if (!rtpEnable) {
182 : // 遍历端口可能较多,避免刷屏不打印
183 102 : continue;
184 : }
185 :
186 219 : feId = eidInfo.funcId;
187 219 : commAddr = eidInfo.commAddr;
188 219 : name = eidInfo.name;
189 219 : findFlag = true;
190 : }
191 0 : EXCEPTION_HANDLE_END
192 :
193 214 : if (!findFlag) {
194 0 : HCCL_WARNING(
195 : "[CcuComponent][%s] dieId[%u] doesn't have usable func ID, "
196 : "devLogicId[%d].",
197 : __func__, dieId, devLogicId);
198 0 : return HcclResult::HCCL_E_INTERNAL;
199 : }
200 :
201 214 : Hccl::IpAddress ipAddr{};
202 214 : CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
203 214 : HCCL_INFO(
204 : "[CcuComponent][%s] dieId[%u] choose: name[%s] feId[%u] ipAddr[%s], "
205 : "devLogicId[%d].",
206 : __func__, dieId, name.c_str(), feId, ipAddr.Describe().c_str(), devLogicId);
207 :
208 214 : return HcclResult::HCCL_SUCCESS;
209 214 : }
210 :
211 108 : HcclResult CcuComponent::ChooseLoopEids(const std::array<bool, CCU_MAX_IODIE_NUM>& dieDrvEnableFlags)
212 : {
213 324 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
214 216 : if (!dieDrvEnableFlags[dieId]) {
215 2 : dieEnableFlags_[dieId] = false;
216 2 : continue;
217 : }
218 :
219 214 : uint32_t feId = 0;
220 214 : CommAddr commAddr{};
221 214 : if (FindOneUsableEid(devLogicId_, devPhyId_, dieId, feId, commAddr) != HcclResult::HCCL_SUCCESS) {
222 0 : dieEnableFlags_[dieId] = false;
223 0 : HCCL_WARNING(
224 : "[CcuComponent][%s] failed to find feId eid, but passed, "
225 : "devLogicId[%d], dieId[%u].",
226 : __func__, devLogicId_, dieId);
227 0 : continue;
228 : }
229 :
230 214 : loopFeCommAddrMap_[dieId] = {feId, commAddr};
231 214 : dieEnableFlags_[dieId] = true;
232 214 : HCCL_RUN_INFO("[CcuComponent][%s] devLogicId[%d] die[%u] is usable.", __func__, devLogicId_, dieId);
233 : }
234 108 : return HcclResult::HCCL_SUCCESS;
235 : }
236 :
237 428 : HcclResult CcuComponent::GetLoopFeIpByDieId(const uint8_t dieId, uint32_t& feId, CommAddr& commAddr)
238 : {
239 428 : const auto& dieIter = loopFeCommAddrMap_.find(dieId);
240 428 : CHK_PRT_RET(
241 : dieIter == loopFeCommAddrMap_.end(),
242 : HCCL_WARNING(
243 : "[CcuComponent][%s] failed but passed, "
244 : "dieId[%u] doesn't have usable loop feId, devLogicId[%d].",
245 : __func__, dieId, devLogicId_),
246 : HcclResult::HCCL_E_NOT_FOUND);
247 :
248 428 : const auto& feIdCommAddr = dieIter->second;
249 428 : feId = feIdCommAddr.first;
250 428 : commAddr = feIdCommAddr.second;
251 :
252 428 : return HcclResult::HCCL_SUCCESS;
253 : }
254 :
255 107 : HcclResult CcuComponent::CreateCcuRmaBuffer()
256 : {
257 107 : auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
258 107 : auto& ccuResSpecs = CcuResSpecifications::GetInstance(devLogicId_);
259 321 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
260 214 : if (!dieEnableFlags_[dieId]) {
261 0 : continue;
262 : }
263 :
264 214 : uint32_t feId = 0;
265 214 : CommAddr commAddr{};
266 214 : if (GetLoopFeIpByDieId(dieId, feId, commAddr) != HcclResult::HCCL_SUCCESS) {
267 0 : continue;
268 : }
269 :
270 214 : uint64_t ccuResAddr = 0;
271 214 : (void)ccuResSpecs.GetResourceAddr(dieId, ccuResAddr);
272 214 : if (ccuResAddr == 0) {
273 0 : HCCL_WARNING(
274 : "[CcuComponent][%s] failed, ccu resource space address[0] is invalid, "
275 : "devLogicId[%d] dieId[%u]",
276 : __func__, devLogicId_, dieId);
277 0 : continue;
278 : }
279 :
280 : // 申请rdmaHandle可能抛异常
281 : EXCEPTION_HANDLE_BEGIN
282 214 : Hccl::IpAddress ipAddr{};
283 214 : CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
284 214 : const CtxHandle ctxHandle = static_cast<CtxHandle>(rdmaHandleMgr.GetByIp(devPhyId_, ipAddr));
285 214 : CHK_PTR_NULL(ctxHandle);
286 214 : const auto ccuBuffer = std::make_shared<Hccl::Buffer>(ccuResAddr, CCU_RESOURCE_SIZE);
287 214 : ccuRmaBufferMap_.emplace(dieId, std::make_unique<Hccl::LocalUbRmaBuffer>(ccuBuffer, ctxHandle));
288 :
289 214 : EXCEPTION_HANDLE_END
290 : }
291 :
292 107 : return HcclResult::HCCL_SUCCESS;
293 : }
294 :
295 214 : static HcclResult CreateChannelCtxMgrByVersion(
296 : const CcuVersion version, const uint32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId,
297 : std::unique_ptr<CcuChannelCtxMgr>& channelCtxMgr)
298 : {
299 214 : switch (version) {
300 176 : case CcuVersion::CCU_V1:
301 176 : channelCtxMgr.reset(new (std::nothrow) CcuChannelCtxMgrV1(devLogicId, dieId, devPhyId));
302 176 : break;
303 38 : case CcuVersion::CCU_V2:
304 38 : channelCtxMgr.reset(new (std::nothrow) CcuChannelCtxMgrV2(devLogicId, dieId, devPhyId));
305 38 : break;
306 0 : default:
307 0 : HCCL_ERROR(
308 : "[CcuComponent][%s] failed, ccu driver version[%s] is not expected, "
309 : "devLogicId[%d] dieId[%u].",
310 : __func__, version.Describe().c_str(), devLogicId, dieId);
311 0 : return HcclResult::HCCL_E_NOT_SUPPORT;
312 : }
313 214 : CHK_PTR_NULL(channelCtxMgr);
314 214 : return HcclResult::HCCL_SUCCESS;
315 : }
316 :
317 107 : HcclResult CcuComponent::CreateResourceManagers()
318 : {
319 321 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
320 214 : if (!dieEnableFlags_[dieId]) {
321 0 : continue;
322 : }
323 :
324 214 : std::unique_ptr<CcuChannelCtxMgr> channelCtxMgrPtr = nullptr;
325 214 : CHK_RET(CreateChannelCtxMgrByVersion(ccuVersion_, devLogicId_, dieId, devPhyId_, channelCtxMgrPtr));
326 214 : CHK_RET(channelCtxMgrPtr->Init());
327 :
328 214 : std::unique_ptr<CcuResAllocator> resAllocatorPtr = nullptr;
329 214 : resAllocatorPtr.reset(new (std::nothrow) CcuResAllocator(devLogicId_, dieId));
330 214 : CHK_PTR_NULL(resAllocatorPtr);
331 214 : CHK_RET(resAllocatorPtr->Init());
332 :
333 214 : channelCtxMgrs_[dieId] = std::move(channelCtxMgrPtr);
334 214 : resAllocators_[dieId] = std::move(resAllocatorPtr);
335 214 : }
336 107 : return HcclResult::HCCL_SUCCESS;
337 : }
338 :
339 107 : HcclResult CcuComponent::CreateLoopChannels()
340 : {
341 321 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
342 214 : loopChannelIds_[dieId] = INVAILD_LOOP_CHANNEL_ID;
343 : // 失败抛异常处理,jetty资源跟随数据结构析构释放
344 214 : auto ret = CreateLoopChannel(dieId, loopChannelIds_[dieId]);
345 214 : CHK_PRT_RET(
346 : ret, HCCL_ERROR("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].", __func__, devLogicId_, dieId),
347 : ret);
348 :
349 214 : if (loopChannelIds_[dieId] == INVAILD_LOOP_CHANNEL_ID) {
350 0 : HCCL_RUN_WARNING(
351 : "[CcuComponent][%s] failed but passed, loop channel id[%u], "
352 : "devLogicId[%d], dieId[%u].",
353 : __func__, loopChannelIds_[dieId], devLogicId_, dieId);
354 0 : continue;
355 : }
356 :
357 214 : HCCL_RUN_INFO(
358 : "[CcuComponent][%s] succeed, loop channel id[%u], "
359 : "devLogicId[%d], dieId[%u].",
360 : __func__, loopChannelIds_[dieId], devLogicId_, dieId);
361 : }
362 :
363 107 : return HcclResult::HCCL_SUCCESS;
364 : }
365 :
366 214 : HcclResult CcuComponent::CreateLoopChannel(const uint8_t dieId, uint32_t& channelId)
367 : {
368 214 : if (!dieEnableFlags_[dieId]) {
369 0 : HCCL_WARNING(
370 : "[CcuComponent][%s] passed, dieId[%u] is not enabled, "
371 : "devLogicId[%d].",
372 : __func__, dieId, devLogicId_);
373 0 : return HcclResult::HCCL_SUCCESS;
374 : }
375 :
376 : // 对于单p或单die场景,可能设备或die不会配置eid,按成功处理不阻塞用例
377 214 : uint32_t feId = 0;
378 214 : CommAddr commAddr{};
379 214 : if (GetLoopFeIpByDieId(dieId, feId, commAddr) != HcclResult::HCCL_SUCCESS) {
380 0 : channelId = INVAILD_LOOP_CHANNEL_ID;
381 0 : HCCL_WARNING(
382 : "[CcuComponent][%s] failed but passed, dieId[%u] doesn't have loop feId, "
383 : "devLogicId[%d].",
384 : __func__, dieId, devLogicId_);
385 0 : return HcclResult::HCCL_SUCCESS;
386 : }
387 : const uint32_t loopChannelSqsize
388 214 : = (ccuVersion_ == CcuVersion::CCU_V1 ? LOOP_CHANNEL_USE_SQSIZE_V1 : LOOP_CHANNEL_USE_SQSIZE_V2);
389 214 : std::vector<ChannelInfo> channelInfos; // 按jetty组分配
390 214 : const ChannelPara channelPara{feId, LOOP_CHANNEL_USE_JETTY, loopChannelSqsize};
391 214 : auto ret = channelCtxMgrs_[dieId]->Alloc(channelPara, channelInfos);
392 214 : CHK_PRT_RET(
393 : ret != HCCL_SUCCESS,
394 : HCCL_WARNING(
395 : "[CcuComponent][%s] failed to alloc channel, "
396 : "devLogicId[%d], dieId[%u].",
397 : __func__, devLogicId_, dieId),
398 : ret);
399 :
400 214 : const auto& channelInfo = channelInfos[0]; // 环回只使用1个channel
401 214 : ret = CreateAndImportLoopJettys(dieId, commAddr, channelInfo.jettyInfos);
402 214 : CHK_PRT_RET(
403 : ret != HCCL_SUCCESS,
404 : HCCL_WARNING(
405 : "[CcuComponent][%s] failed to create or import loop jettys, "
406 : "devLogicId[%d], dieId[%u].",
407 : __func__, devLogicId_, dieId),
408 : ret);
409 :
410 214 : ret = ConfigLoopChannel(dieId, commAddr, channelInfo);
411 214 : CHK_PRT_RET(
412 : ret != HCCL_SUCCESS,
413 : HCCL_WARNING(
414 : "[CcuComponent][%s] failed to config the loop channel, "
415 : "devLogicId[%d], dieId[%u].",
416 : __func__, devLogicId_, dieId),
417 : ret);
418 :
419 214 : channelId = channelInfo.channelId;
420 214 : return HcclResult::HCCL_SUCCESS;
421 214 : }
422 :
423 216 : JettyImportCfg GetJettyImportCfg(const TpInfo& tpInfo, const uint32_t& psn)
424 : {
425 216 : const TpHandle tpHandle = tpInfo.tpHandle;
426 216 : HCCL_INFO("[CcuComponent][%s] loop channel use tp handle[%llu] psn[%u].", __func__, tpHandle, psn);
427 :
428 216 : JettyImportCfg cfg = {};
429 216 : cfg.localTpHandle = tpHandle;
430 216 : cfg.remoteTpHandle = tpHandle;
431 216 : cfg.localPsn = psn;
432 216 : cfg.remotePsn = psn;
433 216 : cfg.protocol = LOOP_JETTY_PROTOCOL;
434 216 : return cfg;
435 : }
436 :
437 216 : HcclResult CcuComponent::CreateAndImportLoopJettys(
438 : const uint8_t dieId, const CommAddr& commAddr, const std::vector<JettyInfo>& jettyInfos)
439 : {
440 216 : Hccl::IpAddress ipAddr{};
441 216 : CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
442 :
443 216 : Hccl::CqCreateInfo cqInfo{};
444 216 : auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
445 216 : const auto ctxHandle = static_cast<CtxHandle>(rdmaHandleMgr.GetByIp(devPhyId_, ipAddr));
446 216 : const auto _jfcHandle = rdmaHandleMgr.GetJfcHandle(ctxHandle, cqInfo, Hccl::HrtUbJfcMode::CCU_POLL);
447 216 : const JfcHandle jfcHandle = reinterpret_cast<JfcHandle>(_jfcHandle);
448 :
449 216 : const auto& rmaBufferIter = ccuRmaBufferMap_.find(dieId);
450 216 : CHK_PRT_RET(
451 : rmaBufferIter == ccuRmaBufferMap_.end(),
452 : HCCL_RUN_WARNING(
453 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
454 : "devLogicId[%d].",
455 : __func__, dieId, devLogicId_),
456 : HcclResult::HCCL_E_NOT_FOUND);
457 :
458 216 : const auto& ccuRmaBuffer = rmaBufferIter->second;
459 216 : const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
460 :
461 216 : auto& createdVec = createdOutParamMap_[dieId];
462 216 : auto& importedVec = importedOutParamMap_[dieId];
463 :
464 216 : TpInfo loopTpInfo{};
465 216 : CHK_RET(GetLoopTpInfo(dieId, commAddr, loopTpInfo));
466 216 : const uint32_t loopJettyQos
467 216 : = loopTpInfo.hasMappedJettyPriority ? (loopTpInfo.mappedJettyPriority & 0xFU) : EnvConfig::UB_QOS_DEFAULT;
468 :
469 216 : uint8_t errTimeout = 0;
470 216 : CHK_RET(GetLoopJettyTimeout(dieId, commAddr, errTimeout));
471 :
472 432 : for (const auto& jettyInfo : jettyInfos) {
473 216 : const auto jettyMode = jettyInfo.jettyType == CcuJettyType::CCUM_CACHED_JETTY ? HrtJettyMode::CCU_CCUM_CACHE :
474 216 : HrtJettyMode::CCU_TA_CACHE;
475 : HrtRaUbCreateJettyParam req{jfcHandle, jfcHandle, ccuBufTokenValue,
476 216 : nullptr, jettyMode, jettyInfo.taJettyId,
477 216 : jettyInfo.sqBufVa, jettyInfo.sqBufSize, jettyInfo.wqeBBStartId,
478 216 : jettyInfo.sqDepth, errTimeout};
479 216 : req.qos = loopJettyQos;
480 :
481 216 : HrtRaUbJettyCreatedOutParam createdOutParam{};
482 216 : CHK_RET(HccpUbCreateJetty(ctxHandle, req, createdOutParam));
483 216 : createdVec.emplace_back(createdOutParam);
484 :
485 216 : const auto psn = GetNewPsn();
486 216 : const auto& jettyImportCfg = GetJettyImportCfg(loopTpInfo, psn);
487 :
488 216 : HrtRaUbJettyImportedOutParam importedOutParam{};
489 216 : CHK_RET(HccpUbTpImportJetty(
490 : ctxHandle, createdOutParam.key, createdOutParam.keySize, ccuBufTokenValue, jettyImportCfg,
491 : importedOutParam));
492 216 : importedVec.emplace_back(std::make_pair(ctxHandle, importedOutParam));
493 : }
494 :
495 216 : return HcclResult::HCCL_SUCCESS;
496 : }
497 :
498 429 : static GetTpInfoParam MakeLoopGetTpInfoParam(const CommAddr& commAddr)
499 : {
500 429 : GetTpInfoParam param;
501 429 : param.locAddr = commAddr;
502 429 : param.rmtAddr = commAddr;
503 429 : param.tpProtocol = LOOP_JETTY_PROTOCOL;
504 429 : param.qos = 0U; // CCU 环回与通信域 hcclQos 解耦;SL 仅由 RaGetTpAttr.slBitmap + loopFirstTpLowestSl 决定
505 429 : param.slLevelCount = 0;
506 429 : param.loopFirstTpLowestSl = true;
507 429 : param.ccuLoopbackGetTpInfo = true;
508 429 : return param;
509 : }
510 :
511 215 : static HcclResult RequestNewLoopTpInfo(const uint32_t devPhyId, const CommAddr& commAddr, TpInfo& tpInfo)
512 : {
513 215 : constexpr auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
514 215 : const auto startTime = std::chrono::steady_clock::now();
515 :
516 215 : auto& tpMgr = TpMgr::GetInstance(devPhyId);
517 215 : const GetTpInfoParam& tpParam = MakeLoopGetTpInfoParam(commAddr);
518 215 : HcclResult ret = HcclResult::HCCL_SUCCESS;
519 : do {
520 639 : if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
521 0 : HCCL_ERROR(
522 : "[CcuComponent][%s] failed, get tp info "
523 : "timeout[%d ms], devPhyId[%u].",
524 : __func__, timeout, devPhyId);
525 0 : return HcclResult::HCCL_E_TIMEOUT;
526 : }
527 :
528 639 : ret = tpMgr.GetTpInfo(tpParam, tpInfo);
529 639 : } while (ret == HcclResult::HCCL_E_AGAIN);
530 :
531 215 : CHK_RET(ret); // 非重试属于异常情况
532 215 : return HcclResult::HCCL_SUCCESS;
533 : }
534 :
535 217 : HcclResult CcuComponent::GetLoopTpInfo(const uint8_t dieId, const CommAddr& commAddr, TpInfo& tpInfo)
536 : {
537 217 : const auto& srcIter = tpInfoMap_.find(dieId);
538 : // 优先使用已经创建过的tpHandle
539 217 : if (srcIter == tpInfoMap_.end()) {
540 215 : TpInfo newTpInfo{};
541 215 : CHK_RET(RequestNewLoopTpInfo(devPhyId_, commAddr, newTpInfo));
542 215 : tpInfoMap_[dieId] = std::move(newTpInfo);
543 : }
544 :
545 217 : tpInfo = tpInfoMap_[dieId];
546 217 : return HcclResult::HCCL_SUCCESS;
547 : }
548 :
549 : static HcclResult
550 214 : RequestNewLoopTpAttr(const uint32_t devPhyId, CtxHandle ctxHandle, const TpHandle tpHandle, TpAttrInfo& tpAttrInfo)
551 : {
552 214 : constexpr auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
553 214 : const auto startTime = std::chrono::steady_clock::now();
554 :
555 214 : auto& tpMgr = TpMgr::GetInstance(devPhyId);
556 214 : constexpr uint32_t kTpAttrRetryTimesInitBit = 0U;
557 214 : constexpr uint32_t kTpAttrAtBit = 1U;
558 214 : constexpr uint32_t TP_ATTR_BITMAP = (1U << kTpAttrRetryTimesInitBit) | (1U << kTpAttrAtBit);
559 214 : const GetTpAttrParam tpAttrParam = {tpHandle, TP_ATTR_BITMAP};
560 214 : HcclResult ret = HcclResult::HCCL_SUCCESS;
561 : do {
562 320 : if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
563 0 : HCCL_ERROR(
564 : "[CcuComponent][%s] failed, get tp attr "
565 : "timeout[%d ms], devPhyId[%d].",
566 : __func__, timeout, devPhyId);
567 0 : return HcclResult::HCCL_E_TIMEOUT;
568 : }
569 :
570 320 : ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, ctxHandle);
571 320 : } while (ret == HcclResult::HCCL_E_AGAIN);
572 :
573 214 : CHK_RET(ret);
574 214 : return HcclResult::HCCL_SUCCESS;
575 : }
576 :
577 218 : HcclResult CcuComponent::GetLoopTpAttr(const uint8_t dieId, const CommAddr& commAddr, TpAttrInfo& tpAttrInfo)
578 : {
579 218 : const auto& srcIter = tpAttrInfoMap_.find(dieId);
580 218 : if (srcIter == tpAttrInfoMap_.end()) {
581 215 : const auto& tpInfoIter = tpInfoMap_.find(dieId);
582 215 : CHK_PRT_RET(
583 : tpInfoIter == tpInfoMap_.end(),
584 : HCCL_ERROR(
585 : "[CcuComponent][%s] failed, tpInfo not found for dieId[%u], "
586 : "devLogicId[%d].",
587 : __func__, dieId, devLogicId_),
588 : HcclResult::HCCL_E_NOT_FOUND);
589 :
590 214 : Hccl::IpAddress ipAddr{};
591 214 : CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
592 214 : auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
593 214 : const CtxHandle ctxHandle = static_cast<CtxHandle>(rdmaHandleMgr.GetByIp(devPhyId_, ipAddr));
594 :
595 214 : TpAttrInfo newTpAttrInfo{};
596 214 : CHK_RET(RequestNewLoopTpAttr(devPhyId_, ctxHandle, tpInfoIter->second.tpHandle, newTpAttrInfo));
597 214 : tpAttrInfoMap_[dieId] = std::move(newTpAttrInfo);
598 : }
599 :
600 217 : tpAttrInfo = tpAttrInfoMap_[dieId];
601 217 : return HcclResult::HCCL_SUCCESS;
602 : }
603 :
604 216 : HcclResult CcuComponent::GetLoopJettyTimeout(const uint8_t dieId, const CommAddr& commAddr, uint8_t& errTimeout)
605 : {
606 216 : TpAttrInfo tpAttrInfo{};
607 216 : CHK_RET(GetLoopTpAttr(dieId, commAddr, tpAttrInfo));
608 : // CTP 协议不感知 TP 建链,跳过 GetTpTotalTimeout(对齐 DevUbConnection::GetTimeOut 的 CTP 分支),
609 : // tpTimeOutMs 保持 0,由 TpManager::CalcTaTimeout 内部按 CTP 规则直接使用 taTimeOut_
610 216 : uint32_t tpTimeOutMs = 0;
611 216 : if (LOOP_JETTY_PROTOCOL != TpProtocol::CTP) {
612 216 : CHK_RET(TpMgr::GetTpTotalTimeout(tpAttrInfo, tpTimeOutMs));
613 : }
614 216 : errTimeout = TpMgr::CalcTaTimeout(LOOP_JETTY_PROTOCOL, TpMgr::TA_TIMEOUT_NOT_SET, tpTimeOutMs);
615 216 : return HcclResult::HCCL_SUCCESS;
616 : }
617 :
618 216 : inline uint32_t GenerateRandomNum()
619 : {
620 216 : uint32_t randNum = std::rand();
621 216 : return randNum;
622 : }
623 :
624 216 : uint32_t CcuComponent::GetNewPsn() const { return GenerateRandomNum(); }
625 :
626 : HcclResult
627 214 : CcuComponent::ConfigLoopChannel(const uint8_t dieId, const CommAddr& commAddr, const ChannelInfo& channelInfo)
628 : {
629 214 : const uint32_t dstDieId = 1 - dieId; // 当前仅存在最多两个die
630 : // 当前环回复用支持die内die间,当两个die均启用时应配置对die,否则为本die
631 214 : auto rmaBufferIter = ccuRmaBufferMap_.find(dstDieId);
632 214 : if (rmaBufferIter == ccuRmaBufferMap_.end()) {
633 0 : rmaBufferIter = ccuRmaBufferMap_.find(dieId);
634 : }
635 :
636 214 : CHK_PRT_RET(
637 : rmaBufferIter == ccuRmaBufferMap_.end(),
638 : HCCL_WARNING(
639 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
640 : "devLogicId[%d].",
641 : __func__, dieId, devLogicId_),
642 : HcclResult::HCCL_E_NOT_FOUND);
643 :
644 214 : const auto& ccuRmaBuffer = rmaBufferIter->second;
645 214 : const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
646 :
647 214 : Hccl::IpAddress ipAddr{};
648 214 : CHK_RET(CommAddrToIpAddress(commAddr, ipAddr));
649 :
650 214 : ChannelCfg cfg{};
651 214 : cfg.channelId = channelInfo.channelId;
652 214 : CHK_RET(IpAddressToReverseHcclEid(ipAddr, cfg.remoteEid));
653 214 : cfg.tpn = importedOutParamMap_[dieId][0].second.tpn; // 环回仅1个对端
654 214 : cfg.remoteCcuVa = ccuRmaBuffer->GetBuf()->GetAddr();
655 214 : cfg.memTokenId = ccuRmaBuffer->GetTokenId();
656 214 : cfg.memTokenValue = ccuBufTokenValue;
657 :
658 214 : const auto& jettyInfos = channelInfo.jettyInfos;
659 214 : const auto& createdVec = createdOutParamMap_[dieId];
660 214 : const uint32_t jettyNum = jettyInfos.size();
661 428 : for (uint32_t i = 0; i < jettyNum; i++) {
662 214 : cfg.jettyCfgs.emplace_back(
663 214 : JettyCfg{jettyInfos[i].jettyCtxId, createdVec[i].dbVa, createdVec[i].dbTokenId, ccuBufTokenValue});
664 : }
665 :
666 214 : return channelCtxMgrs_[dieId]->Config(cfg);
667 214 : }
668 :
669 107 : HcclResult CcuComponent::ConfigMsIdToken()
670 : {
671 107 : const auto serveMode = CcuResSpecifications::GetInstance(devLogicId_).GetServeMode();
672 107 : CustomChannelInfoIn inBuff{};
673 107 : CustomChannelInfoOut outBuff{};
674 321 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
675 214 : const auto& dieIter = ccuRmaBufferMap_.find(dieId);
676 214 : if (dieIter == ccuRmaBufferMap_.end()) {
677 0 : HCCL_WARNING(
678 : "[CcuComponent][%s] failed but passed, ccu rma buffer of die[%u] "
679 : "is not existed, devLogicId[%d].",
680 : __func__, dieId, devLogicId_);
681 0 : continue;
682 : }
683 214 : const auto& ccuRmaBuffer = dieIter->second;
684 214 : const uint32_t tokenId = ccuRmaBuffer->GetTokenId();
685 214 : const uint32_t tokenValue = ccuRmaBuffer->GetTokenValue();
686 214 : uint32_t msId = 0;
687 : // 非A+X, 非die 0,采用默认交织粒度
688 214 : if (serveMode == ServeMode::ARMX86 && dieId == 0) {
689 0 : msId = MSID_CONFIG_ARMX86_MAINBOARD;
690 : } else {
691 214 : CHK_RET(CcuResSpecifications::GetInstance(devLogicId_).GetMsId(dieId, msId));
692 : }
693 :
694 214 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_MSID_TOKEN;
695 214 : inBuff.offsetStartIdx = 0;
696 214 : inBuff.data.dataInfo.udieIdx = dieId;
697 214 : inBuff.data.dataInfo.dataArray[0].baseinfo.msId = msId;
698 214 : inBuff.data.dataInfo.dataArray[0].baseinfo.tokenId = tokenId;
699 214 : inBuff.data.dataInfo.dataArray[0].baseinfo.tokenValue = tokenValue;
700 :
701 214 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
702 214 : if (ret != HCCL_SUCCESS) {
703 0 : HCCL_ERROR(
704 : "[CcuComponent][%s] failed to call ccu driver, "
705 : "devLogicId[%d] dieId[%d] op[%s] ret[%d].",
706 : __func__, devLogicId_, dieId, "SET_MSID_TOKEN", ret);
707 0 : return ret;
708 : }
709 :
710 214 : HCCL_INFO("[CcuComponent][%s] config MS ID token success, dieId[%u], msid[%u]", __func__, dieId, msId);
711 : }
712 :
713 107 : return HcclResult::HCCL_SUCCESS;
714 : }
715 :
716 15 : HcclResult CcuComponent::GetCcuResourceSpaceBufInfo(const uint8_t dieId, uint64_t& addr, uint64_t& size) const
717 : {
718 15 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
719 :
720 15 : auto res = ccuRmaBufferMap_.find(dieId);
721 15 : CHK_PRT_RET(
722 : res == ccuRmaBufferMap_.end(),
723 : HCCL_WARNING(
724 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
725 : "devLogicId[%d].",
726 : __func__, dieId, devLogicId_),
727 : HcclResult::HCCL_E_NOT_FOUND);
728 :
729 15 : const auto rawBuffer = res->second->GetBuf();
730 15 : addr = static_cast<uint64_t>(rawBuffer->GetAddr());
731 15 : size = static_cast<uint64_t>(rawBuffer->GetSize());
732 15 : return HcclResult::HCCL_SUCCESS;
733 : }
734 :
735 : HcclResult
736 213 : CcuComponent::GetCcuResourceSpaceTokenInfo(const uint8_t dieId, uint64_t& tokenId, uint64_t& tokenValue) const
737 : {
738 213 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
739 :
740 213 : auto res = ccuRmaBufferMap_.find(dieId);
741 213 : CHK_PRT_RET(
742 : res == ccuRmaBufferMap_.end(),
743 : HCCL_WARNING(
744 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
745 : "devLogicId[%d].",
746 : __func__, dieId, devLogicId_),
747 : HcclResult::HCCL_E_NOT_FOUND);
748 :
749 213 : const auto& ccuRmaBuffer = res->second;
750 213 : tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
751 213 : tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
752 213 : return HcclResult::HCCL_SUCCESS;
753 : }
754 :
755 : HcclResult
756 15 : CcuComponent::AllocChannels(const uint8_t dieId, const ChannelPara& channelPara, std::vector<ChannelInfo>& channelInfos)
757 : {
758 15 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
759 :
760 15 : CHK_PTR_NULL(channelCtxMgrs_[dieId]);
761 15 : auto ret = channelCtxMgrs_[dieId]->Alloc(channelPara, channelInfos);
762 15 : CHK_PRT_RET(
763 : ret != HcclResult::HCCL_SUCCESS,
764 : HCCL_WARNING(
765 : "[CcuComponent][%s] failed, feId[%u], devLogicId[%d], dieId[%u].", __func__, channelPara.feId, devLogicId_,
766 : dieId),
767 : ret);
768 :
769 15 : return HcclResult::HCCL_SUCCESS;
770 : }
771 :
772 0 : HcclResult CcuComponent::ConfigChannel(const uint8_t dieId, const ChannelCfg& cfg)
773 : {
774 0 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
775 :
776 0 : uint32_t channelId = cfg.channelId;
777 0 : CHK_PRT_RET(
778 : channelId == loopChannelIds_[dieId],
779 : HCCL_WARNING(
780 : "[CcuComponent][%s] failed, refused to config loop channel[%u], "
781 : "devLogicId[%d], dieId[%u].",
782 : __func__, channelId, devLogicId_, dieId),
783 : HcclResult::HCCL_E_PARA);
784 :
785 0 : CHK_PTR_NULL(channelCtxMgrs_[dieId]);
786 0 : auto ret = channelCtxMgrs_[dieId]->Config(cfg);
787 0 : CHK_PRT_RET(
788 : ret != HcclResult::HCCL_SUCCESS,
789 : HCCL_WARNING(
790 : "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId_,
791 : dieId),
792 : ret);
793 :
794 0 : return HcclResult::HCCL_SUCCESS;
795 : }
796 :
797 29 : HcclResult CcuComponent::ReleaseChannel(const uint8_t dieId, const uint32_t channelId)
798 : {
799 29 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
800 29 : CHK_PRT_RET(
801 : channelId == loopChannelIds_[dieId],
802 : HCCL_WARNING(
803 : "[CcuComponent][%s] failed, refused to release loop channel[%u], "
804 : "devLogicId[%d], dieId[%u].",
805 : __func__, channelId, devLogicId_, dieId),
806 : HcclResult::HCCL_E_PARA);
807 :
808 29 : CHK_PTR_NULL(channelCtxMgrs_[dieId]);
809 29 : auto ret = channelCtxMgrs_[dieId]->Release(channelId);
810 29 : CHK_PRT_RET(
811 : ret != HcclResult::HCCL_SUCCESS,
812 : HCCL_WARNING(
813 : "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId_,
814 : dieId),
815 : ret);
816 :
817 29 : return HcclResult::HCCL_SUCCESS;
818 : }
819 :
820 396 : HcclResult CcuComponent::GetLoopChannelId(const uint8_t srcDieId, const uint8_t dstDieId, uint32_t& channelId) const
821 : {
822 396 : channelId = INVAILD_LOOP_CHANNEL_ID; // 允许die未启用时查询环回channelId
823 :
824 396 : CHK_RET(CheckDieValid(__func__, devLogicId_, srcDieId, {true, true}));
825 396 : CHK_RET(CheckDieValid(__func__, devLogicId_, dstDieId, {true, true}));
826 :
827 : // 特殊处理die未启用场景
828 396 : CHK_PRT_RET(
829 : !dieEnableFlags_[srcDieId] || !dieEnableFlags_[dstDieId],
830 : HCCL_WARNING(
831 : "[CcuComponent][%s] passed, srcDie[%u] or dstDie[%u] is not enable,"
832 : "devLogicId[%d].",
833 : __func__, srcDieId, dstDieId, devLogicId_),
834 : HcclResult::HCCL_SUCCESS);
835 :
836 : // 当前环回channel每个die占用1个,不区分die内die间
837 396 : CHK_PRT_RET(
838 : loopChannelIds_[srcDieId] == INVAILD_LOOP_CHANNEL_ID,
839 : HCCL_ERROR(
840 : "[CcuComponent][%s] failed, invalid loop channel id, "
841 : "devLogicId[%d], srcDieId[%u].",
842 : __func__, devLogicId_, srcDieId),
843 : HcclResult::HCCL_E_INTERNAL);
844 :
845 396 : channelId = loopChannelIds_[srcDieId];
846 396 : return HcclResult::HCCL_SUCCESS;
847 : }
848 :
849 1754 : HcclResult CcuComponent::AllocRes(
850 : const uint8_t dieId, const ResType resType, const uint32_t num, const bool consecutive,
851 : std::vector<ResInfo>& resInfos)
852 : {
853 1754 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
854 :
855 1754 : CHK_PTR_NULL(resAllocators_[dieId]);
856 1754 : auto ret = resAllocators_[dieId]->Alloc(resType, num, consecutive, resInfos);
857 1754 : CHK_PRT_RET(
858 : ret != HcclResult::HCCL_SUCCESS,
859 : HCCL_WARNING(
860 : "[CcuComponent][%s] failed, resType[%s], num[%u], devLogicId[%d], dieId[%u].", __func__,
861 : resType.Describe().c_str(), num, devLogicId_, dieId),
862 : ret);
863 :
864 1754 : return HcclResult::HCCL_SUCCESS;
865 : }
866 :
867 : HcclResult
868 0 : CcuComponent::ReleaseRes(const uint8_t dieId, const ResType resType, const uint32_t startId, const uint32_t num)
869 : {
870 0 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
871 :
872 0 : CHK_PTR_NULL(resAllocators_[dieId]);
873 0 : auto ret = resAllocators_[dieId]->Release(resType, startId, num);
874 0 : CHK_PRT_RET(
875 : ret != HcclResult::HCCL_SUCCESS,
876 : HCCL_WARNING(
877 : "[CcuComponent][%s] failed, resType[%s], startId[%u], num[%u], "
878 : "devLogicId[%d], dieId[%u].",
879 : __func__, resType.Describe().c_str(), startId, num, devLogicId_, dieId),
880 : ret);
881 :
882 0 : return HcclResult::HCCL_SUCCESS;
883 : }
884 :
885 0 : uint32_t CcuComponent::GetInsConsecutiveRemainSize(const uint8_t dieId) const
886 : {
887 0 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
888 0 : if (resAllocators_[dieId] == nullptr)
889 0 : return 0;
890 0 : return resAllocators_[dieId]->GetConsecutiveRemainSize(ResType::INS);
891 : }
892 :
893 47 : HcclResult CcuComponent::AllocIns(const uint8_t dieId, const uint32_t num, ResInfo& insInfo)
894 : {
895 47 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
896 :
897 47 : CHK_PTR_NULL(resAllocators_[dieId]);
898 47 : std::vector<ResInfo> resInfos;
899 47 : auto ret = resAllocators_[dieId]->Alloc(ResType::INS, num, true, resInfos);
900 47 : CHK_PRT_RET(
901 : ret != HcclResult::HCCL_SUCCESS,
902 : HCCL_WARNING(
903 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId_, dieId),
904 : ret);
905 :
906 47 : insInfo = resInfos[0]; // 申请连续资源只会有一份
907 47 : return HcclResult::HCCL_SUCCESS;
908 47 : }
909 :
910 47 : HcclResult CcuComponent::ReleaseIns(const uint8_t dieId, const ResInfo& insInfo)
911 : {
912 47 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
913 :
914 47 : CHK_PTR_NULL(resAllocators_[dieId]);
915 47 : auto ret = resAllocators_[dieId]->Release(ResType::INS, insInfo.startId, insInfo.num);
916 47 : CHK_PRT_RET(
917 : ret != HcclResult::HCCL_SUCCESS,
918 : HCCL_WARNING(
919 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__, insInfo.Describe().c_str(),
920 : devLogicId_, dieId),
921 : ret);
922 :
923 47 : return HcclResult::HCCL_SUCCESS;
924 : }
925 :
926 15 : HcclResult CcuComponent::AllocCke(const uint8_t dieId, const uint32_t num, std::vector<ResInfo>& ckeInfos)
927 : {
928 15 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
929 :
930 15 : CHK_PTR_NULL(resAllocators_[dieId]);
931 15 : auto ret = resAllocators_[dieId]->Alloc(ResType::CKE, num, false, ckeInfos);
932 15 : CHK_PRT_RET(
933 : ret != HcclResult::HCCL_SUCCESS,
934 : HCCL_WARNING(
935 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId_, dieId),
936 : ret);
937 :
938 15 : return HcclResult::HCCL_SUCCESS;
939 : }
940 :
941 15 : HcclResult CcuComponent::ReleaseCke(const uint8_t dieId, const std::vector<ResInfo>& ckeInfos)
942 : {
943 15 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
944 :
945 15 : CHK_PTR_NULL(resAllocators_[dieId]);
946 30 : for (auto& ckeInfo : ckeInfos) {
947 15 : auto ret = resAllocators_[dieId]->Release(ResType::CKE, ckeInfo.startId, ckeInfo.num);
948 15 : CHK_PRT_RET(
949 : ret != HcclResult::HCCL_SUCCESS,
950 : HCCL_WARNING(
951 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
952 : ckeInfo.Describe().c_str(), devLogicId_, dieId),
953 : ret);
954 : }
955 :
956 15 : return HcclResult::HCCL_SUCCESS;
957 : }
958 :
959 15 : HcclResult CcuComponent::AllocXn(const uint8_t dieId, const uint32_t num, std::vector<ResInfo>& xnInfos)
960 : {
961 15 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
962 :
963 15 : CHK_PTR_NULL(resAllocators_[dieId]);
964 15 : auto ret = resAllocators_[dieId]->Alloc(ResType::XN, num, false, xnInfos);
965 15 : CHK_PRT_RET(
966 : ret != HcclResult::HCCL_SUCCESS,
967 : HCCL_WARNING(
968 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId_, dieId),
969 : ret);
970 :
971 15 : return HcclResult::HCCL_SUCCESS;
972 : }
973 :
974 15 : HcclResult CcuComponent::ReleaseXn(const uint8_t dieId, const std::vector<ResInfo>& xnInfos)
975 : {
976 15 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
977 :
978 15 : CHK_PTR_NULL(resAllocators_[dieId]);
979 30 : for (auto& xnInfo : xnInfos) {
980 15 : auto ret = resAllocators_[dieId]->Release(ResType::XN, xnInfo.startId, xnInfo.num);
981 15 : CHK_PRT_RET(
982 : ret != HcclResult::HCCL_SUCCESS,
983 : HCCL_WARNING(
984 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
985 : xnInfo.Describe().c_str(), devLogicId_, dieId),
986 : ret);
987 : }
988 :
989 15 : return HcclResult::HCCL_SUCCESS;
990 : }
991 :
992 : constexpr u32 WISH_COUNT_XN_NUM = 511;
993 : constexpr u32 TOTAL_COUNT_XN_NUM = 1;
994 :
995 0 : HcclResult CcuComponent::SetSplitUnit(uint8_t dieId, uint32_t splitPktUnit) const
996 : {
997 0 : CHK_PRT_RET(
998 : dieId >= MAX_CCU_IODIE_NUM,
999 : HCCL_ERROR(
1000 : "[CcuComponent][%s] failed, dieId[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, dieId,
1001 : MAX_CCU_IODIE_NUM, devLogicId_),
1002 : HcclResult::HCCL_E_PARA);
1003 :
1004 0 : CustomChannelInfoIn inBuff{};
1005 0 : CustomChannelInfoOut outBuff{};
1006 :
1007 0 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_TIF_SPLIT_SIZE;
1008 0 : inBuff.data.dataInfo.udieIdx = dieId;
1009 0 : inBuff.data.dataInfo.dataArraySize = 1;
1010 0 : inBuff.data.dataInfo.dataLen = sizeof(CcuDataTypeUnion) * inBuff.data.dataInfo.dataArraySize;
1011 :
1012 0 : inBuff.data.dataInfo.dataArray[0].tifSplitSize.splitPktUnit = splitPktUnit & 0b1;
1013 0 : inBuff.data.dataInfo.dataArray[0].tifSplitSize.tpSplitSize = 0x2; // 0x2:TP模式的拆包size为4KB
1014 0 : inBuff.data.dataInfo.dataArray[0].tifSplitSize.ctpSplitSize = 0x1; // 0x1:CTP模式的拆包size为4KB
1015 :
1016 0 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
1017 0 : if (ret != 0) {
1018 0 : HCCL_ERROR(
1019 : "[CcuComponent][%s] failed to call ccu driver, "
1020 : "devPhyId[%u] dieId[%d] op[%s].",
1021 : __func__, devPhyId_, dieId, "CCU_U_OP_SET_TIF_SPLIT_SIZE");
1022 0 : return HcclResult::HCCL_E_NETWORK;
1023 : }
1024 0 : return HcclResult::HCCL_SUCCESS;
1025 : }
1026 :
1027 0 : HcclResult CcuComponent::GetAvailableTotalCntXnIndex(uint32_t& index) const
1028 : {
1029 0 : for (uint32_t i = 0; i < CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM; ++i) {
1030 0 : if (!usedTotalCntXnFlags_[i]) {
1031 0 : index = i;
1032 0 : return HcclResult::HCCL_SUCCESS;
1033 : }
1034 : }
1035 :
1036 0 : HCCL_ERROR("[CcuComponent][%s] failed, no available TotalCnt Xns.", __func__);
1037 0 : return HcclResult::HCCL_E_UNAVAIL;
1038 : }
1039 :
1040 0 : HcclResult CcuComponent::SetTotalCntXn(uint8_t dieId, uint32_t fromId, uint32_t toId, uint32_t totalId, uint32_t index)
1041 : {
1042 0 : CHK_PRT_RET(
1043 : fromId > toId,
1044 : HCCL_ERROR("[CcuComponent][%s] failed, fromId or toId invalid, fromId[%u] > toId[%u].", __func__, fromId, toId),
1045 : HcclResult::HCCL_E_PARA);
1046 :
1047 0 : CHK_PRT_RET(
1048 : fromId <= totalId && totalId <= toId,
1049 : HCCL_ERROR(
1050 : "[CcuComponent][%s] failed, totalId[%u] invalid, should not be in [fromId[%u], toId[%u]].", __func__,
1051 : totalId, fromId, toId),
1052 : HcclResult::HCCL_E_PARA);
1053 :
1054 0 : HcclResult ret = SetTotalCntXnProcess(dieId, index, fromId, toId, totalId);
1055 0 : CHK_PRT_RET(
1056 : ret != HcclResult::HCCL_SUCCESS,
1057 : HCCL_ERROR(
1058 : "[CcuComponent][%s] failed, dieId[%u], index[%u], devLogicId[%d].", __func__, dieId, index, devLogicId_),
1059 : ret);
1060 :
1061 0 : usedTotalCntXnFlags_[index] = true;
1062 0 : return HcclResult::HCCL_SUCCESS;
1063 : }
1064 :
1065 0 : HcclResult CcuComponent::ResetTotalCntXn(uint8_t dieId, uint32_t index)
1066 : {
1067 0 : if (index >= CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM || !usedTotalCntXnFlags_[index]) {
1068 0 : return HcclResult::HCCL_SUCCESS;
1069 : }
1070 :
1071 : static constexpr uint32_t fromIdDefault = 0xFFFF; // from默认值
1072 : static constexpr uint32_t toIdDefault = 0x0000; // to默认值
1073 : static constexpr uint32_t totalIdDefault[CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM]{
1074 : 0x3FFC, 0x3FFD, 0x3FFE, 0x3FFF}; // total默认值
1075 :
1076 0 : auto ret = SetTotalCntXnProcess(dieId, index, fromIdDefault, toIdDefault, totalIdDefault[index]);
1077 0 : CHK_PRT_RET(
1078 : ret != HcclResult::HCCL_SUCCESS,
1079 : HCCL_ERROR(
1080 : "[CcuComponent][%s] failed, dieId[%u], index[%u], devLogicId[%d].", __func__, dieId, index, devLogicId_),
1081 : ret);
1082 :
1083 0 : usedTotalCntXnFlags_[index] = false;
1084 0 : return HcclResult::HCCL_SUCCESS;
1085 : }
1086 :
1087 0 : HcclResult CcuComponent::SetTotalCntXnProcess(
1088 : uint8_t dieId, uint32_t index, uint32_t fromId, uint32_t toId, uint32_t totalId) const
1089 : {
1090 0 : CHK_PRT_RET(
1091 : dieId >= MAX_CCU_IODIE_NUM,
1092 : HCCL_ERROR(
1093 : "[CcuComponent][%s] failed, dieId[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, dieId,
1094 : MAX_CCU_IODIE_NUM, devLogicId_),
1095 : HcclResult::HCCL_E_PARA);
1096 :
1097 0 : CHK_PRT_RET(
1098 : index >= CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM,
1099 : HCCL_ERROR(
1100 : "[CcuComponent][%s] failed, index[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, index,
1101 : CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM, devLogicId_),
1102 : HcclResult::HCCL_E_PARA);
1103 :
1104 0 : CustomChannelInfoIn inBuff{};
1105 0 : CustomChannelInfoOut outBuff{};
1106 :
1107 0 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_XN_TOTAL_CNT;
1108 0 : inBuff.data.dataInfo.udieIdx = dieId;
1109 0 : inBuff.data.dataInfo.dataArraySize = 1;
1110 0 : inBuff.data.dataInfo.dataLen = sizeof(CcuDataTypeUnion) * inBuff.data.dataInfo.dataArraySize;
1111 :
1112 0 : inBuff.data.dataInfo.dataArray[0].xnTotalCnt.cntIndex = index & 0b11; // range: [0, 3]
1113 0 : inBuff.data.dataInfo.dataArray[0].xnTotalCnt.flagFromAddr = fromId;
1114 0 : inBuff.data.dataInfo.dataArray[0].xnTotalCnt.flagToAddr = toId;
1115 0 : inBuff.data.dataInfo.dataArray[0].xnTotalCnt.totalAddr = totalId;
1116 0 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
1117 0 : if (ret != 0) {
1118 0 : HCCL_ERROR(
1119 : "[CcuComponent][%s] failed to call ccu driver, "
1120 : "devPhyId[%u] dieId[%d] op[%s].",
1121 : __func__, devPhyId_, dieId, "CCU_U_OP_SET_XN_TOTAL_CNT");
1122 0 : return HcclResult::HCCL_E_NETWORK;
1123 : }
1124 :
1125 0 : return HcclResult::HCCL_SUCCESS;
1126 : }
1127 :
1128 0 : HcclResult CcuComponent::ConfirmCntXns(const uint8_t dieId, const std::string& resGroupTag, const ResInfo& cntXnInfos)
1129 : {
1130 0 : struct CntXnBlock cntXnBlock;
1131 0 : uint32_t totalCntXnId = cntXnInfos.startId + cntXnInfos.num - TOTAL_COUNT_XN_NUM;
1132 0 : uint32_t wishCntXnIdBegin = cntXnInfos.startId;
1133 0 : uint32_t wishCntXnIdEnd = totalCntXnId - 1;
1134 0 : uint32_t blockIdx = CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM; // invalid value
1135 :
1136 0 : HCCL_INFO(
1137 : "Set TotalCntXn, wishCntXnIdBegin[%u] wishCntXnIdEnd[%u] totalCntXnId[%u]", wishCntXnIdBegin, wishCntXnIdEnd,
1138 : totalCntXnId);
1139 :
1140 0 : auto ret = GetAvailableTotalCntXnIndex(blockIdx);
1141 0 : CHK_PRT_RET(
1142 : ret != HcclResult::HCCL_SUCCESS,
1143 : HCCL_ERROR(
1144 : "[CcuComponent][%s] failed, no available TotalCnt Xns, dieId[%u], devLogicId[%d].", __func__, dieId,
1145 : devLogicId_),
1146 : ret);
1147 0 : CHK_RET(SetTotalCntXn(dieId, wishCntXnIdBegin, wishCntXnIdEnd, totalCntXnId, blockIdx));
1148 0 : HCCL_INFO("Set TotalCntXn success, index[%u]", blockIdx);
1149 :
1150 0 : ret = SetSplitUnit(dieId, 0); // 0表示stomic store add value的单位是byte。1表示以包为单位
1151 0 : if (ret != HcclResult::HCCL_SUCCESS) {
1152 0 : HCCL_ERROR("[CcuComponent][%s] SetSplitUnit failed, dieId[%u], devLogicId[%d].", __func__, dieId, devLogicId_);
1153 0 : CHK_RET(ResetTotalCntXn(dieId, blockIdx));
1154 0 : return ret;
1155 : }
1156 :
1157 0 : for (u32 idx = wishCntXnIdBegin; idx <= wishCntXnIdEnd; idx++) {
1158 0 : cntXnBlock.wishCntXns.push(idx);
1159 : }
1160 0 : cntXnBlock.resInfo = cntXnInfos;
1161 0 : cntXnBlock.totalCntXn = totalCntXnId;
1162 0 : cntXnBlock.blockIdx = blockIdx;
1163 0 : cntXnBlocks_[dieId].insert(std::make_pair(resGroupTag, cntXnBlock));
1164 0 : return HcclResult::HCCL_SUCCESS;
1165 0 : }
1166 :
1167 0 : HcclResult CcuComponent::AllocWishCntXn(const uint8_t dieId, const std::string& resGroupTag, uint32_t& wishCntXn)
1168 : {
1169 0 : CHK_PRT_RET(
1170 : (ccuVersion_ != CcuVersion::CCU_V2),
1171 : HCCL_ERROR("[CcuComponent][%s] failed, ccuVersion[%d] does not support this interface.", __func__, ccuVersion_),
1172 : HCCL_E_NOT_SUPPORT);
1173 0 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
1174 :
1175 0 : std::unique_lock<std::mutex> lock(cntXnBlockMutex_);
1176 0 : auto& cntXnBlocks = cntXnBlocks_[dieId];
1177 0 : auto iter = cntXnBlocks.find(resGroupTag);
1178 0 : if (iter != cntXnBlocks.end()) {
1179 0 : CHK_PRT_RET(
1180 : (iter->second.wishCntXns.size() == 0),
1181 : HCCL_ERROR(
1182 : "[CcuComponent][%s] failed, wishCntXn is not enough, resGroupTag[%s], devLogicId[%d], "
1183 : "dieId[%u].",
1184 : __func__, resGroupTag.c_str(), devLogicId_, dieId),
1185 : HCCL_E_UNAVAIL);
1186 : } else {
1187 0 : CHK_PRT_RET(
1188 : (cntXnBlocks.size() == CCU_V2_RESOURCE_TOTAL_CNT_XNS_NUM),
1189 : HCCL_ERROR(
1190 : "[CcuComponent][%s] failed, cntXnBlock is not enough, resGroupTag[%s], "
1191 : "devLogicId[%d], dieId[%u].",
1192 : __func__, resGroupTag.c_str(), devLogicId_, dieId),
1193 : HCCL_E_UNAVAIL);
1194 0 : ResInfo countXnInfo;
1195 : // 申请511 + 1个cntXn,前511个为wishCntXn,最后一个为totalCntXn
1196 0 : auto ret = resAllocators_[dieId]->AllocCountXn(WISH_COUNT_XN_NUM + TOTAL_COUNT_XN_NUM, countXnInfo);
1197 0 : CHK_PRT_RET(
1198 : ret != HcclResult::HCCL_SUCCESS,
1199 : HCCL_ERROR(
1200 : "[CcuComponent][%s] failed, num[%u], resGroupTag[%s], devLogicId[%d], dieId[%u].", __func__,
1201 : (WISH_COUNT_XN_NUM + TOTAL_COUNT_XN_NUM), resGroupTag.c_str(), devLogicId_, dieId),
1202 : ret);
1203 : // 配置cntXn
1204 0 : ret = ConfirmCntXns(dieId, resGroupTag, countXnInfo);
1205 0 : if (ret != HcclResult::HCCL_SUCCESS) {
1206 0 : HCCL_ERROR(
1207 : "[CcuComponent][%s] failed[%d] to confirm cnt xns, "
1208 : "try to release new allocated cnt xns, dieId[%u] resGroupTag[%s].",
1209 : __func__, ret, dieId, resGroupTag.c_str());
1210 0 : CHK_RET(resAllocators_[dieId]->ReleaseCountXn(countXnInfo.startId, countXnInfo.num));
1211 0 : return ret;
1212 : }
1213 : }
1214 0 : auto& xnBlock = cntXnBlocks_[dieId][resGroupTag];
1215 0 : HCCL_INFO("resGroupTag[%s] stack size[%u]", resGroupTag.c_str(), xnBlock.wishCntXns.size());
1216 0 : wishCntXn = xnBlock.wishCntXns.top();
1217 0 : xnBlock.wishCntXns.pop();
1218 0 : uint32_t totalCntXn = xnBlock.totalCntXn;
1219 0 : HCCL_INFO(
1220 : "[CcuComponent][%s] success, resGroupTag[%s], devLogicId[%d], dieId[%u], wishCntXn[%u], totalCntXn[%u].",
1221 : __func__, resGroupTag.c_str(), devLogicId_, dieId, wishCntXn, totalCntXn);
1222 :
1223 0 : return HcclResult::HCCL_SUCCESS;
1224 0 : }
1225 :
1226 0 : HcclResult CcuComponent::ReleaseWishCntXn(const uint8_t dieId, const std::string& resGroupTag, uint32_t wishCntXn)
1227 : {
1228 0 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
1229 :
1230 0 : std::unique_lock<std::mutex> lock(cntXnBlockMutex_);
1231 0 : if (cntXnBlocks_[dieId].find(resGroupTag) == cntXnBlocks_[dieId].end()) {
1232 0 : HCCL_ERROR(
1233 : "[CcuComponent][%s] failed, resGroupTag[%s] is not found, devLogicId[%d], dieId[%u].", __func__,
1234 : resGroupTag.c_str(), devLogicId_, dieId);
1235 0 : return HCCL_E_NOT_FOUND;
1236 : }
1237 :
1238 0 : auto& xnBlock = cntXnBlocks_[dieId][resGroupTag];
1239 0 : xnBlock.wishCntXns.push(wishCntXn);
1240 0 : if (xnBlock.wishCntXns.size() != WISH_COUNT_XN_NUM) {
1241 0 : HCCL_INFO(
1242 : "[CcuComponent][%s] success, resGroupTag[%s], devLogicId[%d], dieId[%u], wishCntXn[%u], available "
1243 : "wishCntXn num[%u].",
1244 : __func__, resGroupTag.c_str(), devLogicId_, dieId, wishCntXn, xnBlock.wishCntXns.size());
1245 0 : return HCCL_SUCCESS;
1246 : }
1247 :
1248 : // 所有wishCnt都已经release,释放资源
1249 0 : CHK_RET(ResetTotalCntXn(dieId, xnBlock.blockIdx));
1250 :
1251 0 : auto ret = resAllocators_[dieId]->ReleaseCountXn(xnBlock.resInfo.startId, xnBlock.resInfo.num);
1252 0 : CHK_PRT_RET(
1253 : ret != HcclResult::HCCL_SUCCESS,
1254 : HCCL_ERROR(
1255 : "[CcuComponent][%s] failed, resGroupTag[%s], resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
1256 : resGroupTag.c_str(), xnBlock.resInfo.Describe().c_str(), devLogicId_, dieId),
1257 : ret);
1258 0 : cntXnBlocks_[dieId].erase(resGroupTag);
1259 :
1260 0 : return HcclResult::HCCL_SUCCESS;
1261 0 : }
1262 :
1263 0 : HcclResult CcuComponent::GetCntXnBlock(
1264 : const uint8_t dieId, const std::string& resGroupTag, std::pair<uint32_t, uint32_t>& cntXnPair)
1265 : {
1266 0 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
1267 :
1268 0 : std::unique_lock<std::mutex> lock(cntXnBlockMutex_);
1269 0 : auto iter = cntXnBlocks_[dieId].find(resGroupTag);
1270 0 : if (iter == cntXnBlocks_[dieId].end()) {
1271 0 : HCCL_ERROR(
1272 : "[CcuComponent][%s] failed, resGroupTag[%s] is not found, devLogicId[%d], dieId[%u].", __func__,
1273 : resGroupTag.c_str(), devLogicId_, dieId);
1274 0 : return HCCL_E_NOT_FOUND;
1275 : }
1276 :
1277 0 : cntXnPair = std::make_pair(iter->second.resInfo.startId, iter->second.totalCntXn);
1278 :
1279 0 : return HcclResult::HCCL_SUCCESS;
1280 0 : }
1281 :
1282 0 : HcclResult CcuComponent::GetTotalCntXn(const uint8_t dieId, const std::string& resGroupTag, uint32_t& totalCntXn)
1283 : {
1284 0 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
1285 :
1286 0 : std::unique_lock<std::mutex> lock(cntXnBlockMutex_);
1287 0 : auto iter = cntXnBlocks_[dieId].find(resGroupTag);
1288 0 : if (iter == cntXnBlocks_[dieId].end()) {
1289 0 : HCCL_ERROR(
1290 : "[CcuComponent][%s] failed, resGroupTag[%s] is not found, devLogicId[%d], dieId[%u].", __func__,
1291 : resGroupTag.c_str(), devLogicId_, dieId);
1292 0 : return HCCL_E_NOT_FOUND;
1293 : }
1294 :
1295 0 : totalCntXn = iter->second.totalCntXn;
1296 :
1297 0 : return HcclResult::HCCL_SUCCESS;
1298 0 : }
1299 :
1300 3679 : const std::array<bool, CCU_MAX_IODIE_NUM>& CcuComponent::GetDieEnableFlags() const { return dieEnableFlags_; }
1301 :
1302 393 : HcclResult CcuComponent::ReleaseJettyRes()
1303 : {
1304 393 : CHK_RET(UnimportAllJettys());
1305 393 : CHK_RET(ReleaseAllTpInfos());
1306 390 : CHK_RET(DestroyAllJettys());
1307 : // HrtRaUbLocalMemReg 跟随 LocalUbRmaBuffer 析构时释放
1308 : // 环回channel不需要手动释放,channelCtxMgr跟随CcuComponent释放
1309 390 : return HcclResult::HCCL_SUCCESS;
1310 : }
1311 :
1312 393 : HcclResult CcuComponent::UnimportAllJettys()
1313 : {
1314 609 : for (auto& importedVec : importedOutParamMap_) {
1315 432 : for (auto& paramPair : importedVec.second) {
1316 216 : const auto ctxHandle = paramPair.first;
1317 216 : const auto remoteJettyHandle = paramPair.second.handle;
1318 216 : if (!ctxHandle || !remoteJettyHandle) {
1319 216 : continue;
1320 : }
1321 0 : if (!Hccl::RdmaHandleManager::GetInstance().IsHandleValid(ctxHandle)) {
1322 0 : HCCL_WARNING(
1323 : "[CcuComponent][%s] skip RaCtxQpUnimport, ctxHandle=%p invalid, "
1324 : "remoteJettyHandle=%p, devLogicId[%d].",
1325 : __func__, ctxHandle, remoteJettyHandle, devLogicId_);
1326 0 : paramPair.second.handle = nullptr;
1327 0 : continue;
1328 : }
1329 0 : int32_t ret = RaCtxQpUnimport(ctxHandle, remoteJettyHandle);
1330 0 : if (ret != 0) {
1331 0 : HCCL_ERROR(
1332 : "[CcuComponent][%s] failed, ctxHandle[%p] "
1333 : "remoteJettyHandle[%p], devLogicId[%d].",
1334 : __func__, ctxHandle, remoteJettyHandle, devLogicId_);
1335 : }
1336 0 : paramPair.second.handle = nullptr; // 清理handle,避免重复释放
1337 : }
1338 : }
1339 393 : importedOutParamMap_.clear();
1340 393 : return HcclResult::HCCL_SUCCESS;
1341 : }
1342 :
1343 393 : HcclResult CcuComponent::ReleaseAllTpInfos()
1344 : {
1345 610 : for (auto& item : tpAttrInfoMap_) {
1346 217 : const auto& dieId = item.first;
1347 217 : const auto& tpAttrInfo = item.second;
1348 217 : const auto& tpInfoIter = tpInfoMap_.find(dieId);
1349 217 : if (tpInfoIter != tpInfoMap_.end() && tpInfoIter->second.tpHandle != 0) {
1350 216 : (void)TpMgr::GetInstance(devPhyId_).ReleaseTpAttr(tpInfoIter->second.tpHandle, tpAttrInfo);
1351 : }
1352 : }
1353 393 : tpAttrInfoMap_.clear();
1354 607 : for (auto& item : tpInfoMap_) {
1355 217 : const auto& dieId = item.first;
1356 217 : const auto& tpInfo = item.second;
1357 217 : if (tpInfo.tpHandle == 0) {
1358 0 : continue;
1359 : }
1360 :
1361 217 : const auto& dieIdIter = loopFeCommAddrMap_.find(dieId);
1362 217 : if (dieIdIter == loopFeCommAddrMap_.end()) {
1363 3 : HCCL_ERROR(
1364 : "[CcuComponent][%s] failed, dieId[%u] loop comm address"
1365 : " is not found, devLogicId[%d].",
1366 : __func__, static_cast<uint32_t>(dieId), devLogicId_);
1367 3 : return HcclResult::HCCL_E_NOT_FOUND;
1368 : }
1369 214 : const auto& commAddr = dieIdIter->second.second;
1370 214 : const GetTpInfoParam& tpParam = MakeLoopGetTpInfoParam(commAddr);
1371 214 : (void)TpMgr::GetInstance(devPhyId_).ReleaseTpInfo(tpParam, tpInfo);
1372 214 : item.second.tpHandle = 0; // 清理handle,避免重复释放
1373 : }
1374 390 : tpInfoMap_.clear();
1375 390 : return HcclResult::HCCL_SUCCESS;
1376 : }
1377 :
1378 390 : HcclResult CcuComponent::DestroyAllJettys()
1379 : {
1380 604 : for (auto& createdVec : createdOutParamMap_) {
1381 428 : for (auto& param : createdVec.second) {
1382 214 : const auto jettyHandle = param.handle;
1383 214 : if (!jettyHandle) {
1384 214 : continue;
1385 : }
1386 0 : int32_t ret = RaCtxQpDestroy(jettyHandle);
1387 0 : if (ret != 0) {
1388 0 : HCCL_ERROR(
1389 : "[CcuComponent][%s] failed, jettyHandle[%p], "
1390 : "devLogicId[%d].",
1391 : __func__, jettyHandle, devLogicId_);
1392 : }
1393 0 : param.handle = 0; // 清理handle,避免重复释放
1394 : }
1395 : }
1396 390 : createdOutParamMap_.clear();
1397 390 : return HcclResult::HCCL_SUCCESS;
1398 : }
1399 :
1400 3 : HcclResult CcuComponent::SetProcess(CcuOpcodeType opCode) const
1401 : {
1402 3 : CustomChannelInfoIn inBuff;
1403 3 : CustomChannelInfoOut outBuff;
1404 :
1405 3 : inBuff.op = opCode;
1406 9 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
1407 6 : if (!dieEnableFlags_[dieId]) {
1408 6 : HCCL_WARNING("[%s] devLogicId[%d], dieId[%u] is not enable, skip.", __func__, devLogicId_, dieId);
1409 6 : continue;
1410 : }
1411 0 : HCCL_INFO("[%s] devLogicId[%d], dieId[%u] start.", __func__, devLogicId_, dieId);
1412 0 : inBuff.data.dataInfo.udieIdx = dieId;
1413 0 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
1414 0 : CHK_PRT_RET(
1415 : ret != HCCL_SUCCESS,
1416 : HCCL_ERROR(
1417 : "[%s] failed to call ccu driver, devLogicId[%d] dieId[%u] op[%u] ret[%d].", __func__, devLogicId_,
1418 : dieId, static_cast<uint32_t>(opCode), ret),
1419 : ret);
1420 : }
1421 3 : return HcclResult::HCCL_SUCCESS;
1422 : }
1423 :
1424 1 : HcclResult CcuComponent::CleanTaskKillState() const
1425 : {
1426 1 : CHK_RET(SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE));
1427 1 : return HcclResult::HCCL_SUCCESS;
1428 : }
1429 :
1430 2 : HcclResult CcuComponent::SetTaskKill()
1431 : {
1432 2 : std::lock_guard<std::mutex> _lock(taskKillMutex_); // 加锁,确保线程安全
1433 :
1434 : // 初始化状态下,设置任务kill状态
1435 2 : if (status == CcuTaskKillStatus::INVALID) {
1436 1 : status = CcuTaskKillStatus::INIT;
1437 : }
1438 :
1439 2 : if (status == CcuTaskKillStatus::TASK_KILL) {
1440 1 : HCCL_INFO("No need to set task kill, state = %u, devLogicId = %u", status, devLogicId_);
1441 1 : return HcclResult::HCCL_SUCCESS;
1442 : }
1443 :
1444 1 : if (status != CcuTaskKillStatus::INIT) {
1445 0 : HCCL_ERROR(
1446 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1447 : "state = %u, devLogicId = %d.",
1448 : __func__, status, devLogicId_);
1449 0 : return HcclResult::HCCL_E_INTERNAL;
1450 : }
1451 :
1452 1 : CHK_RET(SetProcess(CcuOpcodeType::CCU_U_OP_SET_TASKKILL));
1453 1 : status = CcuTaskKillStatus::TASK_KILL;
1454 1 : HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d.", __func__, status, devLogicId_);
1455 1 : return HcclResult::HCCL_SUCCESS;
1456 2 : }
1457 :
1458 1 : HcclResult CcuComponent::SetTaskKillDone()
1459 : {
1460 1 : std::lock_guard<std::mutex> _lock(taskKillMutex_); // 加锁,确保线程安全
1461 1 : if (status == CcuTaskKillStatus::INVALID) {
1462 0 : HCCL_ERROR(
1463 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1464 : "state = %u, devLogicId = %d.",
1465 : __func__, status, devLogicId_);
1466 0 : return HcclResult::HCCL_E_INTERNAL;
1467 : }
1468 :
1469 1 : if (status == CcuTaskKillStatus::INIT) {
1470 0 : HCCL_INFO("No need to set task kill done, state = %u, devLogicId = %u", status, devLogicId_);
1471 0 : return HcclResult::HCCL_SUCCESS;
1472 : }
1473 :
1474 1 : if (status != CcuTaskKillStatus::TASK_KILL) {
1475 0 : HCCL_ERROR(
1476 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1477 : "state = %u, devLogicId = %d.",
1478 : __func__, status, devLogicId_);
1479 0 : return HcclResult::HCCL_E_INTERNAL;
1480 : }
1481 :
1482 1 : CHK_RET(SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE));
1483 1 : status = CcuTaskKillStatus::INIT;
1484 1 : HCCL_INFO(
1485 : "[CcuComponent][%s] success, state = INIT(%u), devLogicId = %d", __func__, static_cast<uint8_t>(status),
1486 : devLogicId_);
1487 1 : return HcclResult::HCCL_SUCCESS;
1488 1 : }
1489 :
1490 0 : HcclResult CcuComponent::CcuSetTaskKillDone(const int32_t deviceLogicId) const
1491 : {
1492 0 : HCCL_INFO("[CcuSetTaskKillDone] Input params: deviceLogicId[%d]", deviceLogicId);
1493 : // 入参校验拦截
1494 0 : CHK_PRT_RET(
1495 : (deviceLogicId < 0 || static_cast<u32>(deviceLogicId) >= MAX_MODULE_DEVICE_NUM),
1496 : HCCL_ERROR(
1497 : "[CcuSetTaskKillDone] deviceLogicId[%d] error, MAX_MODULE_DEVICE_NUM[%u]", deviceLogicId,
1498 : MAX_MODULE_DEVICE_NUM),
1499 : HcclResult::HCCL_E_PARA);
1500 0 : return CcuComponent::GetInstance(deviceLogicId).SetTaskKillDone();
1501 : }
1502 :
1503 0 : HcclResult CcuComponent::CcuCleanTaskKillState(const int32_t deviceLogicId) const
1504 : {
1505 0 : HCCL_INFO("[CcuCleanTaskKillState] Input params: deviceLogicId[%d]", deviceLogicId);
1506 : // 入参校验拦截
1507 0 : CHK_PRT_RET(
1508 : (deviceLogicId < 0 || static_cast<u32>(deviceLogicId) >= MAX_MODULE_DEVICE_NUM),
1509 : HCCL_ERROR(
1510 : "[CcuCleanTaskKillState] deviceLogicId[%d] error, MAX_MODULE_DEVICE_NUM[%u]", deviceLogicId,
1511 : MAX_MODULE_DEVICE_NUM),
1512 : HcclResult::HCCL_E_PARA);
1513 0 : return CcuComponent::GetInstance(deviceLogicId).CleanTaskKillState();
1514 : }
1515 :
1516 : // 以下接口用于n秒快恢与TaskException
1517 216 : HcclResult CcuComponent::CleanDieCkes(const uint8_t dieId) const
1518 : {
1519 216 : CHK_PRT_RET(
1520 : dieId >= MAX_CCU_IODIE_NUM,
1521 : HCCL_WARNING(
1522 : "[%s] failed, dieId[%u] is invalid, should be in [0-%u), devLogicId[%d].", __func__, dieId,
1523 : MAX_CCU_IODIE_NUM, devLogicId_),
1524 : HcclResult::HCCL_E_PARA);
1525 :
1526 215 : if (!dieEnableFlags_[dieId]) {
1527 1 : HCCL_INFO("[%s] dieId[%u] is not enable, skip", __func__, dieId);
1528 1 : return HcclResult::HCCL_SUCCESS;
1529 : }
1530 :
1531 214 : CustomChannelInfoIn inBuff{};
1532 214 : CustomChannelInfoOut outBuff{};
1533 :
1534 : // 设置操作码和数据
1535 214 : uint32_t ckeNum = 0;
1536 214 : CHK_RET(CcuResSpecifications::GetInstance(devLogicId_).GetCkeNum(dieId, ckeNum));
1537 214 : HCCL_INFO(
1538 : "[CcuComponent][CleanAllCke]NS recovery devLogicId[%d], dieId[%u], ckeNum[%u].", devLogicId_, dieId, ckeNum);
1539 :
1540 214 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_CKE;
1541 214 : inBuff.data.dataInfo.udieIdx = dieId;
1542 : // 接口限制,目前方案每次最多清理8个cke,超过8个时分多次清理
1543 27606 : for (uint32_t startIdx = 0; startIdx < ckeNum; startIdx += MAX_CKE_DATA_ARRAY_SIZE) {
1544 27392 : inBuff.data.dataInfo.dataArraySize = std::min(ckeNum - startIdx, MAX_CKE_DATA_ARRAY_SIZE);
1545 27392 : inBuff.data.dataInfo.dataLen = sizeof(CcuDataByte8) * inBuff.data.dataInfo.dataArraySize;
1546 27392 : inBuff.offsetStartIdx = startIdx;
1547 27392 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId_, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
1548 27392 : CHK_PRT_RET(
1549 : ret != HCCL_SUCCESS,
1550 : HCCL_ERROR(
1551 : "[%s] failed to call ccu driver, devLogicId[%d] dieId[%u] op[%s] ret[%d].", __func__, devLogicId_,
1552 : dieId, "SET_CKE", ret),
1553 : ret);
1554 : }
1555 :
1556 214 : return HcclResult::HCCL_SUCCESS;
1557 : }
1558 :
1559 : }; // namespace hcomm
|