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

Generated by: LCOV version 2.0-1