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