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