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 "ccu_pfe_mgr.h"
12 :
13 : #include "hccp_ctx.h"
14 :
15 : #include "ccu_res_specs.h"
16 : #include "ccu_pfe_cfg_mgr.h"
17 : #include "hcomm_adapter_hccp.h"
18 :
19 : namespace hcomm {
20 :
21 200 : inline PfeCtx BuildPfeCtx(const uint8_t dieId, const PfeJettyCtxCfg& cfg)
22 : {
23 200 : struct PfeCtx ctx = {};
24 200 : ctx.startJettyId = cfg.startTaJettyId;
25 200 : ctx.jettyNum = cfg.size - 1; // PFE给CCU分配的Jetty个数,配置硬件时需减1
26 200 : ctx.startLocalJettyCtxId = cfg.startJettyCtxId;
27 :
28 200 : HCCL_RUN_INFO(
29 : "[CcuPfeMgr][%s]: dieId[%u] feId[%u], startJettyId[%u], jettyNum(-1)[%u], "
30 : "startLocalJettyCtxId[%u], pfe ctx size[%u]",
31 : __func__, dieId, cfg.feId, ctx.startJettyId, ctx.jettyNum, ctx.startLocalJettyCtxId, sizeof(PfeCtx));
32 200 : return ctx;
33 : }
34 :
35 200 : inline PfeJettyStrategy BuildStrategy(const PfeJettyCtxCfg& cfg)
36 : {
37 200 : struct PfeJettyStrategy pfeJettyStrategy = {};
38 200 : pfeJettyStrategy.feId = cfg.feId;
39 200 : pfeJettyStrategy.pfeId = cfg.feId;
40 200 : pfeJettyStrategy.size = cfg.size;
41 200 : pfeJettyStrategy.startTaJettyId = cfg.startTaJettyId;
42 200 : pfeJettyStrategy.startLocalJettyCtxId = cfg.startJettyCtxId;
43 200 : return pfeJettyStrategy;
44 : }
45 :
46 200 : static HcclResult ConfigPfeTable(
47 : const int32_t devLogicId, const uint32_t devPhyId, const uint8_t dieId, const uint32_t feId,
48 : const uint32_t pfeReservedNum, const PfeCtx& pfeCtx)
49 : {
50 200 : if (UNLIKELY(feId > UINT32_MAX - static_cast<uint32_t>(dieId) * pfeReservedNum)) {
51 0 : HCCL_ERROR(
52 : "[CcuPfeMgr][%s] failed, feId[%u] is greater than expected, "
53 : "pfeReservedNum[%u], will exceed the range of uint32_t, devLogicId[%d] devPhyId[%u], "
54 : "dieId[%u].",
55 : __func__, feId, pfeReservedNum, devLogicId, devPhyId, dieId);
56 0 : return HcclResult::HCCL_E_INTERNAL;
57 : }
58 : // die1 使用后半部分pfe表项,故根据pfe预留数量偏移
59 200 : const uint32_t pfeTableOffset = static_cast<uint32_t>(dieId) * pfeReservedNum + feId;
60 :
61 200 : CustomChannelInfoIn inBuff{};
62 200 : CustomChannelInfoOut outBuff{};
63 200 : inBuff.op = CcuOpcodeType::CCU_U_OP_SET_PFE;
64 200 : inBuff.data.dataInfo.udieIdx = static_cast<uint32_t>(dieId);
65 200 : inBuff.data.dataInfo.dataArraySize = 1;
66 200 : inBuff.data.dataInfo.dataLen = sizeof(struct PfeCtx); // 单个8B
67 200 : inBuff.offsetStartIdx = pfeTableOffset;
68 :
69 200 : (void)memcpy_s(inBuff.data.dataInfo.dataArray, inBuff.data.dataInfo.dataLen, &pfeCtx, inBuff.data.dataInfo.dataLen);
70 :
71 200 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
72 200 : if (ret != HCCL_SUCCESS) {
73 0 : HCCL_ERROR(
74 : "[CcuPfeMgr][%s] failed to call ccu driver, "
75 : "devLogicId[%d] devPhyId[%u] dieId[%d] op[%s] ret[%d].",
76 : __func__, devLogicId, devPhyId, dieId, "SET_PFE", ret);
77 0 : return ret;
78 : }
79 :
80 200 : return HcclResult::HCCL_SUCCESS;
81 : }
82 :
83 223 : HcclResult CcuPfeMgr::Init()
84 : {
85 223 : std::vector<PfeJettyCtxCfg> cfgs = CcuPfeCfgMgr::GetInstance(devLogicId_).GetPfeJettyCtxCfg(dieId_);
86 223 : if (UNLIKELY(cfgs.empty())) { // 此处不中断流程,后续jettyCtx分配时会因无pfe配置报错停止
87 23 : HCCL_WARNING(
88 : "[CcuJettyCtxMgr] config pfe table passed, pfe cfgs size is 0, "
89 : "devLogicId[%d], dieId[%u].",
90 : devLogicId_, dieId_);
91 23 : return HcclResult::HCCL_SUCCESS;
92 : }
93 :
94 200 : uint32_t pfeReservedNum = 0;
95 200 : (void)CcuResSpecifications::GetInstance(devLogicId_).GetPfeReservedNum(dieId_, pfeReservedNum);
96 200 : if (UNLIKELY(pfeReservedNum == 0)) { // 此处不中断流程,后续jettyCtx分配时会因无pfe配置报错停止
97 0 : HCCL_WARNING(
98 : "[CcuPfeMgr] config pfe table passed, pfe reserved num is 0, "
99 : "devLogicId[%d], dieId[%u].",
100 : devLogicId_, dieId_);
101 0 : return HcclResult::HCCL_SUCCESS;
102 : }
103 :
104 400 : for (const auto& cfg : cfgs) {
105 : // 分配策略保证cfg中feId均为ccu可用设备
106 200 : const uint32_t feId = cfg.feId;
107 200 : const auto& iter = pfeJettyMap_.find(feId);
108 200 : if (iter != pfeJettyMap_.end()) {
109 0 : continue; // 跳过已配置pfe
110 : }
111 200 : pfeJettyMap_[feId] = BuildStrategy(cfg);
112 :
113 200 : const auto& pfeCtx = BuildPfeCtx(dieId_, cfg);
114 200 : CHK_RET(ConfigPfeTable(devLogicId_, devPhyId_, dieId_, feId, pfeReservedNum, pfeCtx));
115 : }
116 :
117 200 : return HcclResult::HCCL_SUCCESS;
118 223 : }
119 :
120 216 : HcclResult CcuPfeMgr::GetPfeStrategy(uint32_t feId, PfeJettyStrategy& pfeJettyStrategy) const
121 : {
122 216 : const auto& iter = pfeJettyMap_.find(feId);
123 216 : if (iter == pfeJettyMap_.end()) {
124 2 : HCCL_ERROR(
125 : "[CcuPfeMgr][%s] failed, feId[%u] is not found, "
126 : "devLogicId[%d], dieId[%u].",
127 : __func__, feId, devLogicId_, dieId_);
128 2 : return HCCL_E_NOT_FOUND;
129 : }
130 :
131 214 : pfeJettyStrategy = iter->second;
132 214 : HCCL_RUN_INFO(
133 : "[CcuPfeMgr][%s] dieId[%u] feId[%u] pfeId[%u] size[%u] "
134 : "startTaJettyId[%u] startLocalJettyCtxId[%u]",
135 : __func__, dieId_, pfeJettyStrategy.feId, pfeJettyStrategy.pfeId, pfeJettyStrategy.size,
136 : pfeJettyStrategy.startTaJettyId, pfeJettyStrategy.startLocalJettyCtxId);
137 :
138 214 : return HCCL_SUCCESS;
139 : }
140 :
141 : }; // namespace hcomm
|