LCOV - code coverage report
Current view: top level - base_comm/resources/ccu/ccu_device/ccu_comp/ccu_channel/ccu_channel_ctx_v2 - ccu_channel_ctx_mgr_v2.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.6 % 135 125
Test Date: 2026-07-28 12:11:00 Functions: 100.0 % 12 12

            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_channel_ctx_mgr_v2.h"
      12              : 
      13              : #include "orion_adapter_hccp.h"
      14              : 
      15              : #include "ccu_res_specs.h"
      16              : 
      17              : #include "env_config.h"
      18              : #include "string_util.h"
      19              : 
      20              : namespace hcomm {
      21              : 
      22           15 : CcuChannelCtxMgrV2::CcuChannelCtxMgrV2(const int32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId)
      23           15 :     : CcuChannelCtxMgr(devLogicId, dieId, devPhyId), jettyCtxMgr_(devLogicId, dieId, devPhyId)
      24              : {
      25           15 :     (void)CcuResSpecifications::GetInstance(devLogicId).GetChannelJettyMap(dieId, channelJettyMap_);
      26           15 : }
      27              : 
      28           15 : HcclResult CcuChannelCtxMgrV2::Init()
      29              : {
      30           15 :     uint32_t strategy = 0; // 获取失败或为0场景,分配将按资源不足操作
      31           15 :     (void)CcuResSpecifications::GetInstance(devLogicId_).GetChannelNum(dieId_, strategy);
      32           15 :     channelResInfos_.resize(strategy);
      33           15 :     CHK_RET(jettyCtxMgr_.Init());
      34           15 :     return  HcclResult::HCCL_SUCCESS;
      35              : }
      36              : 
      37           10 : static uint32_t CheckAndAdjustJettyNum(const ChannelPara &channelPara,
      38              :     const CcuChannelJettyMap &channelJettyMap)
      39              : {
      40           10 :     uint32_t jettyNum = channelPara.jettyNum;
      41           10 :     const uint32_t jettyGroupSize = channelJettyMap.jettyNum;
      42           10 :     if (jettyNum != jettyGroupSize) {
      43            5 :         HCCL_INFO("[CcuChannelCtxMgrV2][%s] jetty num[%u] reset to channelJettyMap."
      44              :             "jettyNum[%u], feId[%u].", __func__, jettyNum,
      45              :             jettyGroupSize, channelPara.feId);
      46            5 :         jettyNum = jettyGroupSize;
      47              :     }
      48           10 :     return jettyNum;
      49              : }
      50              : 
      51            9 : static HcclResult GetStartChannelId(const uint32_t jettyCtxStartId,
      52              :     const CcuChannelJettyMap &channelJettyMap,
      53              :     uint32_t &channelId)
      54              : {
      55              :     // channelJettyMap来自静态定义,认为其不会为0
      56            9 :     const uint32_t channelGroupSize = channelJettyMap.channelNum;
      57            9 :     const uint32_t jettyGroupSize = channelJettyMap.jettyNum;
      58            9 :     const uint32_t jettyGroupId = jettyCtxStartId / jettyGroupSize;
      59            9 :     if (UINT32_MAX / channelGroupSize < jettyGroupId) {
      60            0 :         HCCL_ERROR("[CcuChannelCtxMgrV2][%s] failed, channelId result overflow "
      61              :             "UINT32_MAX, jettyStartId[%u].", __func__, jettyCtxStartId);
      62            0 :         return HcclResult::HCCL_E_INTERNAL;
      63              :     }
      64              : 
      65            9 :     channelId = channelGroupSize * jettyGroupId;
      66            9 :     return HcclResult::HCCL_SUCCESS;
      67              : }
      68              : 
      69            9 : static HcclResult CheckChannelRangeAllocatable(
      70              :     const uint32_t startChannelId, const uint32_t channelNum, std::vector<ChannelResInfo> &channelResInfos)
      71              : {
      72            9 :     const uint32_t endChannelId = startChannelId + channelNum;
      73            9 :     CHK_PRT_RET(channelResInfos.size() <= endChannelId || startChannelId >= endChannelId,
      74              :         HCCL_ERROR("[CcuChannelCtxMgrV2][%s] failed, channel id range[%u, %u) is not expected, "
      75              :             "should be less than channelResInfos size[%u].", __func__, startChannelId,
      76              :             endChannelId, channelResInfos.size()),
      77              :         HcclResult::HCCL_E_INTERNAL);
      78              : 
      79           81 :     for (uint32_t i = startChannelId; i < endChannelId; i++) {
      80           72 :         if (channelResInfos[i].allocated) {
      81            0 :             HCCL_WARNING("[CcuChannelCtxMgrV2][%s] failed, channel id[%u] is already allocated, "
      82              :                 "channel group range[%u, %u).", __func__, i, startChannelId, endChannelId);
      83            0 :             return HcclResult::HCCL_E_UNAVAIL;
      84              :         }
      85              :     }
      86              : 
      87            9 :     return HcclResult::HCCL_SUCCESS;
      88              : }
      89              : 
      90           10 : HcclResult CcuChannelCtxMgrV2::Alloc(const ChannelPara &channelPara,
      91              :     std::vector<ChannelInfo> &channelInfos)
      92              : {
      93           10 :     const uint32_t feId = channelPara.feId;
      94           10 :     uint32_t jettyNum = CheckAndAdjustJettyNum(channelPara, channelJettyMap_);
      95              : 
      96           10 :     std::lock_guard<std::mutex> lock(innerMutex_);
      97              : 
      98           10 :     std::vector<JettyInfo> jettyInfos;
      99              :     // sqsize 每个jetty预留32分配
     100           10 :     auto ret = jettyCtxMgr_.Alloc(feId, jettyNum, channelPara.sqSize, jettyInfos);
     101           10 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     102              :         HCCL_WARNING("[CcuChannelCtxMgrV2][%s] failed to allocate jetty contexts of feId[%u], "
     103              :             "devLogicId[%d], dieId[%u].", __func__, feId, devLogicId_, dieId_),
     104              :         ret);
     105              : 
     106            9 :     const uint32_t channelGroupSize = channelJettyMap_.channelNum;
     107              :     // 分配成功保证数量不为0
     108            9 :     const uint32_t jettyCtxStartId = static_cast<uint32_t>(jettyInfos[0].jettyCtxId);
     109            9 :     uint32_t startChannelId = 0;
     110            9 :     CHK_RET(GetStartChannelId(jettyCtxStartId, channelJettyMap_, startChannelId));
     111            9 :     ret = CheckChannelRangeAllocatable(startChannelId, channelGroupSize, channelResInfos_);
     112            9 :     if (ret != HcclResult::HCCL_SUCCESS) {
     113            0 :         HCCL_WARNING("[CcuChannelCtxMgrV2][%s] failed to find free channels, "
     114              :             "jettyCtxStartId[%u], jettyNum[%u], need to release temp jetty contexts.",
     115              :             __func__, jettyCtxStartId, jettyNum);
     116              : 
     117            0 :         for (uint32_t i = 0; i < channelGroupSize; i++) { // 存在借用计数故需多次释放
     118            0 :             CHK_RET(jettyCtxMgr_.Release(feId, jettyInfos));
     119              :         }
     120            0 :         return ret;
     121              :     }
     122              : 
     123            9 :     AllocateChannelResources(channelPara, jettyInfos, startChannelId, channelInfos);
     124            9 :     return HcclResult::HCCL_SUCCESS;
     125           10 : }
     126              : 
     127            9 : void CcuChannelCtxMgrV2::AllocateChannelResources(const ChannelPara &channelPara,
     128              :     const std::vector<CcuJettyInfo> &jettyInfos, uint32_t startChannelId,
     129              :     std::vector<ChannelInfo> &channelInfos)
     130              : {
     131              :     // ccu v2按配比关系以组的粒度分配channel,同channel组复用jettyCtx
     132              :     // 调用者不处理channel组的概念,认为各channel独立
     133            9 :     channelInfos.clear();
     134            9 :     const uint32_t feId = channelPara.feId;
     135            9 :     const uint32_t channelGroupSize = channelJettyMap_.channelNum;
     136           81 :     for (uint32_t i = 0; i < channelGroupSize; i++) {
     137           72 :         uint32_t channelId = i + startChannelId;
     138           72 :         ChannelInfo channelInfo{};
     139           72 :         channelInfo.channelId = channelId;
     140           72 :         channelInfo.dieId = dieId_;
     141           72 :         channelInfo.jettyInfos = jettyInfos; // 拷贝相同的jetty信息
     142              : 
     143           72 :         auto &channelResInfo = channelResInfos_[channelId];
     144           72 :         channelResInfo.feId = feId;
     145           72 :         channelResInfo.channelInfo = channelInfo;
     146           72 :         channelResInfo.allocated = true;
     147           72 :         channelInfos.emplace_back(std::move(channelInfo));
     148           72 :     }
     149              : 
     150            9 :     HCCL_INFO("[CcuChannelCtxMgrV2][%s] allocated channels[%u, %u) successfully, "
     151              :         "devLogicId[%d], ioDie[%u], channelNum[%u].", __func__, startChannelId,
     152              :         startChannelId + channelGroupSize, devLogicId_, dieId_, channelGroupSize);
     153              :     // 只打印首channel,避免刷屏,分配成功保证数量不为0
     154            9 :     HCCL_INFO("[CcuChannelCtxMgrV2][%s] the start channel: ", __func__);
     155            9 :     DumpChannelResInfo(feId, channelInfos[0]);
     156            9 : }
     157              : 
     158            5 : static ChannelDataV2 BuildChannelDataV2(const ChannelCfg &cfg, const uint8_t dieId)
     159              : {
     160            5 :     ChannelDataV2 data{};
     161            5 :     (void)memcpy_s(&data.eidRaw[0], URMA_EID_LEN, &cfg.remoteEid, URMA_EID_LEN);
     162              : 
     163            5 :     data.vtpLow   = cfg.tpn & MASK_VTP_LOW;
     164            5 :     data.vtpHigh  = ((cfg.tpn & MASK_VTP) >> Hccl::SHIFT_16BITS) & MASK_VTP_HIGH;
     165            5 :     data.ioDieId  = static_cast<uint16_t>(dieId);
     166              : 
     167            5 :     return data;
     168              : }
     169              : 
     170            6 : static void DumpChannelDataV2(struct ChannelDataV2 &tmp)
     171              : {
     172            6 :     if (IsEidEmpty(tmp.eidRaw)) {
     173            2 :         return;
     174              :     }
     175              : 
     176            4 :     std::string dstEidInfo = "eidRaw: ";
     177           64 :     for (uint32_t i = 0; i < URMA_EID_LEN - 1; i++) {
     178           60 :         dstEidInfo += Hccl::StringFormat("0x%02x, ", tmp.eidRaw[i]);
     179              :     }
     180            4 :     dstEidInfo += Hccl::StringFormat("0x%02x", tmp.eidRaw[URMA_EID_LEN - 1]);
     181            4 :     HCCL_INFO("[ChannelDataV2][%s] dstEidInfo is %s ",__func__, dstEidInfo.c_str());
     182            4 :     HCCL_INFO("vtpLow: 0x%04x, vtpHigh: 0x%04x, ioDieId: 0x%04x.",
     183              :         tmp.vtpLow, tmp.vtpHigh, tmp.ioDieId);
     184            4 : }
     185              : 
     186            6 : static HcclResult ConfigChannelCtxDataV2(int32_t devLogicId, const uint32_t devPhyId,
     187              :     const uint8_t dieId, const uint32_t channelId, ChannelDataV2 &channelData)
     188              : {
     189            6 :     CustomChannelInfoIn  inBuff{};
     190            6 :     CustomChannelInfoOut outBuff{};
     191              : 
     192            6 :     constexpr uint32_t dataArraySize   = 1; // 每次配置1个Channel
     193            6 :     inBuff.op                          = CcuOpcodeType::CCU_U_OP_SET_CHANNEL;
     194            6 :     inBuff.data.dataInfo.udieIdx       = dieId;
     195            6 :     inBuff.data.dataInfo.dataArraySize = dataArraySize;
     196            6 :     inBuff.data.dataInfo.dataLen       = sizeof(struct ChannelDataV2) * dataArraySize;
     197            6 :     inBuff.offsetStartIdx              = channelId;
     198              : 
     199            6 :     HCCL_INFO("[CcuChannelCtxMgrV2][%s] config data to ccu driver, devPhyId[%u], "
     200              :         "ioDie[%u], idx[%u], size[%u].", __func__, devPhyId, dieId, channelId,
     201              :         sizeof(struct ChannelDataV2));
     202            6 :     DumpChannelDataV2(channelData);
     203              : 
     204            6 :     (void)memcpy_s(inBuff.data.dataInfo.dataArray, sizeof(struct ChannelDataV2), &channelData,
     205              :                    sizeof(struct ChannelDataV2));
     206              : 
     207            6 :     auto ret = HccpRaTlvCcuCustomChannel(devLogicId,
     208              :         static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     209            6 :     if (ret != 0) {
     210            0 :         HCCL_ERROR("[CcuChannelCtxMgrV2][%s] failed to call ccu driver, "
     211              :             "devLogicId[%d] devPhyId[%u] dieId[%d] op[%s] ret[%d].", __func__,
     212              :             devLogicId, devPhyId, dieId, "SET_CHANNEL", ret);
     213            0 :         return ret;
     214              :     }
     215            6 :     return HcclResult::HCCL_SUCCESS;
     216              : }
     217              : 
     218            8 : HcclResult CcuChannelCtxMgrV2::Config(const ChannelCfg &channelCfg)
     219              : {
     220            8 :     std::lock_guard<std::mutex> lock(innerMutex_);
     221            8 :     uint32_t channelId = channelCfg.channelId;
     222            8 :     if (!CheckIfChannelAllocated(channelId)) {
     223            2 :         return HcclResult::HCCL_E_PARA; // 日志已在判断处处理
     224              :     };
     225              : 
     226            6 :     const auto &channelResInfo = channelResInfos_[channelId];
     227            6 :     const uint32_t feId = channelResInfo.feId;
     228            6 :     const std::vector<JettyInfo> &jettyInfos = channelResInfo.channelInfo.jettyInfos;
     229            6 :     auto ret = jettyCtxMgr_.Config(feId, jettyInfos, channelCfg.jettyCfgs);
     230            6 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     231              :         HCCL_ERROR("[CcuChannelCtxMgrV2][%s] failed to config jetty contexts of channelId[%u], "
     232              :             "feId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, feId,
     233              :             devLogicId_, static_cast<uint32_t>(dieId_)),
     234              :         ret);
     235              : 
     236            5 :     ChannelDataV2 data = BuildChannelDataV2(channelCfg, dieId_);
     237            5 :     CHK_RET(ConfigChannelCtxDataV2(devLogicId_, devPhyId_, dieId_, channelId, data));
     238            5 :     return HcclResult::HCCL_SUCCESS;
     239            8 : }
     240              : 
     241            3 : HcclResult CcuChannelCtxMgrV2::Release(const uint32_t channelId)
     242              : {
     243            3 :     std::lock_guard<std::mutex> lock(innerMutex_);
     244            3 :     if (!CheckIfChannelAllocated(channelId)) {
     245            2 :         return HcclResult::HCCL_E_PARA; // 日志已在判断处处理
     246              :     };
     247              : 
     248            1 :     const auto &channelResInfo = channelResInfos_[channelId];
     249            2 :     auto ret = jettyCtxMgr_.Release(channelResInfo.feId,
     250            1 :         channelResInfo.channelInfo.jettyInfos);
     251            1 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     252              :         HCCL_WARNING("[CcuChannelCtxMgrV2][%s] failed to release jetty contexts "
     253              :             "of channelId[%u], feId[%u], devLogicId[%d], dieId[%u].", __func__,
     254              :             channelId, channelResInfos_[channelId].feId, devLogicId_, dieId_),
     255              :         ret);
     256              : 
     257            1 :     channelResInfos_[channelId] = ChannelResInfo{};
     258              :     // V2 验证阶段未启用动态channel,保持重置Channel配置表,避免错误复用
     259            1 :     ChannelDataV2 data = {};
     260            1 :     CHK_RET(ConfigChannelCtxDataV2(devLogicId_, devPhyId_, dieId_, channelId, data));
     261            1 :     return HcclResult::HCCL_SUCCESS;
     262            3 : }
     263              : 
     264              : }; // namespace hcomm
        

Generated by: LCOV version 2.0-1