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