LCOV - code coverage report
Current view: top level - base_comm/resources/ccu/ccu_device/ccu_comp/ccu_channel/ccu_channel_ctx_v1 - ccu_channel_ctx_mgr_v1.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.2 % 120 113
Test Date: 2026-08-04 10:52:23 Functions: 100.0 % 8 8

            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_channel_ctx_mgr_v1.h"
      12              : 
      13              : #include <vector>
      14              : #include <string>
      15              : 
      16              : #include "ccu_res_specs.h"
      17              : #include "hcomm_adapter_hccp.h"
      18              : 
      19              : namespace hcomm {
      20              : 
      21              : constexpr uint32_t CCU_V1_CHANNEL_DEFAULT_JETTY_NUM = 1;
      22              : 
      23          142 : HcclResult CcuChannelCtxMgrV1::Init()
      24              : {
      25          142 :     uint32_t strategy = 0; // 获取失败或为0场景,分配将按资源不足操作
      26          142 :     (void)CcuResSpecifications::GetInstance(devLogicId_).GetChannelNum(dieId_, strategy);
      27          142 :     channelResInfos_.resize(strategy);
      28          142 :     CHK_RET(jettyCtxMgr_.Init());
      29          142 :     return HcclResult::HCCL_SUCCESS;
      30              : }
      31              : 
      32          155 : static HcclResult FindFreeChannelId(std::vector<ChannelResInfo> &channelResInfos,
      33              :     uint32_t &channelId)
      34              : {
      35              :     // ccu v1每次都分配新的channel与jettyCtx
      36              :     // 故直接选择首个可用channel即可
      37          155 :     const uint32_t channelNum = channelResInfos.size();
      38          168 :     for (uint32_t i = 0; i < channelNum; i++) {
      39          168 :         if (!channelResInfos[i].allocated) {
      40          155 :             channelId = i;
      41          155 :             return HcclResult::HCCL_SUCCESS;
      42              :         }
      43              :     }
      44            0 :     return HcclResult::HCCL_E_UNAVAIL;
      45              : }
      46              : 
      47          155 : HcclResult CcuChannelCtxMgrV1::Alloc(const ChannelPara &channelPara,
      48              :     std::vector<ChannelInfo> &channelInfos)
      49              : {
      50          155 :     const uint32_t feId = channelPara.feId;
      51          155 :     uint32_t jettyNum = channelPara.jettyNum;
      52          155 :     if (jettyNum == 0) {
      53          155 :         jettyNum = CCU_V1_CHANNEL_DEFAULT_JETTY_NUM;
      54          155 :         HCCL_INFO("[CcuJettyCtxMgrV1][%s] jettyNum is 0, reset to default[%u], "
      55              :             "feId[%u], devLogicId[%d], dieId[%u].", __func__, jettyNum, feId,
      56              :             devLogicId_, dieId_);
      57              :     }
      58              : 
      59          155 :     std::lock_guard<std::mutex> lock(innerMutex_);
      60          155 :     uint32_t channelId = 0;
      61          155 :     auto ret = FindFreeChannelId(channelResInfos_, channelId);
      62          155 :     CHK_PRT_RET(ret == HcclResult::HCCL_E_UNAVAIL,
      63              :         HCCL_WARNING("[CcuChannelCtxMgrV1][%s] failed to find free channel, channel strategy[%zu], "
      64              :             "left resources are not enough, feId[%u], devLogicId[%d], dieId[%u].",
      65              :             __func__, channelResInfos_.size(), feId, devLogicId_, dieId_),
      66              :         ret);
      67          155 :     CHK_RET(ret);
      68              : 
      69          155 :     ChannelInfo channelInfo = {};
      70          155 :     ret = jettyCtxMgr_.Alloc(feId, jettyNum, channelPara.sqSize,
      71              :         channelInfo.jettyInfos);
      72          155 :     CHK_PRT_RET(ret == HcclResult::HCCL_E_UNAVAIL,
      73              :         HCCL_WARNING("[CcuChannelCtxMgrV1][%s] failed to allocate jetty contexts to channelId[%u], "
      74              :             "left resources are not enough, feId[%u], devLogicId[%d], dieId[%u].",
      75              :             __func__, channelId, feId, devLogicId_, dieId_),
      76              :         ret);
      77          155 :     CHK_RET(ret);
      78              : 
      79          155 :     channelInfo.channelId = channelId;
      80          155 :     channelInfo.dieId = dieId_;
      81          155 :     channelResInfos_[channelId].feId = feId;
      82          155 :     channelResInfos_[channelId].channelInfo = channelInfo;
      83          155 :     channelResInfos_[channelId].allocated = true;
      84          155 :     DumpChannelResInfo(feId, channelInfo);
      85              : 
      86          155 :     channelInfos.clear(); // ccu v1每次仅分配1个channel,不同channel不复用jettyCtx
      87          155 :     channelInfos.emplace_back(std::move(channelInfo));
      88          155 :     return ret;
      89          155 : }
      90              : 
      91          142 : static ChannelCtxDataV1 BuildChannelCtxDataV1(const ChannelCfg &cfg,
      92              :     const uint32_t feId, const uint8_t dieId, const uint16_t startTaJettyId)
      93              : {
      94          142 :     ChannelCtxDataV1 data = {};
      95          142 :     (void)memcpy_s(&data.eidRaw[0], URMA_EID_LEN, &cfg.remoteEid, URMA_EID_LEN);
      96              : 
      97          142 :     data.vtpLow              = cfg.tpn & MASK_VTP_LOW;
      98          142 :     data.vtpHigh             = ((cfg.tpn & MASK_VTP) >> Hccl::SHIFT_16BITS) & MASK_VTP_HIGH;
      99              :     
     100          142 :     data.srcPfeId            = static_cast<uint16_t>(feId);
     101              : 
     102          142 :     data.startJettyIdLow     = startTaJettyId & MASK_START_JETTY_ID_LOW;
     103          142 :     data.startJettyIdHigh    = (startTaJettyId >> Hccl::SHIFT_4BITS) & MASK_START_JETTY_ID_HIGH;
     104              : 
     105              :     // 写入硬件减 1,cfgs的数量一定小于jetty规格数,不会超过uint8_t范围
     106          142 :     uint8_t jettyNum         = static_cast<uint8_t>(cfg.jettyCfgs.size()) - 1;
     107          142 :     data.jettyNumLow         = jettyNum & MASK_JETTY_NUM_LOW;
     108          142 :     data.jettyNumHigh        = (jettyNum >> Hccl::SHIFT_4BITS) & MASK_JETTY_NUM_HIGH;
     109              : 
     110          142 :     data.ioDieId             = static_cast<uint16_t>(dieId);
     111              : 
     112          142 :     data.dstTokenIdLow       = cfg.memTokenId & MASK_TOKEN_ID_LOW;
     113          142 :     data.dstTokenIdHigh      = (cfg.memTokenId >> Hccl::SHIFT_12BITS) & MASK_TOKEN_ID_HIGH;
     114              : 
     115          142 :     data.dstTokenValueLow    = cfg.memTokenValue & MASK_TOKEN_VALUE_LOW;
     116          142 :     data.dstTokenValueMiddle = (cfg.memTokenValue >> Hccl::SHIFT_8BITS) & MASK_TOKEN_VALUE_MID;
     117          142 :     data.dstTokenValueHigh   = (cfg.memTokenValue >> Hccl::SHIFT_24BITS) & MASK_TOKEN_VALUE_HIGH;
     118              : 
     119          142 :     uint64_t dstVa           = (cfg.remoteCcuVa >> REMOTE_CCU_VA_RIGHT_SHIFT_NUM);
     120          142 :     data.dstVaLow            = dstVa & MASK_VA_LOW;
     121          142 :     data.dstVaMiddle         = (dstVa >> Hccl::SHIFT_8BITS) & MASK_VA_MID;
     122          142 :     data.dstVaHigh           = (dstVa >> Hccl::SHIFT_24BITS) & MASK_VA_HIGH;
     123          142 :     data.dstVaHigher         = (dstVa >> Hccl::SHIFT_40BITS) & MASK_VA_HIGHER;
     124          142 :     data.dstTokenValueValid  = TOKEN_VALUE_VALID;
     125          142 :     return data;
     126              : }
     127              : 
     128          155 : static void DumpChannelCtxDataV1(const struct ChannelCtxDataV1 &data)
     129              : {
     130          155 :     if (IsEidEmpty(data.eidRaw)) {
     131           13 :         return;
     132              :     }
     133          142 :     std::string dstEidInfo = "eidRaw: ";
     134         2272 :     for (uint32_t i = 0; i < URMA_EID_LEN - 1; i++) {
     135         2130 :         dstEidInfo += Hccl::StringFormat("0x%02x, ", data.eidRaw[i]);
     136              :     }
     137          142 :     dstEidInfo += Hccl::StringFormat("0x%02x", data.eidRaw[URMA_EID_LEN - 1]);
     138          142 :     HCCL_INFO("%s.", dstEidInfo.c_str());
     139              :     
     140          142 :     HCCL_INFO("vtpLow: 0x%04x, vtpHigh: 0x%04x, srcPfeId: 0x%04x, "
     141              :         "startJettyIdLow: 0x%04x, startJettyIdHigh: 0x%04x, "
     142              :         "JettyNumLow: 0x%04x, JettyNumHigh: 0x%04x, ioDieId: 0x%04x, ",
     143              :         data.vtpLow, data.vtpHigh, data.srcPfeId, data.startJettyIdLow,
     144              :         data.startJettyIdHigh, data.jettyNumLow, data.jettyNumHigh,
     145              :         data.ioDieId);
     146              :     
     147          142 :     HCCL_INFO("dstVaLow: 0x%04x, dstVaMiddle: 0x%04x, "
     148              :         "dstVaHigh: 0x%04x, dstVaHigher: 0x%04x, dstTokenValueValid: 0x%04x",
     149              :         data.dstVaLow, data.dstVaMiddle, data.dstVaHigh, data.dstVaHigher,
     150              :         data.dstTokenValueValid);
     151          142 : }
     152              : 
     153          155 : static HcclResult ConfigChannelCtxDataV1(const int32_t devLogicId, const uint32_t devPhyId, const uint8_t dieId,
     154              :     const uint32_t channelId, const ChannelCtxDataV1 &channelCtxData)
     155              : {
     156          155 :     CustomChannelInfoIn  inBuff{};
     157          155 :     CustomChannelInfoOut outBuff{};
     158              : 
     159          155 :     constexpr uint32_t dataArraySize   = 1; // 每次配置1个Channel
     160          155 :     inBuff.op                          = CcuOpcodeType::CCU_U_OP_SET_CHANNEL;
     161          155 :     inBuff.data.dataInfo.udieIdx       = dieId;
     162          155 :     inBuff.data.dataInfo.dataArraySize = dataArraySize;
     163          155 :     inBuff.data.dataInfo.dataLen       = sizeof(struct ChannelCtxDataV1) * dataArraySize;
     164          155 :     inBuff.offsetStartIdx              = channelId;
     165              : 
     166          155 :     HCCL_INFO("[CcuChannelCtxMgrV1][%s] set data to ccu driver, devLogicId[%d] devPhyId[%u], "
     167              :         "ioDie[%u], idx[%u], size[%u].", __func__, devLogicId, devPhyId, dieId, channelId,
     168              :         sizeof(struct ChannelCtxDataV1));
     169          155 :     DumpChannelCtxDataV1(channelCtxData);
     170              : 
     171          155 :     (void)memcpy_s(inBuff.data.dataInfo.dataArray, sizeof(struct ChannelCtxDataV1), &channelCtxData,
     172              :                    sizeof(struct ChannelCtxDataV1));
     173              :     
     174          155 :     auto ret = HccpRaTlvCcuCustomChannel(devLogicId,
     175              :         static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     176          155 :     if (ret != HCCL_SUCCESS) {
     177            0 :         HCCL_ERROR("[CcuChannelCtxMgrV1][%s] failed to call ccu driver, "
     178              :             "devLogicId[%d] devPhyId[%u] dieId[%d] op[%s] ret[%d].", __func__, devLogicId, devPhyId, dieId,
     179              :             "SET_CHANNEL", ret);
     180            0 :         return ret;
     181              :     }
     182              : 
     183          155 :     return HcclResult::HCCL_SUCCESS;
     184              : }
     185              : 
     186          142 : HcclResult CcuChannelCtxMgrV1::Config(const ChannelCfg &channelCfg)
     187              : {
     188          142 :     std::lock_guard<std::mutex> lock(innerMutex_);
     189          142 :     const uint32_t channelId = channelCfg.channelId;
     190          142 :     if (!CheckIfChannelAllocated(channelId)) {
     191            0 :         return HcclResult::HCCL_E_PARA; // 日志已在判断处处理
     192              :     };
     193              : 
     194          142 :     const auto &channelResInfo = channelResInfos_[channelId];
     195          142 :     const uint32_t feId = channelResInfo.feId;
     196          142 :     const std::vector<JettyInfo> &jettyInfos = channelResInfo.channelInfo.jettyInfos;
     197          142 :     auto ret = jettyCtxMgr_.Config(feId, jettyInfos, channelCfg.jettyCfgs);
     198          142 :     if (ret != HcclResult::HCCL_SUCCESS) {
     199            0 :         HCCL_ERROR("[CcuChannelCtxMgrV1][%s] failed to config jetty contexts of channelId[%u], "
     200              :             "feId[%u], devLogicId[%d], dieId[%u].", __func__, channelId, feId,
     201              :             devLogicId_, dieId_);
     202            0 :         return ret;
     203              :     }
     204              :     // 因jettyCtx连续,从起始jettyCtx配置
     205          142 :     const uint16_t startTaJettyId = jettyInfos[0].taJettyId;
     206          142 :     const ChannelCtxDataV1 &data = BuildChannelCtxDataV1(channelCfg, feId, dieId_, startTaJettyId);
     207          142 :     CHK_RET(ConfigChannelCtxDataV1(devLogicId_, devPhyId_, dieId_, channelId, data));
     208          142 :     return HcclResult::HCCL_SUCCESS;
     209          142 : }
     210              : 
     211           13 : HcclResult CcuChannelCtxMgrV1::Release(const uint32_t channelId)
     212              : {
     213           13 :     std::lock_guard<std::mutex> lock(innerMutex_);
     214           13 :     if (!CheckIfChannelAllocated(channelId)) {
     215            0 :         return HcclResult::HCCL_E_PARA; // 日志已在判断处处理
     216              :     };
     217              : 
     218           13 :     const auto &channelResInfo = channelResInfos_[channelId];
     219           26 :     auto ret = jettyCtxMgr_.Release(channelResInfo.feId,
     220           13 :         channelResInfo.channelInfo.jettyInfos);
     221           13 :     CHK_PRT_RET(ret != HcclResult::HCCL_SUCCESS,
     222              :         HCCL_WARNING("[CcuChannelCtxMgrV1][%s] failed to release jetty contexts "
     223              :             "of channelId[%u], feId[%u], devLogicId[%d], dieId[%u].", __func__,
     224              :             channelId, channelResInfos_[channelId].feId, devLogicId_, dieId_),
     225              :         ret);
     226              :     // 重置并配置Channel表,避免错误复用
     227           13 :     channelResInfos_[channelId] = ChannelResInfo{};
     228           13 :     ChannelCtxDataV1 data = {};
     229           13 :     CHK_RET(ConfigChannelCtxDataV1(devLogicId_, devPhyId_, dieId_, channelId, data));
     230           13 :     return HcclResult::HCCL_SUCCESS;
     231           13 : }
     232              : 
     233              : }; // namespace hcomm
        

Generated by: LCOV version 2.0-1