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

Generated by: LCOV version 2.0-1