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 "ccu_jetty_.h"
12 :
13 : #include "hcom_common.h"
14 :
15 : #include "hccp_ctx.h"
16 :
17 : #include "exception_handler.h"
18 :
19 : // 当前复用orion数据结构
20 : #include "rdma_handle_manager.h"
21 : #include "local_ub_rma_buffer.h"
22 : #include "orion_adapter_hccp.h"
23 :
24 : namespace hcomm {
25 :
26 : HcclResult
27 15 : CcuCreateJetty(const Hccl::IpAddress& ipAddr, const CcuJettyInfo& jettyInfo, std::unique_ptr<CcuJetty>& ccuJetty)
28 : {
29 : EXCEPTION_HANDLE_BEGIN
30 :
31 15 : ccuJetty = std::make_unique<CcuJetty>(ipAddr, jettyInfo);
32 15 : CHK_RET(ccuJetty->Init());
33 :
34 0 : EXCEPTION_HANDLE_END
35 15 : return HcclResult::HCCL_SUCCESS;
36 : }
37 :
38 33 : CcuJetty::CcuJetty(const Hccl::IpAddress& ipAddr, const CcuJettyInfo& jettyInfo)
39 33 : : ipAddr_(ipAddr),
40 33 : jettyInfo_(jettyInfo)
41 33 : {}
42 :
43 17 : HcclResult CcuJetty::Init()
44 : {
45 : EXCEPTION_HANDLE_BEGIN
46 17 : devLogicId_ = HcclGetThreadDeviceId();
47 17 : uint32_t devPhyId{0};
48 17 : Hccl::CqCreateInfo cqInfo{};
49 17 : CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<uint32_t>(devLogicId_), devPhyId));
50 17 : auto& rdmaHandleMgr = Hccl::RdmaHandleManager::GetInstance();
51 17 : ctxHandle_ = rdmaHandleMgr.GetByIp(devPhyId, ipAddr_);
52 17 : CHK_PRT_RET(
53 : !rdmaHandleMgr.IsHandleValid(ctxHandle_),
54 : HCCL_ERROR(
55 : "[CcuJetty][%s] ctxHandle_[%p] is not valid, "
56 : "RdmaHandleManager may have DeInit this device",
57 : __func__, ctxHandle_),
58 : HcclResult::HCCL_E_INTERNAL);
59 17 : const auto _jfcHandle = rdmaHandleMgr.GetJfcHandle(ctxHandle_, cqInfo, Hccl::HrtUbJfcMode::CCU_POLL);
60 17 : const JfcHandle jfcHandle = reinterpret_cast<JfcHandle>(_jfcHandle);
61 17 : const auto tokenValue = Hccl::GetUbToken();
62 17 : const auto jettyMode = jettyInfo_.jettyType == CcuJettyType::CCUM_CACHED_JETTY ? HrtJettyMode::CCU_CCUM_CACHE :
63 17 : HrtJettyMode::CCU_TA_CACHE;
64 :
65 17 : inParam_ = HrtRaUbCreateJettyParam{
66 : jfcHandle,
67 : jfcHandle,
68 : tokenValue,
69 : 0,
70 : jettyMode,
71 17 : jettyInfo_.taJettyId,
72 17 : jettyInfo_.sqBufVa,
73 : jettyInfo_.sqBufSize,
74 : jettyInfo_.wqeBBStartId,
75 17 : jettyInfo_.sqDepth}; // CTP默认为8s
76 0 : EXCEPTION_HANDLE_END
77 :
78 17 : return HcclResult::HCCL_SUCCESS;
79 : }
80 :
81 7 : HcclResult CcuJetty::SetMappedJettyPriority(uint32_t priority)
82 : {
83 7 : const uint8_t mapped = static_cast<uint8_t>(priority & 0xFU);
84 :
85 7 : if (mappedJettyPrioritySet_ && mappedJettyPriority_ != mapped) {
86 1 : HCCL_ERROR(
87 : "[CcuJetty][%s] mappedJettyPriority conflict on shared jetty: existing[%u] new[%u] "
88 : "jettyId[%u] isCreated[%d].",
89 : __func__, static_cast<unsigned>(mappedJettyPriority_), static_cast<unsigned>(mapped), jettyInfo_.taJettyId,
90 : static_cast<int>(isCreated_));
91 1 : return HcclResult::HCCL_E_INTERNAL;
92 : }
93 :
94 : // 多 channel 复用:jetty 已 create,qos 已写入 URMA,不可再改 inParam_
95 6 : if (isCreated_) {
96 0 : HCCL_INFO(
97 : "[CcuJetty][%s] jetty[%u] already created, skip mappedJettyPriority[%u].", __func__, jettyInfo_.taJettyId,
98 : static_cast<unsigned>(mapped));
99 0 : return HcclResult::HCCL_SUCCESS;
100 : }
101 :
102 6 : if (mappedJettyPrioritySet_) {
103 0 : return HcclResult::HCCL_SUCCESS;
104 : }
105 :
106 6 : mappedJettyPriority_ = mapped;
107 6 : mappedJettyPrioritySet_ = true;
108 6 : inParam_.qos = mapped;
109 6 : return HcclResult::HCCL_SUCCESS;
110 : }
111 :
112 33 : CcuJetty::~CcuJetty() { (void)Clean(); }
113 :
114 0 : static HcclResult CheckRequestResult(RequestHandle& reqHandle)
115 : {
116 0 : if (reqHandle == 0) {
117 0 : return HcclResult::HCCL_SUCCESS;
118 : }
119 :
120 0 : RequestResult result = HccpGetAsyncReqResult(reqHandle);
121 0 : if (result == RequestResult::NOT_COMPLETED) {
122 0 : return HcclResult::HCCL_E_AGAIN;
123 : }
124 :
125 0 : if (result != RequestResult::COMPLETED) {
126 0 : HCCL_ERROR("[TpMgr][%s] failed, result[%s] is unexpected.", __func__, result.Describe().c_str());
127 0 : return HcclResult::HCCL_E_NETWORK;
128 : }
129 :
130 0 : return HcclResult::HCCL_SUCCESS;
131 : }
132 :
133 0 : static HcclResult ParseCreateInfo(
134 : const struct QpCreateInfo* infoPtr, const JettyHandle jettyHandle, HrtRaUbJettyCreatedOutParam& outParam)
135 : {
136 0 : outParam.handle = jettyHandle;
137 0 : auto ret = memcpy_s(outParam.key, HRT_UB_QP_KEY_MAX_LEN, infoPtr->key.value, infoPtr->key.size);
138 0 : if (ret != 0) {
139 0 : HCCL_ERROR("[CcuJetty][%s] create info key memcpy_s failed, ret[%d].", __func__, ret);
140 0 : return HcclResult::HCCL_E_MEMORY;
141 : }
142 :
143 0 : constexpr uint32_t URMA_TOKEN_ID_RIGHT_SHIFT = 8;
144 :
145 0 : outParam.jettyVa = infoPtr->va;
146 0 : outParam.uasid = infoPtr->ub.uasid;
147 0 : outParam.id = infoPtr->ub.id;
148 0 : outParam.keySize = infoPtr->key.size;
149 0 : outParam.dbVa = infoPtr->ub.dbAddr;
150 0 : outParam.dbTokenId = infoPtr->ub.dbTokenId >> URMA_TOKEN_ID_RIGHT_SHIFT;
151 : // 不提供 tokenValue,不得打印token相关信息
152 0 : return HcclResult::HCCL_SUCCESS;
153 : }
154 :
155 0 : HcclResult CcuJetty::HandleAsyncRequest()
156 : {
157 0 : if (reqHandle_ == 0) {
158 0 : CHK_RET(HccpUbCreateJettyAsync(ctxHandle_, inParam_, reqDataBuffer_, jettyHandlePtr_, reqHandle_));
159 0 : return HcclResult::HCCL_E_AGAIN; // 首次触发异步接口调用,动作一定未完成
160 : }
161 :
162 0 : auto ret = CheckRequestResult(reqHandle_);
163 0 : if (ret == HcclResult::HCCL_E_AGAIN) {
164 0 : return ret;
165 : }
166 0 : CHK_RET(ret);
167 :
168 0 : const struct QpCreateInfo* info = reinterpret_cast<const QpCreateInfo*>(reqDataBuffer_.data());
169 0 : const JettyHandle jettyHandle = reinterpret_cast<JettyHandle>(jettyHandlePtr_);
170 0 : return ParseCreateInfo(info, jettyHandle, outParam_);
171 : }
172 :
173 0 : HcclResult CcuJetty::CreateJetty(u8 errTimeout)
174 : {
175 0 : if (isError_) {
176 0 : HCCL_ERROR(
177 : "[CcuJetty][%s] failed, jetty[%u] is error, "
178 : "refused to create.",
179 : __func__, inParam_.jettyId);
180 0 : return HcclResult::HCCL_E_INTERNAL;
181 : }
182 :
183 0 : if (isCreated_) {
184 0 : HCCL_INFO("[CcuJetty][%s] passed, jetty[%u] has been created.", __func__, inParam_.jettyId);
185 0 : return HcclResult::HCCL_SUCCESS;
186 : }
187 :
188 0 : inParam_.errTimeout = errTimeout;
189 0 : auto ret = HandleAsyncRequest();
190 0 : if (ret == HcclResult::HCCL_SUCCESS) {
191 0 : isCreated_ = true;
192 0 : } else if (ret != HcclResult::HCCL_E_AGAIN) {
193 0 : isError_ = true;
194 : }
195 :
196 0 : return ret;
197 : }
198 :
199 2 : HrtRaUbCreateJettyParam CcuJetty::GetCreateJettyParam() const { return inParam_; }
200 :
201 4 : HrtRaUbJettyCreatedOutParam CcuJetty::GetJettyedOutParam() const { return outParam_; }
202 :
203 33 : HcclResult CcuJetty::Clean()
204 : {
205 33 : if (isCreated_ && outParam_.handle != 0) {
206 0 : auto jettyHandle = outParam_.handle;
207 0 : outParam_ = {}; // 移动handle并置空,防止二次释放
208 0 : isCreated_ = false;
209 0 : reqHandle_ = 0;
210 0 : jettyHandlePtr_ = nullptr;
211 0 : reqDataBuffer_.clear();
212 :
213 0 : auto ret = RaCtxQpDestroy(jettyHandle);
214 0 : if (ret != 0) {
215 0 : HCCL_ERROR("[CcuJetty][%s] failed, jettyHanlde[0x%llx].", __func__, jettyHandle);
216 0 : return HcclResult::HCCL_E_NETWORK;
217 : }
218 : }
219 33 : isError_ = false;
220 33 : return HcclResult::HCCL_SUCCESS;
221 : }
222 : } // namespace hcomm
|