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-08-04 10:52:23 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           39 : CcuChannelCtxMgrV2::CcuChannelCtxMgrV2(const int32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId)
      23           39 :     : CcuChannelCtxMgr(devLogicId, dieId, devPhyId), jettyCtxMgr_(devLogicId, dieId, devPhyId)
      24              : {
      25           39 :     (void)CcuResSpecifications::GetInstance(devLogicId).GetChannelJettyMap(dieId, channelJettyMap_);
      26           39 : }
      27              : 
      28           39 : HcclResult CcuChannelCtxMgrV2::Init()
      29              : {
      30           39 :     uint32_t strategy = 0; // 获取失败或为0场景,分配将按资源不足操作
      31           39 :     (void)CcuResSpecifications::GetInstance(devLogicId_).GetChannelNum(dieId_, strategy);
      32           39 :     channelResInfos_.resize(strategy);
      33           39 :     CHK_RET(jettyCtxMgr_.Init());
      34           39 :     return  HcclResult::HCCL_SUCCESS;
      35              : }
      36              : 
      37           36 : static uint32_t CheckAndAdjustJettyNum(const ChannelPara &channelPara,
      38              :     const CcuChannelJettyMap &channelJettyMap)
      39              : {
      40           36 :     uint32_t jettyNum = channelPara.jettyNum;
      41           36 :     const uint32_t jettyGroupSize = channelJettyMap.jettyNum;
      42           36 :     if (jettyNum != jettyGroupSize) {
      43           31 :         HCCL_INFO("[CcuChannelCtxMgrV2][%s] jetty num[%u] reset to channelJettyMap."
      44              :             "jettyNum[%u], feId[%u].", __func__, jettyNum,
      45              :             jettyGroupSize, channelPara.feId);
      46           31 :         jettyNum = jettyGroupSize;
      47              :     }
      48           36 :     return jettyNum;
      49              : }
      50              : 
      51           35 : static HcclResult GetStartChannelId(const uint32_t jettyCtxStartId,
      52              :     const CcuChannelJettyMap &channelJettyMap,
      53              :     uint32_t &channelId)
      54              : {
      55              :     // channelJettyMap来自静态定义,认为其不会为0
      56           35 :     const uint32_t channelGroupSize = channelJettyMap.channelNum;
      57           35 :     const uint32_t jettyGroupSize = channelJettyMap.jettyNum;
      58           35 :     const uint32_t jettyGroupId = jettyCtxStartId / jettyGroupSize;
      59           35 :     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           35 :     channelId = channelGroupSize * jettyGroupId;
      66           35 :     return HcclResult::HCCL_SUCCESS;
      67              : }
      68              : 
      69           35 : static HcclResult CheckChannelRangeAllocatable(
      70              :     const uint32_t startChannelId, const uint32_t channelNum, std::vector<ChannelResInfo> &channelResInfos)
      71              : {
      72           35 :     const uint32_t endChannelId = startChannelId + channelNum;
      73           35 :     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[%zu].", __func__, startChannelId,
      76              :             endChannelId, channelResInfos.size()),
      77              :         HcclResult::HCCL_E_INTERNAL);
      78              : 
      79          315 :     for (uint32_t i = startChannelId; i < endChannelId; i++) {
      80          280 :         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           35 :     return HcclResult::HCCL_SUCCESS;
      88              : }
      89              : 
      90           36 : HcclResult CcuChannelCtxMgrV2::Alloc(const ChannelPara &channelPara,
      91              :     std::vector<ChannelInfo> &channelInfos)
      92              : {
      93           36 :     const uint32_t feId = channelPara.feId;
      94           36 :     uint32_t jettyNum = CheckAndAdjustJettyNum(channelPara, channelJettyMap_);
      95              : 
      96           36 :     std::lock_guard<std::mutex> lock(innerMutex_);
      97              : 
      98           36 :     std::vector<JettyInfo> jettyInfos;
      99              :     // sqsize 每个jetty预留32分配
     100           36 :     auto ret = jettyCtxMgr_.Alloc(feId, jettyNum, channelPara.sqSize, jettyInfos);
     101           36 :     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           35 :     const uint32_t channelGroupSize = channelJettyMap_.channelNum;
     107              :     // 分配成功保证数量不为0
     108           35 :     const uint32_t jettyCtxStartId = static_cast<uint32_t>(jettyInfos[0].jettyCtxId);
     109           35 :     uint32_t startChannelId = 0;
     110           35 :     CHK_RET(GetStartChannelId(jettyCtxStartId, channelJettyMap_, startChannelId));
     111           35 :     ret = CheckChannelRangeAllocatable(startChannelId, channelGroupSize, channelResInfos_);
     112           35 :     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           35 :     AllocateChannelResources(channelPara, jettyInfos, startChannelId, channelInfos);
     124           35 :     return HcclResult::HCCL_SUCCESS;
     125           36 : }
     126              : 
     127           35 : 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           35 :     channelInfos.clear();
     134           35 :     const uint32_t feId = channelPara.feId;
     135           35 :     const uint32_t channelGroupSize = channelJettyMap_.channelNum;
     136          315 :     for (uint32_t i = 0; i < channelGroupSize; i++) {
     137          280 :         uint32_t channelId = i + startChannelId;
     138          280 :         ChannelInfo channelInfo{};
     139          280 :         channelInfo.channelId = channelId;
     140          280 :         channelInfo.dieId = dieId_;
     141          280 :         channelInfo.jettyInfos = jettyInfos; // 拷贝相同的jetty信息
     142              : 
     143          280 :         auto &channelResInfo = channelResInfos_[channelId];
     144          280 :         channelResInfo.feId = feId;
     145          280 :         channelResInfo.channelInfo = channelInfo;
     146          280 :         channelResInfo.allocated = true;
     147          280 :         channelInfos.emplace_back(std::move(channelInfo));
     148          280 :     }
     149              : 
     150           35 :     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           35 :     HCCL_INFO("[CcuChannelCtxMgrV2][%s] the start channel: ", __func__);
     155           35 :     DumpChannelResInfo(feId, channelInfos[0]);
     156           35 : }
     157              : 
     158           29 : static ChannelDataV2 BuildChannelDataV2(const ChannelCfg &cfg, const uint8_t dieId)
     159              : {
     160           29 :     ChannelDataV2 data{};
     161           29 :     (void)memcpy_s(&data.eidRaw[0], URMA_EID_LEN, &cfg.remoteEid, URMA_EID_LEN);
     162              : 
     163           29 :     data.vtpLow   = cfg.tpn & MASK_VTP_LOW;
     164           29 :     data.vtpHigh  = ((cfg.tpn & MASK_VTP) >> Hccl::SHIFT_16BITS) & MASK_VTP_HIGH;
     165           29 :     data.ioDieId  = static_cast<uint16_t>(dieId);
     166              : 
     167           29 :     return data;
     168              : }
     169              : 
     170           46 : static void DumpChannelDataV2(struct ChannelDataV2 &tmp)
     171              : {
     172           46 :     if (IsEidEmpty(tmp.eidRaw)) {
     173           18 :         return;
     174              :     }
     175              : 
     176           28 :     std::string dstEidInfo = "eidRaw: ";
     177          448 :     for (uint32_t i = 0; i < URMA_EID_LEN - 1; i++) {
     178          420 :         dstEidInfo += Hccl::StringFormat("0x%02x, ", tmp.eidRaw[i]);
     179              :     }
     180           28 :     dstEidInfo += Hccl::StringFormat("0x%02x", tmp.eidRaw[URMA_EID_LEN - 1]);
     181           28 :     HCCL_INFO("[ChannelDataV2][%s] dstEidInfo is %s ",__func__, dstEidInfo.c_str());
     182           28 :     HCCL_INFO("vtpLow: 0x%04x, vtpHigh: 0x%04x, ioDieId: 0x%04x.",
     183              :         tmp.vtpLow, tmp.vtpHigh, tmp.ioDieId);
     184           28 : }
     185              : 
     186           46 : static HcclResult ConfigChannelCtxDataV2(int32_t devLogicId, const uint32_t devPhyId,
     187              :     const uint8_t dieId, const uint32_t channelId, ChannelDataV2 &channelData)
     188              : {
     189           46 :     CustomChannelInfoIn  inBuff{};
     190           46 :     CustomChannelInfoOut outBuff{};
     191              : 
     192           46 :     constexpr uint32_t dataArraySize   = 1; // 每次配置1个Channel
     193           46 :     inBuff.op                          = CcuOpcodeType::CCU_U_OP_SET_CHANNEL;
     194           46 :     inBuff.data.dataInfo.udieIdx       = dieId;
     195           46 :     inBuff.data.dataInfo.dataArraySize = dataArraySize;
     196           46 :     inBuff.data.dataInfo.dataLen       = sizeof(struct ChannelDataV2) * dataArraySize;
     197           46 :     inBuff.offsetStartIdx              = channelId;
     198              : 
     199           46 :     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           46 :     DumpChannelDataV2(channelData);
     203              : 
     204           46 :     (void)memcpy_s(inBuff.data.dataInfo.dataArray, sizeof(struct ChannelDataV2), &channelData,
     205              :                    sizeof(struct ChannelDataV2));
     206              : 
     207           46 :     auto ret = HccpRaTlvCcuCustomChannel(devLogicId,
     208              :         static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     209           46 :     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           46 :     return HcclResult::HCCL_SUCCESS;
     216              : }
     217              : 
     218           32 : HcclResult CcuChannelCtxMgrV2::Config(const ChannelCfg &channelCfg)
     219              : {
     220           32 :     std::lock_guard<std::mutex> lock(innerMutex_);
     221           32 :     uint32_t channelId = channelCfg.channelId;
     222           32 :     if (!CheckIfChannelAllocated(channelId)) {
     223            2 :         return HcclResult::HCCL_E_PARA; // 日志已在判断处处理
     224              :     }
     225              : 
     226           30 :     const auto &channelResInfo = channelResInfos_[channelId];
     227           30 :     const uint32_t feId = channelResInfo.feId;
     228           30 :     const std::vector<JettyInfo> &jettyInfos = channelResInfo.channelInfo.jettyInfos;
     229           30 :     auto ret = jettyCtxMgr_.Config(feId, jettyInfos, channelCfg.jettyCfgs);
     230           30 :     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           29 :     ChannelDataV2 data = BuildChannelDataV2(channelCfg, dieId_);
     237           29 :     CHK_RET(ConfigChannelCtxDataV2(devLogicId_, devPhyId_, dieId_, channelId, data));
     238           29 :     return HcclResult::HCCL_SUCCESS;
     239           32 : }
     240              : 
     241           19 : HcclResult CcuChannelCtxMgrV2::Release(const uint32_t channelId)
     242              : {
     243           19 :     std::lock_guard<std::mutex> lock(innerMutex_);
     244           19 :     if (!CheckIfChannelAllocated(channelId)) {
     245            2 :         return HcclResult::HCCL_E_PARA; // 日志已在判断处处理
     246              :     };
     247              : 
     248           17 :     const auto &channelResInfo = channelResInfos_[channelId];
     249           34 :     auto ret = jettyCtxMgr_.Release(channelResInfo.feId,
     250           17 :         channelResInfo.channelInfo.jettyInfos);
     251           17 :     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           17 :     channelResInfos_[channelId] = ChannelResInfo{};
     258              :     // V2 验证阶段未启用动态channel,保持重置Channel配置表,避免错误复用
     259           17 :     ChannelDataV2 data = {};
     260           17 :     CHK_RET(ConfigChannelCtxDataV2(devLogicId_, devPhyId_, dieId_, channelId, data));
     261           17 :     return HcclResult::HCCL_SUCCESS;
     262           19 : }
     263              : 
     264              : }; // namespace hcomm
        

Generated by: LCOV version 2.0-1