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

Generated by: LCOV version 2.0-1