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