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 275 : CcuComponent& CcuComponent::GetInstance(const int32_t deviceLogicId)
69 : {
70 341 : static CcuComponent ccuComponent[MAX_MODULE_DEVICE_NUM + 1];
71 :
72 275 : 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 275 : ccuComponent[deviceLogicId].devLogicId = deviceLogicId;
80 275 : 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 : uint32_t tpTimeOutMs = 0;
487 26 : (void)TpManager::GetTpTotalTimeout(tpAttrInfo, tpTimeOutMs);
488 26 : const auto errTimeout = TpManager::CalcTaTimeout(LOOP_JETTY_PROTOCOL, TpManager::TA_TIMEOUT_NOT_SET, tpTimeOutMs);
489 :
490 26 : auto& createdVec = createdOutParamMap[dieId];
491 26 : auto& importedVec = importedOutParamMap[dieId];
492 :
493 : // 与 Next 对齐:环回 Jetty qos 直接用 GetTpInfo(loopFirstTpLowestSl) 映射的 mappedJettyPriority
494 26 : const uint8_t loopJettyQos = tpInfo.hasMappedJettyPriority ?
495 1 : static_cast<uint8_t>(tpInfo.mappedJettyPriority & 0xFU) :
496 : static_cast<uint8_t>(UB_QOS_DEFAULT);
497 :
498 52 : for (const auto& jettyInfo : jettyInfos) {
499 26 : const auto jettyMode = HrtJettyMode::CCU_CCUM_CACHE; // 当前仅支持该模式
500 : HrtRaUbCreateJettyParam req{
501 : jfcHandle,
502 : jfcHandle,
503 : ccuBufTokenValue,
504 : 0,
505 : jettyMode,
506 26 : jettyInfo.taJettyId,
507 26 : jettyInfo.sqBufVa,
508 26 : jettyInfo.sqBufSize,
509 26 : jettyInfo.wqeBBStartId,
510 26 : jettyInfo.sqDepth,
511 26 : errTimeout};
512 26 : req.qos = loopJettyQos;
513 26 : auto createdOutParam = HrtRaUbCreateJetty(rdmaHandle, req);
514 26 : createdVec.emplace_back(createdOutParam);
515 :
516 26 : const auto psn = GetPsn(ipAddr);
517 26 : const auto jettyImportCfg = GetJettyImportCfg(tpInfo, psn);
518 26 : const auto importedOutParam = RaUbTpImportJetty(
519 : rdmaHandle, createdOutParam.key, createdOutParam.keySize, ccuBufTokenValue, jettyImportCfg);
520 26 : importedVec.emplace_back(ImportOutParamPair{rdmaHandle, importedOutParam});
521 : }
522 :
523 26 : return HcclResult::HCCL_SUCCESS;
524 : }
525 :
526 12 : TpInfo CcuComponent::RequestNewTpInfo(const IpAddress& srcIpAddr, const IpAddress& dstIpAddr) const
527 : {
528 12 : TpInfo tpInfo{};
529 :
530 12 : auto& tpManager = TpManager::GetInstance(devLogicId);
531 : // 与 Next `MakeLoopGetTpInfoParam` 对齐:环回与通信域 hcclQos 解耦;SL 由 GetTpAttr.slBitmap + loopFirstTpLowestSl
532 : // 决定
533 12 : const RaUbGetTpInfoParam loopParam = MakeCcuLoopRaUbGetTpInfoParam(srcIpAddr, dstIpAddr);
534 :
535 12 : const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
536 12 : const auto startTime = std::chrono::steady_clock::now();
537 12 : auto ret = tpManager.GetTpInfo(loopParam, tpInfo);
538 14 : while (ret == HcclResult::HCCL_E_AGAIN) {
539 2 : ret = tpManager.GetTpInfo(loopParam, tpInfo);
540 2 : if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
541 0 : THROW<InternalException>(
542 : "[CcuComponent][%s] failed, get tp info "
543 : "timeout[%d ms], devLogicId[%d].",
544 0 : __func__, timeout, devLogicId);
545 : }
546 : }
547 :
548 12 : if (ret != HcclResult::HCCL_SUCCESS) {
549 0 : THROW<InternalException>(
550 : "[CcuComponent][%s] failed, ret[%d], "
551 : "devLogicId[%d].",
552 0 : __func__, static_cast<int>(ret), devLogicId);
553 : }
554 :
555 12 : return tpInfo;
556 : }
557 :
558 26 : TpInfo CcuComponent::GetTpInfo(const IpAddress& ipAddr)
559 : {
560 26 : const auto& srcIter = tpInfoMap.find(ipAddr);
561 : // 优先使用已经创建过的tpHandle
562 26 : if (srcIter == tpInfoMap.end()) {
563 12 : const auto& tpInfo = RequestNewTpInfo(ipAddr, ipAddr);
564 12 : tpInfoMap[ipAddr] = tpInfo;
565 12 : return tpInfo;
566 : }
567 :
568 14 : return srcIter->second;
569 : }
570 :
571 28 : TpAttrInfo CcuComponent::GetLoopTpAttr(const IpAddress& ipAddr, const TpHandle tpHandle)
572 : {
573 28 : const auto& srcIter = tpAttrInfoMap.find(ipAddr);
574 28 : if (srcIter != tpAttrInfoMap.end()) {
575 15 : return srcIter->second;
576 : }
577 :
578 13 : auto& rdmaHandleMgr = RdmaHandleManager::GetInstance();
579 13 : const auto rdmaHandle = rdmaHandleMgr.GetByIp(devPhyId, ipAddr);
580 :
581 13 : constexpr uint32_t kTpAttrRetryTimesInitBit = 0U;
582 13 : constexpr uint32_t kTpAttrAtBit = 1U;
583 13 : constexpr uint32_t TP_ATTR_BITMAP = (1U << kTpAttrRetryTimesInitBit) | (1U << kTpAttrAtBit);
584 13 : const GetTpAttrParam tpAttrParam = {tpHandle, TP_ATTR_BITMAP};
585 :
586 13 : TpAttrInfo tpAttrInfo{};
587 13 : auto& tpMgr = TpManager::GetInstance(devLogicId);
588 13 : const auto timeout = std::chrono::milliseconds(LOOP_CHANNEL_WAIT_TIMEOUT_MS);
589 13 : const auto startTime = std::chrono::steady_clock::now();
590 :
591 13 : HcclResult ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
592 16 : while (ret == HcclResult::HCCL_E_AGAIN) {
593 3 : if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
594 0 : THROW<InternalException>(
595 : "[CcuComponent][%s] failed, get tp attr "
596 : "timeout[%d ms], devLogicId[%d].",
597 : __func__, timeout, devLogicId);
598 : }
599 3 : ret = tpMgr.GetTpAttr(tpAttrParam, tpAttrInfo, rdmaHandle);
600 : }
601 :
602 13 : if (ret != HcclResult::HCCL_SUCCESS) {
603 0 : THROW<InternalException>(
604 : "[CcuComponent][%s] failed, ret[%u], "
605 : "devLogicId[%d].",
606 : __func__, ret, devLogicId);
607 : }
608 :
609 13 : tpAttrInfoMap[ipAddr] = tpAttrInfo;
610 13 : return tpAttrInfo;
611 : }
612 :
613 0 : inline uint32_t GetRandomNum()
614 : {
615 0 : uint32_t randNum = std::rand();
616 0 : return randNum;
617 : }
618 :
619 26 : uint32_t CcuComponent::GetPsn(const IpAddress& ipAddr)
620 : {
621 26 : const auto& srcIter = psnMap.find(ipAddr);
622 26 : if (srcIter == psnMap.end()) {
623 14 : const auto psn = GetRandomNum();
624 14 : psnMap[ipAddr] = psn;
625 14 : return psn;
626 : }
627 :
628 12 : return srcIter->second;
629 : }
630 :
631 24 : HcclResult CcuComponent::ConfigLoopChannel(const uint8_t dieId, const IpAddress& ipAddr, const ChannelInfo& channelInfo)
632 : {
633 72 : HCCL_INFO("[CcuComponent][%s] Create loop channel with another die's address, my dieId[%u]", __func__, dieId);
634 24 : auto rmaBufferIter = ccuRmaBufferMap.find(1 - dieId); // 需要配置另一die的rma buffer
635 24 : if (rmaBufferIter == ccuRmaBufferMap.end()) {
636 0 : HCCL_WARNING(
637 : "[CcuComponent][%s] Another die is not enable, create loop channel with my die[%u]", __func__, dieId);
638 0 : rmaBufferIter = ccuRmaBufferMap.find(dieId);
639 : }
640 24 : CHK_PRT_RET(
641 : rmaBufferIter == ccuRmaBufferMap.end(),
642 : HCCL_WARNING(
643 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
644 : "devLogicId[%d].",
645 : __func__, dieId, devLogicId),
646 : HcclResult::HCCL_E_NOT_FOUND);
647 :
648 24 : const auto& ccuRmaBuffer = rmaBufferIter->second;
649 24 : const auto ccuBufTokenValue = ccuRmaBuffer->GetTokenValue();
650 :
651 24 : ChannelCfg cfg{};
652 24 : cfg.channelId = channelInfo.channelId;
653 24 : cfg.remoteEid = ipAddr.GetReverseEid();
654 72 : HCCL_INFO("[CcuComponent::ConfigLoopChannel] remoteEid=%s", cfg.remoteEid.Describe().c_str());
655 24 : cfg.tpn = importedOutParamMap[dieId][0].second.tpn;
656 :
657 24 : cfg.remoteCcuVa = ccuRmaBuffer->GetBuf()->GetAddr();
658 24 : cfg.memTokenId = ccuRmaBuffer->GetTokenId();
659 24 : cfg.memTokenValue = ccuBufTokenValue;
660 :
661 24 : const auto& jettyInfos = channelInfo.jettyInfos;
662 24 : const auto& createdVec = createdOutParamMap[dieId];
663 24 : const uint32_t jettyNum = jettyInfos.size();
664 48 : for (uint32_t i = 0; i < jettyNum; i++) {
665 24 : cfg.jettyCfgs.emplace_back(
666 24 : JettyCfg{jettyInfos[i].jettyCtxId, createdVec[i].dbVa, createdVec[i].dbTokenId, ccuBufTokenValue});
667 : }
668 :
669 24 : CHK_PTR_NULL(channelMgrs[dieId]);
670 24 : return channelMgrs[dieId]->Config(cfg);
671 24 : }
672 :
673 12 : void CcuComponent::ConfigMsIdToken()
674 : {
675 12 : bool isAX = CcuResSpecifications::GetInstance(devLogicId).GetAXFlag();
676 12 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
677 12 : CHECK_NULLPTR(
678 24 : tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
679 :
680 12 : struct CustomChannelInfoIn inBuff {};
681 12 : struct CustomChannelInfoOut outBuff {};
682 :
683 36 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
684 24 : const auto& dieIter = localCcuRmaBufferMap.find(dieId);
685 24 : if (dieIter == localCcuRmaBufferMap.end()) {
686 0 : HCCL_WARNING(
687 : "[CcuComponent][%s] failed but passed, ccu rma buffer of die[%u] "
688 : "is not existed, devLogicId[%d].",
689 : __func__, dieId, devLogicId);
690 0 : continue;
691 0 : }
692 24 : const auto& ccuRmaBuffer = dieIter->second;
693 24 : const uint32_t tokenId = ccuRmaBuffer->GetTokenId();
694 24 : const uint32_t tokenValue = ccuRmaBuffer->GetTokenValue();
695 24 : uint32_t msId = 0;
696 24 : CHK_RET_THROW(
697 : InternalException,
698 : StringFormat("[CcuComponent][%s] failed, devLogicId[%d], dieId[%u].", __func__, devLogicId, dieId),
699 : CcuResSpecifications::GetInstance(devLogicId).GetMsId(dieId, msId));
700 :
701 24 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_MSID_TOKEN;
702 24 : inBuff.offsetStartIdx = 0;
703 24 : inBuff.data.dataInfo.udieIdx = dieId;
704 :
705 24 : if (isAX && dieId == 0) { // A+X环境,给udie0配置新的交织粒度
706 0 : msId = MSID_CONFIG_AX_MAINBOARD;
707 : }
708 24 : inBuff.data.dataInfo.dataArray[0].baseinfo.msId = msId;
709 24 : inBuff.data.dataInfo.dataArray[0].baseinfo.tokenId = tokenId;
710 24 : inBuff.data.dataInfo.dataArray[0].baseinfo.tokenValue = tokenValue;
711 :
712 24 : HrtRaTlvRequestForCustomChannel(
713 : tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
714 :
715 72 : HCCL_INFO("[CcuComponent][%s] config MS ID token success, dieId[%u], msid[%u]", __func__, dieId, msId);
716 : }
717 12 : }
718 :
719 0 : HcclResult CcuComponent::GetCcuResourceSpaceBufInfo(const uint8_t dieId, uint64_t& addr, uint64_t& size) const
720 : {
721 0 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
722 :
723 0 : auto res = ccuRmaBufferMap.find(dieId);
724 0 : CHK_PRT_RET(
725 : res == ccuRmaBufferMap.end(),
726 : HCCL_WARNING(
727 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
728 : "devLogicId[%d].",
729 : __func__, dieId, devLogicId),
730 : HcclResult::HCCL_E_NOT_FOUND);
731 :
732 0 : const auto rawBuffer = res->second->GetBuf();
733 0 : addr = static_cast<uint64_t>(rawBuffer->GetAddr());
734 0 : size = static_cast<uint64_t>(rawBuffer->GetSize());
735 0 : return HcclResult::HCCL_SUCCESS;
736 : }
737 :
738 : HcclResult
739 0 : CcuComponent::GetCcuResourceSpaceTokenInfoForLocal(const uint8_t dieId, uint64_t& tokenId, uint64_t& tokenValue) const
740 : {
741 0 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
742 :
743 0 : auto res = localCcuRmaBufferMap.find(dieId);
744 0 : CHK_PRT_RET(
745 : res == localCcuRmaBufferMap.end(),
746 : HCCL_WARNING(
747 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
748 : "devLogicId[%d].",
749 : __func__, dieId, devLogicId),
750 : HcclResult::HCCL_E_NOT_FOUND);
751 :
752 0 : const auto& ccuRmaBuffer = res->second;
753 0 : tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
754 0 : tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
755 0 : return HcclResult::HCCL_SUCCESS;
756 : }
757 :
758 : HcclResult
759 0 : CcuComponent::GetCcuResourceSpaceTokenInfo(const uint8_t dieId, uint64_t& tokenId, uint64_t& tokenValue) const
760 : {
761 0 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
762 :
763 0 : auto res = ccuRmaBufferMap.find(dieId);
764 0 : CHK_PRT_RET(
765 : res == ccuRmaBufferMap.end(),
766 : HCCL_WARNING(
767 : "[CcuComponent][%s] failed, ccu rma buffer of die[%u] is not existed, "
768 : "devLogicId[%d].",
769 : __func__, dieId, devLogicId),
770 : HcclResult::HCCL_E_NOT_FOUND);
771 :
772 0 : const auto& ccuRmaBuffer = res->second;
773 0 : tokenId = static_cast<uint64_t>(ccuRmaBuffer->GetTokenId());
774 0 : tokenValue = static_cast<uint64_t>(ccuRmaBuffer->GetTokenValue());
775 0 : return HcclResult::HCCL_SUCCESS;
776 : }
777 :
778 : HcclResult
779 5 : CcuComponent::AllocChannels(const uint8_t dieId, const ChannelPara& channelPara, std::vector<ChannelInfo>& channelInfos)
780 : {
781 8 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
782 :
783 4 : CHK_PTR_NULL(channelMgrs[dieId]);
784 4 : auto ret = channelMgrs[dieId]->Alloc(channelPara, channelInfos);
785 4 : CHK_PRT_RET(
786 : ret != HcclResult::HCCL_SUCCESS,
787 : HCCL_WARNING(
788 : "[CcuComponent][%s] failed, feId[%u], devLogicId[%d], dieId[%u].", __func__, channelPara.feId, devLogicId,
789 : dieId),
790 : ret);
791 :
792 4 : return HcclResult::HCCL_SUCCESS;
793 : }
794 :
795 6 : HcclResult CcuComponent::ConfigChannel(const uint8_t dieId, const ChannelCfg& cfg)
796 : {
797 6 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
798 :
799 6 : uint32_t channelId = cfg.channelId;
800 9 : CHK_PRT_RET(
801 : channelId == loopChannelIds[dieId],
802 : HCCL_WARNING(
803 : "[CcuComponent][%s] failed, refused to config loop channel[%u], "
804 : "devLogicId[%d], dieId[%u].",
805 : __func__, channelId, devLogicId, dieId),
806 : HcclResult::HCCL_E_PARA);
807 :
808 5 : CHK_PTR_NULL(channelMgrs[dieId]);
809 5 : auto ret = channelMgrs[dieId]->Config(cfg);
810 14 : CHK_PRT_RET(
811 : ret != HcclResult::HCCL_SUCCESS,
812 : HCCL_WARNING(
813 : "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId,
814 : dieId),
815 : ret);
816 :
817 2 : return HcclResult::HCCL_SUCCESS;
818 : }
819 :
820 4 : HcclResult CcuComponent::ReleaseChannel(const uint8_t dieId, const uint32_t channelId)
821 : {
822 4 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
823 7 : CHK_PRT_RET(
824 : channelId == loopChannelIds[dieId],
825 : HCCL_WARNING(
826 : "[CcuComponent][%s] failed, refused to release loop channel[%u], "
827 : "devLogicId[%d], dieId[%u].",
828 : __func__, channelId, devLogicId, dieId),
829 : HcclResult::HCCL_E_PARA);
830 :
831 3 : CHK_PTR_NULL(channelMgrs[dieId]);
832 3 : auto ret = channelMgrs[dieId]->Release(channelId);
833 6 : CHK_PRT_RET(
834 : ret != HcclResult::HCCL_SUCCESS,
835 : HCCL_WARNING(
836 : "[CcuComponent][%s] failed, channelId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, devLogicId,
837 : dieId),
838 : ret);
839 :
840 2 : return HcclResult::HCCL_SUCCESS;
841 : }
842 :
843 4 : HcclResult CcuComponent::GetLoopChannelId(const uint8_t srcDieId, const uint8_t dstDieId, uint32_t& channelId) const
844 : {
845 4 : channelId = INVAILD_LOOP_CHANNEL_ID; // 允许die未启用时查询环回channelId
846 4 : CHK_RET(CheckDieValid(__func__, devLogicId, srcDieId, {true, true}));
847 4 : CHK_RET(CheckDieValid(__func__, devLogicId, dstDieId, {true, true}));
848 :
849 4 : CHK_PRT_RET(
850 : loopChannelIds[srcDieId] == INVAILD_LOOP_CHANNEL_ID, // 环回channel每个die共用1个
851 : HCCL_WARNING(
852 : "[CcuComponent][%s] failed, invalid loop channel id, "
853 : "devLogicId[%d], srcDieId[%u].",
854 : __func__, devLogicId, srcDieId),
855 : HcclResult::HCCL_E_INTERNAL);
856 :
857 4 : channelId = loopChannelIds[srcDieId];
858 4 : return HcclResult::HCCL_SUCCESS;
859 : }
860 :
861 34 : HcclResult CcuComponent::AllocRes(
862 : const uint8_t dieId, const ResType resType, const uint32_t num, const bool consecutive, vector<ResInfo>& resInfos)
863 : {
864 34 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
865 :
866 34 : CHK_PTR_NULL(resAllocators[dieId]);
867 34 : auto ret = resAllocators[dieId]->Alloc(resType, num, consecutive, resInfos);
868 37 : CHK_PRT_RET(
869 : ret != HcclResult::HCCL_SUCCESS,
870 : HCCL_WARNING(
871 : "[CcuComponent][%s] failed, resType[%s], num[%u], devLogicId[%d], dieId[%u].", __func__,
872 : resType.Describe().c_str(), num, devLogicId, dieId),
873 : ret);
874 :
875 33 : return HcclResult::HCCL_SUCCESS;
876 : }
877 :
878 : HcclResult
879 9 : CcuComponent::ReleaseRes(const uint8_t dieId, const ResType resType, const uint32_t startId, const uint32_t num)
880 : {
881 9 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
882 :
883 9 : CHK_PTR_NULL(resAllocators[dieId]);
884 9 : auto ret = resAllocators[dieId]->Release(resType, startId, num);
885 9 : CHK_PRT_RET(
886 : ret != HcclResult::HCCL_SUCCESS,
887 : HCCL_WARNING(
888 : "[CcuComponent][%s] failed, resType[%s], startId[%u], num[%u], "
889 : "devLogicId[%d], dieId[%u].",
890 : __func__, resType.Describe().c_str(), startId, num, devLogicId, dieId),
891 : ret);
892 :
893 9 : return HcclResult::HCCL_SUCCESS;
894 : }
895 :
896 0 : uint32_t CcuComponent::GetInsConsecutiveRemainSize(const uint8_t dieId) const
897 : {
898 0 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
899 0 : if (resAllocators[dieId] == nullptr)
900 0 : return 0;
901 0 : return resAllocators[dieId]->GetConsecutiveRemainSize(ResType::INS);
902 : }
903 :
904 7 : HcclResult CcuComponent::AllocIns(const uint8_t dieId, const uint32_t num, ResInfo& insInfo)
905 : {
906 10 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
907 6 : CHK_PTR_NULL(resAllocators[dieId]);
908 :
909 6 : vector<ResInfo> resInfos;
910 6 : auto ret = resAllocators[dieId]->Alloc(ResType::INS, num, true, resInfos);
911 15 : CHK_PRT_RET(
912 : ret != HcclResult::HCCL_SUCCESS,
913 : HCCL_WARNING(
914 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
915 : ret);
916 :
917 3 : insInfo = resInfos[0]; // 申请连续资源只会有一份
918 3 : return HcclResult::HCCL_SUCCESS;
919 6 : }
920 :
921 4 : HcclResult CcuComponent::ReleaseIns(const uint8_t dieId, const ResInfo& insInfo)
922 : {
923 7 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
924 3 : CHK_PTR_NULL(resAllocators[dieId]);
925 :
926 3 : auto ret = resAllocators[dieId]->Release(ResType::INS, insInfo.startId, insInfo.num);
927 3 : CHK_PRT_RET(
928 : ret != HcclResult::HCCL_SUCCESS,
929 : HCCL_WARNING(
930 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__, insInfo.Describe().c_str(),
931 : devLogicId, dieId),
932 : ret);
933 :
934 3 : return HcclResult::HCCL_SUCCESS;
935 : }
936 :
937 184 : HcclResult CcuComponent::AllocCke(const uint8_t dieId, const uint32_t num, vector<ResInfo>& ckeInfos)
938 : {
939 715 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
940 7 : CHK_PTR_NULL(resAllocators[dieId]);
941 :
942 7 : auto ret = resAllocators[dieId]->Alloc(ResType::CKE, num, false, ckeInfos);
943 16 : CHK_PRT_RET(
944 : ret != HcclResult::HCCL_SUCCESS,
945 : HCCL_WARNING(
946 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
947 : ret);
948 :
949 4 : return HcclResult::HCCL_SUCCESS;
950 : }
951 :
952 30 : HcclResult CcuComponent::ReleaseCke(const uint8_t dieId, const vector<ResInfo>& ckeInfos)
953 : {
954 99 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
955 7 : CHK_PTR_NULL(resAllocators[dieId]);
956 :
957 12 : for (auto& ckeInfo : ckeInfos) {
958 7 : auto ret = resAllocators[dieId]->Release(ResType::CKE, ckeInfo.startId, ckeInfo.num);
959 13 : CHK_PRT_RET(
960 : ret != HcclResult::HCCL_SUCCESS,
961 : HCCL_WARNING(
962 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
963 : ckeInfo.Describe().c_str(), devLogicId, dieId),
964 : ret);
965 : }
966 :
967 5 : return HcclResult::HCCL_SUCCESS;
968 : }
969 :
970 7 : HcclResult CcuComponent::AllocXn(const uint8_t dieId, const uint32_t num, vector<ResInfo>& xnInfos)
971 : {
972 10 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
973 6 : CHK_PTR_NULL(resAllocators[dieId]);
974 :
975 6 : auto ret = resAllocators[dieId]->Alloc(ResType::XN, num, false, xnInfos);
976 15 : CHK_PRT_RET(
977 : ret != HcclResult::HCCL_SUCCESS,
978 : HCCL_WARNING(
979 : "[CcuComponent][%s] failed, num[%u], devLogicId[%d], dieId[%u].", __func__, num, devLogicId, dieId),
980 : ret);
981 :
982 3 : return HcclResult::HCCL_SUCCESS;
983 : }
984 :
985 4 : HcclResult CcuComponent::ReleaseXn(const uint8_t dieId, const vector<ResInfo>& xnInfos)
986 : {
987 7 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
988 3 : CHK_PTR_NULL(resAllocators[dieId]);
989 :
990 6 : for (auto& xnInfo : xnInfos) {
991 3 : auto ret = resAllocators[dieId]->Release(ResType::XN, xnInfo.startId, xnInfo.num);
992 3 : CHK_PRT_RET(
993 : ret != HcclResult::HCCL_SUCCESS,
994 : HCCL_WARNING(
995 : "[CcuComponent][%s] failed, resInfo[%s], devLogicId[%d], dieId[%u].", __func__,
996 : xnInfo.Describe().c_str(), devLogicId, dieId),
997 : ret);
998 : }
999 :
1000 3 : return HcclResult::HCCL_SUCCESS;
1001 : }
1002 :
1003 : // 以下接口用于n秒快恢与TaskException
1004 29 : HcclResult CcuComponent::CleanDieCkes(const uint8_t dieId) const
1005 : {
1006 29 : CHK_PRT_RET(
1007 : dieId >= MAX_CCU_IODIE_NUM,
1008 : HCCL_WARNING(
1009 : "[CcuComponent][%s] failed, dieId[%u] is invalid, shoudle be in [0-%u), devLogicId[%d].", __func__, dieId,
1010 : MAX_CCU_IODIE_NUM, devLogicId),
1011 : HcclResult::HCCL_E_PARA);
1012 :
1013 29 : if (!dieEnableFlags[dieId]) {
1014 4 : return HcclResult::HCCL_SUCCESS;
1015 : }
1016 :
1017 25 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
1018 25 : CHK_PTR_NULL(tlvHandle);
1019 25 : CustomChannelInfoIn inBuff{};
1020 25 : CustomChannelInfoOut outBuff{};
1021 :
1022 : // 设置操作码和数据
1023 25 : uint32_t ckeNum = 0;
1024 25 : CHK_RET(CcuResSpecifications::GetInstance(devLogicId).GetCkeNum(dieId, ckeNum));
1025 75 : HCCL_INFO("[CcuComponent][CleanAllCke]Nsrecovery devLogicId[%d], dieId[%u] ckeNum[%u].", devLogicId, dieId, ckeNum);
1026 :
1027 25 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_CKE;
1028 25 : inBuff.data.dataInfo.udieIdx = dieId;
1029 : // 接口限制,目前方案每次最多清理8个cke,超过8个时分多次清理
1030 3225 : for (uint32_t startIdx = 0; startIdx < ckeNum; startIdx += MAX_CKE_DATA_ARRAY_SIZE) {
1031 3200 : inBuff.data.dataInfo.dataArraySize = std::min(ckeNum - startIdx, MAX_CKE_DATA_ARRAY_SIZE);
1032 3200 : inBuff.data.dataInfo.dataLen = sizeof(CcuDataByte8) * inBuff.data.dataInfo.dataArraySize;
1033 3200 : inBuff.offsetStartIdx = startIdx;
1034 3200 : HrtRaTlvRequestForCustomChannel(
1035 : tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
1036 : }
1037 :
1038 25 : return HcclResult::HCCL_SUCCESS;
1039 : }
1040 :
1041 28 : void CcuComponent::SetProcess(CcuOpcodeType opCode) const
1042 : {
1043 28 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
1044 28 : CHECK_NULLPTR(
1045 56 : tlvHandle, StringFormat("[CcuComponent][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
1046 :
1047 28 : struct CustomChannelInfoIn inBuff;
1048 28 : struct CustomChannelInfoOut outBuff;
1049 :
1050 28 : inBuff.op = opCode;
1051 84 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
1052 56 : if (!dieEnableFlags[dieId]) {
1053 12 : HCCL_WARNING(
1054 : "[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] is not enable,"
1055 : "skip SetProcess.",
1056 : devLogicId, dieId);
1057 4 : continue;
1058 4 : }
1059 156 : HCCL_INFO("[CcuComponent::SetProcess] devLogicId[%d], dieId[%u] start.", devLogicId, dieId);
1060 52 : inBuff.data.dataInfo.udieIdx = dieId;
1061 52 : HrtRaTlvRequestForCustomChannel(
1062 : tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
1063 : }
1064 28 : }
1065 :
1066 13 : HcclResult CcuComponent::SetTaskKill()
1067 : {
1068 13 : std::lock_guard<std::mutex> _lock(taskKillMutex_);
1069 :
1070 13 : if (status == CcuTaskKillStatus::INVALID) {
1071 12 : status = CcuTaskKillStatus::INIT;
1072 : }
1073 :
1074 13 : if (status == CcuTaskKillStatus::TASK_KILL) {
1075 0 : HCCL_INFO("No need to set task kill, state = %u, devLogicId = %u", status, devLogicId);
1076 0 : return HcclResult::HCCL_SUCCESS;
1077 : }
1078 :
1079 13 : if (status != CcuTaskKillStatus::INIT) {
1080 0 : HCCL_ERROR(
1081 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1082 : "state = %u, devLogicId = %d.",
1083 : __func__, status, devLogicId);
1084 0 : return HcclResult::HCCL_E_INTERNAL;
1085 : }
1086 :
1087 13 : SetProcess(CcuOpcodeType::CCU_U_OP_SET_TASKKILL);
1088 13 : status = CcuTaskKillStatus::TASK_KILL;
1089 39 : HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d.", __func__, status, devLogicId);
1090 13 : return HcclResult::HCCL_SUCCESS;
1091 13 : }
1092 :
1093 13 : HcclResult CcuComponent::SetTaskKillDone()
1094 : {
1095 13 : std::lock_guard<std::mutex> _lock(taskKillMutex_);
1096 :
1097 13 : if (status == CcuTaskKillStatus::INVALID) {
1098 0 : HCCL_ERROR(
1099 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1100 : "state = %u, devLogicId = %d.",
1101 : __func__, status, devLogicId);
1102 0 : return HcclResult::HCCL_E_INTERNAL;
1103 : }
1104 :
1105 13 : if (status == CcuTaskKillStatus::INIT) {
1106 0 : HCCL_INFO("No need to set task kill done, state = %u, devLogicId = %u", status, devLogicId);
1107 0 : return HcclResult::HCCL_SUCCESS;
1108 : }
1109 :
1110 13 : if (status != CcuTaskKillStatus::TASK_KILL) {
1111 0 : HCCL_ERROR(
1112 : "[CcuComponent][%s] failed, cannot be invoked in the current state, "
1113 : "state = %u, devLogicId = %d.",
1114 : __func__, status, devLogicId);
1115 0 : return HcclResult::HCCL_E_INTERNAL;
1116 : }
1117 :
1118 13 : SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
1119 13 : status = CcuTaskKillStatus::INIT;
1120 39 : HCCL_INFO("[CcuComponent][%s] success, state = %u, devLogicId = %d", __func__, status, devLogicId);
1121 13 : return HcclResult::HCCL_SUCCESS;
1122 13 : }
1123 :
1124 2 : HcclResult CcuComponent::CleanTaskKillState() const
1125 : {
1126 2 : SetProcess(CcuOpcodeType::CCU_U_OP_CLEAN_TASKKILL_STATE);
1127 2 : return HcclResult::HCCL_SUCCESS;
1128 : }
1129 :
1130 2 : const std::array<bool, MAX_CCU_IODIE_NUM>& CcuComponent::GetDieEnableFlags() const { return dieEnableFlags; }
1131 :
1132 81 : CcuComponent::~CcuComponent() { DECTOR_TRY_CATCH("CcuComponent", ReleaseJettyRes()); }
1133 :
1134 83 : void CcuComponent::ReleaseJettyRes()
1135 : {
1136 83 : UnimportAllJetty();
1137 83 : DestroyAllJetty();
1138 : // HrtRaUbLocalMemReg 跟随 LocalUbRmaBuffer 析构时释放
1139 : // 环回channel不需要手动释放,channelMgr跟随CcuComponent释放
1140 83 : }
1141 :
1142 83 : void CcuComponent::UnimportAllJetty()
1143 : {
1144 : // tpInfo不需要主动释放,因为CcuComponent生命周期与TpManager一致
1145 109 : for (auto& importedVec : importedOutParamMap) {
1146 52 : for (auto& paramPair : importedVec.second) {
1147 26 : const auto rdmaHandle = paramPair.first;
1148 26 : const auto remoteJettyHandle = paramPair.second.handle;
1149 26 : if (rdmaHandle != nullptr && remoteJettyHandle != 0) {
1150 0 : paramPair.second.handle = 0;
1151 0 : HrtRaUbUnimportJetty(rdmaHandle, remoteJettyHandle);
1152 : }
1153 : }
1154 : }
1155 :
1156 83 : importedOutParamMap.clear();
1157 83 : }
1158 :
1159 83 : void CcuComponent::DestroyAllJetty()
1160 : {
1161 109 : for (auto& createdVec : createdOutParamMap) {
1162 52 : for (auto& param : createdVec.second) {
1163 26 : const auto jettyHandle = param.handle;
1164 26 : if (jettyHandle != 0) {
1165 0 : param.handle = 0;
1166 0 : HrtRaUbDestroyJetty(jettyHandle);
1167 : }
1168 : }
1169 : }
1170 83 : createdOutParamMap.clear();
1171 83 : }
1172 :
1173 : }; // namespace Hccl
|