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