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