LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/resource/connection/aicpu - rdma_vendor_1825_ops.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 63.9 % 180 115
Test Date: 2026-08-04 10:52:23 Functions: 81.2 % 16 13

            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              : #ifndef RDMA_VENDOR_1825_OPS_H
      12              : #define RDMA_VENDOR_1825_OPS_H
      13              : 
      14              : #include "rma_conn_lite.h"
      15              : #include "rdma_vendor_base_ops.h"
      16              : 
      17              : namespace Hccl {
      18              : 
      19              : // 先默认所有WQE都只占一个WQEBB
      20              : #define WQEBB_SHIFT 6
      21              : 
      22              : #define ROCE_WQE_OWNERBIT_SHIFT 7
      23              : #define ROCE_WQE_CTRL_VALUE 0x40
      24              : #define ROCE_SQ_VA_VALUE 0x20
      25              : #define ROCE_SQ_SIGNAL_SHIFT 7
      26              : #define ROCE_WQE_CQE_SIGNAL_SHIFT 7
      27              : #define ROCE_WQE_CMP_TASK_LEN1 1u /* wqe cl is set to 1 */
      28              : #define ROCE_WQE_CMP_TASK_LEN_SHIFT 28
      29              : #define ROCE_TASK_SEG_ALIGN 8
      30              : #define ROCE_WQE_FAST_DMA_SHIFT 10
      31              : #define ROCE_WQE_SSN_MASK 0x3
      32              : #define ROCE_WQE_SSN_SHIFT 12
      33              : #define ROCE_WQE_DATA_SEG_SHIFT 4
      34              : #define ROCE_WQE_TASK_SEG_LAST_EXT_LEN 4
      35              : #define ROCE_WQE_TASK_REDUCE_OP_OFFSET 4
      36              : #define WQE_SECTION_ALIGN_SHIFT 3
      37              : 
      38              : #define ROCE_WQE_NEXT_SGE_INVALID (1u << 31)
      39              : 
      40              : using Roce3CtrlSeg = struct {
      41              :     // Control Segment
      42              :     uint8_t owner_sl;   /* ownerbit:ctrl_section_length:csl:dif_sl = 1:2:2:3; */
      43              :     uint8_t df_tsl;     /* cr:df:va:tal = 1:1:1:5; */
      44              :     uint16_t wf_bdsl;   /* cf:wf:wqe_msn:fde:fast:drvsl:bdsl = 1:1:2:1:1:2:8; */
      45              :     uint32_t cl_pi;     /* cl:signature:mask_pi = 4:8:20; */
      46              :     uint64_t db;        /* used by direct wqe*/
      47              : };
      48              : 
      49              : union Roce3TaskSeg {
      50              :     struct {
      51              :         uint32_t xrcSrqn : 18;
      52              :         uint32_t ext : 1;
      53              :         uint32_t dif : 1;
      54              :         uint32_t rsvd0 : 3;
      55              :         uint32_t so : 1;
      56              :         uint32_t opType : 5;
      57              :         uint32_t signal : 1;
      58              :         uint32_t fence : 1;
      59              :         uint32_t se : 1;        /* solited event flag; */
      60              :     } dw0;
      61              :     uint32_t value;
      62              : };
      63              : 
      64              : using Roce3TaskWqeSeg = struct {
      65              :     // Task Wqe Segment
      66              :     union Roce3TaskSeg tskSeg;
      67              :     uint32_t dataLen;
      68              :     uint32_t immData;
      69              :     union {
      70              :         struct {
      71              :             uint32_t lastExtLen : 8;
      72              :             uint32_t cmdLen : 8;
      73              :             uint32_t pi : 16;
      74              :         } bs;
      75              : 
      76              :         uint32_t feth; /* cflush feth header */
      77              :         uint32_t value;
      78              :     } dw3;
      79              :     uint64_t va;    /* to indicate remote buf address; */
      80              :     uint32_t rkey;  /* to indicate remote mr buf; */
      81              :     uint32_t ulp;   /* ulp预留字段 */
      82              : };
      83              : 
      84              : static constexpr uint32_t DTYPE_INVALID = 0xFFu;
      85              : 
      86              : static const uint32_t Roce3ReduceDataTypeMap[] = {
      87              :     /* [DINT8]   = */ 0x0,              // INT8
      88              :     /* [DINT16]  = */ 0x1,              // INT16
      89              :     /* [DINT32]  = */ 0x2,              // INT32
      90              :     /* [DFP16]   = */ 0x6,              // FP16_NORMAL
      91              :     /* [DFP32]   = */ 0x7,              // FP32
      92              :     /* [DINT64]  = */ DTYPE_INVALID,    // 硬件不支持
      93              :     /* [DUINT32] = */ DTYPE_INVALID,    // 硬件不支持
      94              : };
      95              : 
      96              : static const uint32_t Roce3ReduceOpTypeMap[] = {
      97              :     /* [SUM]    = */ 0xA,               // ADD
      98              :     /* [PROD]   = */ DTYPE_INVALID,     // 求积, 硬件不支持
      99              :     /* [MAX]    = */ 0x8,               // MAX
     100              :     /* [MIN]    = */ 0x9,               // MIN
     101              :     /* [EQUAL]  = */ 0xB,               // EQUAL
     102              : };
     103              : 
     104              : using Roce3WqeDataSeg = struct {
     105              :     uint64_t bufAddr;   /* buffer address that wqe sge indicate; */
     106              :     uint32_t rLen;      /* buffer length that wqe sge indicate; */
     107              :     uint32_t leKey;     /* buffer lkey that wqe sge indicate; */
     108              : };
     109              : 
     110              : using Roce3WqeEntry = struct {
     111              :     Roce3CtrlSeg ctrl;
     112              :     Roce3TaskWqeSeg task;
     113              :     Roce3WqeDataSeg data;
     114              : };
     115              : 
     116              : // Cqe related
     117              : constexpr uint32_t ROCE_CQE_OPCODE_SHIFT = 27;
     118              : constexpr uint32_t ROCE_CQE_OPCODE_MASK = 0x1f;
     119              : constexpr uint32_t ROCE_CQ_UPDATE_CI_MASK = 0xffffff;   /* cq arm db ci mask; */
     120              : constexpr uint32_t ROCE_CQE_MAX_GEN_NUM = 1024;
     121              : constexpr uint32_t ROCE_CQE_OWNERBIT_SHIFT = 31;
     122              : constexpr uint32_t ROCE_CQE_QPN_MASK = 0xfffff;
     123              : 
     124              : enum class RoceCqeType : uint32_t {
     125              :     ERROR   = 0x1e,  /* indicate the cqe is an error cqe */
     126              :     RESIZE  = 0x16,  /* indicate the cqe is an resize type cqe */
     127              :     INVALID = 0x1f
     128              : };
     129              : 
     130              : struct Roce3CqeEntry{
     131              :     uint32_t owner_id_qpn;  /* ownerbit: cqe_size:dif_en:wq_id:error_code:qpn = 1:2:1:4:4:20; */
     132              :     uint32_t op_sr_wqebb;   /* opcode:s_r:inline_r:merge:fake:rsvd:linkwqe_used:wqebb_index = 5:1:1:1:1:2:1:20; */
     133              :     uint32_t byte_cnt;      /* reflect the data size we reveive; */
     134              :     uint32_t imm_data;      /* the immediate data we receive */
     135              : 
     136              :     union {
     137              :         struct {
     138              :             uint8_t smac_h[2];      /* smac value; */
     139              :             uint16_t vlan_id_pri;   /* vlan_id:vlan_priority:reserved:smac = 12:1:3:16; */
     140              :         } mac_vlanid;
     141              :     } dw4;
     142              :     union {
     143              :         uint8_t smac_l[4];          /* smac value */
     144              :         uint32_t wqe_num;           /* merged wqe num */
     145              :     };
     146              :     uint32_t vlan_queue_index;      /* vlan:force_loopback:reserved:RQPN = 2:1:5:24; */
     147              :     uint8_t syndrome;               /* record syndrome code; */
     148              :     uint8_t reserved2;
     149              :     uint16_t wqe_counter;           /* the wqe index, valid for sq; */
     150              : };
     151              : 
     152              : // Doorbell related
     153              : constexpr uint32_t ROCE_SQ_DOORBELL_TYPE = 21;
     154              : constexpr uint32_t ROCE_INIT_SQ_DB_SGIT_IDX = 1;
     155              : 
     156              : using Roce3DbEntry = struct {
     157              :     union {
     158              :         struct {
     159              :             uint32_t qpn        : 20;   /* indicate the sq qpn; */
     160              :             uint32_t cntxSize   : 2;    /* indicate the qpc size; */
     161              :             uint32_t r          : 1;    /* reserved bit; */
     162              :             uint32_t c          : 1;
     163              :             uint32_t cos        : 3;
     164              :             uint32_t type       : 5;
     165              : 
     166              :             uint32_t pi         : 8;
     167              :             uint32_t resv       : 8;
     168              :             uint32_t xrcvld     : 1;
     169              :             uint32_t vxlan      : 1;
     170              :             uint32_t mtuShift   : 3;
     171              :             uint32_t sgidIndex  : 7;
     172              :             uint32_t subType    : 4;
     173              :         } bs;
     174              :         uint64_t db_value;
     175              :     } dw0;
     176              : };
     177              : 
     178              : enum class ROCE3_OPCODE : uint32_t {
     179              :     ROCE_OPCODE_RDMA_WRITE  = 4U,
     180              :     ROCE_OPCODE_RDMA_READ   = 8U
     181              : };
     182              : 
     183              : 
     184              : // post_send helper
     185              : struct Roce3PostSendParams {
     186              :     const SqeConfigLite         &cfg;
     187              :     const RmaBufSliceLite       &loc;
     188              :     const RmtRmaBufSliceLite    &rmt;
     189              :     const uint32_t              opCode;
     190              : 
     191              :     Roce3PostSendParams(const Roce3PostSendParams &) = delete;
     192              :     Roce3PostSendParams &operator=(const Roce3PostSendParams &) = delete;
     193              : };
     194              : 
     195              : class Rdma1825Ops : public RdmaBaseOps {
     196              : public:
     197           39 :     Rdma1825Ops(RdmaSqContextLite *sqContext, RdmaCqContextLite *cqContext)
     198           39 :         : RdmaBaseOps(sqContext, cqContext) {}
     199              : 
     200           78 :     ~Rdma1825Ops() override {}
     201              : 
     202            7 :     HcclResult BuildDoorbell(u64 &dbAddr, u64 &dbValue) override
     203              :     {
     204              :         Roce3DbEntry dbEntry;
     205            7 :         dbEntry.dw0.db_value        = 0;
     206            7 :         dbEntry.dw0.bs.r            = 0;
     207            7 :         dbEntry.dw0.bs.c            = 0;
     208            7 :         dbEntry.dw0.bs.cntxSize     = 1;
     209            7 :         dbEntry.dw0.bs.qpn          = sqContext_->qpn;
     210            7 :         dbEntry.dw0.bs.subType      = 0;
     211            7 :         dbEntry.dw0.bs.resv         = 0;
     212            7 :         dbEntry.dw0.bs.pi           = ((sqHead_ >> 8) & 0xff);
     213            7 :         dbEntry.dw0.bs.sgidIndex    = ROCE_INIT_SQ_DB_SGIT_IDX;
     214            7 :         dbEntry.dw0.bs.type         = ROCE_SQ_DOORBELL_TYPE;
     215            7 :         dbEntry.dw0.bs.mtuShift     = sqContext_->mtuShift;
     216            7 :         dbEntry.dw0.bs.cos          = 0x7;
     217              : 
     218            7 :         dbAddr  = sqContext_->dbHwVa;
     219            7 :         dbValue = dbEntry.dw0.db_value;
     220              : 
     221           21 :         HCCL_INFO("[Rdma1825Ops::%s] SQ DB ready, qpn[%u], sqHead[%u], dbAddr[0x%llx], dbValue[0x%llx]",
     222              :                    __func__, sqContext_->qpn, sqHead_, dbAddr, dbValue);
     223            7 :         return HCCL_SUCCESS;
     224              :     }
     225              : 
     226            3 :     HcclResult BuildCqDoorbell(u64 &dbAddr, u64 &dbValue) override
     227              :     {
     228            3 :         if (cqDbFlush_) {
     229            2 :             dbAddr  = cqContext_->dbSwVa;
     230              : 
     231            2 :             const uint32_t dbValue32 = Htonl32(cqTail_ & ROCE_CQ_UPDATE_CI_MASK);
     232            2 :             dbValue = dbValue32;
     233              : 
     234              :             // Ring Cq Soft DB
     235            2 :             auto ret = memcpy_sp(reinterpret_cast<void *>(dbAddr), sizeof(uint32_t), &dbValue32, sizeof(uint32_t));
     236            2 :             if (UNLIKELY(ret != 0)) {
     237            0 :                 THROW<InternalException>(
     238            0 :                     StringFormat("[Rdma1825Ops::%s] write soft Cq DB failed, ret = %d", __func__, ret));
     239              :             }
     240            6 :             HCCL_INFO("[Rdma1825Ops::%s] CQ DB updated, cqTail[%u], dbAddr[0x%llx], dbValue[0x%llx]",
     241              :                        __func__, cqTail_, dbAddr, dbValue);
     242              :         } else {
     243            1 :             dbAddr  = 0;
     244            1 :             dbValue = 0;
     245              :         }
     246              : 
     247            3 :         cqDbFlush_ = false;
     248              : 
     249            3 :         return HCCL_SUCCESS;
     250              :     }
     251              : 
     252              : protected:
     253            3 :     HcclResult BuildReadWqe(const RmaBufSliceLite &loc, const RmtRmaBufSliceLite &rmt, const SqeConfigLite &cfg) override
     254              :     {
     255            3 :         Roce3WqeEntry wqe{};
     256            3 :         Roce3PostSendParams params{cfg, loc, rmt, static_cast<uint32_t>(ROCE3_OPCODE::ROCE_OPCODE_RDMA_READ)};
     257              : 
     258            3 :         CHK_RET(FillCtrlSeg(&wqe, params));
     259            3 :         CHK_RET(FillTaskSeg(&wqe, params));
     260            3 :         CHK_RET(FillDataSeg(&wqe, params));
     261              : 
     262            3 :         CHK_RET(CommitWqe(&wqe, sizeof(Roce3WqeEntry)));
     263            9 :         HCCL_INFO("[Rdma1825Ops::%s] WQE committed, qpn[%u], sqHead[%u], loc[0x%llx], rmt[0x%llx], size[%u]",
     264              :                    __func__, sqContext_->qpn, sqHead_, loc.GetAddr(), rmt.GetAddr(), loc.GetSize());
     265            3 :         return HCCL_SUCCESS;
     266              :     }
     267              : 
     268            6 :     HcclResult BuildWriteWqe(const RmaBufSliceLite &loc, const RmtRmaBufSliceLite &rmt, const SqeConfigLite &cfg) override
     269              :     {
     270            6 :         Roce3WqeEntry wqe{};
     271            6 :         Roce3PostSendParams params{cfg, loc, rmt, static_cast<uint32_t>(ROCE3_OPCODE::ROCE_OPCODE_RDMA_WRITE)};
     272              : 
     273            6 :         CHK_RET(FillCtrlSeg(&wqe, params));
     274            6 :         CHK_RET(FillTaskSeg(&wqe, params));
     275            6 :         CHK_RET(FillDataSeg(&wqe, params));
     276              : 
     277            6 :         CHK_RET(CommitWqe(&wqe, sizeof(Roce3WqeEntry)));
     278           18 :         HCCL_INFO("[Rdma1825Ops::%s] WQE committed, qpn[%u], sqHead[%u], loc[0x%llx], rmt[0x%llx], size[%u]",
     279              :                    __func__, sqContext_->qpn, sqHead_, loc.GetAddr(), rmt.GetAddr(), loc.GetSize());
     280            6 :         return HCCL_SUCCESS;
     281              :     }
     282              : 
     283            2 :     HcclResult BuildWriteReduceWqe(const RmaBufSliceLite &loc, const RmtRmaBufSliceLite &rmt, 
     284              :                                    const SqeConfigLite &cfg, DataType dataType, ReduceOp reduceOp) override
     285              :     {
     286            2 :         Roce3WqeEntry wqe{};
     287            2 :         Roce3PostSendParams params{cfg, loc, rmt, static_cast<uint32_t>(ROCE3_OPCODE::ROCE_OPCODE_RDMA_WRITE)};
     288              : 
     289            2 :         CHK_RET(FillCtrlSeg(&wqe, params));
     290            2 :         CHK_RET(FillTaskSeg(&wqe, params));
     291            2 :         CHK_RET(FillReduceTaskSeg(&wqe, params, dataType, reduceOp));
     292            2 :         CHK_RET(FillDataSeg(&wqe, params));
     293              : 
     294            2 :         CHK_RET(CommitWqe(&wqe, sizeof(Roce3WqeEntry)));
     295            6 :         HCCL_INFO("[Rdma1825Ops::%s] WQE committed, qpn[%u], sqHead[%u], loc[0x%llx], rmt[0x%llx], size[%u], "
     296              :                    "dataType[%u], reduceOp[%u]",
     297              :                    __func__, sqContext_->qpn, sqHead_, loc.GetAddr(), rmt.GetAddr(), loc.GetSize(),
     298              :                    static_cast<uint32_t>(dataType), static_cast<uint32_t>(reduceOp));
     299            2 :         return HCCL_SUCCESS;
     300              :     }
     301              : 
     302            0 :     HcclResult WriteInvalidWqebb(uint32_t nextIdx) override
     303              :     {
     304            0 :         const uint32_t sqDepth = sqContext_->depth;
     305            0 :         const uint32_t sqMask = sqDepth - 1U;
     306            0 :         uint8_t ownerSl = ((nextIdx & sqDepth) == 0) ? 0xff : 0x7f;
     307              : 
     308            0 :         auto *dst = reinterpret_cast<void *>(
     309            0 :             sqContext_->sqVa + static_cast<uint64_t>(nextIdx & sqMask) * sqContext_->wqeSize);
     310              : 
     311            0 :         auto ret = memcpy_sp(dst, sizeof(ownerSl), &ownerSl, sizeof(ownerSl));
     312            0 :         if (UNLIKELY(ret != 0)) {
     313            0 :             THROW<InternalException>(
     314            0 :                 StringFormat("[Rdma1825Ops::%s] write invalid wqebb failed, ret = %d", __func__, ret));
     315              :         }
     316            0 :         return HCCL_SUCCESS;
     317              :     }
     318              : 
     319            3 :     int32_t PollCqImpl(int32_t numEntries, std::vector<int32_t> &errList) override
     320              :     {
     321            3 :         int32_t pollNum = 0;
     322            3 :         CqPollStatus ret = CqPollStatus::ERROR;
     323              : 
     324            4 :         while (pollNum < numEntries) {
     325            3 :             ret = PollOne(errList);
     326            3 :             if (ret != CqPollStatus::SUCCESS) {
     327            2 :                 if (ret != CqPollStatus::EMPTY && ret != CqPollStatus::ERROR) {
     328            0 :                     HCCL_ERROR("[Rdma1825Ops::%s][Poll cq] Poll CQ error, ret: %d", __func__,
     329              :                                static_cast<int32_t>(ret));
     330              :                 }
     331            2 :                 break;
     332              :             }
     333              : 
     334              :             // Update Cq CI
     335            1 :             cqTail_ += 1;
     336              : 
     337            1 :             ++pollNum;
     338              :         }
     339              : 
     340            3 :         if ((pollNum != 0) || (ret == CqPollStatus::ERROR)) {
     341              :             // Need to flush Cq DB
     342            2 :             cqDbFlush_ = true;
     343              :         }
     344              : 
     345            3 :         return (ret == CqPollStatus::ERROR) ? static_cast<int32_t>(ret) : pollNum;
     346              :     }
     347              : 
     348              : private:
     349           11 :     HcclResult FillCtrlSeg(Roce3WqeEntry *wqe, const Roce3PostSendParams &params) const
     350              :     {
     351              :         // 赋值本wqe的owner
     352           11 :         uint8_t owner       = (sqHead_ & (sqContext_->depth)) == 0 ? 0 : 1;
     353           11 :         wqe->ctrl.owner_sl  = (owner << ROCE_WQE_OWNERBIT_SHIFT) | ROCE_WQE_CTRL_VALUE;
     354              : 
     355              :         // 不产生cqe + task字段的长度
     356           11 :         wqe->ctrl.df_tsl    = ((params.cfg.cqeEn == true) ? (1U << ROCE_SQ_SIGNAL_SHIFT) : 0) | ROCE_SQ_VA_VALUE;
     357           11 :         wqe->ctrl.df_tsl    |= sizeof(Roce3TaskWqeSeg) / ROCE_TASK_SEG_ALIGN;
     358              : 
     359              :         // fast_dma + SSN + sge长度
     360           11 :         wqe->ctrl.wf_bdsl   = Htons16(static_cast<uint16_t>(0 << ROCE_WQE_FAST_DMA_SHIFT));
     361           11 :         wqe->ctrl.wf_bdsl   |= Htons16((sqHead_ & ROCE_WQE_SSN_MASK) << ROCE_WQE_SSN_SHIFT);
     362           11 :         wqe->ctrl.wf_bdsl   |= Htons16(static_cast<uint16_t>(static_cast<uint32_t>(1) << (ROCE_WQE_DATA_SEG_SHIFT - WQE_SECTION_ALIGN_SHIFT)));
     363              : 
     364              :         // cl
     365           11 :         wqe->ctrl.cl_pi     = Htonl32(ROCE_WQE_CMP_TASK_LEN1 << ROCE_WQE_CMP_TASK_LEN_SHIFT);
     366              : 
     367           11 :         return HCCL_SUCCESS;
     368              :     }
     369              : 
     370           11 :     HcclResult FillTaskSeg(Roce3WqeEntry *wqe, const Roce3PostSendParams &params) const
     371              :     {
     372              :         // ----- Task Seg -----
     373           11 :         wqe->task.tskSeg.value      = 0;
     374           11 :         wqe->task.tskSeg.dw0.signal = !!((wqe->ctrl.df_tsl & (1U << ROCE_WQE_CQE_SIGNAL_SHIFT)) > 0);
     375           11 :         wqe->task.tskSeg.dw0.fence  = params.cfg.fence;
     376           11 :         wqe->task.tskSeg.dw0.opType = params.opCode;
     377           11 :         wqe->task.tskSeg.dw0.se     = 0;
     378           11 :         wqe->task.tskSeg.value      = Htonl32(wqe->task.tskSeg.value);
     379              : 
     380           11 :         wqe->task.dataLen   = Htonl32(params.loc.GetSize());
     381           11 :         wqe->task.immData   = 0;
     382           11 :         wqe->task.dw3.value = (params.opCode == static_cast<uint32_t>(ROCE3_OPCODE::ROCE_OPCODE_RDMA_READ) ? Htonl32(ROCE_WQE_TASK_SEG_LAST_EXT_LEN) : 0);
     383           11 :         wqe->task.va        = Htonll64(params.rmt.GetAddr());
     384           11 :         wqe->task.rkey      = Htonl32(params.rmt.GetRkey());
     385           11 :         wqe->task.ulp       = Htonl32(params.loc.GetLkey() & 0xffff);
     386              : 
     387           11 :         return HCCL_SUCCESS;
     388              :     }
     389              : 
     390            2 :     HcclResult FillReduceTaskSeg(Roce3WqeEntry *wqe, const Roce3PostSendParams &params, DataType dataType, ReduceOp reduceOp) const
     391              :     {
     392              :         // Hcomm Type -> Roce3 Type
     393            2 :         uint32_t dataTypeIdx = static_cast<uint32_t>(dataType);
     394            2 :         if (dataTypeIdx >= sizeof(Roce3ReduceDataTypeMap) / sizeof(uint32_t)) {
     395            0 :             HCCL_ERROR("[Rdma1825Ops::%s] invalid DataType %u", __func__, dataTypeIdx);
     396            0 :             return HCCL_E_PARA;
     397              :         }
     398            2 :         uint32_t reduceDataType = Roce3ReduceDataTypeMap[dataTypeIdx];
     399            2 :         if (reduceDataType == DTYPE_INVALID) {
     400            0 :             HCCL_ERROR("[Rdma1825Ops::%s] DataType %u not support by inline reduce", __func__, dataTypeIdx);
     401            0 :             return HCCL_E_NOT_SUPPORT;
     402              :         }
     403              : 
     404            2 :         uint32_t reduceOpIdx = static_cast<uint32_t>(reduceOp);
     405            2 :         if (reduceOpIdx >= sizeof(Roce3ReduceOpTypeMap) / sizeof(uint32_t)) {
     406            0 :             HCCL_ERROR("[Rdma1825Ops::%s] invalid ReduceOpType %u", __func__, reduceOpIdx);
     407            0 :             return HCCL_E_PARA;
     408              :         }
     409            2 :         uint32_t reduceOpType = Roce3ReduceOpTypeMap[reduceOpIdx];
     410            2 :         if (reduceOpType == DTYPE_INVALID) {
     411            0 :             HCCL_ERROR("[Rdma1825Ops::%s] ReduceOpType %u not support by inline reduce", __func__, reduceOpIdx);
     412            0 :             return HCCL_E_NOT_SUPPORT;
     413              :         }
     414              : 
     415              :         // Reduce data
     416            2 :         uint32_t mptIndex       = params.loc.GetLkey() & 0xffff;
     417            2 :         uint32_t reduceOpInfo   = ((reduceOpType << ROCE_WQE_TASK_REDUCE_OP_OFFSET) | reduceDataType);
     418              : 
     419              :         // ----- Task Reduce Seg -----
     420            2 :         wqe->task.ulp = Htonl32(mptIndex | reduceOpInfo);
     421              : 
     422            2 :         return HCCL_SUCCESS;
     423              :     }
     424              : 
     425           11 :     HcclResult FillDataSeg(Roce3WqeEntry *wqe, const Roce3PostSendParams &params) const
     426              :     {
     427              :         // ----- Data Seg -----
     428           11 :         wqe->data.bufAddr   = Htonll64(static_cast<uint64_t>(params.loc.GetAddr()));
     429           11 :         wqe->data.leKey     = Htonl32((params.loc.GetLkey() & (~ROCE_WQE_NEXT_SGE_INVALID)) | ROCE_WQE_NEXT_SGE_INVALID);  // 当前sge就是最后一个
     430           11 :         wqe->data.rLen      = Htonl32(params.loc.GetSize());
     431              : 
     432           11 :         return HCCL_SUCCESS;
     433              :     }
     434              : 
     435            0 :     CqPollStatus PollOne(std::vector<int32_t> &errList)
     436              :     {
     437            0 :         bool need_poll = true;
     438            0 :         while (need_poll) {
     439            0 :             Roce3CqeEntry *rcqe = nullptr;
     440            0 :             rcqe = Roce3GetOneCqe(cqHead_);
     441            0 :             if (rcqe == nullptr) {
     442            0 :                 return CqPollStatus::EMPTY;
     443              :             }
     444              : 
     445            0 :             ++cqHead_;
     446              : 
     447            0 :             uint32_t syndrome = static_cast<uint32_t>(rcqe->syndrome);
     448            0 :             uint32_t ownerIdQpn = static_cast<uint32_t>(rcqe->owner_id_qpn);
     449            0 :             auto cqeType = static_cast<RoceCqeType>(
     450            0 :                 (rcqe->op_sr_wqebb >> ROCE_CQE_OPCODE_SHIFT) & ROCE_CQE_OPCODE_MASK);
     451              :             // 存在错误
     452            0 :             if (cqeType == RoceCqeType::ERROR) {
     453            0 :                 const uint32_t cqeErrCode = (ownerIdQpn >> 20U) & 0xfU;
     454              : 
     455            0 :                 HCCL_ERROR("[Rdma1825Ops::%s][Poll cq] CQE error, qpn[%u], syndrome[%u], cqeErrCode[%u], "
     456              :                            "wqeCounter[%u]",
     457              :                            __func__, ownerIdQpn & ROCE_CQE_QPN_MASK, syndrome, cqeErrCode,
     458              :                            static_cast<uint32_t>(rcqe->wqe_counter));
     459              : 
     460              :                 // 后续优化为具体ErrorCode
     461            0 :                 int32_t ERROR_CODE = 1;
     462            0 :                 errList.push_back(ERROR_CODE);
     463            0 :                 return CqPollStatus::ERROR;
     464              :             }
     465              : 
     466            0 :             HCCL_INFO("[Rdma1825Ops::%s][Poll cq] CQE completed, cqHead[%u], qpn[%u], syndrome[%u], "
     467              :                        "wqeCounter[%u]",
     468              :                        __func__, cqHead_, ownerIdQpn & ROCE_CQE_QPN_MASK, syndrome,
     469              :                        static_cast<uint32_t>(rcqe->wqe_counter));
     470            0 :             need_poll = false;
     471              :         }
     472              : 
     473            0 :         return CqPollStatus::SUCCESS;
     474              :     }
     475              : 
     476            0 :     Roce3CqeEntry* Roce3GetOneCqe(uint32_t consIndex)
     477              :     {
     478            0 :         uint32_t cqeSize        = 64;
     479            0 :         uint32_t cqDepthReal    = cqContext_->cqDepth + ROCE_CQE_MAX_GEN_NUM;   // Must be power of 2
     480            0 :         uint32_t cqeMask        = cqDepthReal - 1;
     481            0 :         uint32_t cqeSlot        = consIndex & cqeMask;
     482              : 
     483              :         // Calculate Cqe Addr
     484            0 :         auto cqeAddr = reinterpret_cast<Roce3CqeEntry *>(
     485            0 :             reinterpret_cast<uint8_t *>(cqContext_->cqVa) + static_cast<size_t>(cqeSlot * cqeSize));
     486              : 
     487              :         // Memcpy Cqe
     488            0 :         auto ret = memcpy_sp(&cqeReadback_, sizeof(cqeReadback_), cqeAddr, sizeof(cqeReadback_));
     489            0 :         if (UNLIKELY(ret != 0)) {
     490            0 :             THROW<InternalException>(StringFormat("[Rdma1825Ops::%s] memcpy_sp cqe failed, ret = %d", __func__, ret));
     491              :         }
     492              : 
     493              :         // Cqe Details Parse
     494            0 :         uint32_t opSrWqebb = cqeReadback_.op_sr_wqebb;
     495            0 :         uint32_t ownerIdQpn = cqeReadback_.owner_id_qpn;
     496            0 :         auto cqeType = static_cast<RoceCqeType>((opSrWqebb >> ROCE_CQE_OPCODE_SHIFT) & ROCE_CQE_OPCODE_MASK);
     497            0 :         if (cqeType == RoceCqeType::INVALID) {
     498            0 :             HCCL_INFO("[Rdma1825Ops::%s][Poll cq] CQE invalid, consIndex[%u], slot[%u]", __func__, consIndex,
     499              :                        cqeSlot);
     500            0 :             return nullptr;
     501              :         }
     502              : 
     503              :         // Judge Owner bit
     504            0 :         uint32_t calHwOwner = static_cast<uint32_t>((consIndex & cqDepthReal) == 0);
     505            0 :         uint32_t curCqeOwner = !((ownerIdQpn & (1U << ROCE_CQE_OWNERBIT_SHIFT)) == 0);
     506            0 :         if ((calHwOwner ^ curCqeOwner) == 0) {
     507            0 :             HCCL_INFO("[Rdma1825Ops::%s][Poll cq] CQE owner not ready, consIndex[%u], slot[%u], "
     508              :                        "calHwOwner[%u], curCqeOwner[%u]",
     509              :                        __func__, consIndex, cqeSlot, calHwOwner, curCqeOwner);
     510            0 :             return nullptr;
     511              :         }
     512              : 
     513            0 :         return &cqeReadback_;
     514              :     }
     515              : 
     516              :     Roce3CqeEntry cqeReadback_{};
     517              : };
     518              : 
     519              : }
     520              : #endif // RDMA_VENDOR_1825_OPS_H
        

Generated by: LCOV version 2.0-1