LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/resource/connection - dev_ub_connection.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.3 % 753 529
Test Date: 2026-08-29 17:38:31 Functions: 79.0 % 81 64

            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 "dev_ub_connection.h"
      12              : 
      13              : #include <cstdlib>
      14              : 
      15              : #include "hccp_ctx.h"
      16              : #include "exception_util.h"
      17              : #include "rma_conn_exception.h"
      18              : #include "rdma_handle_manager.h"
      19              : #include "exchange_ub_conn_dto.h"
      20              : #include "env_config/env_config_v2.h"
      21              : 
      22              : namespace Hccl {
      23              : 
      24              : constexpr u32 OPBASED_UB_SQ_DEPTH_MAX = 8192;
      25              : constexpr u32 UB_SQ_OFFLOAD_DEPTH = 128;
      26              : constexpr u32 UB_SQ_WQEBB_SIZE = 64;
      27              : constexpr u32 WQE_NUM_PER_SQE = 4;                   // URMA约束每个SQE包含4个WQEBB
      28              : constexpr u32 UB_MAX_TRANS_SIZE = 256 * 1024 * 1024; // UB单次最大传输量256*1024*1024 Byte
      29              : constexpr uint32_t kTpAttrRetryTimesInitBit = 0U;
      30              : constexpr uint32_t kTpAttrAtBit = 1U;
      31              : 
      32          110 : DevUbConnection::DevUbConnection(
      33              :     const RdmaHandle rdmaHandle, const IpAddress& locAddr, const IpAddress& rmtAddr, const OpMode opMode,
      34              :     const bool devUsed, const HrtUbJfcMode jfcMode, const IpAddress& locIpv4Addr, const IpAddress& rmtIpv4Addr, u8 qos,
      35          110 :     u8 taTimeOut, CommEngine engine, u32 inSqDepth, JettyMode jettyMode)
      36              :     : RmaConnection(nullptr, RmaConnType::UB),
      37          110 :       rdmaHandle(rdmaHandle),
      38          110 :       locAddr(locAddr),
      39          110 :       rmtAddr(rmtAddr),
      40          110 :       opMode(opMode),
      41          110 :       jfcMode(jfcMode),
      42          110 :       engine_(engine),
      43          110 :       locIpv4Addr(locIpv4Addr),
      44          110 :       rmtIpv4Addr(rmtIpv4Addr),
      45          110 :       rmtEid(rmtAddr.GetEid()),
      46          110 :       locEid(locAddr.GetEid()),
      47          110 :       rmtReverseEid(rmtAddr.GetReverseEid()),
      48          110 :       qos_(qos),
      49          110 :       devUsed_(devUsed),
      50          110 :       taTimeOut_(taTimeOut),
      51          110 :       sqDepth(inSqDepth),
      52          220 :       jettyMode_(jettyMode)
      53              : {
      54          330 :     HCCL_INFO(
      55              :         "[DevUbConnection::DevUbConnection] rmtEid=%s, engine=%d, jettyMode=%d", rmtEid.Describe().c_str(),
      56              :         static_cast<s32>(engine_), static_cast<s32>(jettyMode_));
      57          110 :     devLogicId = HrtGetDevice();
      58              : 
      59          110 :     auto dieIdAndFuncId = RdmaHandleManager::GetInstance().GetDieAndFuncId(rdmaHandle); // 获取dieId和FuncId
      60          110 :     dieId = dieIdAndFuncId.first;
      61          110 :     funcId = dieIdAndFuncId.second;
      62              : 
      63              :     // EXTERNAL_INJECT 模式:跳过建 JFC/jetty,等外部调 SetSharedJettyFields 填充
      64          110 :     if (jettyMode_ == JettyMode::EXTERNAL_INJECT) {
      65            0 :         sqDepth = OPBASED_UB_SQ_DEPTH_MAX;
      66            0 :         HCCL_INFO("[DevUbConnection][Constructor] EXTERNAL_INJECT mode, skip JFC/Jetty creation.");
      67            0 :         return;
      68              :     }
      69              : 
      70          110 :     if (engine_ == COMM_ENGINE_AIV) {
      71            1 :         CreateAivUrmaJfc();
      72          109 :     } else if (jfcMode == HrtUbJfcMode::USER_CTL) {
      73            0 :         jfcHandle = RdmaHandleManager::GetInstance().GetJfcHandleAndCqInfo(rdmaHandle, cqInfo_, jfcMode);
      74              :     } else {
      75          109 :         jfcHandle = RdmaHandleManager::GetInstance().GetJfcHandle(rdmaHandle, cqInfo_, jfcMode);
      76              :     }
      77          110 :     if (sqDepth == UB_SQ_DEPTH_NOT_SET) {
      78          108 :         sqDepth = OPBASED_UB_SQ_DEPTH_MAX;
      79          108 :         if (opMode == OpMode::OFFLOAD && !devUsed) {
      80            5 :             sqDepth = UB_SQ_OFFLOAD_DEPTH;
      81              :         }
      82              :     }
      83          330 :     HCCL_INFO(
      84              :         "[DevUbConnection][Constructor] sqDepth[%u], opMode[%d], devUsed[%d]", sqDepth, static_cast<s32>(opMode),
      85              :         devUsed);
      86              : 
      87          110 :     if (sqDepth > (UINT32_MAX / UB_SQ_WQEBB_SIZE / WQE_NUM_PER_SQE)) {
      88            0 :         THROW<InternalException>("integer overflow occurs");
      89              :     }
      90              : 
      91          110 :     if (!devUsed_) {
      92          108 :         CreateJetty(devUsed_);
      93              :     } else {
      94            6 :         HCCL_INFO("[DevUbConnection][Constructor] devUsed: defer CreateJetty until GetTpInfo maps qos.");
      95              :     }
      96            0 : }
      97              : 
      98            2 : DevUbTpConnection::DevUbTpConnection(
      99              :     const RdmaHandle rdmaHandle, const IpAddress& locAddr, const IpAddress& rmtAddr, const OpMode opMode,
     100              :     const bool devUsed, const HrtUbJfcMode jfcMode, const IpAddress& locIpv4Addr, const IpAddress& rmtIpv4Addr, u8 qos,
     101            2 :     u8 taTimeOut, CommEngine engine, u32 sqDepth, JettyMode jettyMode)
     102              :     : DevUbConnection(
     103              :           rdmaHandle, locAddr, rmtAddr, opMode, devUsed, jfcMode, locIpv4Addr, rmtIpv4Addr, qos, taTimeOut, engine,
     104            2 :           sqDepth, jettyMode)
     105              : {
     106            2 :     tpProtocol = TpProtocol::TP;
     107            2 : }
     108              : 
     109            4 : DevUbCtpConnection::DevUbCtpConnection(
     110              :     const RdmaHandle rdmaHandle, const IpAddress& locAddr, const IpAddress& rmtAddr, const OpMode opMode,
     111              :     const bool devUsed, const HrtUbJfcMode jfcMode, const IpAddress& locIpv4Addr, const IpAddress& rmtIpv4Addr, u8 qos,
     112            4 :     u8 taTimeOut, CommEngine engine, u32 sqDepth, JettyMode jettyMode)
     113              :     : DevUbConnection(
     114              :           rdmaHandle, locAddr, rmtAddr, opMode, devUsed, jfcMode, locIpv4Addr, rmtIpv4Addr, qos, taTimeOut, engine,
     115            4 :           sqDepth, jettyMode)
     116              : {
     117            4 :     tpProtocol = TpProtocol::CTP;
     118            4 : }
     119              : 
     120            0 : DevUbUboeConnection::DevUbUboeConnection(
     121              :     const RdmaHandle rdmaHandle, const IpAddress& locAddr, const IpAddress& rmtAddr, const OpMode opMode,
     122              :     const bool devUsed, const HrtUbJfcMode jfcMode, const IpAddress& locIpv4Addr, const IpAddress& rmtIpv4Addr, u8 qos,
     123            0 :     u8 taTimeOut, CommEngine engine, u32 sqDepth, JettyMode jettyMode)
     124              :     : DevUbConnection(
     125              :           rdmaHandle, locAddr, rmtAddr, opMode, devUsed, jfcMode, locIpv4Addr, rmtIpv4Addr, qos, taTimeOut, engine,
     126            0 :           sqDepth, jettyMode)
     127              : {
     128            0 :     tpProtocol = TpProtocol::UBOE;
     129            0 :     jettyTimeOut = 16; // UBOE Jetty异步创建超时 hw_val=16 (对应8s)
     130            0 : }
     131              : 
     132            1 : DevUbRtpConnection::DevUbRtpConnection(
     133              :     const RdmaHandle rdmaHandle, const IpAddress& locAddr, const IpAddress& rmtAddr, const OpMode opMode,
     134              :     const bool devUsed, const HrtUbJfcMode jfcMode, const IpAddress& locAddrEid, const IpAddress& rmtAddrEid,
     135            1 :     const u8 qos, u8 taTimeOut, CommEngine engine, u32 sqDepth, JettyMode jettyMode)
     136              :     : DevUbConnection(
     137              :           rdmaHandle, locAddr, rmtAddr, opMode, devUsed, jfcMode, locAddrEid, rmtAddrEid, qos, taTimeOut, engine,
     138            1 :           sqDepth, jettyMode)
     139              : {
     140            1 :     tpProtocol = TpProtocol::UB_RTP;
     141              :     // UB_RTP与UBOE同属UB传输,Jetty异步创建超时一致,均为16秒
     142            1 :     jettyTimeOut = 16;
     143            1 : }
     144              : 
     145           47 : std::vector<char> DevUbConnection::GetUniqueId() const
     146              : {
     147           47 :     BinaryStream binaryStream;
     148           47 :     binaryStream << dieId;
     149           47 :     binaryStream << funcId;
     150           47 :     binaryStream << jettyId;
     151              : 
     152           47 :     u32 jfcPollMode = 0;          // 待修改,0代表STARS POLL,1代表software Poll
     153           47 :     bool dwqeCacheLocked = false; // 待修改,该jetty是否支持dwqeCachedLocked,默认不支持
     154           47 :     u64 sqCiAddr = 0; // 待修改,软件poll CQ情况下,需要AICPU从该地址中读取CI,依赖UB驱动支持
     155           47 :     binaryStream << jfcPollMode;
     156           47 :     binaryStream << dwqeCacheLocked;
     157           47 :     binaryStream << dbAddr;
     158           47 :     binaryStream << sqCiAddr;
     159           47 :     binaryStream << sqBuffVa;
     160           47 :     binaryStream << sqDepth;
     161           47 :     binaryStream << tpn;
     162           47 :     binaryStream << rmtEid.raw;
     163           47 :     binaryStream << locEid.raw;
     164           47 :     binaryStream << maxReadSize;
     165           47 :     binaryStream << maxWriteSize;
     166           47 :     binaryStream << static_cast<uint64_t>(jettyHandle);
     167              : 
     168           47 :     std::vector<char> result;
     169           47 :     binaryStream.Dump(result);
     170          141 :     HCCL_INFO("DevUbConnection::GetUniqueId:%s", Describe().c_str());
     171          141 :     HCCL_INFO(
     172              :         "type=%s, jfcPollMode=%u, dwqeCacheLocked=%d, sqCiAddr=0x%llx", rmaConnType.Describe().c_str(), jfcPollMode,
     173              :         dwqeCacheLocked, sqCiAddr);
     174           47 :     return result;
     175           47 : }
     176              : 
     177            0 : void DevUbConnection::SetCqInfo(HcclAiRMACQ& cq) const
     178              : {
     179            0 :     cq.jfcId = cqInfo_.id;
     180            0 :     cq.cqVA = cqInfo_.va;
     181            0 :     cq.cqeSize = cqInfo_.cqeSize;
     182            0 :     cq.cqDepth = cqInfo_.cqDepth;
     183            0 :     cq.dbAddr = cqInfo_.swdbAddr;
     184            0 : }
     185              : 
     186            2 : void DevUbConnection::SetWqInfo(HcclAiRMAWQ& wq)
     187              : {
     188            2 :     wq.jettyId = jettyId;
     189            2 :     wq.dbAddr = dbAddr;
     190            2 :     wq.sqVA = sqBuffVa;
     191            2 :     wq.sqDepth = sqDepth * WQE_NUM_PER_SQE;
     192            2 :     wq.tp_id = tpn;
     193            2 :     errno_t ret = memcpy_s(wq.rmtEid, sizeof(wq.rmtEid), rmtReverseEid.raw, sizeof(wq.rmtEid));
     194            2 :     if (ret != EOK) {
     195            3 :         HCCL_ERROR("[DevUbConnection][%s] memcpy_s failed, ret=%d", __func__, ret);
     196            2 :         ThrowAbnormalStatus(std::string(__func__));
     197              :     }
     198            1 : }
     199              : 
     200            2 : void DevUbConnection::SetSqContextInfo(SqContext& sq)
     201              : {
     202            2 :     sq.contextInfo.ubJfs.jfsID = jettyId;
     203            2 :     sq.contextInfo.ubJfs.dbVa = dbAddr;
     204            2 :     sq.contextInfo.ubJfs.sqVa = sqBuffVa;
     205            2 :     sq.contextInfo.ubJfs.sqDepth = sqDepth * WQE_NUM_PER_SQE;
     206            2 :     sq.contextInfo.ubJfs.tpID = tpn;
     207            4 :     errno_t ret = memcpy_s(
     208            2 :         sq.contextInfo.ubJfs.remoteEID, sizeof(sq.contextInfo.ubJfs.remoteEID), rmtReverseEid.raw,
     209              :         sizeof(sq.contextInfo.ubJfs.remoteEID));
     210            2 :     if (ret != EOK) {
     211            3 :         HCCL_ERROR("[DevUbConnection][%s] memcpy_s failed, ret=%d", __func__, ret);
     212            2 :         ThrowAbnormalStatus(std::string(__func__));
     213              :     }
     214            1 : }
     215              : 
     216            0 : void DevUbConnection::SetCqContextInfo(CqContext& cq) const
     217              : {
     218            0 :     cq.contextInfo.ubJfc.jfcID = cqInfo_.id;
     219            0 :     cq.contextInfo.ubJfc.scqVa = cqInfo_.va;
     220            0 :     cq.contextInfo.ubJfc.cqeSize = cqInfo_.cqeSize;
     221            0 :     cq.contextInfo.ubJfc.cqDepth = cqInfo_.cqDepth;
     222            0 :     cq.contextInfo.ubJfc.dbVa = cqInfo_.swdbAddr;
     223            0 : }
     224              : 
     225            0 : void DevUbConnection::Connect() { GetStatus(); }
     226              : 
     227            0 : inline uint32_t GetRandomNum()
     228              : {
     229            0 :     uint32_t randNum = std::rand();
     230            0 :     return randNum;
     231              : }
     232              : 
     233            1 : HcclResult DevUbConnection::CalcTotalTimeout(uint32_t& outTotalTimeoutMs)
     234              : {
     235            1 :     TpHandle tpHandle = tpInfo.tpHandle;
     236            1 :     uint32_t attrBitmap = (1U << kTpAttrRetryTimesInitBit) | (1U << kTpAttrAtBit);
     237            1 :     struct TpAttr tpAttr = {};
     238            1 :     u32 devicePhyId = HrtGetDevicePhyIdByIndex(devLogicId);
     239            4 :     CHK_RET(HrtRaGetTpAttrAsync(devicePhyId, rdmaHandle, tpHandle, attrBitmap, tpAttr, reqHandle));
     240            0 :     TpAttrInfo tpAttrInfo = TpAttrInfo(tpAttr);
     241            0 :     CHK_RET(TpManager::GetTpTotalTimeout(tpAttrInfo, outTotalTimeoutMs));
     242            0 :     return HCCL_SUCCESS;
     243              : }
     244              : 
     245            6 : void DevUbConnection::GetTimeOut() // 基于调用方按协议从环境变量获取并传入的超时值控制
     246              : {
     247            6 :     if (tpProtocol == TpProtocol::INVALID) { // 不感知tp建链,当前默认不支持
     248            0 :         HCCL_ERROR(
     249              :             "[DevUbConnection][%s] failed, tpProtocol[%s] is not expected.", __func__, tpProtocol.Describe().c_str());
     250            0 :         ThrowAbnormalStatus(std::string(__func__));
     251            0 :         return;
     252              :     }
     253              : 
     254              :     // CTP 协议不感知 TP 建链,跳过 CalcTotalTimeout,
     255              :     // tpTimeOutMs 保持 0,由 TpManager::CalcTaTimeout 内部按 CTP 规则直接使用 taTimeOut_
     256            6 :     uint32_t tpTimeOutMs = 0;
     257            6 :     if (tpProtocol != TpProtocol::CTP) {
     258            1 :         HcclResult ret = CalcTotalTimeout(tpTimeOutMs);
     259            1 :         if (ret != HCCL_SUCCESS) {
     260            3 :             HCCL_RUN_WARNING(
     261              :                 "[DevUbConnection][%s] CalcTotalTimeout failed[%d], tpTimeOutMs remains 0.", __func__, ret);
     262              :         }
     263              :     }
     264            6 :     jettyTimeOut = TpManager::CalcTaTimeout(tpProtocol, taTimeOut_, tpTimeOutMs);
     265           18 :     HCCL_INFO(
     266              :         "[DevUbConnection][%s] final TA Timeout [%u] (%ums).", __func__, jettyTimeOut,
     267              :         TpManager::TaHwValueToMs(jettyTimeOut));
     268              : }
     269              : 
     270              : /*
     271              :  * UB 建链状态机(GetTpInfo/CreateJetty 异步未完成则停;同步成功时可同次推进):
     272              :  *   INIT                  --GetTpInfo fail--> TP_INFO_GETTING
     273              :  *   INIT / TP_INFO_GETTING --GetTpInfo ok--> CreateJetty --> JETTY_CREATING | JETTY_CREATED
     274              :  *                         (EXTERNAL_INJECT 模式时跳过 CreateJetty,直接 JETTY_CREATED)
     275              :  *   JETTY_CREATING         --create done--> JETTY_CREATED (EXCHANGEABLE)
     276              :  *   JETTY_CREATED          --ImportRmtDto--> JETTY_IMPORTING(此处不推进)
     277              :  *   JETTY_IMPORTING        --import done--> READY
     278              :  */
     279            4 : void DevUbConnection::AdvanceUbConnFromJettyImporting()
     280              : {
     281            4 :     SetImportInfo();
     282              : 
     283            4 :     if (jettyMode_ == JettyMode::EXTERNAL_INJECT) {
     284            0 :         if (publishRemoteCb_ == nullptr) {
     285            0 :             THROW<InternalException>("[DevUbConnection][%s] publish callback is null.", __func__);
     286              :         }
     287            0 :         HcclResult ret = publishRemoteCb_(remoteQpKey, keySize, remoteJettyHandle, remoteJettyHandlePtr, tpn);
     288            0 :         if (ret != HCCL_SUCCESS) {
     289            0 :             THROW<InternalException>(
     290              :                 "[DevUbConnection][%s] publish shared remote jetty failed, ret[%d].", __func__, ret);
     291              :         }
     292              :     }
     293              : 
     294            4 :     status = RmaConnStatus::READY;
     295            4 :     ubConnStatus = UbConnStatus::READY;
     296            4 : }
     297              : 
     298            0 : void DevUbConnection::AdvanceUbConnFromJettyImportWaiting()
     299              : {
     300              :     // 超时检查:超过 jettyTimeOut 秒仍未 publish,则对端异常,抛异常避免永久阻塞。
     301              :     // 每次轮询都检查,保证超时判定不被退避延迟。
     302              :     auto elapsedSec
     303            0 :         = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - importWaitingStart_);
     304            0 :     if (elapsedSec.count() >= static_cast<int64_t>(jettyTimeOut)) {
     305            0 :         HCCL_ERROR(
     306              :             "[DevUbConnection][%s] JETTY_IMPORT_WAITING timeout[%us], remote jetty not published.", __func__,
     307              :             static_cast<uint32_t>(elapsedSec.count()));
     308            0 :         THROW<InternalException>("[DevUbConnection][%s] wait shared remote jetty publish timeout.");
     309              :     }
     310              : 
     311              :     // 退避:每 8 次 GetStatus 轮询才真正调 acquireRemoteCb_ 一次,减少 JettyContext 锁竞争。
     312              :     // 首次进入立即调用(pollCount==0),后续每 8 次轮询触发一次实际查询。
     313            0 :     if (importWaitingPollCount_ > 0 && (importWaitingPollCount_ % 8U) != 0U) {
     314            0 :         importWaitingPollCount_++;
     315            0 :         return;
     316              :     }
     317            0 :     importWaitingPollCount_++;
     318              : 
     319            0 :     AcquireOrWaitSharedRemoteJetty();
     320              : }
     321              : 
     322           20 : RmaConnStatus DevUbConnection::GetStatus()
     323              : {
     324              :     // 稳定态 / 等待外部 ImportRmtDto:无需推进
     325           20 :     if (ubConnStatus == UbConnStatus::READY || ubConnStatus == UbConnStatus::JETTY_CREATED) {
     326            2 :         return status;
     327              :     }
     328              : 
     329           18 :     if (!CheckRequestResult()) {
     330            0 :         return status;
     331              :     }
     332              : 
     333           18 :     switch (ubConnStatus) {
     334            6 :         case UbConnStatus::INIT:
     335            6 :             ProcessInit();
     336            6 :             break;
     337            6 :         case UbConnStatus::TP_INFO_GETTING:
     338            6 :             if (!GetTpInfo()) {
     339            0 :                 break;
     340              :             }
     341            6 :             ProcessCreateJetty();
     342            6 :             break;
     343            1 :         case UbConnStatus::JETTY_CREATING:
     344            1 :             SetJettyInfo();
     345            1 :             status = RmaConnStatus::EXCHANGEABLE;
     346            1 :             ubConnStatus = UbConnStatus::JETTY_CREATED;
     347            1 :             break;
     348            4 :         case UbConnStatus::JETTY_IMPORTING:
     349            4 :             AdvanceUbConnFromJettyImporting();
     350            4 :             break;
     351            0 :         case UbConnStatus::JETTY_IMPORT_WAITING:
     352            0 :             AdvanceUbConnFromJettyImportWaiting();
     353            0 :             break;
     354            0 :         case UbConnStatus::READY:
     355            0 :             break;
     356            1 :         default:
     357            2 :             ThrowAbnormalStatus(std::string(__func__));
     358            0 :             break;
     359              :     }
     360              : 
     361           17 :     return status;
     362              : }
     363              : 
     364            6 : void DevUbConnection::ProcessInit()
     365              : {
     366           18 :     HCCL_INFO(
     367              :         "[DevUbConnection][%s] start, status[%s], ubConnStatus[%s].", __func__, status.Describe().c_str(),
     368              :         ubConnStatus.Describe().c_str());
     369            6 :     if (!GetTpInfo()) {
     370            6 :         ubConnStatus = UbConnStatus::TP_INFO_GETTING;
     371            6 :         return;
     372              :     }
     373            0 :     ProcessCreateJetty();
     374              : }
     375              : 
     376            6 : void DevUbConnection::ProcessCreateJetty()
     377              : {
     378            6 :     GetTimeOut();
     379            6 :     if (jettyMode_ == JettyMode::EXTERNAL_INJECT) {
     380              :         // 共享 jetty:句柄已由 SetSharedJettyFields 注入,跳过 CreateJetty
     381            0 :         status = RmaConnStatus::EXCHANGEABLE;
     382            0 :         ubConnStatus = UbConnStatus::JETTY_CREATED;
     383            0 :         HCCL_INFO("[DevUbConnection][%s] shared jetty mode, skip CreateJetty, direct to JETTY_CREATED.", __func__);
     384            0 :         return;
     385              :     }
     386            6 :     CreateJetty(devUsed_);
     387            6 :     if (devUsed_ || !CheckRequestResult()) {
     388            1 :         ubConnStatus = UbConnStatus::JETTY_CREATING;
     389            1 :         return;
     390              :     }
     391            5 :     SetJettyInfo();
     392            5 :     status = RmaConnStatus::EXCHANGEABLE;
     393            5 :     ubConnStatus = UbConnStatus::JETTY_CREATED;
     394              : }
     395              : 
     396            6 : std::unique_ptr<Serializable> DevUbConnection::GetExchangeDto()
     397              : {
     398            6 :     if (status != RmaConnStatus::READY && status != RmaConnStatus::EXCHANGEABLE) {
     399            0 :         HCCL_ERROR("[DevUbConnection][%s] status[%s] is not expected.", __func__, status.Describe().c_str());
     400            0 :         ThrowAbnormalStatus(std::string(__func__));
     401              :     }
     402              : 
     403            6 :     if (tpProtocol != TpProtocol::INVALID) {
     404            4 :         jettyImportCfg.localTpHandle = tpInfo.tpHandle;
     405              : 
     406           12 :         HCCL_INFO(
     407              :             "[DevUbConnection][%s] tpEnable, localTpHandle[0x%llx] localPsn[%u].", __func__,
     408              :             jettyImportCfg.localTpHandle, jettyImportCfg.localPsn);
     409              :     }
     410              : 
     411              :     std::unique_ptr<ExchangeUbConnDto> dto
     412            6 :         = make_unique<ExchangeUbConnDto>(tokenValue, keySize, jettyImportCfg.localTpHandle, jettyImportCfg.localPsn);
     413            6 :     (void)memcpy_s(dto->qpKey, HRT_UB_QP_KEY_MAX_LEN, localQpKey, HRT_UB_QP_KEY_MAX_LEN);
     414           12 :     return std::unique_ptr<Serializable>(dto.release());
     415            6 : }
     416              : 
     417            4 : void DevUbConnection::ParseRmtExchangeDto(const Serializable& rmtDto)
     418              : {
     419            4 :     auto dto = dynamic_cast<const ExchangeUbConnDto&>(rmtDto);
     420           12 :     HCCL_INFO("[DevUbConnection][%s] remoteConnDto[%s]", __func__, dto.Describe().c_str());
     421            4 :     remoteTokenValue = dto.tokenValue;
     422            4 :     (void)memcpy_s(remoteQpKey, HRT_UB_QP_KEY_MAX_LEN, dto.qpKey, HRT_UB_QP_KEY_MAX_LEN);
     423              : 
     424            4 :     if (tpProtocol != TpProtocol::INVALID) {
     425            4 :         jettyImportCfg.remoteTpHandle = dto.tpHandle;
     426            4 :         jettyImportCfg.remotePsn = dto.psn;
     427           12 :         HCCL_INFO(
     428              :             "[DevUbConnection][%s] tpEnable, remoteTpHandle[0x%llx], remotePsn[%u].", __func__,
     429              :             jettyImportCfg.remoteTpHandle, jettyImportCfg.remotePsn);
     430              :     }
     431            4 : }
     432              : 
     433            6 : void DevUbConnection::ImportRmtDto()
     434              : {
     435            6 :     if (ubConnStatus == UbConnStatus::READY) {
     436            3 :         HCCL_WARNING("[DevUbConnection][%s] import jetty already, %s.", __func__, Describe().c_str());
     437            1 :         return;
     438              :     }
     439              : 
     440            5 :     if (ubConnStatus != UbConnStatus::JETTY_CREATED) {
     441            0 :         HCCL_ERROR(
     442              :             "[DevUbConnection][%s] failed, ubConnStatus[%s] is not expected.", __func__,
     443              :             ubConnStatus.Describe().c_str());
     444            0 :         ThrowAbnormalStatus(std::string(__func__));
     445              :     }
     446              : 
     447            5 :     if (jettyMode_ == JettyMode::EXTERNAL_INJECT) {
     448            0 :         AcquireOrWaitSharedRemoteJetty();
     449            0 :         return;
     450              :     }
     451              : 
     452            5 :     ImportJetty();
     453            5 :     ubConnStatus = UbConnStatus::JETTY_IMPORTING;
     454              : }
     455              : 
     456            4 : void DevUbConnection::ThrowAbnormalStatus(std::string funcName)
     457              : {
     458            4 :     auto errMsg = StringFormat("[DevUbConnection][%s] failed, [%s].", funcName.c_str(), Describe().c_str());
     459            4 :     status = RmaConnStatus::CONN_INVALID;
     460            4 :     ubConnStatus = UbConnStatus::CONN_INVALID;
     461            4 :     THROW<RmaConnException>(errMsg);
     462            4 : }
     463              : 
     464           23 : bool DevUbConnection::CheckRequestResult()
     465              : {
     466           23 :     if (reqHandle == 0) {
     467            7 :         return true;
     468              :     }
     469              : 
     470           16 :     ReqHandleResult result = HrtRaGetAsyncReqResult(reqHandle);
     471           16 :     if (result == ReqHandleResult::NOT_COMPLETED) {
     472            0 :         return false;
     473              :     }
     474              : 
     475           16 :     if (result != ReqHandleResult::COMPLETED) {
     476            0 :         THROW<InternalException>(
     477            0 :             "[DevUbConnection][%s] failed, result[%s] is unexpected.", __func__, result.Describe().c_str());
     478              :     }
     479              : 
     480           16 :     return true;
     481              : }
     482              : 
     483          116 : void DevUbConnection::CreateJetty(const bool devUsed)
     484              : {
     485          116 :     if (sqDepth > UINT32_MAX / UB_SQ_WQEBB_SIZE / WQE_NUM_PER_SQE) {
     486            0 :         THROW<InternalException>(
     487              :             "[DevUbConnection][%s] failed, sqDepth[%u] times "
     488              :             "UB_SQ_WQEBB_SIZE[%u] overflow uint32 max.",
     489              :             __func__, sqDepth, UB_SQ_WQEBB_SIZE);
     490              :     }
     491          116 :     u32 size = static_cast<u32>(sqDepth) * static_cast<u32>(UB_SQ_WQEBB_SIZE) * static_cast<u32>(WQE_NUM_PER_SQE);
     492              :     HrtRaUbCreateJettyParam req{
     493              :         jfcHandle,
     494              :         jfcHandle,
     495              :         GetUbToken(),
     496              :         0,
     497              :         HrtJettyMode::HOST_OPBASE, // 默认HOST单算子模式
     498              :         0,                         // HOST展开与AICPU展开传入jetty id为0,申请一个新的jetty
     499              :         0,                         // va由底层分配,此处填0即可。
     500              :         size,
     501              :         0,
     502              :         sqDepth,
     503          116 :         jettyTimeOut}; // 非CCUv2不需要填写sqeBufIndex
     504              : 
     505          116 :     if (opMode == OpMode::OFFLOAD) { // HOST展开图模式切换模式
     506            5 :         req.jettyMode = HrtJettyMode::HOST_OFFLOAD;
     507              :     }
     508              : 
     509          116 :     if (devUsed) { // AICPU场景切换模式
     510            1 :         req.jettyMode = HrtJettyMode::DEV_USED;
     511            3 :         HCCL_INFO("[DevUbConnection][%s] HrtJettyMode is DEV_USED.", __func__);
     512              :     }
     513              : 
     514          116 :     if (tpInfo.hasMappedJettyPriority) {
     515            2 :         req.qos = static_cast<u8>(tpInfo.mappedJettyPriority & 0xFU);
     516              :     }
     517          348 :     HCCL_INFO(
     518              :         "[DevUbConnection][%s] jetty create qos[%u] (maps to attr.ub.priority lower 4 bits).", __func__,
     519              :         static_cast<unsigned int>(req.qos));
     520              : 
     521          116 :     reqHandle = RaUbCreateJettyAsync(rdmaHandle, req, reqDataBuffer, jettyHandlePtr);
     522          116 : }
     523              : 
     524            0 : HcclResult DevUbConnection::SetSharedJettyFields(
     525              :     JettyHandle jettyHdl, void* jettyHdlPtr, uint32_t jId, uint64_t sqVa, uint64_t db, const uint8_t* qpKey,
     526              :     uint32_t kSize, uint32_t sDepth, JfcHandle sharedJfc, CqCreateInfo sharedCqInfo, uint32_t sharedLocalPsn,
     527              :     void* epTag, std::function<void(void*)> releaseCb, AcquireSharedRemoteJettyCallback acquireRemoteCb,
     528              :     PublishSharedRemoteJettyCallback publishRemoteCb)
     529              : {
     530            0 :     if (jettyHdl == 0 || jettyHdlPtr == nullptr || sDepth == 0 || acquireRemoteCb == nullptr
     531            0 :         || publishRemoteCb == nullptr) {
     532            0 :         HCCL_ERROR(
     533              :             "[DevUbConnection][%s] invalid params, jettyHdl[0x%llx], jettyHdlPtr[%p], sDepth[%u], "
     534              :             "acquireRemoteCb[%d], publishRemoteCb[%d].",
     535              :             __func__, static_cast<unsigned long long>(jettyHdl), jettyHdlPtr, sDepth,
     536              :             acquireRemoteCb == nullptr ? 0 : 1, publishRemoteCb == nullptr ? 0 : 1);
     537            0 :         return HCCL_E_PARA;
     538              :     }
     539            0 :     if (jettyMode_ != JettyMode::EXTERNAL_INJECT) {
     540            0 :         HCCL_ERROR(
     541              :             "[DevUbConnection][%s] not EXTERNAL_INJECT mode, jettyMode[%d], reject SetSharedJettyFields.", __func__,
     542              :             static_cast<s32>(jettyMode_));
     543            0 :         return HCCL_E_INTERNAL;
     544              :     }
     545              :     // EXTERNAL_INJECT 模式构造时跳过了建 JFC/jetty,此处填充共享字段,无需销毁私有 JFC
     546            0 :     if (qpKey != nullptr && kSize > 0 && kSize <= HRT_UB_QP_KEY_MAX_LEN) {
     547            0 :         s32 ret = memcpy_s(&localQpKey[0], HRT_UB_QP_KEY_MAX_LEN, qpKey, kSize);
     548            0 :         if (ret != EOK) {
     549            0 :             HCCL_ERROR("[DevUbConnection][%s] memcpy_s localQpKey failed, ret[%d].", __func__, ret);
     550            0 :             return HCCL_E_INTERNAL;
     551              :         }
     552              :     }
     553            0 :     endpointTag_ = epTag;
     554            0 :     releaseCb_ = std::move(releaseCb);
     555            0 :     acquireRemoteCb_ = std::move(acquireRemoteCb);
     556            0 :     publishRemoteCb_ = std::move(publishRemoteCb);
     557              :     // 共享 jetty 模式下主 connection 仍各自调 GetTpInfo 申请本 pair 的 tpHandle(TpManager useCnt++),
     558              :     // 析构时必须 ReleaseTp 释放引用,否则 useCnt 泄漏导致 tpHandle 永不回收。
     559            0 :     releaseTpOnDestroy_ = true;
     560            0 :     jettyHandle = jettyHdl;
     561            0 :     jettyHandlePtr = jettyHdlPtr;
     562            0 :     jettyId = jId;
     563            0 :     sqBuffVa = sqVa;
     564            0 :     dbAddr = db;
     565            0 :     keySize = kSize;
     566            0 :     sqDepth = sDepth;
     567            0 :     jfcHandle = sharedJfc;
     568            0 :     cqInfo_ = sharedCqInfo;
     569              :     // 注入临时 connection 生成的 localPsn,使主 connection 的 GetExchangeDto 发送与共享 jetty
     570              :     // 一致的 psn。多个主 connection 共享同一本地 jetty/SQ,必须用同一 localPsn,避免各自
     571              :     // GenerateLocalPsn 生成不同 psn 后 import 同一 TP 对时 psn 互相覆盖导致硬件传输错乱。
     572              :     // 注意:tpHandle 不在此注入——一对多场景下各主 connection 到不同对端需各自向管控面申请
     573              :     // 自己的 tpHandle,否则对端 import 时 peerTpHandle 路由不匹配。
     574            0 :     jettyImportCfg.localPsn = sharedLocalPsn;
     575              :     // 注入后不直接跳状态机:仍需走 GetTpInfo 申请本 pair 的 TP,由 ProcessCreateJetty
     576              :     // 中 EXTERNAL_INJECT 分支跳过 CreateJetty 直接进入 JETTY_CREATED
     577            0 :     HCCL_INFO(
     578              :         "[DevUbConnection][%s] shared jetty fields set, handle[0x%llx], jettyId[%u], sqDepth[%u], "
     579              :         "jfcHandle[%llu].",
     580              :         __func__, static_cast<unsigned long long>(jettyHandle), jettyId, sqDepth,
     581              :         static_cast<unsigned long long>(jfcHandle));
     582            0 :     return HCCL_SUCCESS;
     583              : }
     584              : 
     585            0 : void DevUbConnection::DetachJetty()
     586              : {
     587              :     // SELF_CREATE 模式建好 jetty 后调用:分离 jetty 所有权,析构不销毁 jetty,交由 JettyContext 管理。
     588              :     // 注意:不置 releaseTpOnDestroy_=false——临时 connection 自己申请的 TP 引用仍需在析构时
     589              :     // ReleaseTp 释放(TpManager 引用计数 -1),否则 useCnt 泄漏。
     590              :     // 共享 jetty 模式下主 connection 不复用临时 connection 的 tpHandle:一对多场景各主 connection
     591              :     // 到不同对端需各自向 TpManager 申请本 pair 的 tpHandle,否则对端 import 时 peerTpHandle 路由不匹配。
     592              :     // 临时 connection 的 tpHandle 引用随析构释放,不影响主 connection 各自申请的 tpHandle。
     593            0 :     jettyDetached_ = true;
     594            0 :     HCCL_INFO(
     595              :         "[DevUbConnection][%s] jetty ownership detached, handle[0x%llx].", __func__,
     596              :         static_cast<unsigned long long>(jettyHandle));
     597            0 : }
     598              : 
     599            0 : HcclResult DevUbConnection::GetJettyInfo(JettyInfo& info) const
     600              : {
     601            0 :     info.handle = jettyHandle;
     602            0 :     info.handlePtr = jettyHandlePtr;
     603            0 :     info.jettyId = jettyId;
     604            0 :     info.sqBuffVa = sqBuffVa;
     605            0 :     info.dbAddr = dbAddr;
     606            0 :     info.keySize = keySize;
     607            0 :     info.sqDepth = sqDepth;
     608            0 :     info.rdmaHandle = rdmaHandle;
     609            0 :     info.jfcHandle = jfcHandle;
     610            0 :     info.cqInfo = cqInfo_;
     611            0 :     info.localPsn = jettyImportCfg.localPsn;
     612            0 :     auto sRet = memcpy_s(&info.localQpKey[0], HRT_UB_QP_KEY_MAX_LEN, localQpKey, HRT_UB_QP_KEY_MAX_LEN);
     613            0 :     if (sRet != EOK) {
     614            0 :         HCCL_ERROR("[DevUbConnection][%s] memcpy_s failed, ret[%d].", __func__, sRet);
     615            0 :         return HCCL_E_INTERNAL;
     616              :     }
     617            0 :     return HCCL_SUCCESS;
     618              : }
     619              : 
     620            7 : void DevUbConnection::SetJettyInfo()
     621              : {
     622            7 :     struct QpCreateInfo* info = reinterpret_cast<QpCreateInfo*>(reqDataBuffer.data());
     623            7 :     jettyId = info->ub.id;
     624            7 :     jettyHandle = reinterpret_cast<JettyHandle>(jettyHandlePtr);
     625            7 :     keySize = info->key.size;
     626            7 :     sqBuffVa = info->ub.sqBuffVa; // hccp提供
     627           21 :     HCCL_RUN_INFO(
     628              :         "[DevUbConnection][%s] Get sqBuffVa is %llx. jettyId[%u], jettyHandle[%llx], dieId[%u], funcId[%u]", __func__,
     629              :         sqBuffVa, jettyId, jettyHandle, dieId, funcId);
     630              : 
     631            7 :     s32 ret = memcpy_s(&localQpKey[0], HRT_UB_QP_KEY_MAX_LEN, info->key.value, info->key.size);
     632            7 :     if (ret != 0) {
     633            0 :         THROW<InternalException>(StringFormat("[DevUbConnection][%s] memcpy_s failed, ret=%d", __func__, ret));
     634              :     }
     635              : 
     636            7 :     dbAddr = info->ub.dbAddr;
     637            7 : }
     638              : 
     639           12 : bool DevUbConnection::GetTpInfo()
     640              : {
     641           12 :     if (tpProtocol == TpProtocol::INVALID) { // 不感知tp建链,当前默认不支持
     642            0 :         HCCL_ERROR(
     643              :             "[DevUbConnection][%s] failed, tpProtocol[%s] is not expected.", __func__, tpProtocol.Describe().c_str());
     644            0 :         ThrowAbnormalStatus(std::string(__func__));
     645              :     }
     646              : 
     647              :     // 共享 jetty 模式:tpHandle 不复用临时 connection 的值——一对多场景下各主 connection 到不同对端
     648              :     // 必须各自向管控面申请本 pair 的 tpHandle,否则对端 import 时 peerTpHandle 路由不匹配。
     649              :     // 但 localPsn 已由 SetSharedJettyFields 注入(来自临时 connection),不在此 GenerateLocalPsn,
     650              :     // 避免多主 connection 共享同一本地 jetty/SQ 各自生成不同 psn 后 import 同一 TP 对时互相覆盖。
     651           12 :     const bool isSharedJettyMode = (jettyMode_ == JettyMode::EXTERNAL_INJECT);
     652              : 
     653           12 :     RaUbGetTpInfoParam p{};
     654           12 :     p.locAddr = locAddr;
     655           12 :     p.rmtAddr = rmtAddr;
     656           12 :     p.tpProtocol = tpProtocol;
     657           12 :     p.qos = static_cast<uint32_t>(qos_);
     658           12 :     p.slLevelCount = 0;
     659           12 :     p.loopFirstTpLowestSl = false;
     660           12 :     p.locIpv4Addr = locIpv4Addr;
     661           12 :     p.rmtIpv4Addr = rmtIpv4Addr;
     662              : 
     663           12 :     auto ret = TpManager::GetInstance(devLogicId).GetTpInfo(p, tpInfo);
     664              : 
     665           12 :     switch (ret) {
     666            6 :         case HcclResult::HCCL_SUCCESS:
     667            6 :             if (isSharedJettyMode) {
     668            0 :                 HCCL_INFO(
     669              :                     "[DevUbConnection][%s] shared jetty mode, apply own tpHandle[0x%llx] for rmtAddr[%s], "
     670              :                     "reuse injected localPsn[%u].",
     671              :                     __func__, static_cast<unsigned long long>(tpInfo.tpHandle), rmtAddr.Describe().c_str(),
     672              :                     jettyImportCfg.localPsn);
     673              :             } else {
     674            6 :                 GenerateLocalPsn();
     675              :             }
     676            6 :             return true;
     677            6 :         case HcclResult::HCCL_E_AGAIN:
     678            6 :             return false;
     679            0 :         case HcclResult::HCCL_E_NOT_FOUND:
     680              :         default:
     681            0 :             HCCL_ERROR("[DevUbConnection][%s] failed, hccl result[%d]", __func__, ret);
     682            0 :             ThrowAbnormalStatus(std::string(__func__));
     683            0 :             break;
     684              :     }
     685            0 :     return true;
     686              : }
     687              : 
     688            6 : void DevUbConnection::GenerateLocalPsn() { jettyImportCfg.localPsn = GetRandomNum(); }
     689              : 
     690            5 : void DevUbConnection::ImportJetty()
     691              : {
     692            5 :     HrtRaUbJettyImportedInParam in{};
     693            5 :     in.key = remoteQpKey;
     694            5 :     in.keyLen = keySize;
     695            5 :     in.tokenValue = remoteTokenValue;
     696            5 :     in.jettyImportCfg = jettyImportCfg;
     697            5 :     in.jettyImportCfg.protocol = tpProtocol;
     698              : 
     699            7 :     if (tpProtocol != TpProtocol::CTP && tpProtocol != TpProtocol::TP && tpProtocol != TpProtocol::UBOE
     700            7 :         && tpProtocol != TpProtocol::UB_RTP) {
     701            0 :         HCCL_ERROR(
     702              :             "[DevUbConnection][%s] failed, tp protocol[%s] is not expected, %s.", __func__,
     703              :             tpProtocol.Describe().c_str(), Describe().c_str());
     704            0 :         ThrowAbnormalStatus(std::string(__func__));
     705              :     }
     706              : 
     707            5 :     reqHandle = RaUbTpImportJettyAsync(rdmaHandle, in, reqDataBuffer, remoteJettyHandlePtr);
     708            5 : }
     709              : 
     710            4 : void DevUbConnection::SetImportInfo()
     711              : {
     712            4 :     struct QpImportInfoT* info = reinterpret_cast<QpImportInfoT*>(reqDataBuffer.data());
     713            4 :     remoteJettyHandle = reinterpret_cast<TargetJettyHandle>(remoteJettyHandlePtr);
     714            4 :     tpn = info->out.ub.tpn;
     715            4 : }
     716              : 
     717            0 : void DevUbConnection::SetSharedRemoteJettyInfo(TargetJettyHandle handle, void* handlePtr, uint32_t remoteTpn)
     718              : {
     719            0 :     remoteJettyHandle = handle;
     720            0 :     remoteJettyHandlePtr = handlePtr;
     721            0 :     tpn = remoteTpn;
     722            0 :     status = RmaConnStatus::READY;
     723            0 :     ubConnStatus = UbConnStatus::READY;
     724            0 :     HCCL_INFO(
     725              :         "[DevUbConnection][%s] reuse shared remote jetty, handle[0x%llx], tpn[%u].", __func__,
     726              :         static_cast<unsigned long long>(handle), remoteTpn);
     727            0 : }
     728              : 
     729            0 : void DevUbConnection::AcquireOrWaitSharedRemoteJetty()
     730              : {
     731            0 :     if (acquireRemoteCb_ == nullptr) {
     732            0 :         THROW<InternalException>("[DevUbConnection][%s] acquire callback is null.", __func__);
     733              :     }
     734              : 
     735            0 :     bool needImport = false;
     736            0 :     TargetJettyHandle cachedHandle = 0;
     737            0 :     void* cachedHandlePtr = nullptr;
     738            0 :     uint32_t cachedTpn = 0;
     739            0 :     HcclResult ret = acquireRemoteCb_(remoteQpKey, keySize, needImport, cachedHandle, cachedHandlePtr, cachedTpn);
     740            0 :     if (ret != HCCL_SUCCESS) {
     741            0 :         THROW<InternalException>("[DevUbConnection][%s] acquire shared remote jetty failed, ret[%d].", __func__, ret);
     742              :     }
     743              : 
     744            0 :     if (cachedHandle != 0) {
     745            0 :         SetSharedRemoteJettyInfo(cachedHandle, cachedHandlePtr, cachedTpn);
     746            0 :         return;
     747              :     }
     748            0 :     if (needImport) {
     749            0 :         ImportJetty();
     750            0 :         ubConnStatus = UbConnStatus::JETTY_IMPORTING;
     751            0 :         HCCL_INFO("[DevUbConnection][%s] start shared remote jetty import.", __func__);
     752            0 :         return;
     753              :     }
     754              :     // 进入 WAITING:记录起始时刻,供 AdvanceUbConnFromJettyImportWaiting 做超时判断
     755            0 :     if (ubConnStatus != UbConnStatus::JETTY_IMPORT_WAITING) {
     756            0 :         importWaitingStart_ = std::chrono::steady_clock::now();
     757            0 :         importWaitingPollCount_ = 0;
     758              :     }
     759            0 :     ubConnStatus = UbConnStatus::JETTY_IMPORT_WAITING;
     760              : }
     761              : 
     762          114 : void DevUbConnection::ReleaseTp()
     763              : {
     764          114 :     ReleaseUbConnectionTp(devLogicId, locAddr, rmtAddr, tpProtocol, tpInfo, static_cast<uint32_t>(qos_));
     765          114 : }
     766              : 
     767          112 : void DevUbConnection::ReleaseRemoteJettyIfImported(bool ctxValid)
     768              : {
     769              :     // EXTERNAL_INJECT 模式(主 connection):远端 jetty 由 JettyContext 统一 unimport,不在此处理
     770          112 :     if (jettyMode_ == JettyMode::EXTERNAL_INJECT) {
     771            0 :         return;
     772              :     }
     773          112 :     if (remoteJettyHandle == 0) {
     774          112 :         return;
     775              :     }
     776            0 :     if (!ctxValid) {
     777            0 :         HCCL_WARNING(
     778              :             "[DevUbConnection][%s] skip HrtRaUbUnimportJetty, "
     779              :             "rdmaHandle=%p invalid (DeInit/DestroyAll done), remoteJettyHandle=0x%llx",
     780              :             __func__, rdmaHandle, static_cast<unsigned long long>(remoteJettyHandle));
     781              :     } else {
     782            0 :         HrtRaUbUnimportJetty(rdmaHandle, remoteJettyHandle);
     783              :     }
     784            0 :     remoteJettyHandle = 0;
     785              : }
     786              : 
     787            0 : void DevUbConnection::ReleaseSharedJettyModeResources(bool ctxValid)
     788              : {
     789              :     // EXTERNAL_INJECT 模式(主 connection):构造时跳过 JFC/jetty 创建,jetty + JFC + CQ 全部由
     790              :     // JettyContext 统一管理,connection 不销毁。通过 releaseCb_ 通知 Endpoint 减引用计数
     791              :     // (refCount 归 0 时 JettyContext 销毁共享资源)。
     792            0 :     jettyHandle = 0;
     793            0 :     jfcHandle = 0;
     794            0 :     if (releaseCb_) {
     795            0 :         releaseCb_(endpointTag_);
     796            0 :         releaseCb_ = nullptr;
     797              :     }
     798            0 :     HCCL_INFO("[DevUbConnection][%s] EXTERNAL_INJECT mode, skip DestroyJetty, releaseCb invoked.", __func__);
     799              :     (void)ctxValid; // EXTERNAL_INJECT 模式无私有 JFC 需销毁,ctxValid 不影响
     800            0 : }
     801              : 
     802          112 : void DevUbConnection::ReleaseOwnedJettyAndJfc(bool ctxValid)
     803              : {
     804          112 :     if (jettyHandle != 0) {
     805            4 :         if (!ctxValid) {
     806           12 :             HCCL_WARNING(
     807              :                 "[DevUbConnection][%s] skip HrtRaUbDestroyJetty, "
     808              :                 "rdmaHandle=%p invalid, jettyHandle=0x%llx",
     809              :                 __func__, rdmaHandle, static_cast<unsigned long long>(jettyHandle));
     810              :         } else {
     811            0 :             HrtRaUbDestroyJetty(jettyHandle);
     812              :         }
     813            4 :         jettyHandle = 0;
     814              :     }
     815              : 
     816          112 :     if (engine_ == COMM_ENGINE_AIV && jfcHandle != 0) {
     817            0 :         if (!ctxValid) {
     818            0 :             HCCL_WARNING(
     819              :                 "[DevUbConnection][%s] skip HrtRaUbDestroyJfc, "
     820              :                 "rdmaHandle=%p invalid, jfcHandle=0x%llx",
     821              :                 __func__, rdmaHandle, static_cast<unsigned long long>(jfcHandle));
     822              :         } else {
     823            0 :             HrtRaUbDestroyJfc(rdmaHandle, jfcHandle);
     824              :         }
     825            0 :         jfcHandle = 0;
     826              :     }
     827          112 : }
     828              : 
     829          112 : void DevUbConnection::ReleaseResource()
     830              : {
     831          112 :     const bool ctxValid = (rdmaHandle != nullptr) && RdmaHandleManager::GetInstance().IsHandleValid(rdmaHandle);
     832              : 
     833          112 :     ReleaseRemoteJettyIfImported(ctxValid);
     834              : 
     835          112 :     if (releaseTpOnDestroy_) {
     836          112 :         ReleaseTp();
     837              :     }
     838              : 
     839              :     // EXTERNAL_INJECT 模式(主 connection):jetty/JFC 由 JettyContext 统一管理,调 releaseCb_ 减引用
     840          112 :     if (jettyMode_ == JettyMode::EXTERNAL_INJECT) {
     841            0 :         ReleaseSharedJettyModeResources(ctxValid);
     842            0 :         return;
     843              :     }
     844              : 
     845              :     // SELF_CREATE + DetachJetty(临时 connection):jetty/JFC 所有权已移交给 JettyContext,不销毁
     846          112 :     if (jettyDetached_) {
     847            0 :         HCCL_INFO("[DevUbConnection][%s] SELF_CREATE + DetachJetty, skip DestroyJetty/Jfc.", __func__);
     848            0 :         jettyHandle = 0;
     849            0 :         jfcHandle = 0;
     850            0 :         return;
     851              :     }
     852              : 
     853          112 :     ReleaseOwnedJettyAndJfc(ctxValid);
     854              : }
     855              : 
     856            1 : void DevUbConnection::CreateAivUrmaJfc()
     857              : {
     858            1 :     jfcHandle = HrtRaUbCreateJfcUserCtl(rdmaHandle, cqInfo_);
     859            3 :     HCCL_INFO("[DevUbConnection][CreateAivUrmaJfc] create jfcHandle[%p] for rdmaHandle[%p].", jfcHandle, rdmaHandle);
     860            1 : }
     861              : 
     862          112 : DevUbConnection::~DevUbConnection() { DECTOR_TRY_CATCH("DevUbConnection", ReleaseResource()); }
     863              : 
     864              : // Suspend接口当前已不使用,由框架调用触发析构流程
     865            3 : bool DevUbConnection::Suspend()
     866              : {
     867            9 :     HCCL_WARNING("[DevUbConnection][%s] should not be called.", __func__);
     868            3 :     if (status == RmaConnStatus::SUSPENDED) {
     869            3 :         HCCL_INFO("[DevUbConnection][%s] RmaConnStatus is SUSPENDED, status[%s].", __func__, status.Describe().c_str());
     870            1 :         return true;
     871              :     }
     872              : 
     873            2 :     if (status != RmaConnStatus::READY) {
     874            2 :         ThrowAbnormalStatus(std::string(__func__));
     875              :     }
     876              : 
     877            1 :     ReleaseResource();
     878            1 :     status = RmaConnStatus::SUSPENDED;
     879            1 :     return true;
     880              : }
     881              : 
     882           15 : static void PrepareUbSendWrReqParamForWriteOrRead(
     883              :     HrtRaUbSendWrReqParam& sendWrReq, const HrtUbSendWrOpCode sendWrOpCode, const MemoryBuffer& remoteMemBuf,
     884              :     const MemoryBuffer& localMemBuf, JettyHandle remoteJettyHandle, const SqeConfig& config, u32 cqeEnable = 1)
     885              : {
     886           15 :     sendWrReq.cqeEn = cqeEnable;
     887           15 :     sendWrReq.opcode = sendWrOpCode;
     888           15 :     sendWrReq.size = localMemBuf.size;
     889           15 :     sendWrReq.localAddr = localMemBuf.addr;
     890           15 :     sendWrReq.remoteAddr = remoteMemBuf.addr;
     891              : 
     892           15 :     sendWrReq.lmemHandle = localMemBuf.memHandle;
     893           15 :     sendWrReq.rmemHandle = remoteMemBuf.memHandle;
     894           15 :     sendWrReq.handle = remoteJettyHandle;
     895              : 
     896              :     // 打印入参
     897           45 :     HCCL_INFO(
     898              :         "PrepareOneUbSendForRead params opCode=[%u], size=[%u], localAddr=[0x%llx], "
     899              :         "remoteAddr=[0x%llx], lmemHandle=[0x%llx], rmemHandle=[0x%llx], "
     900              :         "jettyHandle=[0x%llx], cqeEn=[%u], config=[%d]",
     901              :         static_cast<u32>(sendWrReq.opcode), sendWrReq.size, localMemBuf.addr, remoteMemBuf.addr, localMemBuf.memHandle,
     902              :         remoteMemBuf.memHandle, remoteJettyHandle, sendWrReq.cqeEn, config);
     903           15 : }
     904              : 
     905            9 : static void PrepareUbSendWrReqParamReduceInfo(HrtRaUbSendWrReqParam& sendWrReq, DataType dataType, ReduceOp reduceOp)
     906              : {
     907            9 :     sendWrReq.inlineReduceFlag = true;
     908            9 :     sendWrReq.dataType = dataType;
     909            9 :     sendWrReq.reduceOp = reduceOp;
     910           27 :     HCCL_INFO(
     911              :         "PrepareUbSendWrReqParamReduceInfo params inlineReduceFlag[%u], dataType[%s], reduceOp[%s]",
     912              :         sendWrReq.inlineReduceFlag, dataType.Describe().c_str(), reduceOp.Describe().c_str());
     913            9 : }
     914              : 
     915              : static void
     916            4 : PrepareUbSendWrReqParamNotifyInfo(HrtRaUbSendWrReqParam& sendWrReq, u64 data, const MemoryBuffer& remoteNotifyMemBuf)
     917              : {
     918            4 :     sendWrReq.opcode = HrtUbSendWrOpCode::WRITE_WITH_NOTIFY;
     919            4 :     sendWrReq.notifyData = data;
     920            4 :     sendWrReq.notifyAddr = remoteNotifyMemBuf.addr;
     921            4 :     sendWrReq.notifyHandle = remoteNotifyMemBuf.memHandle;
     922           12 :     HCCL_INFO(
     923              :         "PrepareUbSendWrReqParamNotifyInfo params opCode[%u], "
     924              :         "notifyData[0x%llx], notifyAddr[0x%llx], notifyHandle[0x%llx]",
     925              :         static_cast<u32>(sendWrReq.opcode), sendWrReq.notifyData, sendWrReq.notifyAddr, sendWrReq.notifyHandle);
     926            4 : }
     927              : 
     928              : std::unique_ptr<BaseTask>
     929           18 : DevUbConnection::ConstructTaskUbSend(const HrtRaUbSendWrRespParam& sendWrResp, const SqeConfig& config)
     930              : {
     931           18 :     unique_ptr<BaseTask> result;
     932           18 :     if (opMode == OpMode::OPBASE) {
     933           15 :         if (config.wqeMode == WqeMode::DWQE) {
     934            7 :             result = make_unique<TaskUbDirectSend>(
     935            7 :                 sendWrResp.funcId, sendWrResp.dieId, sendWrResp.jettyId, sendWrResp.dwqeSize, sendWrResp.dwqe);
     936            8 :         } else if (config.wqeMode == WqeMode::DB_SEND) {
     937              :             result
     938            7 :                 = make_unique<TaskUbDbSend>(sendWrResp.jettyId, sendWrResp.funcId, sendWrResp.piVal, sendWrResp.dieId);
     939            1 :         } else if (config.wqeMode == WqeMode::WRITE_VALUE) {
     940            3 :             HCCL_INFO("[DevUbConnection::%s] dbAddr=[%llx], piVal=[%u]", __func__, dbAddr, sendWrResp.piVal);
     941            1 :             result = make_unique<TaskWriteValue>(dbAddr, sendWrResp.piVal);
     942              :         } else {
     943            0 :             auto msg = StringFormat("Invalid WqeMode[%s]", config.wqeMode.Describe().c_str());
     944            0 :             THROW<InvalidParamsException>(msg);
     945            0 :         }
     946            3 :     } else if (opMode == OpMode::OFFLOAD) {
     947            8 :         CHK_PRT_THROW(
     948              :             sendWrResp.piVal < piVal,
     949              :             HCCL_ERROR(
     950              :                 "[DevUbConnection::%s] sendWrResp.piVal[%u] is less than piVal[%u]", __func__, sendWrResp.piVal, piVal),
     951              :             InvalidParamsException, "sendWrResp.piVal or piVal is invalid");
     952            2 :         u32 sendPiVal = sendWrResp.piVal - piVal;
     953            2 :         result = make_unique<TaskUbDbSend>(sendWrResp.jettyId, sendWrResp.funcId, sendPiVal, sendWrResp.dieId);
     954            6 :         HCCL_INFO(
     955              :             "[DevUbConnection::%s] sendPiVal[%u] piVal[%u] sendWrResp.piVal[%u]", __func__, sendPiVal, piVal,
     956              :             sendWrResp.piVal);
     957              :     } else {
     958            0 :         auto msg = StringFormat("Invalid OpMode[%s]", opMode.Describe().c_str());
     959            0 :         THROW<InvalidParamsException>(msg);
     960            0 :     }
     961              : 
     962           17 :     piVal = sendWrResp.piVal;
     963           17 :     return result;
     964            1 : }
     965              : 
     966           11 : void DevUbConnection::ProcessSlices(
     967              :     const MemoryBuffer& loc, const MemoryBuffer& rmt,
     968              :     std::function<void(const MemoryBuffer&, const MemoryBuffer&, u32)> processOneSlice, DataType dataType) const
     969              : {
     970           33 :     HCCL_INFO("[DevUbConnection::%s] start", __func__);
     971              : 
     972              :     // reduce操作需要保证切片大小是数据类型大小的整数倍
     973           11 :     u32 sliceSize = UB_MAX_TRANS_SIZE;
     974           11 :     if (dataType != DataType::INVALID) {
     975            7 :         u32 dataTypeSize = DATA_TYPE_SIZE_MAP.at(dataType);
     976            7 :         sliceSize = UB_MAX_TRANS_SIZE / dataTypeSize * dataTypeSize;
     977              :     }
     978              : 
     979           11 :     u32 locBufSize = loc.size;
     980           11 :     u32 sliceNum = locBufSize / sliceSize;
     981           11 :     u32 lastSliceSize = locBufSize % sliceSize;
     982           11 :     u64 totalSize = static_cast<u64>(sliceNum) * static_cast<u64>(sliceSize);
     983           11 :     if (loc.addr > UINT64_MAX - totalSize || rmt.addr > UINT64_MAX - totalSize) {
     984            0 :         THROW<InternalException>("integer overflow occurs");
     985              :     }
     986           11 :     for (u32 sliceIdx = 0; sliceIdx < sliceNum; sliceIdx++) {
     987            0 :         MemoryBuffer locSlice(loc.addr + sliceIdx * sliceSize, sliceSize, loc.memHandle);
     988            0 :         MemoryBuffer rmtSlice(rmt.addr + sliceIdx * sliceSize, sliceSize, rmt.memHandle);
     989              :         // 当前是最后一片,且没有lastSlice时,启用cqe
     990            0 :         u32 cqeEnable = (sliceIdx == sliceNum - 1 && lastSliceSize == 0) ? 1 : 0;
     991            0 :         processOneSlice(locSlice, rmtSlice, cqeEnable);
     992              :     }
     993              : 
     994           11 :     if (lastSliceSize > 0) {
     995           11 :         MemoryBuffer lastLocSlice(loc.addr + sliceNum * sliceSize, lastSliceSize, loc.memHandle);
     996           11 :         MemoryBuffer lastRmtSlice(rmt.addr + sliceNum * sliceSize, lastSliceSize, rmt.memHandle);
     997           11 :         processOneSlice(lastLocSlice, lastRmtSlice, 1);
     998           11 :         sliceNum++;
     999              :     }
    1000              : 
    1001           33 :     HCCL_INFO(
    1002              :         "[DevUbConnection::%s] end, locBufSize[%u], sliceNum[%u], sliceSize[%u], lastSliceSize[%u]", __func__,
    1003              :         locBufSize, sliceNum, sliceSize, lastSliceSize);
    1004           11 : }
    1005              : 
    1006            4 : void DevUbConnection::ProcessSlicesWithNotify(
    1007              :     const MemoryBuffer& loc, const MemoryBuffer& rmt,
    1008              :     std::function<void(const MemoryBuffer&, const MemoryBuffer&, u32)> processOneSlice,
    1009              :     std::function<void(const MemoryBuffer&, const MemoryBuffer&)> processOneSliceWithNotify, DataType dataType) const
    1010              : {
    1011           12 :     HCCL_INFO("[DevUbConnection::%s] start", __func__);
    1012              : 
    1013              :     // reduce操作需要保证切片大小是数据类型大小的整数倍
    1014            4 :     u32 sliceSize = UB_MAX_TRANS_SIZE;
    1015            4 :     if (dataType != DataType::INVALID) {
    1016            2 :         u32 dataTypeSize = DATA_TYPE_SIZE_MAP.at(dataType);
    1017            2 :         sliceSize = UB_MAX_TRANS_SIZE / dataTypeSize * dataTypeSize;
    1018              :     }
    1019              : 
    1020            4 :     u32 locBufSize = loc.size;
    1021            4 :     u32 sliceNum = locBufSize / sliceSize;
    1022            4 :     u32 lastSliceSize = locBufSize % sliceSize;
    1023            4 :     if (sliceNum > 0 && lastSliceSize == 0) {
    1024            0 :         sliceNum--;
    1025            0 :         lastSliceSize = sliceSize;
    1026              :     }
    1027              : 
    1028            4 :     for (u32 sliceIdx = 0; sliceIdx < sliceNum; sliceIdx++) {
    1029            0 :         MemoryBuffer locSlice(loc.addr + sliceIdx * sliceSize, sliceSize, loc.memHandle);
    1030            0 :         MemoryBuffer rmtSlice(rmt.addr + sliceIdx * sliceSize, sliceSize, rmt.memHandle);
    1031              :         // 固定会有lastSlice,则前面的cqe都不启用
    1032            0 :         processOneSlice(locSlice, rmtSlice, 0);
    1033              :     }
    1034              : 
    1035            4 :     if (lastSliceSize > 0) {
    1036            4 :         MemoryBuffer lastLocSlice(loc.addr + sliceNum * sliceSize, lastSliceSize, loc.memHandle);
    1037            4 :         MemoryBuffer lastRmtSlice(rmt.addr + sliceNum * sliceSize, lastSliceSize, rmt.memHandle);
    1038            4 :         processOneSliceWithNotify(lastLocSlice, lastRmtSlice);
    1039            4 :         sliceNum++;
    1040              :     }
    1041              : 
    1042           12 :     HCCL_INFO(
    1043              :         "[DevUbConnection::%s] end, locBufSize[%u], sliceNum[%u], sliceSize[%u], lastSliceSize[%u]", __func__,
    1044              :         locBufSize, sliceNum, sliceSize, lastSliceSize);
    1045            4 : }
    1046              : 
    1047              : unique_ptr<BaseTask>
    1048            2 : DevUbConnection::PrepareRead(const MemoryBuffer& remoteMemBuf, const MemoryBuffer& localMemBuf, const SqeConfig& config)
    1049              : {
    1050            2 :     VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareRead");
    1051              : 
    1052            2 :     if (localMemBuf.size == 0) {
    1053            0 :         return nullptr;
    1054              :     }
    1055              : 
    1056            2 :     HrtRaUbSendWrRespParam sendWrResp{};
    1057            2 :     ProcessSlices(
    1058            2 :         localMemBuf, remoteMemBuf, [&](const MemoryBuffer& locSlice, const MemoryBuffer& rmtSlice, u32 cqeEnable) {
    1059            2 :             HrtRaUbSendWrReqParam sendWrReq = {};
    1060            2 :             PrepareUbSendWrReqParamForWriteOrRead(
    1061              :                 sendWrReq, HrtUbSendWrOpCode::READ, rmtSlice, locSlice, remoteJettyHandle, config, cqeEnable);
    1062              : 
    1063            2 :             sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1064            2 :         });
    1065              : 
    1066            2 :     return ConstructTaskUbSend(sendWrResp, config);
    1067              : }
    1068              : 
    1069            2 : unique_ptr<BaseTask> DevUbConnection::PrepareReadReduce(
    1070              :     const MemoryBuffer& remoteMemBuf, const MemoryBuffer& localMemBuf, DataType dataType, ReduceOp reduceOp,
    1071              :     const SqeConfig& config)
    1072              : {
    1073            2 :     VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareReadReduce");
    1074              : 
    1075            2 :     if (localMemBuf.size == 0) {
    1076            0 :         return nullptr;
    1077              :     }
    1078              : 
    1079            2 :     HrtRaUbSendWrRespParam sendWrResp{};
    1080            2 :     ProcessSlices(
    1081              :         localMemBuf, remoteMemBuf,
    1082            2 :         [&](const MemoryBuffer& locSlice, const MemoryBuffer& rmtSlice, u32 cqeEnable) {
    1083            2 :             HrtRaUbSendWrReqParam sendWrReq = {};
    1084            2 :             PrepareUbSendWrReqParamForWriteOrRead(
    1085              :                 sendWrReq, HrtUbSendWrOpCode::READ, rmtSlice, locSlice, remoteJettyHandle, config, cqeEnable);
    1086            2 :             PrepareUbSendWrReqParamReduceInfo(sendWrReq, dataType, reduceOp);
    1087              : 
    1088            2 :             sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1089            2 :         },
    1090              :         dataType);
    1091              : 
    1092            2 :     return ConstructTaskUbSend(sendWrResp, config);
    1093              : }
    1094              : 
    1095            6 : unique_ptr<BaseTask> DevUbConnection::PrepareWrite(
    1096              :     const MemoryBuffer& remoteMemBuf, const MemoryBuffer& localMemBuf, const SqeConfig& config)
    1097              : {
    1098            8 :     VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareWrite");
    1099              : 
    1100            4 :     if (localMemBuf.size == 0) {
    1101            2 :         return nullptr;
    1102              :     }
    1103              : 
    1104            2 :     HrtRaUbSendWrRespParam sendWrResp{};
    1105            2 :     ProcessSlices(
    1106            2 :         localMemBuf, remoteMemBuf, [&](const MemoryBuffer& locSlice, const MemoryBuffer& rmtSlice, u32 cqeEnable) {
    1107            2 :             HrtRaUbSendWrReqParam sendWrReq = {};
    1108            2 :             PrepareUbSendWrReqParamForWriteOrRead(
    1109              :                 sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice, remoteJettyHandle, config, cqeEnable);
    1110            2 :             sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1111            2 :         });
    1112              : 
    1113            2 :     return ConstructTaskUbSend(sendWrResp, config);
    1114              : }
    1115              : 
    1116            7 : unique_ptr<BaseTask> DevUbConnection::PrepareWriteReduce(
    1117              :     const MemoryBuffer& remoteMemBuf, const MemoryBuffer& localMemBuf, DataType dataType, ReduceOp reduceOp,
    1118              :     const SqeConfig& config)
    1119              : {
    1120            8 :     VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareWriteReduce");
    1121              : 
    1122            6 :     if (localMemBuf.size == 0) {
    1123            1 :         return nullptr;
    1124              :     }
    1125              : 
    1126            5 :     HrtRaUbSendWrRespParam sendWrResp{};
    1127            5 :     ProcessSlices(
    1128              :         localMemBuf, remoteMemBuf,
    1129            5 :         [&](const MemoryBuffer& locSlice, const MemoryBuffer& rmtSlice, u32 cqeEnable) {
    1130            5 :             HrtRaUbSendWrReqParam sendWrReq = {};
    1131            5 :             PrepareUbSendWrReqParamForWriteOrRead(
    1132              :                 sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice, remoteJettyHandle, config, cqeEnable);
    1133            5 :             PrepareUbSendWrReqParamReduceInfo(sendWrReq, dataType, reduceOp);
    1134            5 :             sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1135            5 :         },
    1136              :         dataType);
    1137              : 
    1138            5 :     return ConstructTaskUbSend(sendWrResp, config);
    1139              : }
    1140              : 
    1141              : unique_ptr<BaseTask>
    1142            3 : DevUbConnection::PrepareInlineWrite(const MemoryBuffer& remoteMemBuf, u64 data, const SqeConfig& config)
    1143              : {
    1144            3 :     HrtRaUbSendWrReqParam sendWrReq = {};
    1145            3 :     sendWrReq.opcode = HrtUbSendWrOpCode::WRITE;
    1146            3 :     sendWrReq.remoteAddr = remoteMemBuf.addr;
    1147            3 :     sendWrReq.rmemHandle = remoteMemBuf.memHandle;
    1148            3 :     sendWrReq.handle = remoteJettyHandle;
    1149            3 :     sendWrReq.inlineFlag = true;
    1150            3 :     sendWrReq.inlineData = reinterpret_cast<u8*>(&data);
    1151            3 :     sendWrReq.size = sizeof(data);
    1152              :     /*
    1153              :      * 当前只有前后同步使用writeValue任务
    1154              :      * 由于writeValue任务不使能cqe,
    1155              :      * writeValue和dwqe混用会有潜在问题,所以后面需要区分开这两种任务模式
    1156              :      * 不在同一个connection里面既使用writeValue又使用dwqe
    1157              :      */
    1158            3 :     if (config.wqeMode == WqeMode::WRITE_VALUE && opMode == OpMode::OPBASE) {
    1159              :         // 当前只有inlineWrite使用write value
    1160              :         // 图模式不能使用writeValue
    1161              :         // writeValue 不需要使能cqe
    1162            1 :         sendWrReq.cqeEn = false;
    1163              :     }
    1164              : 
    1165            9 :     HCCL_INFO(
    1166              :         "DevUbConnection::PrepareInlineWrite params opCode=[%u], "
    1167              :         "remoteAddr=[0x%llx], rmemHandle=[0x%llx], remoteJettyHandle=[0x%llx], inlineFlag[%u], size=[%u], data=[%u]",
    1168              :         sendWrReq.opcode, sendWrReq.remoteAddr, sendWrReq.rmemHandle, sendWrReq.handle, sendWrReq.inlineFlag,
    1169              :         sendWrReq.size, static_cast<u32>(*sendWrReq.inlineData));
    1170            3 :     auto res = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1171              : 
    1172            6 :     return ConstructTaskUbSend(res, config);
    1173              : }
    1174              : 
    1175              : inline HrtRaUbSendWrReqParam ConstructUbSendWrReqParamForWriteWithNotify(
    1176              :     const MemoryBuffer& remoteMemBuf, const MemoryBuffer& localMemBuf, u64 data, const MemoryBuffer& remoteNotifyMemBuf)
    1177              : {
    1178              :     HrtRaUbSendWrReqParam sendWrReq = {};
    1179              :     sendWrReq.opcode = HrtUbSendWrOpCode::WRITE_WITH_NOTIFY;
    1180              :     sendWrReq.size = remoteMemBuf.size;
    1181              :     sendWrReq.localAddr = localMemBuf.addr;
    1182              :     sendWrReq.remoteAddr = remoteMemBuf.addr;
    1183              :     sendWrReq.lmemHandle = localMemBuf.memHandle;
    1184              :     sendWrReq.rmemHandle = remoteMemBuf.memHandle;
    1185              :     sendWrReq.notifyData = data;
    1186              :     sendWrReq.notifyAddr = remoteNotifyMemBuf.addr;
    1187              :     sendWrReq.notifyHandle = remoteNotifyMemBuf.memHandle;
    1188              : 
    1189              :     return sendWrReq;
    1190              : }
    1191              : 
    1192            2 : unique_ptr<BaseTask> DevUbConnection::PrepareWriteWithNotify(
    1193              :     const MemoryBuffer& remoteMemBuf, const MemoryBuffer& localMemBuf, u64 data, const MemoryBuffer& remoteNotifyMemBuf,
    1194              :     const SqeConfig& config)
    1195              : {
    1196            2 :     VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareWriteWithNotify");
    1197              : 
    1198            2 :     if (localMemBuf.size == 0) {
    1199            0 :         return nullptr;
    1200              :     }
    1201              : 
    1202            2 :     HrtRaUbSendWrRespParam sendWrResp{};
    1203            2 :     ProcessSlicesWithNotify(
    1204              :         localMemBuf, remoteMemBuf,
    1205            4 :         [&](const MemoryBuffer& locSlice, const MemoryBuffer& rmtSlice, u32 cqeEnable) {
    1206            0 :             HrtRaUbSendWrReqParam sendWrReq = {};
    1207            0 :             PrepareUbSendWrReqParamForWriteOrRead(
    1208              :                 sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice, remoteJettyHandle, config, cqeEnable);
    1209            0 :             sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1210            0 :         },
    1211            2 :         [&](const MemoryBuffer& locSlice, const MemoryBuffer& rmtSlice) {
    1212            2 :             HrtRaUbSendWrReqParam sendWrReq = {};
    1213            2 :             PrepareUbSendWrReqParamForWriteOrRead(
    1214              :                 sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice, remoteJettyHandle, config);
    1215            2 :             PrepareUbSendWrReqParamNotifyInfo(sendWrReq, data, remoteNotifyMemBuf);
    1216              : 
    1217            2 :             sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1218            2 :         });
    1219              : 
    1220            2 :     return ConstructTaskUbSend(sendWrResp, config);
    1221              : }
    1222              : 
    1223            2 : unique_ptr<BaseTask> DevUbConnection::PrepareWriteReduceWithNotify(
    1224              :     const MemoryBuffer& remoteMemBuf, const MemoryBuffer& localMemBuf, DataType dataType, ReduceOp reduceOp, u64 data,
    1225              :     const MemoryBuffer& remoteNotifyMemBuf, const SqeConfig& config)
    1226              : {
    1227            2 :     VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareWriteReduceWithNotify");
    1228              : 
    1229            2 :     if (localMemBuf.size == 0) {
    1230            0 :         return nullptr;
    1231              :     }
    1232              : 
    1233            2 :     HrtRaUbSendWrRespParam sendWrResp{};
    1234            2 :     ProcessSlicesWithNotify(
    1235              :         localMemBuf, remoteMemBuf,
    1236            4 :         [&](const MemoryBuffer& locSlice, const MemoryBuffer& rmtSlice, u32 cqeEnable) {
    1237            0 :             HrtRaUbSendWrReqParam sendWrReq = {};
    1238            0 :             PrepareUbSendWrReqParamForWriteOrRead(
    1239              :                 sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice, remoteJettyHandle, config, cqeEnable);
    1240            0 :             PrepareUbSendWrReqParamReduceInfo(sendWrReq, dataType, reduceOp);
    1241            0 :             sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1242            0 :         },
    1243            2 :         [&](const MemoryBuffer& locSlice, const MemoryBuffer& rmtSlice) {
    1244            2 :             HrtRaUbSendWrReqParam sendWrReq = {};
    1245            2 :             PrepareUbSendWrReqParamForWriteOrRead(
    1246              :                 sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice, remoteJettyHandle, config);
    1247            2 :             PrepareUbSendWrReqParamReduceInfo(sendWrReq, dataType, reduceOp);
    1248            2 :             PrepareUbSendWrReqParamNotifyInfo(sendWrReq, data, remoteNotifyMemBuf);
    1249            2 :             sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
    1250            2 :         },
    1251              :         dataType);
    1252              : 
    1253            2 :     return ConstructTaskUbSend(sendWrResp, config);
    1254              : }
    1255              : 
    1256          152 : string DevUbConnection::Describe() const
    1257              : {
    1258              :     return StringFormat(
    1259              :         "DevUbConnection[locAddr=%s, rmtAddr=%s, status=%s, dieId=%u, funcId=%u, jettyId=%u, sqBuffVa=%llx, "
    1260              :         "sqDepth=%u, maxReadSize=%u, maxWriteSize=%u, tpn=%u, dbAddr=0x%llx]",
    1261          456 :         locAddr.Describe().c_str(), rmtAddr.Describe().c_str(), status.Describe().c_str(), dieId, funcId, jettyId,
    1262          608 :         sqBuffVa, sqDepth, maxReadSize, maxWriteSize, tpn, dbAddr);
    1263              : }
    1264              : 
    1265            1 : HcclResult DevUbConnection::Describe(std::string& dfxMsg)
    1266              : {
    1267            1 :     uint16_t udpSport = 0xFFFF; // 无法获取实际的udpSport,使用0xFFFF表示未知
    1268            1 :     if (tpProtocol == TpProtocol::TP) {
    1269            1 :         struct TpAttr tpAttr {};
    1270            1 :         uint32_t attrBitmap = 1 << 13; // 13对应dataUdpSrcport
    1271            1 :         TRY_CATCH_PRINT_ERROR(
    1272              :             u32 devicePhyId = HrtGetDevicePhyIdByIndex(devLogicId);
    1273              :             HcclResult ret
    1274              :             = HrtRaGetTpAttrAsync(devicePhyId, rdmaHandle, tpInfo.tpHandle, attrBitmap, tpAttr, reqHandle);
    1275              :             if (ret == HCCL_E_NOT_SUPPORT) {
    1276              :                 HCCL_ERROR(
    1277              :                     "[DevUbConnection::%s] this package does not support RaGetTpAttrAsync for device,"
    1278              :                     " please change new package, devPhyId[%u]",
    1279              :                     __func__, devicePhyId);
    1280              :                 return ret;
    1281              :             } else if (ret != HCCL_SUCCESS) {
    1282              :                 HCCL_ERROR("[DevUbConnection::%s] failed, hccl result[%d]", __func__, ret);
    1283              :                 return ret;
    1284              :             });
    1285            1 :         udpSport = tpAttr.dataUdpSrcport;
    1286              :     }
    1287            1 :     udpSport = udpSport & 0xFF;
    1288              : 
    1289              :     std::string dfxStr = StringFormat(
    1290              :         "chip id[%u] die id[%u] func id[%u] jetty id[%u] "
    1291              :         "local %s remote %s udp sport[%u]",
    1292            1 :         devLogicId, dieId, funcId, jettyId, locEid.Describe().c_str(), rmtEid.Describe().c_str(), udpSport);
    1293            1 :     dfxMsg += dfxStr;
    1294            3 :     HCCL_INFO("[DevUbConnection::%s] %s", __func__, dfxStr.c_str());
    1295            1 :     return HCCL_SUCCESS;
    1296            1 : }
    1297              : 
    1298            4 : void DevUbConnection::AddNop(const Stream& stream)
    1299              : {
    1300            4 :     if (opMode != OpMode::OFFLOAD) {
    1301            3 :         HCCL_WARNING("[DevUbConnection][AddNop]Invalid OpMode[%s]", opMode.Describe().c_str());
    1302            1 :         return;
    1303              :     }
    1304            3 :     if (sqDepth < piVal) {
    1305            1 :         auto msg = StringFormat("Invalid piVal[%u], piVal should be less than or equal to sqDepth[%u]", piVal, sqDepth);
    1306            1 :         THROW<InvalidParamsException>(msg);
    1307            1 :     }
    1308            2 :     if (sqDepth == piVal) {
    1309            0 :         return;
    1310              :     }
    1311            2 :     u32 numNop = sqDepth - piVal;
    1312            2 :     HrtRaUbPostNops(jettyHandle, remoteJettyHandle, numNop);
    1313              : 
    1314              :     HrtUbDbInfo info;
    1315            2 :     info.dbNum = 1;
    1316            2 :     info.wrCqe = 0; // 默认值是0 不会cqe  如果传1,驱动分发,会给hccl cqe,用于维护ci指针。
    1317            2 :     info.info[0].functionId = funcId;
    1318            2 :     info.info[0].dieId = dieId;
    1319            2 :     info.info[0].jettyId = jettyId;
    1320            2 :     info.info[0].piValue = numNop;
    1321            2 :     HrtUbDbSend(info, stream.GetPtr());
    1322              : 
    1323            2 :     piVal = sqDepth;
    1324              : }
    1325              : 
    1326            4 : HrtUbJfcMode DevUbConnection::GetUbJfcMode() const { return jfcMode; }
    1327              : 
    1328            5 : JettyHandle& DevUbConnection::GetJettyHandle() { return jettyHandle; }
    1329              : 
    1330            2 : JettyHandle& DevUbConnection::GetRemoteJettyHandle() { return remoteJettyHandle; }
    1331              : 
    1332            2 : RdmaHandle& DevUbConnection::GetRdmaHandle() { return rdmaHandle; }
    1333              : 
    1334            6 : u32 DevUbConnection::GetPiVal() const { return piVal; }
    1335              : 
    1336            5 : u32 DevUbConnection::GetCiVal() const { return ciVal; }
    1337              : 
    1338            5 : u32 DevUbConnection::GetSqDepth() const { return sqDepth; }
    1339              : 
    1340            2 : void DevUbConnection::UpdateCiVal(u32 ci) { ciVal = ci; }
    1341              : 
    1342            7 : std::vector<DevUbConnection*> GetStarsPollUbConns(const std::vector<RmaConnection*>& rmaConns)
    1343              : {
    1344            7 :     std::vector<DevUbConnection*> ubConns;
    1345            8 :     for (auto& rmaConn : rmaConns) {
    1346            1 :         if (rmaConn->GetRmaConnType() == RmaConnType::UB) {
    1347            1 :             if (dynamic_cast<DevUbConnection*>(rmaConn)->GetUbJfcMode() == HrtUbJfcMode::STARS_POLL) {
    1348            1 :                 ubConns.emplace_back(dynamic_cast<DevUbConnection*>(rmaConn));
    1349              :             }
    1350              :         }
    1351              :     }
    1352            7 :     return ubConns;
    1353            0 : }
    1354              : 
    1355            7 : bool IfNeedUpdatingUbCi(const std::vector<DevUbConnection*>& ubConns)
    1356              : {
    1357            9 :     for (auto& ubConn : ubConns) {
    1358            2 :         u32 pi = ubConn->GetPiVal();
    1359            2 :         u32 ci = ubConn->GetCiVal();
    1360            2 :         u32 sqDepth = ubConn->GetSqDepth();
    1361              :         // 考虑pi翻转场景
    1362            2 :         u32 extra = pi >= ci ? 0 : sqDepth;
    1363            2 :         constexpr u32 thresholdDivisor = 2;
    1364              : 
    1365            2 :         if (static_cast<double>(pi + extra - ci)
    1366            2 :             >= static_cast<double>(sqDepth) / thresholdDivisor) { // 当pi和ci差距大于sqDepth/2时,更新ci
    1367            0 :             return true;
    1368              :         }
    1369              :     }
    1370            7 :     return false;
    1371              : }
    1372              : 
    1373            0 : void DevUbConnection::SetMaxReadSize(u32 value) { maxReadSize = value; }
    1374              : 
    1375            0 : void DevUbConnection::SetMaxWriteSize(u32 value) { maxWriteSize = value; }
    1376              : 
    1377              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1