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