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 "host_rdma_connection.h"
12 : #include "dtype_common.h"
13 : #include "exchange_rdma_conn_dto.h"
14 : #include "hccp.h"
15 :
16 : namespace hcomm {
17 : constexpr u32 WAIT_US_COUNT = 1000;
18 : constexpr uint32_t TC_TEMP = 132;
19 : constexpr uint32_t SL_TEMP = 4;
20 : constexpr uint32_t RETRY_CNT_TEMP = 7;
21 : constexpr uint32_t RETRY_TIME_TEMP = 20;
22 :
23 35 : HostRdmaConnection::HostRdmaConnection(Hccl::Socket* socket, RdmaHandle rdmaHandle)
24 35 : : socket_(socket),
25 35 : rdmaHandle_(rdmaHandle)
26 35 : {}
27 :
28 14 : HcclResult HostRdmaConnection::Init()
29 : {
30 14 : if (rdmaConnStatus_ != RdmaConnStatus::CLOSED) {
31 1 : HCCL_INFO(
32 : "[HostRdmaConnection][%s] status[%s] is not need init.", __func__, rdmaConnStatus_.Describe().c_str());
33 1 : return HCCL_SUCCESS;
34 : }
35 :
36 13 : int qpMode = 0;
37 : DevType devType;
38 13 : CHK_RET(hrtGetDeviceType(devType));
39 13 : if (devType == DevType::DEV_TYPE_950 || devType == DevType::DEV_TYPE_960) {
40 8 : qpMode = Hccl::OPBASE_QP_MODE;
41 5 : } else if (devType == DevType::DEV_TYPE_910B) {
42 0 : qpMode = Hccl::QP_FLAG_RC;
43 : } else {
44 5 : HCCL_ERROR(
45 : "Cannot support this device type!"
46 : "errNo[0x%016llx], device type[%d]",
47 : HCCL_ERROR_CODE(HcclResult::HCCL_E_NOT_SUPPORT), devType);
48 5 : return HCCL_E_NOT_SUPPORT;
49 : }
50 8 : qpInfo_.qpMode = qpMode;
51 8 : qpInfo_.rdmaHandle = rdmaHandle_;
52 8 : rdmaConnStatus_ = RdmaConnStatus::INIT;
53 8 : return HCCL_SUCCESS;
54 : }
55 :
56 39 : HostRdmaConnection::~HostRdmaConnection()
57 : {
58 35 : if (rdmaConnStatus_ == RdmaConnStatus::CLOSED || rdmaConnStatus_ == RdmaConnStatus::INIT) {
59 31 : return;
60 : }
61 4 : HcclResult ret = DestroyQp();
62 4 : if (ret != HCCL_SUCCESS) {
63 1 : HCCL_ERROR("[%s]call DestroyQp failed: hcclRet -> %d", __func__, ret);
64 : }
65 35 : }
66 :
67 0 : std::string HostRdmaConnection::Describe() const
68 : {
69 0 : return Hccl::StringFormat("HostRdmaConnection[status=%s]", rdmaConnStatus_.Describe().c_str());
70 : }
71 :
72 7 : HcclResult HostRdmaConnection::CreateQp()
73 : {
74 7 : if (socket_->GetStatus() != Hccl::SocketStatus::OK) {
75 1 : HCCL_WARNING("[HostRdmaConnection::CreateQp] socket status is not ok, please");
76 1 : return HCCL_E_AGAIN;
77 : }
78 :
79 : // 创建receive & send channel,用于poll cq,避免软件一直轮询cq
80 6 : HCCL_INFO("HostRdmaConnection CreateCompChannel");
81 6 : s32 ret = RaCreateCompChannel(qpInfo_.rdmaHandle, &sendCompChannel_);
82 6 : CHK_PRT_RET(
83 : ret != 0,
84 : HCCL_ERROR(
85 : "[HostRdmaConnection::CreateQp][CreateSendCompChannel]errNo[0x%016llx] RaCreateCompChannel fail. "
86 : "return[%d], params: rdmaHandle[%p], sendCompChannel[%p]",
87 : HCCL_ERROR_CODE(HCCL_E_NETWORK), ret, qpInfo_.rdmaHandle, &sendCompChannel_),
88 : HCCL_E_NETWORK);
89 6 : ret = RaCreateCompChannel(qpInfo_.rdmaHandle, &recvCompChannel_);
90 6 : CHK_PRT_RET(
91 : ret != 0,
92 : HCCL_ERROR(
93 : "[HostRdmaConnection::CreateQp][CreateReceiveCompChannel]errNo[0x%016llx] RaCreateCompChannel fail. "
94 : "return[%d], params: rdmaHandle[%p], rcvCompChannel[%p]",
95 : HCCL_ERROR_CODE(HCCL_E_NETWORK), ret, qpInfo_.rdmaHandle, &recvCompChannel_),
96 : HCCL_E_NETWORK);
97 :
98 : // 创建CQ和QP
99 : // qp创建时不指定srq/srq cq/srq context,由qp创建时创建独立的sq和rq,并创建对应的cq
100 : // cq for sq句柄保存在qpInfo_.sendCq中; cq for rq句柄保存在qpInfo_.receiveCq变量中
101 6 : HCCL_INFO("HostRdmaConnection CreateCqAndQp");
102 6 : CHK_RET(
103 : Hccl::HrtRaCreateQpWithCq(qpInfo_.rdmaHandle, -1, -1, sendCompChannel_, recvCompChannel_, qpInfo_, isHdcMode_));
104 :
105 5 : struct QosAttr qosAttr = {};
106 5 : qosAttr.tc = qpInfo_.trafficClass;
107 5 : qosAttr.sl = qpInfo_.serviceLevel;
108 5 : HCCL_INFO("[%s]Set qp qos success by config, TC[%u] SL[%u]", __func__, qosAttr.tc, qosAttr.sl);
109 5 : roceAttr_.tc = qpInfo_.trafficClass;
110 5 : roceAttr_.sl = qpInfo_.serviceLevel;
111 5 : roceAttr_.retryCnt = qpInfo_.retryCnt;
112 5 : roceAttr_.retryInterval = qpInfo_.retryInterval;
113 :
114 5 : ret = RaSetQpAttrQos(qpInfo_.qpHandle, &qosAttr);
115 5 : CHK_PRT_RET(
116 : ret != 0,
117 : HCCL_ERROR(
118 : "[HostRdmaConnection::CreateQp][SetQpAttrQos]errNo[0x%016llx] RaSetQpAttrQos fail. "
119 : "return[%d], params: qpHandle[%p], trafficClass[%u], serviceLevel[%u]",
120 : HCCL_ERROR_CODE(HCCL_E_NETWORK), ret, qpInfo_.qpHandle, qosAttr.tc, qosAttr.sl),
121 : HCCL_E_NETWORK);
122 4 : ret = RaSetQpAttrTimeout(qpInfo_.qpHandle, &(qpInfo_.retryInterval));
123 4 : CHK_PRT_RET(
124 : ret != 0,
125 : HCCL_ERROR(
126 : "[HostRdmaConnection::CreateQp][SetQpAttrTimeout]errNo[0x%016llx] RaSetQpAttrTimeout fail. "
127 : "return[%d], params: qpHandle[%p], retryInterval[%u]",
128 : HCCL_ERROR_CODE(HCCL_E_NETWORK), ret, qpInfo_.qpHandle, qpInfo_.retryInterval),
129 : HCCL_E_NETWORK);
130 3 : ret = RaSetQpAttrRetryCnt(qpInfo_.qpHandle, &(qpInfo_.retryCnt));
131 3 : CHK_PRT_RET(
132 : ret != 0,
133 : HCCL_ERROR(
134 : "[HostRdmaConnection::CreateQp][SetQpAttrRetryCnt]errNo[0x%016llx] RaSetQpAttrRetryCnt fail. "
135 : "return[%d], params: qpHandle[%p], retryCnt[%u]",
136 : HCCL_ERROR_CODE(HCCL_E_NETWORK), ret, qpInfo_.qpHandle, qpInfo_.retryCnt),
137 : HCCL_E_NETWORK);
138 2 : rdmaConnStatus_ = RdmaConnStatus::QP_CREATED;
139 2 : return HCCL_SUCCESS;
140 : }
141 :
142 5 : HcclResult HostRdmaConnection::DestroyQp()
143 : {
144 5 : if (rdmaConnStatus_ == RdmaConnStatus::CLOSED || rdmaConnStatus_ == RdmaConnStatus::INIT) {
145 0 : return HCCL_SUCCESS;
146 : }
147 :
148 5 : CHK_RET(Hccl::HrtRaDestroyQpWithCq(qpInfo_, isHdcMode_));
149 :
150 5 : s32 ret = RaDestroyCompChannel(qpInfo_.rdmaHandle, sendCompChannel_);
151 5 : CHK_PRT_RET(
152 : ret != 0,
153 : HCCL_ERROR(
154 : "[HostRdmaConnection::DestroyQp]errNo[0x%016llx] ra_destroy_comp_channel fail. "
155 : "return[%d], params: rdmaHandle[%p], sendCompChannel[%p]",
156 : HCCL_ERROR_CODE(HCCL_E_NETWORK), ret, qpInfo_.rdmaHandle, &sendCompChannel_),
157 : HCCL_E_NETWORK);
158 4 : ret = RaDestroyCompChannel(qpInfo_.rdmaHandle, recvCompChannel_);
159 4 : CHK_PRT_RET(
160 : ret != 0,
161 : HCCL_ERROR(
162 : "[HostRdmaConnection::DestroyQp]errNo[0x%016llx] ra_destroy_comp_channel fail. "
163 : "return[%d], params: rdmaHandle[%p], rcvCompChannel[%p]",
164 : HCCL_ERROR_CODE(HCCL_E_NETWORK), ret, qpInfo_.rdmaHandle, &recvCompChannel_),
165 : HCCL_E_NETWORK);
166 :
167 4 : qpInfo_ = Hccl::QpInfo();
168 4 : rdmaConnStatus_ = RdmaConnStatus::CLOSED;
169 4 : return HCCL_SUCCESS;
170 : }
171 :
172 2 : HcclResult HostRdmaConnection::GetExchangeDto(std::unique_ptr<Hccl::Serializable>& locQpAttrserial)
173 : {
174 2 : if (rdmaConnStatus_ != RdmaConnStatus::QP_CREATED && rdmaConnStatus_ != RdmaConnStatus::QP_MODIFIED) {
175 0 : HCCL_ERROR(
176 : "[HostRdmaConnection][%s] status[%s] is not expected.", __func__, rdmaConnStatus_.Describe().c_str());
177 0 : return HCCL_E_AGAIN;
178 : }
179 :
180 : struct QpAttr localQpAttr;
181 2 : s32 ret = RaGetQpAttr(qpInfo_.qpHandle, &localQpAttr);
182 2 : if (ret != 0) {
183 0 : HCCL_ERROR("[HostRdmaConnection::GetExchangeDto]RaGetQpAttr failed, ret(%d)", ret);
184 0 : return HCCL_E_ROCE_CONNECT;
185 : }
186 2 : std::unique_ptr<ExchangeRdmaConnDto> dto = nullptr;
187 2 : EXCEPTION_CATCH(
188 : dto = std::make_unique<ExchangeRdmaConnDto>(localQpAttr.qpn, localQpAttr.psn, localQpAttr.gidIdx),
189 : return HCCL_E_PTR);
190 2 : CHK_SAFETY_FUNC_RET(memcpy_s(dto->gid_, HCCP_GID_RAW_LEN, localQpAttr.gid, HCCP_GID_RAW_LEN));
191 2 : CHK_SAFETY_FUNC_RET(
192 : memcpy_s(dto->feature_, HYPER_FEATURE_LEN, &localQpAttr.feature, HYPER_FEATURE_LEN)); // feature扩展
193 2 : locQpAttrserial = std::unique_ptr<Hccl::Serializable>(std::move(dto));
194 2 : return HCCL_SUCCESS;
195 2 : }
196 :
197 1 : HcclResult HostRdmaConnection::ParseRmtExchangeDto(const Hccl::Serializable& rmtQpAttrSerial)
198 : {
199 1 : auto dto = dynamic_cast<const ExchangeRdmaConnDto&>(rmtQpAttrSerial);
200 1 : HCCL_INFO("[HostRdmaConnection][%s] remoteConnDto[%s]", __func__, dto.Describe().c_str());
201 1 : rmtQpAttr_.psn = dto.psn_;
202 1 : rmtQpAttr_.qpn = dto.qpn_;
203 1 : rmtQpAttr_.gid_idx = dto.gid_idx_;
204 1 : CHK_SAFETY_FUNC_RET(memcpy_s(rmtQpAttr_.gid, HCCP_GID_RAW_LEN, dto.gid_, HCCP_GID_RAW_LEN));
205 1 : CHK_SAFETY_FUNC_RET(
206 : memcpy_s(rmtQpAttr_.feature, HYPER_FEATURE_LEN, dto.feature_, HYPER_FEATURE_LEN)); // feature扩展
207 1 : return HCCL_SUCCESS;
208 1 : }
209 :
210 3 : HcclResult HostRdmaConnection::ModifyQp()
211 : {
212 3 : if (rdmaConnStatus_ == RdmaConnStatus::QP_MODIFIED) {
213 0 : HCCL_WARNING(
214 : "[HostRdmaConnection][%s] modify qp already, status[%s].", __func__, rdmaConnStatus_.Describe().c_str());
215 0 : return HCCL_SUCCESS;
216 : }
217 3 : if (rdmaConnStatus_ != RdmaConnStatus::QP_CREATED) {
218 0 : HCCL_ERROR(
219 : "[HostRdmaConnection][%s] status[%s] is not expected.", __func__, rdmaConnStatus_.Describe().c_str());
220 0 : return HCCL_E_AGAIN;
221 : }
222 :
223 3 : if (!rmtQpAttr_.IsValid()) {
224 0 : HCCL_ERROR("[HostRdmaConnection][%s] romate Qp Attr is empty, exchange qp attr first", __func__);
225 0 : return HCCL_E_INTERNAL;
226 : }
227 :
228 : struct QpAttr localQpAttr;
229 3 : s32 ret = RaGetQpAttr(qpInfo_.qpHandle, &localQpAttr);
230 3 : if (ret != 0) {
231 0 : return HCCL_E_ROCE_CONNECT;
232 : }
233 :
234 3 : HCCL_INFO(
235 : "[HostRdmaConnection::ModifyQp] HostRdmaConnection qpInfo_: serviceLevel[%d], trafficClass[%d], retryCnt[%d], "
236 : "retryInterval[%d]. "
237 : "roceAttr_: sl[%d], tc[%d], retryCnt[%d], retryInterval[%d]",
238 : qpInfo_.serviceLevel, qpInfo_.trafficClass, qpInfo_.retryCnt, qpInfo_.retryInterval, roceAttr_.sl, roceAttr_.tc,
239 : roceAttr_.retryCnt, roceAttr_.retryInterval);
240 3 : HCCL_DEBUG(
241 : "[HostRdmaConnection::ModifyQp] HostRdmaConnection localQp: qpn[%u], psn[%u], gidIdx[%u]", localQpAttr.qpn,
242 : localQpAttr.psn, localQpAttr.gidIdx);
243 3 : HCCL_DEBUG(
244 : "[HostRdmaConnection::ModifyQp] HostRdmaConnection remoteQp: qpn[%u], psn[%u], gidIdx[%u]", rmtQpAttr_.qpn,
245 : rmtQpAttr_.psn, rmtQpAttr_.gid_idx);
246 :
247 : struct TypicalQp localQp;
248 : struct TypicalQp rmtQp;
249 3 : localQp.sl = roceAttr_.sl;
250 3 : localQp.tc = roceAttr_.tc;
251 3 : localQp.retryCnt = roceAttr_.retryCnt;
252 3 : localQp.retryTime = roceAttr_.retryInterval;
253 3 : localQp.qpn = localQpAttr.qpn;
254 3 : localQp.psn = localQpAttr.psn;
255 3 : localQp.gidIdx = localQpAttr.gidIdx;
256 3 : localQp.udpSport = qpInfo_.udpSport;
257 3 : CHK_SAFETY_FUNC_RET(memcpy_s(localQp.gid, HCCP_GID_RAW_LEN, localQpAttr.gid, HCCP_GID_RAW_LEN));
258 3 : rmtQp.sl = qpInfo_.serviceLevel;
259 3 : rmtQp.tc = qpInfo_.trafficClass;
260 3 : rmtQp.retryCnt = qpInfo_.retryCnt;
261 3 : rmtQp.retryTime = qpInfo_.retryInterval;
262 3 : rmtQp.qpn = rmtQpAttr_.qpn;
263 3 : rmtQp.psn = rmtQpAttr_.psn;
264 3 : rmtQp.gidIdx = rmtQpAttr_.gid_idx;
265 3 : CHK_SAFETY_FUNC_RET(memcpy_s(rmtQp.gid, HCCP_GID_RAW_LEN, rmtQpAttr_.gid, HCCP_GID_RAW_LEN));
266 3 : CHK_SAFETY_FUNC_RET(memcpy_s(&rmtQp.feature, HYPER_FEATURE_LEN, rmtQpAttr_.feature, HYPER_FEATURE_LEN));
267 3 : ret = RaTypicalQpModify(qpInfo_.qpHandle, &localQp, &rmtQp);
268 3 : if (ret != 0) {
269 0 : HCCL_ERROR("[modify][ra_qp]modify qp failed, ret(%d)", ret);
270 0 : return HCCL_E_ROCE_CONNECT;
271 : }
272 : // 调整setlbvalue到RTS状态后
273 3 : if (qpInfo_.lbValue >= 0) {
274 2 : HCCL_DEBUG(
275 : "[HostRdmaConnection::ModifyQp] before RaSetQpLbValue, qp_num[%u], lbValue[%d], qpHandle[%p]",
276 : qpInfo_.qp->qp_num, qpInfo_.lbValue, qpInfo_.qpHandle);
277 2 : ret = RaSetQpLbValue(qpInfo_.qpHandle, qpInfo_.lbValue);
278 2 : CHK_PRT_RET(
279 : ret != 0,
280 : HCCL_ERROR(
281 : "[HostRdmaConnection::ModifyQp][SetQpLbValue]errNo[0x%016llx] RaSetQpLbValue fail. "
282 : "return[%d], params: qpHandle[%p], lbValue[%d]",
283 : HCCL_ERROR_CODE(HCCL_E_NETWORK), ret, qpInfo_.qpHandle, qpInfo_.lbValue),
284 : HCCL_E_NETWORK);
285 : }
286 2 : rdmaConnStatus_ = RdmaConnStatus::QP_MODIFIED;
287 2 : return HCCL_SUCCESS;
288 : }
289 :
290 : } // namespace hcomm
|