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 : #ifndef ENDPOINT_H
12 : #define ENDPOINT_H
13 :
14 : #include <memory>
15 : #include <mutex>
16 : #include <functional>
17 : #include <vector>
18 : #include <string>
19 : #include "reged_mem_mgr.h"
20 : #include "socket/socket.h"
21 : #include "socket_handle_manager.h"
22 : #include "rdma_handle_manager.h"
23 : #include "../../common/orion_adpt_utils.h"
24 : #include "hccp_hdc_manager.h"
25 : #include "hcomm_nic_plugin.h"
26 :
27 : namespace hcomm {
28 : /**
29 : * @note 职责:通信设备Endpoint的C++抽象接口类,管理通信设备上下文,以及设备上的注册内存。
30 : * 共享 Jetty 上下文也归属本类管理("同一 EndpointHandle 共享一个 Jetty"),
31 : * IS_SHARED_QUEUE=true 时,本 endpoint 下创建的 channel 复用 sharedJettyCtx_ 中的 jetty 句柄。
32 : */
33 : class Endpoint {
34 : public:
35 : /**
36 : * @brief 共享 Jetty 上下文:缓存的本地 jetty 句柄及其衍生字段,供同 endpoint 下多 channel 复用。
37 : */
38 : struct SharedJettyCtx {
39 : Hccl::JettyHandle handle{0};
40 : void* handlePtr{nullptr};
41 : uint32_t jettyId{0};
42 : uint64_t sqBuffVa{0};
43 : uint64_t dbAddr{0};
44 : uint8_t localQpKey[Hccl::HRT_UB_QP_KEY_MAX_LEN]{0};
45 : uint32_t keySize{0};
46 : uint32_t sqDepth{0};
47 : uint64_t tpHandle{0};
48 : uint32_t refCount{0};
49 : bool valid{false}; // 是否已填充有效 jetty
50 : bool creating{false}; // 是否正在首次创建中(用于并发等待)
51 : // 共享 SQ/CQ 的 PI/CI 索引内存(device 侧),同 endpoint 下多 channel 共用,
52 : // 避免各 channel 各自分配 PI/CI 指向同一 SQ 导致生产者索引无法协调前进。
53 : void* sqPiPtr{nullptr};
54 : void* sqCiPtr{nullptr};
55 : void* cqPiPtr{nullptr};
56 : void* cqCiPtr{nullptr};
57 : uint64_t queueIndexMemSize{0}; // 单段 PI/CI 内存字节数
58 : // 临时 connection 创建的 JFC 及其关联的 RDMA 句柄,由 Endpoint 在销毁共享 jetty 时统一销毁。
59 : // 临时 connection 走 TransferJettyOwnership 路径(releaseCb_ 为空),ReleaseResource 不销毁 JFC,
60 : // 需由 Endpoint 接管 ownership 防止设备资源泄漏。
61 : void* rdmaHandle{nullptr};
62 : uint64_t jfcHandle{0};
63 : };
64 :
65 : explicit Endpoint(const EndpointDesc& endpointDesc);
66 :
67 : virtual ~Endpoint();
68 :
69 : static HcclResult CreateEndpoint(const EndpointDesc& endpointDesc, std::unique_ptr<Endpoint>& endpointPtr);
70 :
71 : virtual HcclResult Init() = 0;
72 :
73 : virtual HcclResult ServerSocketListen(const uint32_t port) = 0;
74 :
75 0 : virtual HcclResult ServerSocketStopListen([[maybe_unused]] const uint32_t port) { return HCCL_E_NOT_SUPPORT; };
76 1 : virtual HcclResult ServerSocketGetListenPort([[maybe_unused]] uint32_t* port) { return HCCL_E_NOT_SUPPORT; };
77 :
78 43 : virtual std::shared_ptr<RegedMemMgr> GetRegedMemMgr() { return regedMemMgr_; }
79 :
80 140 : void* GetRdmaHandle() { return ctxHandle_; }
81 :
82 7 : bool IsCtxHandleValid() const
83 : {
84 7 : if (ctxHandle_ == nullptr) {
85 2 : return false;
86 : }
87 5 : return Hccl::RdmaHandleManager::GetInstance().IsHandleValid(static_cast<Hccl::RdmaHandle>(ctxHandle_));
88 : }
89 :
90 315 : EndpointDesc GetEndpointDesc() { return endpointDesc_; }
91 :
92 : // 注册内存
93 : virtual HcclResult RegisterMemory(HcommMem mem, const char* memTag, void** memHandle) = 0;
94 :
95 : // 注销内存
96 : virtual HcclResult UnregisterMemory(void* memHandle) = 0;
97 :
98 : // 导出指定内存描述,用于交换
99 : virtual HcclResult MemoryExport(void* memHandle, void** memDesc, uint32_t* memDescLen) = 0;
100 :
101 : // 基于内存描述,导入获得内存
102 : virtual HcclResult MemoryImport(const void* memDesc, uint32_t descLen, HcommMem* outMem) = 0;
103 :
104 : // 关闭内存
105 : virtual HcclResult MemoryUnimport(const void* memDesc, uint32_t descLen) = 0;
106 :
107 : virtual HcclResult GetAllMemHandles(void** memHandles, uint32_t* memHandleNum) = 0;
108 :
109 0 : virtual HcclResult MemoryGrant([[maybe_unused]] const HcommMemGrantInfo* remoteGrantInfo) { return HCCL_SUCCESS; }
110 :
111 : static HcclResult CheckFeature(const EndpointDesc& endpointDesc, HcommEndpointFeatureType featureType, bool& value);
112 :
113 : // 获取UB异步事件
114 0 : virtual HcclResult GetAsyncEvents(uint32_t devPhyId, struct AsyncEvent events[], uint32_t& num)
115 : {
116 : (void)devPhyId;
117 : (void)events;
118 0 : num = 0;
119 0 : return HCCL_SUCCESS;
120 : }
121 :
122 : // ---- 共享 Jetty 管理(仅 IS_SHARED_QUEUE=true 时使用)----
123 : /**
124 : * @brief 获取或创建共享 jetty。命中复用 refCount++;未命中调 provideCtx 创建并缓存。
125 : * @param[in] provideCtx 创建回调(首次时调用,回调内创建 jetty 并填入 ctx)
126 : * @param[out] outCtx 输出的 jetty 上下文
127 : */
128 : HcclResult AcquireSharedJetty(const std::function<HcclResult(SharedJettyCtx&)>& provideCtx, SharedJettyCtx& outCtx);
129 : /** 释放共享 jetty 引用,refCount-- 归 0 时销毁 jetty 并清空 ctx */
130 : HcclResult ReleaseSharedJetty();
131 : // ------------------ NIC插件相关 ------------------
132 94 : void SetNicEndpointCtx(HcommNicEndpointOps* nicOps, void* nicCtx)
133 : {
134 94 : nicOps_ = nicOps;
135 94 : nicCtx_ = nicCtx;
136 94 : }
137 274 : HcommNicEndpointOps* GetNicOps() const { return nicOps_; }
138 130 : void* GetNicCtx() const { return nicCtx_; }
139 :
140 : protected:
141 : static HcclResult CreateEndpointBase(const EndpointDesc& endpointDesc, std::unique_ptr<Endpoint>& endpointPtr);
142 : void DestroySharedJettyRaResources(SharedJettyCtx& ctx, Hccl::RdmaHandle rdmaHandle, bool ctxValid) const;
143 : void FreeSharedJettyPtrs(SharedJettyCtx& ctx) const;
144 : void* ctxHandle_{nullptr};
145 : std::shared_ptr<RegedMemMgr> regedMemMgr_{};
146 : EndpointDesc endpointDesc_;
147 :
148 : // 共享 jetty 上下文及保护锁,仅 IS_SHARED_QUEUE=true 时使用
149 : mutable std::mutex sharedJettyMtx_;
150 : SharedJettyCtx sharedJettyCtx_{};
151 : HcommNicEndpointOps* nicOps_{nullptr};
152 : void* nicCtx_{nullptr};
153 : };
154 :
155 : } // namespace hcomm
156 : #endif // ENDPOINT_H
|