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 <cstdlib>
12 :
13 : #include "ccu_component.h"
14 :
15 : #include "exception_util.h"
16 : #include "hccl_common_v2.h"
17 : #include "ccu_api_exception.h"
18 : #include "orion_adapter_rts.h"
19 : #include "internal_exception.h"
20 : #include "rdma_handle_manager.h"
21 :
22 : #include "ccu_eid_info.h"
23 : #include "ccu_res_specs_legacy.h"
24 :
25 : #include "ccu_channel_mgr_v1.h"
26 : #include "hccp_ctx_tp.h"
27 : #include "env_config_v2.h"
28 : #include "hccp_tlv_hdc_manager.h"
29 :
30 : namespace Hccl {
31 :
32 : namespace {
33 : constexpr uint8_t CCU_MAX_MISSION_NUM = 16;
34 : } // namespace
35 :
36 : constexpr uint16_t INVAILD_LOOP_CHANNEL_ID = 0xFFFF;
37 :
38 : // 设置为0,分配数量由channelMgr决定,v1 默认1个
39 : constexpr uint32_t LOOP_CHANNEL_USE_JETTY = 0;
40 : constexpr uint32_t LOOP_CHANNEL_USE_SQSIZE = 16;
41 :
42 : // 环回获取TP信息超时等待10s
43 : constexpr uint32_t LOOP_CHANNEL_WAIT_TIMEOUT_MS = 10000;
44 : // 环回获取TP信息间隔1ms
45 : constexpr u32 ONE_MILLISECOND_OF_USLEEP = 1000;
46 :
47 : // 清理CKE批量申请大小
48 : constexpr u32 MAX_CKE_DATA_ARRAY_SIZE = 8;
49 :
50 : // 环境是A+X时,配置die0的MS交织粒度为1<<7 = 128
51 : constexpr uint32_t MSID_CONFIG_AX_MAINBOARD = 7;
52 : constexpr TpProtocol LOOP_JETTY_PROTOCOL = TpProtocol::TP; // 环回使用TP避免被环境link down阻塞
53 :
54 : // 与 TpManager 缓存键一致:须与 RequestNewTpInfo / Deinit::ReleaseTpInfo 使用同一套 qos 与环回标志
55 12 : static RaUbGetTpInfoParam MakeCcuLoopRaUbGetTpInfoParam(const IpAddress& locAddr, const IpAddress& rmtAddr)
56 : {
57 12 : RaUbGetTpInfoParam p{};
58 12 : p.locAddr = locAddr;
59 12 : p.rmtAddr = rmtAddr;
60 12 : p.tpProtocol = LOOP_JETTY_PROTOCOL;
61 12 : p.qos = 0U;
62 12 : p.slLevelCount = 0U;
63 12 : p.loopFirstTpLowestSl = true;
64 12 : p.ccuLoopbackGetTpInfo = true;
65 12 : return p;
66 : }
67 :
68 272 : CcuComponent& CcuComponent::GetInstance(const int32_t deviceLogicId)
69 : {
70 338 : static CcuComponent ccuComponent[MAX_MODULE_DEVICE_NUM + 1];
71 :
72 272 : if (deviceLogicId < 0 || static_cast<uint32_t>(deviceLogicId) > MAX_MODULE_DEVICE_NUM) {
73 0 : THROW<InvalidParamsException>(
74 : "[CcuComponent][%s] failed, devLogicId[%d] should be less "
75 : "than %u.",
76 : __func__, deviceLogicId, MAX_MODULE_DEVICE_NUM);
77 : }
78 :
79 272 : ccuComponent[deviceLogicId].devLogicId = deviceLogicId;
80 272 : return ccuComponent[deviceLogicId];
81 : }
82 :
83 24 : void CcuComponent::PrintCcuMissionStatus(int32_t devLogicId) const
84 : {
85 24 : uint16_t status = 0;
86 72 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
87 48 : if (!dieEnableFlags[dieId]) {
88 0 : HCCL_WARNING("[%s]devLogicId[%d], dieId[%u] is not enable, skip.", __func__, devLogicId, dieId);
89 0 : continue;
90 0 : }
91 48 : std::string missionStatus;
92 816 : for (uint8_t missionId = 0; missionId < CCU_MAX_MISSION_NUM; missionId++) {
93 768 : status = Hccl::CcuErrorHandler::GetCcuMissionContext(devLogicId, dieId, missionId).GetStatus();
94 768 : missionStatus += "missionId[" + std::to_string(missionId) + "]=status[" + std::to_string(status) + "] ";
95 : }
96 144 : HCCL_RUN_INFO("Init devLogicId[%d], dieId[%d], content[%s]", devLogicId, dieId, missionStatus.c_str());
97 48 : }
98 24 : }
99 :
100 18 : void CcuComponent::Init()
101 : {
102 18 : std::lock_guard<std::mutex> _lock(innerMutex);
103 :
104 18 : if (ifInit) {
105 5 : return;
106 : }
107 :
108 13 : devPhyId = HrtGetDevicePhyIdByIndex(devLogicId);
109 13 : CheckDiesEnable();
110 36 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
111 24 : CleanDieCkes(dieId);
112 : }
113 12 : CreateCcuRmaBuffer();
114 12 : CreateResourceManagers();
115 12 : CreateLoopChannels();
116 12 : ConfigMsIdToken();
117 : // 打印最初的mission状态
118 12 : PrintCcuMissionStatus(devLogicId);
119 12 : SetTaskKill();
120 12 : SetTaskKillDone();
121 : // 打印taskKill恢复后的mission状态
122 12 : PrintCcuMissionStatus(devLogicId);
123 12 : ifInit = true;
124 18 : }
125 : // 资源清理
126 2 : void CcuComponent::Deinit()
127 : {
128 2 : std::lock_guard<std::mutex> _lock(innerMutex);
129 2 : ReleaseJettyRes();
130 :
131 6 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
132 4 : CleanDieCkes(dieId);
133 : }
134 :
135 2 : for (const auto& item : tpAttrInfoMap) {
136 0 : const auto& ipAddr = item.first;
137 0 : const auto& tpAttrInfo = item.second;
138 0 : const auto& tpInfoIter = tpInfoMap.find(ipAddr);
139 0 : if (tpInfoIter != tpInfoMap.end() && tpInfoIter->second.tpHandle != 0) {
140 0 : (void)TpManager::GetInstance(devLogicId).ReleaseTpAttr(tpInfoIter->second.tpHandle, tpAttrInfo);
141 : }
142 : }
143 2 : tpAttrInfoMap.clear();
144 :
145 2 : for (const auto& item : tpInfoMap) {
146 0 : const auto& ipAddr = item.first;
147 0 : const auto& tpInfo = item.second;
148 0 : (void)TpManager::GetInstance(devLogicId).ReleaseTpInfo(MakeCcuLoopRaUbGetTpInfoParam(ipAddr, ipAddr), tpInfo);
149 : }
150 :
151 2 : createdOutParamMap.clear();
152 2 : importedOutParamMap.clear();
153 2 : tpInfoMap.clear();
154 2 : psnMap.clear();
155 :
156 2 : loopFeIpAddrMap.clear();
157 2 : ccuRmaBufferMap.clear();
158 2 : localCcuRmaBufferMap.clear();
159 2 : additionalCcuRmaBufferMap.clear();
160 6 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
161 4 : channelMgrs[dieId] = nullptr;
162 4 : resAllocators[dieId] = nullptr;
163 4 : loopChannelIds[dieId] = INVAILD_LOOP_CHANNEL_ID;
164 : }
165 :
166 2 : ifInit = false;
167 2 : }
168 :
169 13 : void CcuComponent::CheckDiesEnable()
170 : {
171 13 : ccuVersion = CcuResSpecifications::GetInstance(devLogicId).GetCcuVersion();
172 39 : HCCL_INFO(
173 : "[CcuComponent][%s] ccu version[%s], devLogicId[%d].", __func__, ccuVersion.Describe().c_str(), devLogicId);
174 :
175 13 : std::array<bool, MAX_CCU_IODIE_NUM> dieDrvEnableFlags{false, false};
176 13 : bool allDieDisable = true;
177 13 : const auto& ccuResSpecs = CcuResSpecifications::GetInstance(devLogicId);
178 39 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
179 26 : dieEnableFlags[dieId] = false;
180 26 : (void)ccuResSpecs.GetDieEnableFlag(dieId, dieDrvEnableFlags[dieId]);
181 26 : ChooseLoopEid(dieDrvEnableFlags[dieId], dieId);
182 26 : allDieDisable = allDieDisable && !dieEnableFlags[dieId];
183 26 : if (!dieEnableFlags[dieId]) { // 调用接口失败时不会改变dieEnableFlags[i]
184 6 : HCCL_WARNING("[CcuComponent][%s] devLogicId[%d], dieId[%u] is not usable.", __func__, devLogicId, dieId);
185 2 : continue;
186 2 : }
187 :
188 72 : HCCL_INFO("[CcuComponent][%s] devLogicId[%d] die[%u] is usable.", __func__, devLogicId, dieId);
189 : }
190 :
191 13 : if (allDieDisable) {
192 1 : THROW<CcuApiException>(
193 : "[CcuComponent][%s] failed, because all dies are "
194 : "disabled, devLogicId[%d].",
195 : __func__, devLogicId);
196 : }
197 12 : }
198 :
199 26 : static HcclResult FindOneUsableEid(const uint32_t devLogicId, const uint8_t dieId, uint32_t& feId, IpAddress& ipAddr)
200 : {
201 26 : std::vector<HrtDevEidInfo> eidInfoList;
202 26 : auto ret = CcuEidInfo::GetInstance(devLogicId).GetEidInfo(devLogicId, eidInfoList);
203 32 : CHK_PRT_RET(
204 : ret != HCCL_SUCCESS,
205 : HCCL_WARNING("[CcuComponent][%s] failed, devLogicId[%u], dieId[%u].", __func__, devLogicId, dieId), ret);
206 :
207 24 : std::string name;
208 24 : bool findFlag = false;
209 24 : u32 devPhyId = HrtGetDevicePhyIdByIndex(devLogicId);
210 :
211 : // 如果无法查询设备是否为uboe设备,报错退出
212 24 : CHK_RET(HrtGetUboeFlagEnable(devPhyId));
213 :
214 24 : auto& rdmaHandleMgr = RdmaHandleManager::GetInstance();
215 : // 当前结论,需要选择可以申请到Tp handle的eid
216 36 : for (auto& eidInfo : eidInfoList) {
217 : // 如果是UBOE设备,则跳过
218 36 : if (HrtCheckUboeSupported(eidInfo.devFeature) || (eidInfo.dieId != dieId)) {
219 12 : continue;
220 : }
221 24 : const RdmaHandle rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, eidInfo.ipAddress);
222 24 : const bool rtpEnable = rdmaHandleMgr.GetRtpEnable(rdmaHandle);
223 24 : if (rtpEnable) {
224 24 : feId = eidInfo.funcId;
225 24 : ipAddr = eidInfo.ipAddress;
226 24 : name = eidInfo.name;
227 72 : HCCL_RUN_INFO(
228 : "[%s] rtpEnable[%d] dieId[%u] choose:"
229 : "name[%s] feId[%u] ipAddr[%s], devLogicId[%u]",
230 : __func__, rtpEnable, dieId, name.c_str(), feId, ipAddr.Describe().c_str(), devLogicId);
231 24 : findFlag = true;
232 24 : break;
233 : }
234 : }
235 :
236 24 : if (!findFlag) {
237 0 : HCCL_RUN_INFO(
238 : "[CcuComponent][%s] dieId[%u] doesn't have usable func ID, "
239 : "devLogicId[%u].",
240 : __func__, dieId, devLogicId);
241 0 : return HcclResult::HCCL_E_INTERNAL;
242 : }
243 :
244 72 : HCCL_INFO(
245 : "[CcuComponent][%s] dieId[%u] choose: name[%s] feId[%u] ipAddr[%s], "
246 : "devLogicId[%u].",
247 : __func__, dieId, name.c_str(), feId, ipAddr.Describe().c_str(), devLogicId);
248 :
249 24 : return HcclResult::HCCL_SUCCESS;
250 26 : }
251 :
252 26 : void CcuComponent::ChooseLoopEid(bool& dieDrvEnableFlag, uint8_t dieId)
253 : {
254 26 : if (!dieDrvEnableFlag) {
255 2 : return;
256 : }
257 :
258 26 : uint32_t feId = 0;
259 26 : IpAddress ipAddr = IpAddress();
260 26 : if (FindOneUsableEid(devLogicId, dieId, feId, ipAddr) != HcclResult::HCCL_SUCCESS) {
261 6 : HCCL_WARNING(
262 : "[CcuComponent][%s] failed to find feId eid, but passed, "
263 : "devLogicId[%d], dieId[%u].",
264 : __func__, devLogicId, dieId);
265 2 : return;
266 : }
267 :
268 24 : loopFeIpAddrMap[dieId] = {feId, ipAddr};
269 24 : dieEnableFlags[dieId] = dieDrvEnableFlag;
270 72 : HCCL_INFO("[CcuComponent][%s] die[%u] is enable", __func__, dieId);
271 : }
272 :
273 48 : HcclResult CcuComponent::GetLoopFeIpByDieId(const uint8_t dieId, uint32_t& feId, IpAddress& ipAddr)
274 : {
275 48 : const auto& dieIter = loopFeIpAddrMap.find(dieId);
276 48 : CHK_PRT_RET(
277 : dieIter == loopFeIpAddrMap.end(),
278 : HCCL_WARNING(
279 : "[CcuComponent][%s] failed, dieId[%u] doesn't have usable loop feId, "
280 : "devLogicId[%d].",
281 : __func__, dieId, devLogicId),
282 : HcclResult::HCCL_E_NOT_FOUND);
283 :
284 48 : const auto& feIdIpAddr = dieIter->second;
285 48 : feId = feIdIpAddr.first;
286 48 : ipAddr = feIdIpAddr.second;
287 :
288 48 : return HcclResult::HCCL_SUCCESS;
289 : }
290 :
291 12 : void CcuComponent::CreateCcuRmaBuffer()
292 : {
293 12 : auto& ccuResSpecs = CcuResSpecifications::GetInstance(devLogicId);
294 12 : auto& rdmaHandleMgr = RdmaHandleManager::GetInstance();
295 36 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
296 24 : if (!dieEnableFlags[dieId]) {
297 0 : continue;
298 : }
299 :
300 24 : uint32_t feId = 0;
301 24 : IpAddress ipAddr{};
302 24 : if (GetLoopFeIpByDieId(dieId, feId, ipAddr) != HcclResult::HCCL_SUCCESS) {
303 0 : continue;
304 : }
305 :
306 24 : uint64_t ccuResAddr = 0;
307 24 : (void)ccuResSpecs.GetResourceAddr(dieId, ccuResAddr);
308 24 : if (ccuResAddr == 0) {
309 0 : HCCL_WARNING(
310 : "[CcuComponent][%s] failed, ccu resource space address[0] is invalid, "
311 : "devLogicId[%d] dieId[%u]",
312 : __func__, devLogicId, dieId);
313 0 : continue;
314 0 : }
315 :
316 24 : const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
317 24 : CHECK_NULLPTR(
318 48 : rdmaHandle, StringFormat(
319 : "[CcuComponent][%s] failed, rdmaHandle is nullptr, "
320 : "devLogicId[%d] dieId[%u]",
321 : __func__, devLogicId, dieId));
322 :
323 24 : std::array<CcuMemInfo, CCU_MEM_INFO_SIZE> memInfoList{};
324 24 : uint32_t count{0};
325 24 : ccuResSpecs.GetCcuMemInfoList(dieId, memInfoList.data(), count);
326 456 : for (uint32_t i = 0; i < count; i++) {
327 432 : if (memInfoList[i].memVa == ccuResAddr) {
328 24 : const auto ccuBuffer = std::make_shared<Buffer>(ccuResAddr, memInfoList[i].memSize);
329 24 : ccuRmaBufferMap.emplace(dieId, std::make_unique<LocalUbRmaBuffer>(ccuBuffer, rdmaHandle));
330 24 : } else {
331 408 : const auto ccuBuffer = std::make_shared<Buffer>(memInfoList[i].memVa, memInfoList[i].memSize);
332 408 : additionalCcuRmaBufferMap.emplace_back(std::make_unique<LocalUbRmaBuffer>(ccuBuffer, rdmaHandle));
333 408 : }
334 : }
335 24 : const auto ccuBuffer = std::make_shared<Buffer>(ccuResAddr, CCU_RESOURCE_SIZE);
336 : // 本端专用的buffer,具有整块内存的权限
337 24 : localCcuRmaBufferMap.emplace(dieId, std::make_unique<LocalUbRmaBuffer>(ccuBuffer, rdmaHandle));
338 24 : }
339 12 : }
340 :
341 24 : inline std::unique_ptr<CcuChannelMgr> CreateChannelMgrByVersion(
342 : const CcuVersion version, const uint32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId)
343 : {
344 24 : switch (version) {
345 24 : case CcuVersion::CCU_V1:
346 24 : return std::make_unique<CcuChannelMgrV1>(devLogicId, dieId, devPhyId);
347 0 : default:
348 0 : break;
349 : }
350 :
351 0 : return nullptr;
352 : }
353 :
354 12 : void CcuComponent::CreateResourceManagers()
355 : {
356 36 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
357 24 : if (!dieEnableFlags[dieId]) {
358 0 : continue;
359 : }
360 :
361 : std::unique_ptr<CcuChannelMgr> channelMgrPtr
362 24 : = CreateChannelMgrByVersion(ccuVersion, devLogicId, dieId, devPhyId);
363 24 : CHECK_NULLPTR(
364 48 : channelMgrPtr, StringFormat(
365 : "[CcuComponent][%s] failed, ccu driver version[%s] is not expected, "
366 : "devLogicId[%d] dieId[%u].",
367 48 : __func__, ccuVersion.Describe().c_str(), devLogicId, dieId));
368 :
369 24 : channelMgrs[dieId] = std::move(channelMgrPtr);
370 24 : resAllocators[dieId] = std::make_unique<CcuResAllocator>(devLogicId, dieId);
371 24 : }
372 12 : }
373 :
374 12 : void CcuComponent::CreateLoopChannels()
375 : {
376 36 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
377 24 : loopChannelIds[dieId] = INVAILD_LOOP_CHANNEL_ID;
378 : }
379 :
380 36 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
381 : // 失败抛异常处理,jetty资源跟随数据结构析构释放
382 24 : CHK_RET_THROW(
383 : InternalException,
384 : StringFormat("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId),
385 : CreateLoopChannel(dieId, loopChannelIds[dieId]));
386 :
387 72 : HCCL_INFO(
388 : "[CcuComponent][%s] succeed, loop channel id[%u], "
389 : "devLogicId[%d], dieId[%u].",
390 : __func__, loopChannelIds[dieId], devLogicId, dieId);
391 : }
392 12 : }
393 :
394 24 : HcclResult CcuComponent::CreateLoopChannel(const uint8_t dieId, uint32_t& channelId)
395 : {
396 24 : if (!dieEnableFlags[dieId]) {
397 0 : HCCL_WARNING(
398 : "CcuComponent][%s] passed, dieId[%u] is not enable, "
399 : "devLogicId[%d].",
400 : __func__, dieId, devLogicId);
401 0 : return HcclResult::HCCL_SUCCESS;
402 : }
403 :
404 : // 对于单p或单die场景,可能设备或die不会配置eid,按成功处理不阻塞用例
405 24 : uint32_t feId = 0;
406 24 : IpAddress ipAddr{};
407 24 : if (GetLoopFeIpByDieId(dieId, feId, ipAddr) != HcclResult::HCCL_SUCCESS) {
408 0 : channelId = INVAILD_LOOP_CHANNEL_ID;
409 0 : HCCL_WARNING(
410 : "[CcuComponent][%s] failed but passed, dieId[%u] doesn't have loop feId, "
411 : "devLogicId[%d].",
412 : __func__, dieId, devLogicId);
413 0 : return HcclResult::HCCL_SUCCESS;
414 : }
415 :
416 24 : std::vector<ChannelInfo> channelInfos; // 按jetty组分配
417 24 : const ChannelPara channelPara{feId, LOOP_CHANNEL_USE_JETTY, LOOP_CHANNEL_USE_SQSIZE};
418 24 : auto ret = channelMgrs[dieId]->Alloc(channelPara, channelInfos);
419 24 : CHK_PRT_RET(
420 : ret != HCCL_SUCCESS,
421 : HCCL_WARNING(
422 : "[CcuComponent][%s] failed to alloc channel, "
423 : "devLogicId[%d], dieId[%u].",
424 : __func__, devLogicId, dieId),
425 : ret);
426 :
427 24 : const auto& channelInfo = channelInfos[0]; // 环回只使用1个channel
428 24 : ret = CreateAndImportLoopJettys(dieId, ipAddr, channelInfo.jettyInfos);
429 24 : CHK_PRT_RET(
430 : ret != HCCL_SUCCESS,
431 : HCCL_WARNING(
432 : "[CcuComponent][%s] failed to create or import loop jettys, "
433 : "devLogicId[%d], dieId[%u].",
434 : __func__, devLogicId, dieId),
435 : ret);
436 :
437 24 : ret = ConfigLoopChannel(dieId, ipAddr, channelInfo);
438 24 : CHK_PRT_RET(
439 : ret != HCCL_SUCCESS,
440 : HCCL_WARNING(
441 : "[CcuComponent][%s] failed to config the loop channel, "
442 : "devLogicId[%d], dieId[%u].",
443 : __func__, devLogicId, dieId),
444 : ret);
445 :
446 24 : channelId = channelInfo.channelId;
447 24 : return HcclResult::HCCL_SUCCESS;
448 24 : }
449 :
450 26 : JettyImportCfg GetJettyImportCfg(const TpInfo& tpInfo, const uint32_t& psn)
451 : {
452 26 : const TpHandle tpHandle = tpInfo.tpHandle;
453 78 : HCCL_INFO("[CcuComponent][%s] loop channel use tp handle[%llu] psn[%u].", __func__, tpHandle, psn);
454 :
455 26 : JettyImportCfg cfg = {};
456 26 : cfg.localTpHandle = tpHandle;
457 26 : cfg.remoteTpHandle = tpHandle;
458 26 : cfg.localPsn = psn;
459 26 : cfg.remotePsn = psn;
460 26 : cfg.protocol = LOOP_JETTY_PROTOCOL;
461 26 : return cfg;
462 : }
463 :
464 26 : HcclResult CcuComponent::CreateAndImportLoopJettys(
465 : const uint8_t dieId, const IpAddress& ipAddr, const vector<JettyInfo>& jettyInfos)
466 : {
467 26 : Hccl::CqCreateInfo cqInfo{};
468 26 : auto& rdmaHandleMgr = RdmaHandleManager::GetInstance();
469 26 : const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
470 26 : const auto jfcHandle = rdmaHandleMgr.GetJfcHandle(rdmaHandle, cqInfo, HrtUbJfcMode::CCU_POLL);
471 :
472 26 : const auto& rmaBufferIter = localCcuRmaBufferMap.find(dieId);
473 26 : CHK_PRT_RET(
474 : rmaBufferIter == localCcuRmaBufferMap.end(),
475 : HCCL_WARNING(
476 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
477 : "devLogicId[%d].",
478 : __func__, dieId, devLogicId),
479 : HcclResult::HCCL_E_NOT_FOUND);
480 :
481 26 : const auto& ccuRmaBuffer = rmaBufferIter->second;
482 26 : const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
483 :
484 26 : const auto& tpInfo = GetTpInfo(ipAddr);
485 26 : const auto tpAttrInfo = GetLoopTpAttr(ipAddr, tpInfo.tpHandle);
486 26 : const uint8_t errTimeout = TpManager::CalcTaTimeout(tpAttrInfo);
487 :
488 26 : auto& createdVec = createdOutParamMap[dieId];
489 26 : auto& importedVec = importedOutParamMap[dieId];
490 :
491 : // 与 Next 对齐:环回 Jetty qos 直接用 GetTpInfo(loopFirstTpLowestSl) 映射的 mappedJettyPriority
492 26 : const uint8_t loopJettyQos = tpInfo.hasMappedJettyPriority ?
493 1 : static_cast<uint8_t>(tpInfo.mappedJettyPriority & 0xFU) :
494 : static_cast<uint8_t>(UB_QOS_DEFAULT);
495 :
496 52 : for (const auto& jettyInfo : jettyInfos) {
497 26 : const auto jettyMode = HrtJettyMode::CCU_CCUM_CACHE; // 当前仅支持该模式
498 : HrtRaUbCreateJettyParam req{
499 : jfcHandle,
500 : jfcHandle,
501 : ccuBufTokenValue,
502 : 0,
503 : jettyMode,
504 26 : jettyInfo.taJettyId,
505 26 : jettyInfo.sqBufVa,
506 26 : jettyInfo.sqBufSize,
507 26 : jettyInfo.wqeBBStartId,
508 26 : jettyInfo.sqDepth,
509 26 : errTimeout};
510 26 : req.qos = loopJettyQos;
511 26 : auto createdOutParam = HrtRaUbCreateJetty(rdmaHandle, req);
512 26 : createdVec.emplace_back(createdOutParam);
513 :
514 26 : const auto psn = GetPsn(ipAddr);
515 26 : const auto jettyImportCfg = GetJettyImportCfg(tpInfo, psn);
516 26 : const auto importedOutParam = RaUbTpImportJetty(
517 : rdmaHandle, createdOutParam.key, createdOutParam.keySize, ccuBufTokenValue, jettyImportCfg);
518 26 : importedVec.emplace_back(ImportOutParamPair{rdmaHandle, importedOutParam});
519 : }
520 :
521 26 : return HcclResult::HCCL_SUCCESS;
522 : }
523 :
524 12 : TpInfo CcuComponent::RequestNewTpInfo(const IpAddress& srcIpAddr, const IpAddress& dstIpAddr) const
525 : {
526 12 : TpInfo tpInfo{};
527 :
528 12 : auto& tpManager = TpManager::GetInstance(devLogicId);
529 : // 与 Next `MakeLoopGetTpInfoParam` 对齐:环回与通信域 hcclQos 解耦;SL 由 GetTpAttr.slBitmap + loopFirstTpLowestSl
530 : // 决定
531 12 : const RaUbGetTpInfoParam loopParam = MakeCcuLoopRaUbGetTpInfoParam(srcIpAddr, dstIpAddr);
532 :
533 12 : const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
534 12 : const auto startTime = std::chrono::steady_clock::now();
535 12 : auto ret = tpManager.GetTpInfo(loopParam, tpInfo);
536 14 : while (ret == HcclResult::HCCL_E_AGAIN) {
537 2 : ret = tpManager.GetTpInfo(loopParam, tpInfo);
538 2 : if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
539 0 : THROW<InternalException>(
540 : "[CcuComponent][%s] failed, get tp info "
541 : "timeout[%d ms], devLogicId[%d].",
542 0 : __func__, timeout, devLogicId);
543 : }
544 : }
545 :
546 12 : if (ret != HcclResult::HCCL_SUCCESS) {
547 0 : THROW<InternalException>(
548 : "[CcuComponent][%s] failed, ret[%d], "
549 : "devLogicId[%d].",
550 0 : __func__, static_cast<int>(ret), devLogicId);
551 : }
552 :
553 12 : return tpInfo;
554 : }
555 :
556 26 : TpInfo CcuComponent::GetTpInfo(const IpAddress& ipAddr)
557 : {
558 26 : const auto& srcIter = tpInfoMap.find(ipAddr);
559 : // 优先使用已经创建过的tpHandle
560 26 : if (srcIter == tpInfoMap.end()) {
561 12 : const auto& tpInfo = RequestNewTpInfo(ipAddr, ipAddr);
562 12 : tpInfoMap[ipAddr] = tpInfo;
563 12 : return tpInfo;
564 : }
565 :
566 14 : return srcIter->second;
567 : }
568 :
569 28 : TpAttrInfo CcuComponent::GetLoopTpAttr(const IpAddress& ipAddr, const TpHandle tpHandle)
570 : {
571 28 : const auto& srcIter = tpAttrInfoMap.find(ipAddr);
572 28 : if (srcIter != tpAttrInfoMap.end()) {
573 15 : return srcIter->second;
574 : }
575 :
576 13 : auto& rdmaHandleMgr = RdmaHandleManager::GetInstance();
577 13 : const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
578 :
579 13 : constexpr uint32_t TP_ATTR_BITMAP = 0;
580 13 : const GetTpAttrParam tpAttrParam = {tpHandle, TP_ATTR_BITMAP};
581 :
582 13 : TpAttrInfo tpAttrInfo{};
583 13 : auto& tpMgr = TpManager::GetInstance(devLogicId);
584 13 : const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
585 13 : const auto startTime = std::chrono::steady_clock::now();
586 :
587 13 : HcclResult ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
588 16 : while (ret == HcclResult::HCCL_E_AGAIN) {
589 3 : if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
590 0 : THROW<InternalException>(
591 : "[CcuComponent][%s] failed, get tp attr "
592 : "timeout[%d ms], devLogicId[%d].",
593 : __func__, timeout, devLogicId);
594 : }
595 3 : ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
596 : }
597 :
598 13 : if (ret != HcclResult::HCCL_SUCCESS) {
599 0 : THROW<InternalException>(
600 : "[CcuComponent][%s] failed, ret[%u], "
601 : "devLogicId[%d].",
602 : __func__, ret, devLogicId);
603 : }
604 :
605 13 : tpAttrInfoMap[ipAddr] = tpAttrInfo;
606 13 : return tpAttrInfo;
607 : }
608 :
609 0 : inline uint32_t GetRandomNum()
610 : {
611 0 : uint32_t randNum = std::rand();
612 0 : return randNum;
613 : }
614 :
615 26 : uint32_t CcuComponent::GetPsn(const IpAddress& ipAddr)
616 : {
617 26 : const auto& srcIter = psnMap.find(ipAddr);
618 26 : if (srcIter == psnMap.end()) {
619 14 : const auto psn = GetRandomNum();
620 14 : psnMap[ipAddr] = psn;
621 14 : return psn;
622 : }
623 :
624 12 : return srcIter->second;
625 : }
626 :
627 24 : HcclResult CcuComponent::ConfigLoopChannel(const uint8_t dieId, const IpAddress& ipAddr, const ChannelInfo& channelInfo)
628 : {
629 72 : HCCL_INFO("[CcuComponent][%s] Create loop channel with another die's address, my dieId[%u]", __func__, dieId);
630 24 : auto rmaBufferIter = ccuRmaBufferMap.find(1 - dieId); // 需要配置另一die的rma buffer
631 24 : if (rmaBufferIter == ccuRmaBufferMap.end()) {
632 0 : HCCL_WARNING(
633 : "[CcuComponent][%s] Another die is not enable, create loop channel with my die[%u]", __func__, dieId);
634 0 : rmaBufferIter = ccuRmaBufferMap.find(dieId);
635 : }
636 24 : 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 24 : const auto& ccuRmaBuffer = rmaBufferIter->second;
645 24 : const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
646 :
647 24 : ChannelCfg cfg{};
648 24 : cfg.channelId = channelInfo.channelId;
649 24 : cfg.remoteEid = ipAddr.GetReverseEid();
650 72 : HCCL_INFO("[CcuComponent::ConfigLoopChannel] remoteEid=%s", cfg.remoteEid.Describe().c_str());
651 24 : cfg.tpn = importedOutParamMap[dieId][0].second.tpn;
652 :
653 24 : cfg.remoteCcuVa = ccuRmaBuffer->GetBuf()->GetAddr();
654 24 : cfg.memTokenId = ccuRmaBuffer->GetTokenId();
655 24 : cfg.memTokenValue = ccuBufTokenValue;
656 :
657 24 : const auto& jettyInfos = channelInfo.jettyInfos;
658 24 : const auto& createdVec = createdOutParamMap[dieId];
659 24 : const uint32_t jettyNum = jettyInfos.size();
660 48 : for (uint32_t i = 0; i < jettyNum; i++) {
661 24 : cfg.jettyCfgs.emplace_back(
662 24 : JettyCfg{jettyInfos[i].jettyCtxId, createdVec[i].dbVa, createdVec[i].dbTokenId, ccuBufTokenValue});
663 : }
664 :
665 24 : CHK_PTR_NULL(channelMgrs[dieId]);
666 24 : return channelMgrs[dieId]->Config(cfg);
667 24 : }
668 :
669 12 : void CcuComponent::ConfigMsIdToken()
670 : {
671 12 : bool isAX = CcuResSpecifications::GetInstance(devLogicId).GetAXFlag();
672 12 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
673 12 : CHECK_NULLPTR(
674 24 : tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
675 :
676 12 : struct CustomChannelInfoIn inBuff {};
677 12 : struct CustomChannelInfoOut outBuff {};
678 :
679 36 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
680 24 : const auto& dieIter = localCcuRmaBufferMap.find(dieId);
681 24 : if (dieIter == localCcuRmaBufferMap.end()) {
682 0 : HCCL_WARNING(
683 : "[CcuComponent][%s] failed but passed, ccu rma buffer of die[%u] "
684 : "is not existed, devLogicId[%d].",
685 : __func__, dieId, devLogicId);
686 0 : continue;
687 0 : }
688 24 : const auto& ccuRmaBuffer = dieIter->second;
689 24 : const uint32_t tokenId = ccuRmaBuffer->GetTokenId();
690 24 : const uint32_t tokenValue = ccuRmaBuffer->GetTokenValue();
691 24 : uint32_t msId = 0;
692 24 : CHK_RET_THROW(
693 : InternalException,
694 : StringFormat("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId),
695 : CcuResSpecifications::GetInstance(devLogicId).GetMsId(dieId, msId));
696 :
697 24 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_MSID_TOKEN;
698 24 : inBuff.offsetStartIdx = 0;
699 24 : inBuff.data.dataInfo.udieIdx = dieId;
700 :
701 24 : if (isAX && dieId == 0) { // A+X环境,给udie0配置新的交织粒度
702 0 : msId = MSID_CONFIG_AX_MAINBOARD;
703 : }
704 24 : inBuff.data.dataInfo.dataArray[0].baseinfo.msId = msId;
705 24 : inBuff.data.dataInfo.dataArray[0].baseinfo.tokenId = tokenId;
706 24 : inBuff.data.dataInfo.dataArray[0].baseinfo.tokenValue = tokenValue;
707 :
708 24 : HrtRaTlvRequestForCustomChannel(
709 : tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
710 :
711 72 : HCCL_INFO("[CcuComponent][%s] config MS ID token success, dieId[%u], msid[%u]", __func__, dieId, msId);
712 : }
713 12 : }
714 :
715 0 : HcclResult CcuComponent::GetCcuResourceSpaceBufInfo(const uint8_t dieId, uint64_t& addr, uint64_t& size) const
716 : {
717 0 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
718 :
719 0 : auto res = ccuRmaBufferMap.find(dieId);
720 0 : CHK_PRT_RET(
721 : res == ccuRmaBufferMap.end(),
722 : HCCL_WARNING(
723 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
724 : "devLogicId[%d].",
725 : __func__, dieId, devLogicId),
726 : HcclResult::HCCL_E_NOT_FOUND);
727 :
728 0 : const auto rawBuffer = res->second->GetBuf();
729 0 : addr = static_cast<uint64_t>(rawBuffer->GetAddr());
730 0 : size = static_cast<uint64_t>(rawBuffer->GetSize());
731 0 : return HcclResult::HCCL_SUCCESS;
732 : }
733 :
734 : HcclResult
735 0 : CcuComponent::GetCcuResourceSpaceTokenInfoForLocal(const uint8_t dieId, uint64_t& tokenId, uint64_t& tokenValue) const
736 : {
737 0 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
738 :
739 0 : auto res = localCcuRmaBufferMap.find(dieId);
740 0 : CHK_PRT_RET(
741 : res == localCcuRmaBufferMap.end(),
742 : HCCL_WARNING(
743 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
744 : "devLogicId[%d].",
745 : __func__, dieId, devLogicId),
746 : HcclResult::HCCL_E_NOT_FOUND);
747 :
748 0 : const auto& ccuRmaBuffer = res->second;
749 0 : tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
750 0 : tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
751 0 : return HcclResult::HCCL_SUCCESS;
752 : }
753 :
754 : HcclResult
755 0 : CcuComponent::GetCcuResourceSpaceTokenInfo(const uint8_t dieId, uint64_t& tokenId, uint64_t& tokenValue) const
756 : {
757 0 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
758 :
759 0 : auto res = ccuRmaBufferMap.find(dieId);
760 0 : CHK_PRT_RET(
761 : res == ccuRmaBufferMap.end(),
762 : HCCL_WARNING(
763 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
764 : "devLogicId[%d].",
765 : __func__, dieId, devLogicId),
766 : HcclResult::HCCL_E_NOT_FOUND);
767 :
768 0 : const auto& ccuRmaBuffer = res->second;
769 0 : tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
770 0 : tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
771 0 : return HcclResult::HCCL_SUCCESS;
772 : }
773 :
774 : HcclResult
775 5 : CcuComponent::AllocChannels(const uint8_t dieId, const ChannelPara& channelPara, std::vector<ChannelInfo>& channelInfos)
776 : {
777 8 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
778 :
779 4 : CHK_PTR_NULL(channelMgrs[dieId]);
780 4 : auto ret = channelMgrs[dieId]->Alloc(channelPara, channelInfos);
781 4 : CHK_PRT_RET(
782 : ret != HcclResult::HCCL_SUCCESS,
783 : HCCL_WARNING(
784 : "[CcuComponent][%s] failed, feId[%u], devLogicId[%d], dieId[%u].", __func__, channelPara.feId, devLogicId,
785 : dieId),
786 : ret);
787 :
788 4 : return HcclResult::HCCL_SUCCESS;
789 : }
790 :
791 6 : HcclResult CcuComponent::ConfigChannel(const uint8_t dieId, const ChannelCfg& cfg)
792 : {
793 6 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
794 :
795 6 : uint32_t channelId = cfg.channelId;
796 9 : CHK_PRT_RET(
797 : channelId == loopChannelIds[dieId],
798 : HCCL_WARNING(
799 : "[CcuComponent][%s] failed, refused to config loop channel[%u], "
800 : "devLogicId[%d], dieId[%u].",
801 : __func__, channelId, devLogicId, dieId),
802 : HcclResult::HCCL_E_PARA);
803 :
804 5 : CHK_PTR_NULL(channelMgrs[dieId]);
805 5 : auto ret = channelMgrs[dieId]->Config(cfg);
806 14 : CHK_PRT_RET(
807 : ret != HcclResult::HCCL_SUCCESS,
808 : HCCL_WARNING(
809 : "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId,
810 : dieId),
811 : ret);
812 :
813 2 : return HcclResult::HCCL_SUCCESS;
814 : }
815 :
816 4 : HcclResult CcuComponent::ReleaseChannel(const uint8_t dieId, const uint32_t channelId)
817 : {
818 4 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
819 7 : CHK_PRT_RET(
820 : channelId == loopChannelIds[dieId],
821 : HCCL_WARNING(
822 : "[CcuComponent][%s] failed, refused to release loop channel[%u], "
823 : "devLogicId[%d], dieId[%u].",
824 : __func__, channelId, devLogicId, dieId),
825 : HcclResult::HCCL_E_PARA);
826 :
827 3 : CHK_PTR_NULL(channelMgrs[dieId]);
828 3 : auto ret = channelMgrs[dieId]->Release(channelId);
829 6 : CHK_PRT_RET(
830 : ret != HcclResult::HCCL_SUCCESS,
831 : HCCL_WARNING(
832 : "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId,
833 : dieId),
834 : ret);
835 :
836 2 : return HcclResult::HCCL_SUCCESS;
837 : }
838 :
839 4 : HcclResult CcuComponent::GetLoopChannelId(const uint8_t srcDieId, const uint8_t dstDieId, uint32_t& channelId) const
840 : {
841 4 : channelId = INVAILD_LOOP_CHANNEL_ID; // 允许die未启用时查询环回channelId
842 4 : CHK_RET(CheckDieValid(__func__, devLogicId, srcDieId, {true, true}));
843 4 : CHK_RET(CheckDieValid(__func__, devLogicId, dstDieId, {true, true}));
844 :
845 4 : CHK_PRT_RET(
846 : loopChannelIds[srcDieId] == INVAILD_LOOP_CHANNEL_ID, // 环回channel每个die共用1个
847 : HCCL_WARNING(
848 : "[CcuComponent][%s] failed, invalid loop channel id, "
849 : "devLogicId[%d], srcDieId[%u].",
850 : __func__, devLogicId, srcDieId),
851 : HcclResult::HCCL_E_INTERNAL);
852 :
853 4 : channelId = loopChannelIds[srcDieId];
854 4 : return HcclResult::HCCL_SUCCESS;
855 : }
856 :
857 34 : HcclResult CcuComponent::AllocRes(
858 : const uint8_t dieId, const ResType resType, const uint32_t num, const bool consecutive, vector<ResInfo>& resInfos)
859 : {
860 34 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
861 :
862 34 : CHK_PTR_NULL(resAllocators[dieId]);
863 34 : auto ret = resAllocators[dieId]->Alloc(resType, num, consecutive, resInfos);
864 37 : CHK_PRT_RET(
865 : ret != HcclResult::HCCL_SUCCESS,
866 : HCCL_WARNING(
867 : "[CcuComponent][%s] failed, resType[%s], num[%u], devLogicId[%d], dieId[%u].", __func__,
868 : resType.Describe().c_str(), num, devLogicId, dieId),
869 : ret);
870 :
871 33 : return HcclResult::HCCL_SUCCESS;
872 : }
873 :
874 : HcclResult
875 9 : CcuComponent::ReleaseRes(const uint8_t dieId, const ResType resType, const uint32_t startId, const uint32_t num)
876 : {
877 9 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
878 :
879 9 : CHK_PTR_NULL(resAllocators[dieId]);
880 9 : auto ret = resAllocators[dieId]->Release(resType, startId, num);
881 9 : CHK_PRT_RET(
882 : ret != HcclResult::HCCL_SUCCESS,
883 : HCCL_WARNING(
884 : "[CcuComponent][%s] failed, resType[%s], startId[%u], num[%u], "
885 : "devLogicId[%d], dieId[%u].",
886 : __func__, resType.Describe().c_str(), startId, num, devLogicId, dieId),
887 : ret);
888 :
889 9 : return HcclResult::HCCL_SUCCESS;
890 : }
891 :
892 0 : uint32_t CcuComponent::GetInsConsecutiveRemainSize(const uint8_t dieId) const
893 : {
894 0 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
895 0 : if (resAllocators[dieId] == nullptr)
896 0 : return 0;
897 0 : return resAllocators[dieId]->GetConsecutiveRemainSize(ResType::INS);
898 : }
899 :
900 7 : HcclResult CcuComponent::AllocIns(const uint8_t dieId, const uint32_t num, ResInfo& insInfo)
901 : {
902 10 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
903 6 : CHK_PTR_NULL(resAllocators[dieId]);
904 :
905 6 : vector<ResInfo> resInfos;
906 6 : auto ret = resAllocators[dieId]->Alloc(ResType::INS, num, true, resInfos);
907 15 : CHK_PRT_RET(
908 : ret != HcclResult::HCCL_SUCCESS,
909 : HCCL_WARNING(
910 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
911 : ret);
912 :
913 3 : insInfo = resInfos[0]; // 申请连续资源只会有一份
914 3 : return HcclResult::HCCL_SUCCESS;
915 6 : }
916 :
917 4 : HcclResult CcuComponent::ReleaseIns(const uint8_t dieId, const ResInfo& insInfo)
918 : {
919 7 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
920 3 : CHK_PTR_NULL(resAllocators[dieId]);
921 :
922 3 : auto ret = resAllocators[dieId]->Release(ResType::INS, insInfo.startId, insInfo.num);
923 3 : CHK_PRT_RET(
924 : ret != HcclResult::HCCL_SUCCESS,
925 : HCCL_WARNING(
926 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__, insInfo.Describe().c_str(),
927 : devLogicId, dieId),
928 : ret);
929 :
930 3 : return HcclResult::HCCL_SUCCESS;
931 : }
932 :
933 184 : HcclResult CcuComponent::AllocCke(const uint8_t dieId, const uint32_t num, vector<ResInfo>& ckeInfos)
934 : {
935 715 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
936 7 : CHK_PTR_NULL(resAllocators[dieId]);
937 :
938 7 : auto ret = resAllocators[dieId]->Alloc(ResType::CKE, num, false, ckeInfos);
939 16 : CHK_PRT_RET(
940 : ret != HcclResult::HCCL_SUCCESS,
941 : HCCL_WARNING(
942 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
943 : ret);
944 :
945 4 : return HcclResult::HCCL_SUCCESS;
946 : }
947 :
948 30 : HcclResult CcuComponent::ReleaseCke(const uint8_t dieId, const vector<ResInfo>& ckeInfos)
949 : {
950 99 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
951 7 : CHK_PTR_NULL(resAllocators[dieId]);
952 :
953 12 : for (auto& ckeInfo : ckeInfos) {
954 7 : auto ret = resAllocators[dieId]->Release(ResType::CKE, ckeInfo.startId, ckeInfo.num);
955 13 : CHK_PRT_RET(
956 : ret != HcclResult::HCCL_SUCCESS,
957 : HCCL_WARNING(
958 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
959 : ckeInfo.Describe().c_str(), devLogicId, dieId),
960 : ret);
961 : }
962 :
963 5 : return HcclResult::HCCL_SUCCESS;
964 : }
965 :
966 7 : HcclResult CcuComponent::AllocXn(const uint8_t dieId, const uint32_t num, vector<ResInfo>& xnInfos)
967 : {
968 10 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
969 6 : CHK_PTR_NULL(resAllocators[dieId]);
970 :
971 6 : auto ret = resAllocators[dieId]->Alloc(ResType::XN, num, false, xnInfos);
972 15 : CHK_PRT_RET(
973 : ret != HcclResult::HCCL_SUCCESS,
974 : HCCL_WARNING(
975 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
976 : ret);
977 :
978 3 : return HcclResult::HCCL_SUCCESS;
979 : }
980 :
981 4 : HcclResult CcuComponent::ReleaseXn(const uint8_t dieId, const vector<ResInfo>& xnInfos)
982 : {
983 7 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
984 3 : CHK_PTR_NULL(resAllocators[dieId]);
985 :
986 6 : for (auto& xnInfo : xnInfos) {
987 3 : auto ret = resAllocators[dieId]->Release(ResType::XN, xnInfo.startId, xnInfo.num);
988 3 : CHK_PRT_RET(
989 : ret != HcclResult::HCCL_SUCCESS,
990 : HCCL_WARNING(
991 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
992 : xnInfo.Describe().c_str(), devLogicId, dieId),
993 : ret);
994 : }
995 :
996 3 : return HcclResult::HCCL_SUCCESS;
997 : }
998 :
999 : // 以下接口用于n秒快恢与TaskException
1000 29 : HcclResult CcuComponent::CleanDieCkes(const uint8_t dieId) const
1001 : {
1002 29 : CHK_PRT_RET(
1003 : dieId >= MAX_CCU_IODIE_NUM,
1004 : HCCL_WARNING(
1005 : "[CcuComponent][%s] failed, dieId[%u] is invalid, shoudle be in [0-%u), devLogicId[%d].", __func__, dieId,
1006 : MAX_CCU_IODIE_NUM, devLogicId),
1007 : HcclResult::HCCL_E_PARA);
1008 :
1009 29 : if (!dieEnableFlags[dieId]) {
1010 4 : return HcclResult::HCCL_SUCCESS;
1011 : }
1012 :
1013 25 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
1014 25 : CHK_PTR_NULL(tlvHandle);
1015 25 : CustomChannelInfoIn inBuff{};
1016 25 : CustomChannelInfoOut outBuff{};
1017 :
1018 : // 设置操作码和数据
1019 25 : uint32_t ckeNum = 0;
1020 25 : CHK_RET(CcuResSpecifications::GetInstance(devLogicId).GetCkeNum(dieId, ckeNum));
1021 75 : HCCL_INFO("[CcuComponent][CleanAllCke]Nsrecovery devLogicId[%d], dieId[%u] ckeNum[%u].", devLogicId, dieId, ckeNum);
1022 :
1023 25 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_CKE;
1024 25 : inBuff.data.dataInfo.udieIdx = dieId;
1025 : // 接口限制,目前方案每次最多清理8个cke,超过8个时分多次清理
1026 3225 : for (uint32_t startIdx = 0; startIdx < ckeNum; startIdx += MAX_CKE_DATA_ARRAY_SIZE) {
1027 3200 : inBuff.data.dataInfo.dataArraySize = std::min(ckeNum - startIdx, MAX_CKE_DATA_ARRAY_SIZE);
1028 3200 : inBuff.data.dataInfo.dataLen = sizeof(CcuDataByte8) * inBuff.data.dataInfo.dataArraySize;
1029 3200 : inBuff.offsetStartIdx = startIdx;
1030 3200 : HrtRaTlvRequestForCustomChannel(
1031 : tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
1032 : }
1033 :
1034 25 : return HcclResult::HCCL_SUCCESS;
1035 : }
1036 :
1037 26 : void CcuComponent::SetProcess(CcuOpcodeType opCode) const
1038 : {
1039 26 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
1040 26 : CHECK_NULLPTR(
1041 52 : tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
1042 :
1043 26 : struct CustomChannelInfoIn inBuff;
1044 26 : struct CustomChannelInfoOut outBuff;
1045 :
1046 26 : inBuff.op = opCode;
1047 78 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
1048 52 : if (!dieEnableFlags[dieId]) {
1049 0 : HCCL_WARNING(
1050 : "[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] is not enable,"
1051 : "skip SetProcess.",
1052 : devLogicId, dieId);
1053 0 : continue;
1054 0 : }
1055 156 : HCCL_INFO("[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] start.", devLogicId, dieId);
1056 52 : inBuff.data.dataInfo.udieIdx = dieId;
1057 52 : HrtRaTlvRequestForCustomChannel(
1058 : tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
1059 : }
1060 26 : }
1061 :
1062 13 : HcclResult CcuComponent::SetTaskKill()
1063 : {
1064 13 : std::lock_guard<std::mutex> _lock(taskKillMutex_);
1065 :
1066 13 : if (status == CcuTaskKillStatus::INVALID) {
1067 12 : status = CcuTaskKillStatus::INIT;
1068 : }
1069 :
1070 13 : if (status == CcuTaskKillStatus::TASK_KILL) {
1071 0 : HCCL_INFO("No need to set task kill, state = %u, devLogicId = %u", status, devLogicId);
1072 0 : return HcclResult::HCCL_SUCCESS;
1073 : }
1074 :
1075 13 : if (status != CcuTaskKillStatus::INIT) {
1076 0 : HCCL_ERROR(
1077 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1078 : "state = %u, devLogicId = %d.",
1079 : __func__, status, devLogicId);
1080 0 : return HcclResult::HCCL_E_INTERNAL;
1081 : }
1082 :
1083 13 : SetProcess(CcuOpcodeType::CCU_U_OP_SET_TASKKILL);
1084 13 : status = CcuTaskKillStatus::TASK_KILL;
1085 39 : HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d.", __func__, status, devLogicId);
1086 13 : return HcclResult::HCCL_SUCCESS;
1087 13 : }
1088 :
1089 13 : HcclResult CcuComponent::SetTaskKillDone()
1090 : {
1091 13 : std::lock_guard<std::mutex> _lock(taskKillMutex_);
1092 :
1093 13 : if (status == CcuTaskKillStatus::INVALID) {
1094 0 : HCCL_ERROR(
1095 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1096 : "state = %u, devLogicId = %d.",
1097 : __func__, status, devLogicId);
1098 0 : return HcclResult::HCCL_E_INTERNAL;
1099 : }
1100 :
1101 13 : if (status == CcuTaskKillStatus::INIT) {
1102 0 : HCCL_INFO("No need to set task kill done, state = %u, devLogicId = %u", status, devLogicId);
1103 0 : return HcclResult::HCCL_SUCCESS;
1104 : }
1105 :
1106 13 : if (status != CcuTaskKillStatus::TASK_KILL) {
1107 0 : HCCL_ERROR(
1108 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1109 : "state = %u, devLogicId = %d.",
1110 : __func__, status, devLogicId);
1111 0 : return HcclResult::HCCL_E_INTERNAL;
1112 : }
1113 :
1114 13 : SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
1115 13 : status = CcuTaskKillStatus::INIT;
1116 39 : HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d", __func__, status, devLogicId);
1117 13 : return HcclResult::HCCL_SUCCESS;
1118 13 : }
1119 :
1120 0 : HcclResult CcuComponent::CleanTaskKillState() const
1121 : {
1122 0 : SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
1123 0 : return HcclResult::HCCL_SUCCESS;
1124 : }
1125 :
1126 2 : const std::array<bool, MAX_CCU_IODIE_NUM>& CcuComponent::GetDieEnableFlags() const { return dieEnableFlags; }
1127 :
1128 81 : CcuComponent::~CcuComponent() { DECTOR_TRY_CATCH("CcuComponent", ReleaseJettyRes()); }
1129 :
1130 83 : void CcuComponent::ReleaseJettyRes()
1131 : {
1132 83 : UnimportAllJetty();
1133 83 : DestroyAllJetty();
1134 : // HrtRaUbLocalMemReg 跟随 LocalUbRmaBuffer 析构时释放
1135 : // 环回channel不需要手动释放,channelMgr跟随CcuComponent释放
1136 83 : }
1137 :
1138 83 : void CcuComponent::UnimportAllJetty()
1139 : {
1140 : // tpInfo不需要主动释放,因为CcuComponent生命周期与TpManager一致
1141 109 : for (auto& importedVec : importedOutParamMap) {
1142 52 : for (auto& paramPair : importedVec.second) {
1143 26 : const auto rdmaHandle = paramPair.first;
1144 26 : const auto remoteJettyHandle = paramPair.second.handle;
1145 26 : if (rdmaHandle != nullptr && remoteJettyHandle != 0) {
1146 0 : paramPair.second.handle = 0;
1147 0 : HrtRaUbUnimportJetty(rdmaHandle, remoteJettyHandle);
1148 : }
1149 : }
1150 : }
1151 :
1152 83 : importedOutParamMap.clear();
1153 83 : }
1154 :
1155 83 : void CcuComponent::DestroyAllJetty()
1156 : {
1157 109 : for (auto& createdVec : createdOutParamMap) {
1158 52 : for (auto& param : createdVec.second) {
1159 26 : const auto jettyHandle = param.handle;
1160 26 : if (jettyHandle != 0) {
1161 0 : param.handle = 0;
1162 0 : HrtRaUbDestroyJetty(jettyHandle);
1163 : }
1164 : }
1165 : }
1166 83 : createdOutParamMap.clear();
1167 83 : }
1168 :
1169 : }; // namespace Hccl
|