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

Generated by: LCOV version 2.0-1