LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/communicator/hostdpu - flush_handle.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 81.6 % 147 120
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 15 15

            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 "flush_handle.h"
      12              : #include <stdlib.h>
      13              : #include "hccp.h"
      14              : #include "orion_adapter_rts.h"
      15              : 
      16              : namespace Hccl {
      17              : 
      18            7 : FlushHandle::FlushHandle() : flushIsInitialized(false) {}
      19              : 
      20            7 : FlushHandle::~FlushHandle() { Destroy(); }
      21              : 
      22            5 : HcclResult FlushHandle::Init(IpAddress ip, u32 devPhyId)
      23              : {
      24            5 :     int lbMax = 0;
      25              :     // 获取 RDMA handle
      26            5 :     CHK_RET(GetRdmaHandle(ip, devPhyId, &rdmaHandle));
      27              : 
      28              :     // 获取 LbMax
      29            5 :     CHK_RET(GetLbMax(&lbMax));
      30              : 
      31            5 :     if (lbMax > 0) {
      32            2 :         SetFlushOpcodeSupport();
      33              :     }
      34              : 
      35              :     // 分配 Local Memory
      36            5 :     CHK_RET(AllocateLocalMemory());
      37              : 
      38              :     // 分配 Device Memory
      39            8 :     CHK_RET(AllocateDeviceMemory());
      40              : 
      41              :     // 创建环回 QP
      42            7 :     CHK_RET(CreateLoopbackQp());
      43              : 
      44              :     // 注册 Local MR
      45            6 :     CHK_RET(RegisterLocalMr());
      46              : 
      47              :     // 注册 Remote MR
      48            2 :     CHK_RET(RegisterRemoteMr());
      49              : 
      50            2 :     flushIsInitialized = true;
      51            2 :     return HCCL_SUCCESS;
      52              : }
      53              : 
      54            5 : HcclResult FlushHandle::GetLbMax(int* lbMax) const
      55              : {
      56            5 :     int ret = RaGetLbMax(rdmaHandle, lbMax);
      57            5 :     if (ret != 0) {
      58            0 :         HCCL_ERROR("[GetLbMax]Failed to get load balance max value. error_code=%d.", ret);
      59            0 :         return HCCL_E_ROCE_CONNECT;
      60              :     }
      61           15 :     HCCL_INFO("[GetLbMax]Get load balance max value successfully, lbMax = %d", *lbMax);
      62            5 :     return HCCL_SUCCESS;
      63              : }
      64              : 
      65           13 : HcclResult FlushHandle::Destroy()
      66              : {
      67           13 :     HcclResult finalResult = HCCL_SUCCESS;
      68           26 :     finalResult = std::max(finalResult, DeregisterMr(remoteMrHandle, "Remote"));
      69           13 :     finalResult = std::max(finalResult, DeregisterMr(localMrHandle, "Local"));
      70           13 :     finalResult = std::max(finalResult, DestroyLoopbackQp());
      71           13 :     finalResult = std::max(finalResult, FreeLocalMemory());
      72           13 :     finalResult = std::max(finalResult, FreeDeviceMemory());
      73           13 :     return finalResult;
      74              : }
      75              : 
      76            5 : HcclResult FlushHandle::GetRdmaHandle(IpAddress ip, u32 devPhyId, void** rdmaHandle) const
      77              : {
      78              :     *rdmaHandle
      79            5 :         = RdmaHandleManager::GetInstance().GetByAddr(devPhyId, LinkProtoType::RDMA, ip, PortDeploymentType::HOST_NET);
      80            5 :     CHK_PTR_NULL(*rdmaHandle);
      81              : 
      82           15 :     HCCL_DEBUG("[GetRdmaHandle]RDMA handle initialized. ");
      83              : 
      84            5 :     return HCCL_SUCCESS;
      85              : }
      86              : 
      87            5 : HcclResult FlushHandle::AllocateLocalMemory()
      88              : {
      89            5 :     u64 bufferSize = FLUSH_BUFFER_SIZE;
      90            5 :     if (flushOpcodeSupport_) {
      91              :         // 1825 主动排空要求使用device 内存
      92            2 :         localMem = HrtMalloc(bufferSize, static_cast<int>(ACL_MEM_TYPE_HIGH_BAND_WIDTH));
      93              :     } else {
      94            3 :         localMem = malloc(bufferSize);
      95              :     }
      96              : 
      97            5 :     if (localMem == nullptr) {
      98            0 :         HcclResult eRet = Destroy();
      99            0 :         HCCL_ERROR("[%s]Failed to Allocate Local Memory. Destroy Flush code=%d", __func__, eRet);
     100            0 :         return HCCL_E_MEMORY;
     101              :     }
     102           15 :     HCCL_DEBUG("[%s]Local memory allocated at %p, size=%u", __func__, localMem, bufferSize);
     103            5 :     return HCCL_SUCCESS;
     104              : }
     105              : 
     106            5 : HcclResult FlushHandle::AllocateDeviceMemory()
     107              : {
     108            5 :     u64 bufferSize = FLUSH_BUFFER_SIZE;
     109            5 :     deviceMem = HrtMalloc(bufferSize, static_cast<int>(ACL_MEM_TYPE_HIGH_BAND_WIDTH));
     110            5 :     if (deviceMem == nullptr) {
     111            1 :         HcclResult eRet = Destroy();
     112            3 :         HCCL_ERROR("[AllocateDeviceMemory]Failed to Allocate Device Memory. Destroy Flush code=%d", eRet);
     113            1 :         return HCCL_E_MEMORY;
     114              :     }
     115           12 :     HCCL_DEBUG("[AllocateDeviceMemory]Device memory allocated at %p, size=%u", deviceMem, bufferSize);
     116            4 :     return HCCL_SUCCESS;
     117              : }
     118              : 
     119            4 : HcclResult FlushHandle::CreateLoopbackQp()
     120              : {
     121            4 :     int ret = RaLoopbackQpCreate(rdmaHandle, &loopBackQpParam, &qpHandle);
     122            4 :     if (ret != 0) {
     123            1 :         HcclResult eRet = Destroy();
     124            3 :         HCCL_ERROR("[CreateLoopbackQp]Failed to create loopback QP. error_code=%d. Destroy Flush code=%d", ret, eRet);
     125            1 :         return HCCL_E_ROCE_CONNECT;
     126              :     }
     127            9 :     HCCL_DEBUG("[CreateLoopbackQp]Loopback QP created successfully. QP Handle=%p", qpHandle);
     128            3 :     return HCCL_SUCCESS;
     129              : }
     130              : 
     131            3 : HcclResult FlushHandle::RegisterLocalMr()
     132              : {
     133            3 :     u64 bufferSize = FLUSH_BUFFER_SIZE;
     134            3 :     loopBackQpMrLocalInfo.addr = localMem;
     135            3 :     loopBackQpMrLocalInfo.size = bufferSize;
     136            3 :     loopBackQpMrLocalInfo.access = RA_ACCESS_LOCAL_WRITE;
     137              : 
     138            3 :     int localRet = RaRegisterMr(rdmaHandle, &loopBackQpMrLocalInfo, &localMrHandle);
     139            3 :     if (localRet != 0 || localMrHandle == nullptr) {
     140            3 :         HCCL_ERROR(
     141              :             "[RegisterLocalMr]Failed to register local MR. localMrHandle=0x%p, error_code=%d", localMrHandle, localRet);
     142            1 :         HcclResult eRet = Destroy();
     143            3 :         HCCL_ERROR(
     144              :             "[RegisterLocalMr]Failed to register local MR. error_code=%d. Destroy Flush code=%d", localRet, eRet);
     145            1 :         return HCCL_E_MEMORY;
     146              :     }
     147            6 :     HCCL_DEBUG("[RegisterLocalMr]Local MR registered successfully. MR Handle=0x%p", localMrHandle);
     148            2 :     return HCCL_SUCCESS;
     149              : }
     150              : 
     151            2 : HcclResult FlushHandle::RegisterRemoteMr()
     152              : {
     153            2 :     u64 bufferSize = FLUSH_BUFFER_SIZE;
     154            2 :     loopBackQpMrRemoteInfo.addr = deviceMem;
     155            2 :     loopBackQpMrRemoteInfo.size = bufferSize;
     156              :     loopBackQpMrRemoteInfo.access
     157            2 :         = RA_ACCESS_REMOTE_WRITE | RA_ACCESS_LOCAL_WRITE | RA_ACCESS_REMOTE_READ | RA_ACCESS_REMOTE_ATOMIC;
     158              : 
     159            2 :     int remoteRet = RaRegisterMr(rdmaHandle, &loopBackQpMrRemoteInfo, &remoteMrHandle);
     160            2 :     if (remoteRet != 0 || remoteMrHandle == nullptr) {
     161            0 :         HCCL_ERROR(
     162              :             "[RegisterRemoteMr]Failed to register remote MR. remoteMrHandle=0x%p, error_code=%d", remoteMrHandle,
     163              :             remoteRet);
     164            0 :         HcclResult eRet = Destroy();
     165            0 :         HCCL_ERROR(
     166              :             "[RegisterLocalMr]Failed to register remote MR. error_code=%d. Destroy Flush code=%d", remoteRet, eRet);
     167            0 :         return HCCL_E_MEMORY;
     168              :     }
     169            6 :     HCCL_DEBUG("[RegisterRemoteMr]Remote MR registered successfully. MR Handle=0x%p", remoteMrHandle);
     170            2 :     return HCCL_SUCCESS;
     171              : }
     172              : 
     173              : // 销毁 MR
     174           26 : HcclResult FlushHandle::DeregisterMr(MrHandle& mrHandle, std::string logTag) const
     175              : {
     176           78 :     HCCL_DEBUG("[DeregisterMr] Starting to destroy %s MR...", logTag.c_str());
     177              : 
     178           26 :     if (mrHandle == nullptr || rdmaHandle == nullptr) {
     179           63 :         HCCL_DEBUG("[DeregisterMr] %s MR is already null, skipping.", logTag.c_str());
     180           21 :         return HCCL_SUCCESS;
     181              :     }
     182              : 
     183            5 :     int ret = RaDeregisterMr(rdmaHandle, mrHandle);
     184            5 :     if (ret != 0) {
     185            0 :         HCCL_ERROR(
     186              :             "[DeregisterMr] Failed to deregister %s MR, mrHandle=0x%p, error_code=%d.", logTag.c_str(), mrHandle, ret);
     187            0 :         mrHandle = nullptr; // 防止重复调用
     188            0 :         return HCCL_E_INTERNAL;
     189              :     }
     190              : 
     191            5 :     mrHandle = nullptr;
     192           15 :     HCCL_DEBUG("[DeregisterMr] %s MR successfully deregistered.", logTag.c_str());
     193            5 :     return HCCL_SUCCESS;
     194              : }
     195              : 
     196              : // 销毁环回 QP
     197           13 : HcclResult FlushHandle::DestroyLoopbackQp()
     198              : {
     199           39 :     HCCL_DEBUG("[DestroyLoopbackQp] Starting to destroy loopback QP...");
     200              : 
     201           13 :     if (qpHandle == nullptr) {
     202           36 :         HCCL_DEBUG("[DestroyLoopbackQp] QP already null, skipping.");
     203           12 :         return HCCL_SUCCESS;
     204              :     }
     205              : 
     206            1 :     int ret = RaQpDestroy(qpHandle);
     207            1 :     if (ret != 0) {
     208            0 :         HCCL_ERROR("[DestroyLoopbackQp] Failed to destroy QP. qpHandle=%p, error=%d", qpHandle, ret);
     209            0 :         qpHandle = nullptr;
     210            0 :         return HCCL_E_INTERNAL;
     211              :     }
     212              : 
     213            1 :     qpHandle = nullptr;
     214            3 :     HCCL_DEBUG("[DestroyLoopbackQp] Loopback QP successfully destroyed.");
     215            1 :     return HCCL_SUCCESS;
     216              : }
     217              : 
     218              : // 释放 Local MR 内存
     219           13 : HcclResult FlushHandle::FreeLocalMemory()
     220              : {
     221           39 :     HCCL_DEBUG("[%s] Starting to free local memory...", __func__);
     222              : 
     223           13 :     if (localMem == nullptr) {
     224           21 :         HCCL_DEBUG("[%s] Local memory already null, skipping.", __func__);
     225            7 :         return HCCL_SUCCESS;
     226              :     }
     227              : 
     228              :     try {
     229            6 :         if (flushOpcodeSupport_) {
     230            3 :             HrtFree(localMem);
     231              :         } else {
     232            3 :             free(localMem);
     233              :         }
     234            0 :     } catch (HcclException& e) {
     235            0 :         HCCL_ERROR("[%s] Exception occurred: %s", __func__, e.what());
     236            0 :         return e.GetErrorCode();
     237            0 :     } catch (...) {
     238            0 :         HCCL_ERROR("[%s] Exception caught while freeing local memory.", __func__);
     239            0 :         return HcclResult::HCCL_E_INTERNAL;
     240            0 :     }
     241            6 :     localMem = nullptr;
     242           18 :     HCCL_DEBUG("[%s] Local memory successfully freed.", __func__);
     243            6 :     return HCCL_SUCCESS;
     244              : }
     245              : 
     246              : // 释放 Device 内存
     247           13 : HcclResult FlushHandle::FreeDeviceMemory()
     248              : {
     249           39 :     HCCL_DEBUG("[FreeDeviceMemory] Starting to free device memory...");
     250              : 
     251           13 :     if (deviceMem == nullptr) {
     252           27 :         HCCL_DEBUG("[FreeDeviceMemory] Device memory already null, skipping.");
     253            9 :         return HCCL_SUCCESS;
     254              :     }
     255              : 
     256              :     try {
     257            4 :         HrtFree(deviceMem);
     258            4 :         deviceMem = nullptr;
     259           12 :         HCCL_DEBUG("[FreeDeviceMemory] Device memory successfully freed.");
     260            4 :         return HCCL_SUCCESS;
     261            0 :     } catch (...) {
     262            0 :         HCCL_ERROR("[FreeDeviceMemory] Exception caught while freeing device memory.");
     263            0 :         deviceMem = nullptr;
     264            0 :         return HCCL_E_RUNTIME;
     265            0 :     }
     266              : }
     267              : 
     268              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1