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