LCOV - code coverage report
Current view: top level - base_comm/resources/endpoints - endpoint.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 79.7 % 123 98
Test Date: 2026-08-25 19:18:03 Functions: 75.9 % 29 22

            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 "endpoint.h"
      12              : #include <functional>
      13              : #include "aicpu_ts_roce_endpoint.h"
      14              : #include "cpu_roce_endpoint.h"
      15              : #include "urma_endpoint.h"
      16              : #include "ub_mem_endpoint.h"
      17              : #include "uboe_endpoint.h"
      18              : #include "ub_rtp_endpoint.h"
      19              : #include "cpu_urma_endpoint.h"
      20              : #include "aicputs_hccs_endpoint.h"
      21              : #include "hccp_nda.h"
      22              : #include "adapter_rts_common.h"
      23              : #include "rdma_handle_manager.h"
      24              : #include "proc_reged_mem_mgr_cache.h"
      25              : #include "dfx/endpoint_monitor.h"
      26              : #include "log.h"
      27              : 
      28              : namespace hcomm {
      29           89 : static bool IsSupported(const EndpointDesc& endpointDesc)
      30              : {
      31           89 :     bool protocolSupported = false;
      32           89 :     bool locTypeSupported = false;
      33           89 :     switch (endpointDesc.protocol) {
      34           89 :         case COMM_PROTOCOL_ROCE:
      35              :         case COMM_PROTOCOL_UBC_TP:
      36              :         case COMM_PROTOCOL_UB_CTP:
      37              :         case COMM_PROTOCOL_UB_MEM:
      38              :         case COMM_PROTOCOL_PCIE:
      39              :         case COMM_PROTOCOL_UBOE:
      40              :         case COMM_PROTOCOL_UB_RTP:
      41              :         case COMM_PROTOCOL_HCCS:
      42           89 :             protocolSupported = true;
      43           89 :             break;
      44            0 :         default:
      45            0 :             return false;
      46              :     }
      47           89 :     switch (endpointDesc.loc.locType) {
      48           89 :         case ENDPOINT_LOC_TYPE_DEVICE:
      49              :         case ENDPOINT_LOC_TYPE_HOST:
      50           89 :             locTypeSupported = true;
      51           89 :             break;
      52            0 :         default:
      53            0 :             return false;
      54              :     }
      55              : 
      56           89 :     return protocolSupported && locTypeSupported;
      57              : }
      58              : 
      59          332 : Endpoint::Endpoint(const EndpointDesc& endpointDesc) { endpointDesc_ = endpointDesc; }
      60              : 
      61          332 : Endpoint::~Endpoint()
      62              : {
      63          332 :     ReleaseEndpointMonitor(reinterpret_cast<EndpointHandle>(this));
      64          332 :     ReleaseCache();
      65              :     // JettyContext 由 unique_ptr 自动析构:refCount 归 0 销毁 jetty,refCount > 0 告警避免 use-after-free。
      66              :     // 控制面资源(设备上下文/注册内存)由各子类析构处理,与数据面 jetty 资源解耦。
      67              :     // SharedJettyMgr 反查记录由 HcommEndpointDestroy 在 RemoveEndpoint 前摘除(运行期单例确定存活),
      68              :     // 不在 ~Endpoint 调用,规避 g_EndpointMap 静态析构与 SharedJettyMgr 单例析构顺序不确定的风险。
      69          332 : }
      70              : 
      71              : HcclResult
      72            6 : Endpoint::AcquireSharedJetty(const std::function<HcclResult(SharedJettyCtx&)>& provideCtx, SharedJettyCtx& outCtx)
      73              : {
      74            6 :     JettyContext* ctx = GetJettyContext();
      75            6 :     CHK_PTR_NULL(ctx);
      76            6 :     return ctx->Acquire(provideCtx, outCtx);
      77              : }
      78              : 
      79            0 : HcclResult Endpoint::AcquireSharedRemoteJetty(
      80              :     const uint8_t* remoteQpKey, uint32_t keySize, bool& needImport, uint64_t& handle, void*& handlePtr, uint32_t& tpn)
      81              : {
      82            0 :     JettyContext* ctx = GetJettyContext();
      83            0 :     CHK_PTR_NULL(ctx);
      84            0 :     return ctx->AcquireSharedRemoteJetty(remoteQpKey, keySize, needImport, handle, handlePtr, tpn);
      85              : }
      86              : 
      87            0 : HcclResult Endpoint::PublishSharedRemoteJetty(
      88              :     const uint8_t* remoteQpKey, uint32_t keySize, uint64_t handle, void* handlePtr, uint32_t tpn)
      89              : {
      90            0 :     JettyContext* ctx = GetJettyContext();
      91            0 :     CHK_PTR_NULL(ctx);
      92            0 :     return ctx->PublishSharedRemoteJetty(remoteQpKey, keySize, handle, handlePtr, tpn);
      93              : }
      94              : 
      95            7 : HcclResult Endpoint::ReleaseSharedJetty()
      96              : {
      97            7 :     JettyContext* ctx = GetJettyContext();
      98            7 :     CHK_PTR_NULL(ctx);
      99            7 :     return ctx->Release();
     100              : }
     101              : 
     102           13 : JettyContext* Endpoint::GetJettyContext()
     103              : {
     104           13 :     std::call_once(jettyContextOnce_, [this] {
     105            4 :         jettyContext_ = std::make_unique<JettyContext>();
     106            4 :     });
     107           13 :     return jettyContext_.get();
     108              : }
     109              : 
     110           89 : HcclResult Endpoint::CreateEndpoint(const EndpointDesc& endpointDesc, std::unique_ptr<Endpoint>& endpointPtr)
     111              : {
     112           89 :     if (!IsSupported(endpointDesc)) {
     113            0 :         HCCL_ERROR(
     114              :             "[%s]endpointDesc is not supported. endpointDesc.protocol [%d] endpointDesc.loc.locType [%d].", __func__,
     115              :             endpointDesc.protocol, endpointDesc.loc.locType);
     116            0 :         return HCCL_E_PARA;
     117              :     }
     118              : 
     119           89 :     HCCL_INFO(
     120              :         "[%s]endpointDesc.protocol [%d] endpointDesc.loc.locType [%d].", __func__, endpointDesc.protocol,
     121              :         endpointDesc.loc.locType);
     122              : 
     123           89 :     return CreateEndpointBase(endpointDesc, endpointPtr);
     124              : }
     125              : 
     126           89 : HcclResult Endpoint::CreateEndpointBase(const EndpointDesc& endpointDesc, std::unique_ptr<Endpoint>& endpointPtr)
     127              : {
     128              :     using EndpointCreator = std::function<std::unique_ptr<Endpoint>(const EndpointDesc&)>;
     129              :     struct Entry {
     130              :         CommProtocol protocol;
     131              :         EndpointLocType locType;
     132              :         EndpointCreator creator;
     133              :     };
     134              :     static const Entry table[] = {
     135              :         {COMM_PROTOCOL_ROCE, ENDPOINT_LOC_TYPE_HOST,
     136           22 :          [](const EndpointDesc& d) {
     137           18 :              return std::make_unique<CpuRoceEndpoint>(d);
     138              :          }},
     139              :         {COMM_PROTOCOL_UBC_TP, ENDPOINT_LOC_TYPE_HOST,
     140            4 :          [](const EndpointDesc& d) {
     141            0 :              return std::make_unique<CpuUrmaEndpoint>(d);
     142              :          }},
     143              :         {COMM_PROTOCOL_UB_CTP, ENDPOINT_LOC_TYPE_HOST,
     144            4 :          [](const EndpointDesc& d) {
     145            0 :              return std::make_unique<CpuUrmaEndpoint>(d);
     146              :          }},
     147              :         {COMM_PROTOCOL_UBC_TP, ENDPOINT_LOC_TYPE_DEVICE,
     148            4 :          [](const EndpointDesc& d) {
     149            0 :              return std::make_unique<UrmaEndpoint>(d);
     150              :          }},
     151              :         {COMM_PROTOCOL_UB_CTP, ENDPOINT_LOC_TYPE_DEVICE,
     152           24 :          [](const EndpointDesc& d) {
     153           20 :              return std::make_unique<UrmaEndpoint>(d);
     154              :          }},
     155              :         {COMM_PROTOCOL_UB_MEM, ENDPOINT_LOC_TYPE_DEVICE,
     156           21 :          [](const EndpointDesc& d) {
     157           17 :              return std::make_unique<UbMemEndpoint>(d);
     158              :          }},
     159              :         {COMM_PROTOCOL_PCIE, ENDPOINT_LOC_TYPE_DEVICE,
     160            4 :          [](const EndpointDesc& d) {
     161            0 :              return std::make_unique<UbMemEndpoint>(d);
     162              :          }},
     163              :         {COMM_PROTOCOL_UBOE, ENDPOINT_LOC_TYPE_DEVICE,
     164           17 :          [](const EndpointDesc& d) {
     165           13 :              return std::make_unique<UboeEndpoint>(d);
     166              :          }},
     167              :         {COMM_PROTOCOL_UB_RTP, ENDPOINT_LOC_TYPE_DEVICE,
     168            6 :          [](const EndpointDesc& d) {
     169            2 :              return std::make_unique<UbRtpEndpoint>(d);
     170              :          }},
     171              :         {COMM_PROTOCOL_ROCE, ENDPOINT_LOC_TYPE_DEVICE,
     172            5 :          [](const EndpointDesc& d) {
     173            1 :              return std::make_unique<AicpuTsRoceEndpoint>(d);
     174              :          }},
     175              :         {COMM_PROTOCOL_HCCS, ENDPOINT_LOC_TYPE_DEVICE,
     176            4 :          [](const EndpointDesc& d) {
     177           16 :              return std::make_unique<AicpuTsHccsEndpoint>(d);
     178              :          }},
     179           89 :     };
     180              : 
     181          552 :     for (const auto& entry : table) {
     182          550 :         if (entry.protocol == endpointDesc.protocol && entry.locType == endpointDesc.loc.locType) {
     183           87 :             EXCEPTION_CATCH(endpointPtr = entry.creator(endpointDesc), return HCCL_E_PTR);
     184           87 :             return HCCL_SUCCESS;
     185              :         }
     186              :     }
     187              : 
     188            2 :     HCCL_ERROR(
     189              :         "[%s] failed, endpointDesc.protocol [%d] and endpointDesc.loc.locType [%d] do not match.", __func__,
     190              :         endpointDesc.protocol, endpointDesc.loc.locType);
     191            2 :     return HCCL_E_PARA;
     192              : }
     193              : 
     194            1 : HcclResult Endpoint::CheckFeature(const EndpointDesc& endpointDesc, HcommEndpointFeatureType featureType, bool& value)
     195              : {
     196            1 :     if (featureType == HCOMM_ENDPOINT_FEATURE_NDA) {
     197            1 :         if (endpointDesc.protocol != COMM_PROTOCOL_ROCE || endpointDesc.loc.locType != ENDPOINT_LOC_TYPE_HOST) {
     198            0 :             HCCL_WARNING(
     199              :                 "[%s] not support NDA, protocol[%d], locType[%d]", __func__, endpointDesc.protocol,
     200              :                 endpointDesc.loc.locType);
     201            0 :             value = false;
     202            0 :             return HCCL_SUCCESS;
     203              :         }
     204              : 
     205            1 :         Hccl::IpAddress ipAddr{};
     206            1 :         CHK_RET(CommAddrToIpAddress(endpointDesc.commAddr, ipAddr));
     207            1 :         s32 devId = 0;
     208            1 :         CHK_RET(hrtGetDevice(&devId));
     209            1 :         u32 devPhyId = 0;
     210            1 :         CHK_RET(hrtGetDevicePhyIdByIndex(devId, devPhyId));
     211              : 
     212            1 :         auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
     213              :         void* rdmaHandle = static_cast<void*>(
     214            1 :             rdmaHandleMgr.GetByAddr(devPhyId, Hccl::LinkProtoType::RDMA, ipAddr, Hccl::PortDeploymentType::HOST_NET));
     215            1 :         CHK_PTR_NULL(rdmaHandle);
     216              : 
     217            1 :         s32 directFlag = 0;
     218            1 :         s32 ret = RaNdaGetDirectFlag(rdmaHandle, &directFlag);
     219            1 :         CHK_PRT_RET(
     220              :             ret != HCCL_SUCCESS, HCCL_ERROR("[%s] failed to get directFlag, ret[%d]", __func__, ret), HCCL_E_INTERNAL);
     221            1 :         value = (directFlag != DIRECT_FLAG_NOTSUPP);
     222            1 :         HCCL_INFO(
     223              :             "[%s] %s NDA, rdmaHandle[%p], directFlag[%d]", __func__, value ? "support" : "not support", rdmaHandle,
     224              :             directFlag);
     225              :     } else {
     226            0 :         HCCL_WARNING("[%s] unsupported featureType[%d]", __func__, featureType);
     227            0 :         value = false;
     228              :     }
     229              : 
     230            1 :     return HCCL_SUCCESS;
     231              : }
     232              : 
     233          200 : HcclResult Endpoint::AttachCache(const MemMgrCacheKey& key, std::function<std::shared_ptr<RegedMemMgr>()> creator)
     234              : {
     235          200 :     cacheKey_ = key;
     236          200 :     cacheKeepAlive_ = ProcRegedMemMgrCache::GetHolder();
     237          200 :     regedMemMgr_ = cacheKeepAlive_->GetOrCreate(cacheKey_, std::move(creator));
     238          200 :     if (regedMemMgr_ == nullptr) {
     239            0 :         ReleaseCache();
     240            0 :         return HCCL_E_INTERNAL;
     241              :     }
     242          200 :     return HCCL_SUCCESS;
     243              : }
     244              : 
     245          334 : void Endpoint::ReleaseCache()
     246              : {
     247          334 :     if (cacheKeepAlive_ == nullptr) {
     248          131 :         return;
     249              :     }
     250          203 :     cacheKeepAlive_->Release(cacheKey_);
     251          203 :     cacheKeepAlive_.reset();
     252              : }
     253              : 
     254           23 : void Endpoint::AttachMonitor(s32 logicId) { monitorKeepAlive_ = EndpointMonitor::GetHolder(logicId); }
     255              : 
     256           20 : HcclResult Endpoint::RegisterToEndpointMonitor(s32 logicId, EndpointHandle handle)
     257              : {
     258           20 :     CHK_PRT_RET(
     259              :         monitorKeepAlive_ == nullptr, HCCL_ERROR("[Endpoint][%s] monitor not attached", __func__), HCCL_E_INTERNAL);
     260           19 :     return monitorKeepAlive_->RegisterToEndpointMonitor(logicId, handle);
     261              : }
     262              : 
     263          389 : void Endpoint::ReleaseEndpointMonitor(EndpointHandle handle)
     264              : {
     265          389 :     if (monitorKeepAlive_ == nullptr) {
     266          366 :         return;
     267              :     }
     268           23 :     monitorKeepAlive_->RemoveEpHandleFromEndpointMonitor(handle);
     269           23 :     monitorKeepAlive_.reset();
     270              : }
     271              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1