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

            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_jetty_ctx_mgr.h"
      12              : 
      13              : #include "ccu_res_specs.h"
      14              : 
      15              : #include "hccp_ctx.h"
      16              : 
      17              : #include "hcomm_adapter_hccp.h"
      18              : 
      19              : namespace hcomm {
      20              : 
      21          193 : CcuJettyCtxMgr::CcuJettyCtxMgr(const int32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId)
      22          193 :     : devLogicId_(devLogicId), dieId_(dieId), devPhyId_(devPhyId), pfeMgr_(devLogicId, dieId, devPhyId)
      23              : {
      24          193 : }
      25              : 
      26              : // 对一个数求以2为底的对数,num已保证不为0
      27          173 : inline uint16_t Log2OfPowerOfTwo(uint32_t num)
      28              : {
      29          173 :     uint16_t log2 = 0;
      30          896 :     while (num > 1) {
      31          723 :         num >>= 1;
      32          723 :         log2++;
      33              :     }
      34          173 :     return log2;
      35              : }
      36              : 
      37              : union DoorbellAddr {
      38              :     uint64_t dbAddr;
      39              :     uint16_t dbAddr16[4];
      40              : };
      41              : 
      42          173 : LocalJettyCtxData BuildJettyCtxData(const uint8_t dieId, const uint32_t pfeId,
      43              :     const JettyInfo& jettyInfo, const JettyCfg& jettyCfg)
      44              : {
      45          173 :     LocalJettyCtxData data{};
      46              : 
      47              :     DoorbellAddr dbAddr;
      48          173 :     dbAddr.dbAddr = jettyCfg.dbVa;
      49          173 :     data.doorbellAddr[0] = dbAddr.dbAddr16[0];
      50          173 :     data.doorbellAddr[1] = dbAddr.dbAddr16[1];
      51          173 :     data.doorbellAddr[2] = dbAddr.dbAddr16[2]; // 2: doorbell 地址访问
      52          173 :     data.doorbellAddr[3] = dbAddr.dbAddr16[3]; // 3: doorbell 地址访问
      53              :     
      54          173 :     data.pfeIdx = static_cast<uint8_t>(pfeId);
      55          173 :     data.ioDieId = dieId;
      56              :     
      57          173 :     data.doorbellAddrType  = DB_ADDR_TYPE;
      58          173 :     data.tokenValueIsValid = TOKEN_VALUE_IS_VALIDE;
      59              :     
      60          173 :     data.tokenIdLow = jettyCfg.dbTokenId & MASK_TK_ID_LOW;
      61          173 :     data.tokenIdHigh = (jettyCfg.dbTokenId >> Hccl::SHIFT_8BITS) & MASK_TK_ID_HIGH; // tokenId右移8位
      62              :     
      63          173 :     data.tokenValueLow = jettyCfg.dbTokenValue & MASK_TK_VALUE_LOW;
      64          173 :     data.tokenValueMiddle =
      65          173 :         (jettyCfg.dbTokenValue >> Hccl::SHIFT_4BITS) & MASK_TK_VALUE_MID; // tokenValue右移4位
      66          173 :     data.tokenValueHigh =
      67          173 :         (jettyCfg.dbTokenValue >> Hccl::SHIFT_20BITS) & MASK_TK_VALUE_HIGH; // tokenValue右移20位
      68              :     
      69          173 :     const uint16_t wqeBBShift = Log2OfPowerOfTwo(jettyInfo.sqDepth * CCU_WQE_NUM_PER_SQE);
      70          173 :     data.sqeBasicBlockLeftShifts = wqeBBShift;
      71              : 
      72          173 :     const uint16_t wqeBBIdx = jettyInfo.wqeBBStartId;
      73          173 :     data.startWqeBasicBlockIdxLow = wqeBBIdx & MASK_WQEBB_IDX_LOW;
      74          173 :     data.startWqeBasicBlockIdxHigh = (wqeBBIdx >> Hccl::SHIFT_4BITS) & MASK_WQEBB_IDX_HIGH; // 右移4位
      75              :     
      76          173 :     data.pi = CCU_HARDWARE_DEFAULT_VALUE;
      77          173 :     data.ci = CCU_HARDWARE_DEFAULT_VALUE;
      78          173 :     data.maxCi = CCU_HARDWARE_DEFAULT_VALUE;
      79          173 :     data.oooCqeCnt = CCU_HARDWARE_DEFAULT_VALUE;
      80          173 :     data.doorbellSendState = CCU_HARDWARE_DEFAULT_VALUE;
      81              : 
      82          173 :     return data;
      83              : }
      84              : 
      85          173 : void DumpJettyCtxData(const LocalJettyCtxData &tmp)
      86              : {
      87          173 :     HCCL_RUN_INFO("doorbellAddr: [3]0x%04x, [2]0x%04x, [1]0x%04x, [0]0x%04x",
      88              :         tmp.doorbellAddr[3], // 3: doorbell 地址访问
      89              :         tmp.doorbellAddr[2], // 2: doorbell 地址访问
      90              :         tmp.doorbellAddr[1],
      91              :         tmp.doorbellAddr[0]);
      92              : 
      93              :     // 安全问题:禁止打印token相关信息
      94          173 :     HCCL_RUN_INFO("pfeIdx: 0x%04x, ioDieId: 0x%04x, doorbellAddrType: 0x%04x, "
      95              :         "tokenValueIsValid: 0x%04x", tmp.pfeIdx, tmp.ioDieId, tmp.doorbellAddrType,
      96              :         tmp.tokenValueIsValid);
      97              : 
      98          173 :     HCCL_RUN_INFO("sqeBasicBlockLeftShifts: 0x%04x, pi: 0x%04x, ci: 0x%04x, "
      99              :         "maxCi: 0x%04x, oooCqeCnt: 0x%04x, startWqeBasicBlockIdxLow: 0x%04x, "
     100              :         "startWqeBasicBlockIdxHigh: 0x%04x, doorbellSendState: 0x%04x",
     101              :         tmp.sqeBasicBlockLeftShifts, tmp.pi, tmp.ci, tmp.maxCi, tmp.oooCqeCnt,
     102              :         tmp.startWqeBasicBlockIdxLow, tmp.startWqeBasicBlockIdxHigh, tmp.doorbellSendState);
     103          173 : }
     104              : 
     105          173 : HcclResult ConfigJettyCtxData(const int32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId,
     106              :     const uint16_t startJettyCtxId, std::vector<LocalJettyCtxData>& jettyCtxData)
     107              : {
     108          173 :     const uint32_t jettyNum = jettyCtxData.size(); // 分配与配置前校验已保证不为0
     109          173 :     CustomChannelInfoIn  inBuff{};
     110          173 :     CustomChannelInfoOut outBuff{};
     111              : 
     112          173 :     inBuff.op = CcuOpcodeType::CCU_U_OP_SET_JETTY_CTX;
     113          173 :     (void)memset_s(inBuff.data.raw, sizeof(inBuff.data.raw), 0, sizeof(inBuff.data.raw));
     114          173 :     inBuff.data.dataInfo.udieIdx       = dieId;
     115          173 :     inBuff.data.dataInfo.dataArraySize = jettyNum;
     116              : 
     117              :     // 设置数据长度,目前设备管理A5最多使用5个JettyCtx,需要长度上限为 32 * 5 = 160B
     118              :     // A6 依据配比关系,最大长度为 32 * 8 = 256B,当前业务仅使用 32 * 1 = 32B
     119          173 :     inBuff.data.dataInfo.dataLen =
     120          173 :         sizeof(struct LocalJettyCtxData) * inBuff.data.dataInfo.dataArraySize;
     121          173 :     inBuff.offsetStartIdx = startJettyCtxId; // 设置起始Jetty上下文ID,注意应从0开始,非TaJettyId
     122              : 
     123          173 :     HCCL_INFO("[CcuJettyCtxMgr][%s] iodie[%u], startJettyCtxId[%u], jettyCtxData.size[%u]",
     124              :         __func__, dieId, startJettyCtxId, jettyNum);
     125              : 
     126          346 :     for (size_t i = 0; i < jettyNum; i++) {
     127          173 :         DumpJettyCtxData(jettyCtxData[i]);
     128              : 
     129          173 :         (void)memcpy_s(&inBuff.data.dataInfo.dataArray[i], sizeof(struct LocalJettyCtxData),
     130          173 :             &jettyCtxData[i], sizeof(struct LocalJettyCtxData));
     131              :     }
     132              : 
     133          173 :     auto ret = HccpRaTlvCcuCustomChannel(devLogicId,
     134              :         static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
     135          173 :     if (ret != HCCL_SUCCESS) {
     136            1 :         HCCL_ERROR("[CcuJettyCtxMgr][%s] failed to call ccu driver, "
     137              :             "devLogicId[%d] devPhyId[%u] dieId[%d] op[%s] ret[%d].", __func__, devLogicId, devPhyId, dieId,
     138              :             "SET_JETTY_CTX", ret);
     139            1 :         return ret;
     140              :     }
     141              : 
     142          172 :     return HcclResult::HCCL_SUCCESS;
     143              : }
     144              : 
     145          155 : static HcclResult GetSqeBuffVa(const uint64_t ccuResBaseVa, const uint32_t jettyCtxId, uint64_t &sqeBuffVa)
     146              : {
     147          155 :     sqeBuffVa = 0;
     148          155 :     if (UINT32_MAX / CCU_SQ_BUFFER_SIZE < jettyCtxId) {
     149            0 :         HCCL_ERROR("[CcuJettyCtxMgr][%s] jetty context id[%u] is greater "
     150              :             "than expected, CCU_SQ_UBFFER_SIZE[%u], their product will exceed the "
     151              :             "range of uint32_t.", __func__, jettyCtxId, CCU_SQ_BUFFER_SIZE);
     152            0 :         return HcclResult::HCCL_E_INTERNAL;
     153              :     }
     154          155 :     const uint64_t jettyCtxOffset = static_cast<uint64_t>(jettyCtxId) * CCU_SQ_BUFFER_SIZE;
     155              : 
     156          155 :     if (UINT64_MAX - CCU_V1_WQE_BASIC_BLOCK_OFFSET - jettyCtxOffset < ccuResBaseVa) {
     157            0 :         HCCL_ERROR("[CcuJettyCtxMgr][%s] ccu resource space base va[%llu] "
     158              :             "is greater than expected, jettyCtxId[%u], the sqe buff va exceed the "
     159              :             "range of uint64_t.", __func__, ccuResBaseVa, jettyCtxId);
     160            0 :         return HcclResult::HCCL_E_INTERNAL;
     161              :     }
     162              : 
     163              :     // 内部分配保证jettyCtxId 小于 jettyCtx规格数量,地址不应越界
     164          155 :     sqeBuffVa = ccuResBaseVa + CCU_V1_WQE_BASIC_BLOCK_OFFSET + jettyCtxOffset;
     165          155 :     return HcclResult::HCCL_SUCCESS;
     166              : }
     167              : 
     168          197 : HcclResult CcuJettyCtxMgr::TryAllocWqeBBResource(uint32_t sqSize,
     169              :     uint32_t jettyCtxStartId, uint32_t taJettyStartId,
     170              :     CcuJettyType jettyType, std::vector<JettyInfo> &jettyInfos)
     171              : {
     172          197 :     const uint32_t jettyNum = jettyInfos.size();
     173          197 :     if (jettyNum == 0) {
     174            0 :         HCCL_ERROR("[CcuJettyCtxMgr][%s] failed, jettyInfos size is 0, "
     175              :             "devLogicId[%d], dieId[%u].", __func__, devLogicId_, dieId_);
     176            0 :         return HcclResult::HCCL_E_PARA;
     177              :     }
     178              : 
     179          197 :     if (UNLIKELY(ccuResBaseVa_ == 0)) { // 直接终止,避免访问非法地址
     180            0 :         HCCL_ERROR("[CcuJettyCtxMgr] init failed, ccu resource base addr is 0, "
     181              :             "devLogicId[%d] dieId[%u].", devLogicId_, dieId_);
     182            0 :         return HcclResult::HCCL_E_INTERNAL;
     183              :     }
     184              : 
     185          394 :     for (uint32_t i = 0; i < jettyNum; i++) {
     186          197 :         ResInfo wqeBBInfo(0, 0);
     187              :         // a5/a6 wqebb分配策略不同,保留根据jettyCtxId决策wqebb分配的能力
     188              :         // 当前a5仅使用sqSize,a6 每个jetty ctx平均占用32个wqebb
     189          197 :         const WqeBBReq wqeBBReq{sqSize, jettyCtxStartId};
     190          197 :         HcclResult ret = wqeBBMgr_->Alloc(wqeBBReq, wqeBBInfo);
     191          197 :         if (ret == HcclResult::HCCL_E_UNAVAIL) {
     192            0 :             HCCL_WARNING("[CcuJettyCtxMgr][%s] failed to alloc wqe basic block resource, "
     193              :                 "left resources are not enough, devLogicId[%d], dieId[%u].",
     194              :                 __func__, devLogicId_, dieId_);
     195            0 :             return ret;
     196              :         }
     197          197 :         CHK_RET(ret);
     198              : 
     199          197 :         auto &jettyInfo = jettyInfos[i];
     200          197 :         jettyInfo.jettyType  = jettyType;
     201          197 :         jettyInfo.jettyCtxId = static_cast<uint16_t>(jettyCtxStartId + i);
     202          197 :         jettyInfo.taJettyId  = static_cast<uint16_t>(taJettyStartId + i);
     203              : 
     204          197 :         const uint32_t wqeBBReqNum = wqeBBInfo.num;
     205          197 :         jettyInfo.sqDepth      = wqeBBReqNum / CCU_WQE_NUM_PER_SQE;
     206          197 :         jettyInfo.wqeBBStartId = wqeBBInfo.startId;
     207          197 :         if (jettyType == CcuJettyType::CCUM_CACHED_JETTY) {
     208          155 :             jettyInfo.sqBufSize = wqeBBReqNum * CCU_ONE_WQE_SIZE;
     209          155 :             CHK_RET(GetSqeBuffVa(ccuResBaseVa_, static_cast<uint32_t>(jettyInfo.jettyCtxId),
     210              :                 jettyInfo.sqBufVa)); // 检查溢出,分配成功的wqeBB资源已经记录
     211              :         }
     212              :     }
     213              : 
     214          197 :     return HcclResult::HCCL_SUCCESS;
     215              : }
     216              : 
     217           16 : HcclResult CcuJettyCtxMgr::ReleaseWqeBBResource(const std::vector<JettyInfo> &jettyInfos)
     218              : {
     219           32 :     for (const auto &jettyInfo : jettyInfos) {
     220           16 :         if (jettyInfo.sqDepth == 0) {
     221            0 :             continue; // 该jetty未分配完成,跳过wqeBB资源释放
     222              :         }
     223              : 
     224           16 :         uint32_t wqeBBIdx = static_cast<uint32_t>(jettyInfo.wqeBBStartId);
     225              :         // jettyInfo 为内部数据,分配保证不会溢出
     226           16 :         uint32_t wqeBBNum = jettyInfo.sqDepth * CCU_WQE_NUM_PER_SQE;
     227           16 :         const auto resInfo = ResInfo(wqeBBIdx, wqeBBNum);
     228           16 :         CHK_RET(wqeBBMgr_->Release(resInfo));
     229              :     }
     230           16 :     return HcclResult::HCCL_SUCCESS;
     231              : }
     232              : 
     233          176 : HcclResult CcuJettyCtxMgr::CheckIfJettyCfgsValid(const std::vector<JettyInfo> &jettyInfos,
     234              :     const std::vector<JettyCfg>& jettyCfgs) const
     235              : {
     236          176 :     const uint32_t jettyNum = jettyInfos.size();
     237          176 :     const uint32_t jettyCfgNum = jettyCfgs.size();
     238          176 :     CHK_PRT_RET(jettyCfgNum != jettyNum,
     239              :         HCCL_ERROR("[CcuJettyCtxMgr][%s] failed, jettyCfgs size[%u] is not expected, "
     240              :             "which should be equal to jettyInfo size[%u], devLogicId[%d], dieId[%u].",
     241              :             __func__, jettyCfgNum, jettyNum, devLogicId_, dieId_),
     242              :         HcclResult::HCCL_E_PARA);
     243              : 
     244          350 :     for (uint32_t i = 0; i < jettyNum; i++) {
     245          175 :         if (jettyInfos[i].jettyCtxId != jettyCfgs[i].jettyCtxId) {
     246            0 :             HCCL_ERROR("[CcuJettyCtxMgr][%s] failed, jettyCtxId of jettyInfo[%u] and "
     247              :                 "jettyCfg[%u] are not same, devLogicId[%d], dieId[%u].", __func__,
     248              :                 jettyInfos[i].jettyCtxId, jettyCfgs[i].jettyCtxId, devLogicId_, dieId_);
     249            0 :             return HcclResult::HCCL_E_PARA;
     250              :         }
     251              :     }
     252          175 :     return HcclResult::HCCL_SUCCESS;
     253              : }
     254              : 
     255              : }; // namespace hcomm
     256              : 
        

Generated by: LCOV version 2.0-1