Line data Source code
1 : /**
2 : * Copyright (c) 2026 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 "ccu_jetty_ctx_mgr_v2.h"
12 :
13 : #include "ccu_pfe_cfg_generator.h"
14 :
15 : #include "ccu_wqebb_mgr_v2.h"
16 :
17 : namespace hcomm {
18 :
19 53 : CcuJettyCtxMgrV2::CcuJettyCtxMgrV2(const int32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId)
20 53 : : CcuJettyCtxMgr(devLogicId, dieId, devPhyId)
21 : {
22 53 : (void)CcuResSpecifications::GetInstance(devLogicId).GetChannelJettyMap(dieId, channelJettyMap_);
23 53 : }
24 :
25 53 : HcclResult CcuJettyCtxMgrV2::Init()
26 : {
27 : // 获取失败或为0场景,分配将按资源不足操作
28 53 : (void)CcuResSpecifications::GetInstance(devLogicId_).GetJettyNum(dieId_, jettySpecNum_);
29 53 : (void)CcuResSpecifications::GetInstance(devLogicId_).GetResourceAddr(dieId_, ccuResBaseVa_);
30 :
31 53 : wqeBBMgr_.reset(new (std::nothrow) CcuWqeBBMgrV2(devLogicId_, dieId_));
32 53 : CHK_PTR_NULL(wqeBBMgr_);
33 53 : CHK_RET(wqeBBMgr_->Init());
34 53 : CHK_RET(pfeMgr_.Init());
35 53 : return HcclResult::HCCL_SUCCESS;
36 : }
37 :
38 109 : HcclResult CcuJettyCtxMgrV2::CheckCtxGroupsByFeId(const uint32_t feId)
39 : {
40 : // 当前a5与a6待机,所有pfe配置均使用所有jetty,故基于fe生成一份资源即可
41 109 : if (ctxGroups_.size() != 0) {
42 63 : HCCL_INFO("[CcuJettyCtxMgrV2][%s]ctxGroups_.size[%zu]", __func__, ctxGroups_.size());
43 63 : return HcclResult::HCCL_SUCCESS;
44 : }
45 46 : PfeJettyStrategy strategy = {};
46 46 : CHK_RET(pfeMgr_.GetPfeStrategy(feId, strategy));
47 :
48 44 : const uint32_t jettyNum = static_cast<uint32_t>(strategy.size);
49 44 : const uint32_t startTaJettyId = strategy.startTaJettyId;
50 44 : const uint32_t startJettyCtxId = strategy.startLocalJettyCtxId;
51 44 : const uint32_t jettyGroupSize = channelJettyMap_.jettyNum;
52 44 : CHK_PRT_RET(
53 : (jettySpecNum_ < jettyNum || startJettyCtxId > jettySpecNum_ - jettyNum),
54 : HCCL_ERROR(
55 : "[CcuJettyCtxMgrV2][%s] failed, allocated jettyCtxId[%u] is invalid, "
56 : "jettyCtxId should in [0, %u).",
57 : __func__, startJettyCtxId, jettySpecNum_ - jettyNum),
58 : HcclResult::HCCL_E_INTERNAL);
59 :
60 44 : CHK_PRT_RET(
61 : jettyNum < jettyGroupSize || jettyGroupSize == 0, // fe策略不够分1个jetty组,认为资源不足
62 : HCCL_WARNING(
63 : "[CcuJettyCtxMgrV2][%s] failed, jettyNum[%u] of feId[%u] is too small to "
64 : "allocated a jetty group, groupSize[%u], devLogicId[%d], dieId[%u].",
65 : __func__, jettyNum, feId, jettyGroupSize, devLogicId_, dieId_),
66 : HcclResult::HCCL_E_UNAVAIL);
67 :
68 : // ccu v2 按组的粒度分配,保证jettyNum为不大于分配规格的整除最大数
69 44 : const uint32_t groupNum = jettyNum / jettyGroupSize; // 未对齐是仍向下取整
70 44 : ctxGroups_.resize(groupNum);
71 5549 : for (uint32_t i = 0; i < groupNum; i++) {
72 5505 : ctxGroups_[i].startJettyCtxId = startJettyCtxId + i * jettyGroupSize;
73 5505 : ctxGroups_[i].startTaJettyId = startTaJettyId + i * jettyGroupSize;
74 : }
75 44 : return HcclResult::HCCL_SUCCESS;
76 : }
77 :
78 45 : static HcclResult FindFreeCtxGroup(const std::vector<JettyCtxGroup>& ctxGroups, uint32_t& freeGroupId)
79 : {
80 45 : CHK_PRT_RET(
81 : ctxGroups.empty(), HCCL_ERROR("[CcuJettyCtxMgrV2][%s] failed, ctxGroups is empty.", __func__),
82 : HcclResult::HCCL_E_PARA);
83 : // 任意jettyCtx组均可,选择首个可用的
84 45 : const uint32_t groupSize = ctxGroups.size();
85 48 : for (uint32_t i = 0; i < groupSize; i++) {
86 47 : if (ctxGroups[i].useCnt == 0) {
87 44 : freeGroupId = i;
88 44 : return HcclResult::HCCL_SUCCESS;
89 : }
90 : }
91 :
92 1 : HCCL_WARNING("[CcuJettyCtxMgrV2][%s] failed, no free ctxGroup left.", __func__);
93 1 : return HcclResult::HCCL_E_UNAVAIL;
94 : }
95 :
96 47 : HcclResult CcuJettyCtxMgrV2::Alloc(
97 : const uint32_t feId, const uint32_t jettyNum, const uint32_t sqSize, std::vector<JettyInfo>& jettyInfos)
98 : {
99 : // 检查feId对应jettyCtx信息是否初始化
100 47 : auto ret = CheckCtxGroupsByFeId(feId);
101 47 : CHK_PRT_RET(
102 : ret != HcclResult::HCCL_SUCCESS,
103 : HCCL_WARNING(
104 : "[CcuJettyCtxMgrV2][%s] failed to find jetty contexts by feId[%u], "
105 : "devLogicId[%d], dieId[%u].",
106 : __func__, feId, devLogicId_, dieId_),
107 : ret);
108 :
109 45 : uint32_t freeGroupId = 0;
110 45 : ret = FindFreeCtxGroup(ctxGroups_, freeGroupId);
111 45 : CHK_PRT_RET(
112 : ret != HcclResult::HCCL_SUCCESS,
113 : HCCL_WARNING(
114 : "[CcuJettyCtxMgrV2][%s] failed to find free jetty contexts of feId[%u], "
115 : "devLogicId[%d], dieId[%u].",
116 : __func__, feId, devLogicId_, dieId_),
117 : ret);
118 44 : HCCL_INFO("[CcuJettyCtxMgrV2][%s] freeGroupId[%u].", __func__, freeGroupId);
119 44 : const uint32_t jettyCtxStartId = ctxGroups_[freeGroupId].startJettyCtxId;
120 44 : const uint32_t taJettyStartId = ctxGroups_[freeGroupId].startTaJettyId;
121 44 : constexpr CcuJettyType jettyType_ = CcuJettyType::TA_CACHED_JETTY;
122 44 : jettyInfos.resize(jettyNum);
123 :
124 44 : uint32_t allocSqSize = sqSize;
125 44 : if (allocSqSize != CCU_V2_FIXED_SQ_SIZE) {
126 3 : HCCL_RUN_WARNING(
127 : "[CcuJettyCtxMgr][%s] failed, sqSize is not equal 32, "
128 : "sqSize is [%u]",
129 : __func__, allocSqSize);
130 3 : allocSqSize = CCU_V2_FIXED_SQ_SIZE;
131 : }
132 :
133 44 : ret = TryAllocWqeBBResource(allocSqSize, jettyCtxStartId, taJettyStartId, jettyType_, jettyInfos);
134 44 : if (ret != HCCL_SUCCESS) {
135 0 : HCCL_RUN_WARNING(
136 : "[CcuJettyCtxMgrV2][%s] failed to alloc wqebb resource to jetty contexts "
137 : "of feId[%u], request sq size[%u], devLogicId[%d], dieId[%u].",
138 : __func__, feId, allocSqSize, devLogicId_, dieId_);
139 0 : CHK_RET(ReleaseWqeBBResource(jettyInfos));
140 0 : return ret;
141 : }
142 :
143 44 : const uint32_t channelGroupSize = channelJettyMap_.channelNum;
144 44 : ctxGroups_[freeGroupId].useCnt = channelGroupSize; // 一次性分配整组channel
145 44 : ctxGroups_[freeGroupId].configured = false;
146 44 : return HcclResult::HCCL_SUCCESS;
147 : }
148 :
149 36 : HcclResult CcuJettyCtxMgrV2::Config(
150 : const uint32_t feId, const std::vector<JettyInfo>& jettyInfos, const std::vector<JettyCfg>& jettyCfgs)
151 : {
152 36 : CHK_RET(CheckIfJettyCfgsValid(jettyInfos, jettyCfgs));
153 35 : CHK_RET(CheckCtxGroupsByFeId(feId));
154 : // jettyInfo由channelMgr提供,属于内部数据,分配与配置的校验保证是增序,不会越界
155 35 : const uint32_t startJettyCtxId = jettyInfos[0].jettyCtxId;
156 : // 创建ctxGroup校验已保证ctxGroupMap[feId]非空
157 35 : const uint32_t feStartjettyCtxId = ctxGroups_[0].startJettyCtxId;
158 35 : const uint32_t groupId = (startJettyCtxId - feStartjettyCtxId) / channelJettyMap_.jettyNum;
159 35 : auto& ctxGroup = ctxGroups_[groupId];
160 35 : HCCL_INFO(
161 : "[CcuJettyCtxMgrV2][%s]jetty contexts[start id[%u], num[%u], feStartjettyCtxId[%u], groupId[%u]] "
162 : "of feId[%u] have not been allocated yet, devLogicId[%d], dieId[%u].",
163 : __func__, startJettyCtxId, channelJettyMap_.jettyNum, feStartjettyCtxId, groupId, feId, devLogicId_, dieId_);
164 35 : CHK_PRT_RET(
165 : ctxGroup.useCnt == 0,
166 : HCCL_ERROR(
167 : "[CcuJettyCtxMgrV2][%s] failed, jetty contexts[start id[%u], num[%u]] "
168 : "of feId[%u] have not been allocated yet, devLogicId[%d], dieId[%u].",
169 : __func__, startJettyCtxId, channelJettyMap_.jettyNum, feId, devLogicId_, dieId_),
170 : HcclResult::HCCL_E_PARA);
171 :
172 34 : if (ctxGroup.configured) {
173 1 : HCCL_INFO(
174 : "[CcuJettyCtxMgrV2][%s] passed, jetty contexts[start id[%u], num[%u]] "
175 : "of feId[%u] have been configured, devLogicId[%d], dieId[%u].",
176 : __func__, startJettyCtxId, channelJettyMap_.jettyNum, feId, devLogicId_, dieId_);
177 1 : return HcclResult::HCCL_SUCCESS;
178 : }
179 :
180 33 : std::vector<LocalJettyCtxData> jettyCtxData;
181 33 : uint32_t jettyNum = jettyInfos.size();
182 66 : for (size_t i = 0; i < jettyNum; i++) {
183 33 : jettyCtxData.emplace_back(BuildJettyCtxData(dieId_, feId, jettyInfos[i], jettyCfgs[i]));
184 : }
185 :
186 33 : CHK_RET(ConfigJettyCtxData(devLogicId_, dieId_, devPhyId_, startJettyCtxId, jettyCtxData));
187 32 : ctxGroup.configured = true;
188 32 : return HcclResult::HCCL_SUCCESS;
189 33 : }
190 :
191 28 : HcclResult CcuJettyCtxMgrV2::Release(const uint32_t feId, const std::vector<JettyInfo>& jettyInfos)
192 : {
193 28 : if (jettyInfos.empty()) {
194 1 : HCCL_INFO(
195 : "[CcuJettyCtxMgrV2][%s] passed, jettyInfos is empty, no need to release, ",
196 : "devLogicId[%d], dieId[%u], feId[%u].", __func__, devLogicId_, dieId_, feId);
197 1 : return HcclResult::HCCL_SUCCESS;
198 : }
199 27 : CHK_RET(CheckCtxGroupsByFeId(feId));
200 : // jettyInfo由channelMgr提供,属于内部数据,分配与配置的校验保证是增序,不会越界
201 27 : const uint32_t startJettyCtxId = jettyInfos[0].jettyCtxId;
202 : // 创建ctxGroup校验已保证ctxGroupMap[feId]非空
203 27 : const uint32_t feStartjettyCtxId = ctxGroups_[0].startJettyCtxId;
204 27 : const uint32_t groupId = (startJettyCtxId - feStartjettyCtxId) / channelJettyMap_.jettyNum;
205 27 : auto& ctxGroup = ctxGroups_[groupId];
206 27 : CHK_PRT_RET(
207 : ctxGroup.useCnt == 0,
208 : HCCL_ERROR(
209 : "[CcuJettyCtxMgrV2][%s] failed, jetty contexts[start id[%u], num[%u]] "
210 : "of feId[%u] have not been allocated yet, devLogicId[%d], dieId[%u].",
211 : __func__, startJettyCtxId, channelJettyMap_.jettyNum, feId, devLogicId_, dieId_),
212 : HcclResult::HCCL_E_PARA);
213 :
214 26 : if (ctxGroup.useCnt > 1) {
215 23 : ctxGroup.useCnt -= 1;
216 23 : HCCL_INFO(
217 : "[CcuJettyCtxMgr][%s] passed, jetty contexts[start id[%u], num[%u]] is "
218 : "still in use, left use count is %u, devLogicId[%d], dieId[%u].",
219 : __func__, startJettyCtxId, channelJettyMap_.jettyNum, ctxGroup.useCnt, devLogicId_, dieId_);
220 23 : return HcclResult::HCCL_SUCCESS;
221 : }
222 3 : CHK_RET(ReleaseWqeBBResource(jettyInfos));
223 :
224 3 : ctxGroup.configured = false;
225 3 : ctxGroup.useCnt = 0;
226 3 : return HcclResult::HCCL_SUCCESS;
227 : }
228 :
229 : }; // namespace hcomm
|