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 27 : CcuJettyCtxMgrV2::CcuJettyCtxMgrV2(const int32_t devLogicId, const uint8_t dieId,
20 27 : const uint32_t devPhyId) : CcuJettyCtxMgr(devLogicId, dieId, devPhyId)
21 : {
22 27 : (void)CcuResSpecifications::GetInstance(devLogicId).GetChannelJettyMap(dieId, channelJettyMap_);
23 27 : }
24 :
25 27 : HcclResult CcuJettyCtxMgrV2::Init()
26 : {
27 : // 获取失败或为0场景,分配将按资源不足操作
28 27 : (void)CcuResSpecifications::GetInstance(devLogicId_).GetJettyNum(dieId_, jettySpecNum_);
29 27 : (void)CcuResSpecifications::GetInstance(devLogicId_).GetResourceAddr(dieId_, ccuResBaseVa_);
30 :
31 27 : wqeBBMgr_.reset(new (std::nothrow) CcuWqeBBMgrV2(devLogicId_, dieId_));
32 27 : CHK_PTR_NULL(wqeBBMgr_);
33 27 : CHK_RET(wqeBBMgr_->Init());
34 27 : CHK_RET(pfeMgr_.Init());
35 27 : return HcclResult::HCCL_SUCCESS;
36 : }
37 :
38 39 : HcclResult CcuJettyCtxMgrV2::CheckCtxGroupsByFeId(const uint32_t feId)
39 : {
40 : // 当前a5与a6待机,所有pfe配置均使用所有jetty,故基于fe生成一份资源即可
41 39 : if (ctxGroups_.size() != 0) {
42 19 : HCCL_INFO("[CcuJettyCtxMgrV2][%s]ctxGroups_.size[%zu]", __func__, ctxGroups_.size());
43 19 : return HcclResult::HCCL_SUCCESS;
44 : }
45 20 : PfeJettyStrategy strategy = {};
46 20 : CHK_RET(pfeMgr_.GetPfeStrategy(feId, strategy));
47 :
48 18 : const uint32_t jettyNum = static_cast<uint32_t>(strategy.size);
49 18 : const uint32_t startTaJettyId = strategy.startTaJettyId;
50 18 : const uint32_t startJettyCtxId = strategy.startLocalJettyCtxId;
51 18 : const uint32_t jettyGroupSize = channelJettyMap_.jettyNum;
52 18 : 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 18 : 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 18 : const uint32_t groupNum = jettyNum / jettyGroupSize; // 未对齐是仍向下取整
65 18 : ctxGroups_.resize(groupNum);
66 2195 : for (uint32_t i = 0; i < groupNum; i++) {
67 2177 : ctxGroups_[i].startJettyCtxId = startJettyCtxId + i * jettyGroupSize;
68 2177 : ctxGroups_[i].startTaJettyId = startTaJettyId + i * jettyGroupSize;
69 : }
70 18 : return HcclResult::HCCL_SUCCESS;
71 : }
72 :
73 17 : static HcclResult FindFreeCtxGroup(const std::vector<JettyCtxGroup> &ctxGroups,
74 : uint32_t &freeGroupId)
75 : {
76 17 : CHK_PRT_RET(ctxGroups.empty(),
77 : HCCL_ERROR("[CcuJettyCtxMgrV2][%s] failed, ctxGroups is empty.", __func__),
78 : HcclResult::HCCL_E_PARA);
79 : // 任意jettyCtx组均可,选择首个可用的
80 17 : const uint32_t groupSize = ctxGroups.size();
81 18 : for (uint32_t i = 0; i < groupSize; i++) {
82 17 : if (ctxGroups[i].useCnt == 0) {
83 16 : freeGroupId = i;
84 16 : 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 19 : 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 19 : auto ret = CheckCtxGroupsByFeId(feId);
97 19 : 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 17 : uint32_t freeGroupId = 0;
103 17 : ret = FindFreeCtxGroup(ctxGroups_, freeGroupId);
104 17 : 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 16 : HCCL_INFO("[CcuJettyCtxMgrV2][%s] freeGroupId[%u].", __func__, freeGroupId);
109 16 : const uint32_t jettyCtxStartId = ctxGroups_[freeGroupId].startJettyCtxId;
110 16 : const uint32_t taJettyStartId = ctxGroups_[freeGroupId].startTaJettyId;
111 16 : constexpr CcuJettyType jettyType_ = CcuJettyType::TA_CACHED_JETTY;
112 16 : jettyInfos.resize(jettyNum);
113 :
114 16 : uint32_t allocSqSize = sqSize;
115 16 : if (allocSqSize != CCU_V2_FIXED_SQ_SIZE) {
116 1 : HCCL_RUN_WARNING("[CcuJettyCtxMgr][%s] failed, sqSize is not equal 32, "
117 : "sqSize is [%u]", __func__, allocSqSize);
118 1 : allocSqSize = CCU_V2_FIXED_SQ_SIZE;
119 : }
120 :
121 16 : ret = TryAllocWqeBBResource(allocSqSize, jettyCtxStartId, taJettyStartId, jettyType_, jettyInfos);
122 16 : 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 16 : const uint32_t channelGroupSize = channelJettyMap_.channelNum;
131 16 : ctxGroups_[freeGroupId].useCnt = channelGroupSize; // 一次性分配整组channel
132 16 : ctxGroups_[freeGroupId].configured = false;
133 16 : return HcclResult::HCCL_SUCCESS;
134 : }
135 :
136 10 : HcclResult CcuJettyCtxMgrV2::Config(const uint32_t feId,
137 : const std::vector<JettyInfo> &jettyInfos,
138 : const std::vector<JettyCfg>& jettyCfgs)
139 : {
140 10 : CHK_RET(CheckIfJettyCfgsValid(jettyInfos, jettyCfgs));
141 9 : CHK_RET(CheckCtxGroupsByFeId(feId));
142 : // jettyInfo由channelMgr提供,属于内部数据,分配与配置的校验保证是增序,不会越界
143 9 : const uint32_t startJettyCtxId = jettyInfos[0].jettyCtxId;
144 : // 创建ctxGroup校验已保证ctxGroupMap[feId]非空
145 9 : const uint32_t feStartjettyCtxId = ctxGroups_[0].startJettyCtxId;
146 9 : const uint32_t groupId = (startJettyCtxId - feStartjettyCtxId) / channelJettyMap_.jettyNum;
147 9 : auto &ctxGroup = ctxGroups_[groupId];
148 9 : 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 9 : 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 8 : 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 7 : std::vector<LocalJettyCtxData> jettyCtxData;
165 7 : uint32_t jettyNum = jettyInfos.size();
166 14 : for (size_t i = 0; i < jettyNum; i++) {
167 7 : jettyCtxData.emplace_back(BuildJettyCtxData(dieId_, feId, jettyInfos[i], jettyCfgs[i]));
168 : }
169 :
170 7 : CHK_RET(ConfigJettyCtxData(devLogicId_, dieId_, devPhyId_, startJettyCtxId, jettyCtxData));
171 6 : ctxGroup.configured = true;
172 6 : return HcclResult::HCCL_SUCCESS;
173 7 : }
174 :
175 12 : HcclResult CcuJettyCtxMgrV2::Release(const uint32_t feId, const std::vector<JettyInfo> &jettyInfos)
176 : {
177 12 : 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 11 : CHK_RET(CheckCtxGroupsByFeId(feId));
183 : // jettyInfo由channelMgr提供,属于内部数据,分配与配置的校验保证是增序,不会越界
184 11 : const uint32_t startJettyCtxId = jettyInfos[0].jettyCtxId;
185 : // 创建ctxGroup校验已保证ctxGroupMap[feId]非空
186 11 : const uint32_t feStartjettyCtxId = ctxGroups_[0].startJettyCtxId;
187 11 : const uint32_t groupId = (startJettyCtxId - feStartjettyCtxId) / channelJettyMap_.jettyNum;
188 11 : auto &ctxGroup = ctxGroups_[groupId];
189 11 : 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 10 : if (ctxGroup.useCnt > 1) {
196 9 : ctxGroup.useCnt -= 1;
197 9 : 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 9 : return HcclResult::HCCL_SUCCESS;
201 : }
202 1 : CHK_RET(ReleaseWqeBBResource(jettyInfos));
203 :
204 1 : ctxGroup.configured = false;
205 1 : ctxGroup.useCnt = 0;
206 1 : return HcclResult::HCCL_SUCCESS;
207 : }
208 :
209 : }; // namespace hcomm
210 :
|