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: 82.0 % 150 123
Test Date: 2026-07-28 12:11:00 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()
      20              : {
      21            7 :     Destroy();
      22            7 : }
      23              : 
      24            5 : HcclResult FlushHandle::Init(IpAddress ip, u32 devPhyId)
      25              : {
      26            5 :     int lbMax = 0;
      27              :     // 获取 RDMA handle
      28            5 :     CHK_RET(GetRdmaHandle(ip, devPhyId, &rdmaHandle));
      29              : 
      30              :     // 获取 LbMax
      31            5 :     CHK_RET(GetLbMax(&lbMax));
      32              : 
      33            5 :     if (lbMax > 0) {
      34            2 :         SetFlushOpcodeSupport();
      35              :     }
      36              : 
      37              :     // 分配 Local Memory
      38            5 :     CHK_RET(AllocateLocalMemory());
      39              : 
      40              :     // 分配 Device Memory
      41            8 :     CHK_RET(AllocateDeviceMemory());
      42              : 
      43              :     // 创建环回 QP
      44            7 :     CHK_RET(CreateLoopbackQp());
      45              : 
      46              :     // 注册 Local MR
      47            6 :     CHK_RET(RegisterLocalMr());
      48              : 
      49              :     // 注册 Remote MR
      50            2 :     CHK_RET(RegisterRemoteMr());
      51              : 
      52            2 :     flushIsInitialized = true;
      53            2 :     return HCCL_SUCCESS;
      54              : }
      55              : 
      56            5 : HcclResult FlushHandle::GetLbMax(int *lbMax) const
      57              : {
      58            5 :     int ret = RaGetLbMax(rdmaHandle, lbMax);
      59            5 :     if (ret != 0) {
      60            0 :         HCCL_ERROR("[GetLbMax]Failed to get load balance max value. error_code=%d.", ret);
      61            0 :         return HCCL_E_ROCE_CONNECT;
      62              :     }
      63           15 :     HCCL_INFO("[GetLbMax]Get load balance max value successfully, ibMax = %d", *lbMax);
      64            5 :     return HCCL_SUCCESS;
      65              : }
      66              : 
      67           13 : HcclResult FlushHandle::Destroy()
      68              : {
      69           13 :     HcclResult finalResult = HCCL_SUCCESS;
      70           26 :     finalResult = std::max(finalResult, DeregisterMr(remoteMrHandle, "Remote"));
      71           13 :     finalResult = std::max(finalResult, DeregisterMr(localMrHandle, "Local"));
      72           13 :     finalResult = std::max(finalResult, DestroyLoopbackQp());
      73           13 :     finalResult = std::max(finalResult, FreeLocalMemory());
      74           13 :     finalResult = std::max(finalResult, FreeDeviceMemory());
      75           13 :     return finalResult;
      76              : }
      77              : 
      78            5 : HcclResult FlushHandle::GetRdmaHandle(IpAddress ip, u32 devPhyId, void **rdmaHandle) const
      79              : {
      80            5 :     *rdmaHandle =
      81            5 :         RdmaHandleManager::GetInstance().GetByAddr(devPhyId, LinkProtoType::RDMA, ip, PortDeploymentType::HOST_NET);
      82            5 :     CHK_PTR_NULL(*rdmaHandle);
      83              : 
      84           15 :     HCCL_DEBUG("[GetRdmaHandle]RDMA handle initialized. ");
      85              : 
      86            5 :     return HCCL_SUCCESS;
      87              : }
      88              : 
      89            5 : HcclResult FlushHandle::AllocateLocalMemory()
      90              : {
      91            5 :     u64 bufferSize = FLUSH_BUFFER_SIZE;
      92            5 :     if (flushOpcodeSupport_) {
      93              :         // 1825 主动排空要求使用device 内存
      94            2 :         localMem = HrtMalloc(bufferSize, static_cast<int>(ACL_MEM_TYPE_HIGH_BAND_WIDTH));
      95              :     } else {
      96            3 :         localMem = malloc(bufferSize);
      97              :     }
      98              : 
      99            5 :     if (localMem == nullptr) {
     100            0 :         HcclResult eRet = Destroy();
     101            0 :         HCCL_ERROR("[%s]Failed to Allocate Local Memory. Destroy Flush code=%d", __func__, eRet);
     102            0 :         return HCCL_E_MEMORY;
     103              :     }
     104           15 :     HCCL_DEBUG("[%s]Local memory allocated at %p, size=%u", __func__, localMem, bufferSize);
     105            5 :     return HCCL_SUCCESS;
     106              : }
     107              : 
     108            5 : HcclResult FlushHandle::AllocateDeviceMemory()
     109              : {
     110            5 :     u64 bufferSize = FLUSH_BUFFER_SIZE;
     111            5 :     deviceMem = HrtMalloc(bufferSize, static_cast<int>(ACL_MEM_TYPE_HIGH_BAND_WIDTH));
     112            5 :     if (deviceMem == nullptr) {
     113            1 :         HcclResult eRet = Destroy();
     114            3 :         HCCL_ERROR("[AllocateDeviceMemory]Failed to Allocate Device Memory. Destroy Flush code=%d", eRet);
     115            1 :         return HCCL_E_MEMORY;
     116              :     }
     117           12 :     HCCL_DEBUG("[AllocateDeviceMemory]Device memory allocated at %p, size=%u", deviceMem, bufferSize);
     118            4 :     return HCCL_SUCCESS;
     119              : }
     120              : 
     121            4 : HcclResult FlushHandle::CreateLoopbackQp()
     122              : {
     123            4 :     int ret = RaLoopbackQpCreate(rdmaHandle, &loopBackQpParam, &qpHandle);
     124            4 :     if (ret != 0) {
     125            1 :         HcclResult eRet = Destroy();
     126            3 :         HCCL_ERROR("[CreateLoopbackQp]Failed to create loopback QP. error_code=%d. Destroy Flush code=%d", ret, eRet);
     127            1 :         return HCCL_E_ROCE_CONNECT;
     128              :     }
     129            9 :     HCCL_DEBUG("[CreateLoopbackQp]Loopback QP created successfully. QP Handle=%p", qpHandle);
     130            3 :     return HCCL_SUCCESS;
     131              : }
     132              : 
     133            3 : HcclResult FlushHandle::RegisterLocalMr()
     134              : {
     135            3 :     u64 bufferSize = FLUSH_BUFFER_SIZE;
     136            3 :     loopBackQpMrLocalInfo.addr = localMem;
     137            3 :     loopBackQpMrLocalInfo.size = bufferSize;
     138            3 :     loopBackQpMrLocalInfo.access = RA_ACCESS_LOCAL_WRITE;
     139              : 
     140            3 :     int localRet = RaRegisterMr(rdmaHandle, &loopBackQpMrLocalInfo, &localMrHandle);
     141            3 :     if (localRet != 0 || localMrHandle == nullptr) {
     142            3 :         HCCL_ERROR("[RegisterLocalMr]Failed to register local MR. localMrHandle=0x%p, error_code=%d", localMrHandle,
     143              :                    localRet);
     144            1 :         HcclResult eRet = Destroy();
     145            3 :         HCCL_ERROR("[RegisterLocalMr]Failed to register local MR. error_code=%d. Destroy Flush code=%d", localRet,
     146              :                    eRet);
     147            1 :         return HCCL_E_MEMORY;
     148              :     }
     149            6 :     HCCL_DEBUG("[RegisterLocalMr]Local MR registered successfully. MR Handle=0x%p", localMrHandle);
     150            2 :     return HCCL_SUCCESS;
     151              : }
     152              : 
     153            2 : HcclResult FlushHandle::RegisterRemoteMr()
     154              : {
     155            2 :     u64 bufferSize = FLUSH_BUFFER_SIZE;
     156            2 :     loopBackQpMrRemoteInfo.addr = deviceMem;
     157            2 :     loopBackQpMrRemoteInfo.size = bufferSize;
     158            2 :     loopBackQpMrRemoteInfo.access = RA_ACCESS_REMOTE_WRITE | RA_ACCESS_LOCAL_WRITE | RA_ACCESS_REMOTE_READ | RA_ACCESS_REMOTE_ATOMIC;
     159              : 
     160            2 :     int remoteRet = RaRegisterMr(rdmaHandle, &loopBackQpMrRemoteInfo, &remoteMrHandle);
     161            2 :     if (remoteRet != 0 || remoteMrHandle == nullptr) {
     162            0 :         HCCL_ERROR("[RegisterRemoteMr]Failed to register remote MR. remoteMrHandle=0x%p, error_code=%d", remoteMrHandle,
     163              :                    remoteRet);
     164            0 :         HcclResult eRet = Destroy();
     165            0 :         HCCL_ERROR("[RegisterLocalMr]Failed to register remote MR. error_code=%d. Destroy Flush code=%d", remoteRet,
     166              :                    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("[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