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 <stdlib.h>
12 : #include <string.h>
13 : #include <dlfcn.h>
14 : #include "securec.h"
15 : #include "dl_hal_function.h"
16 : #include "hccp.h"
17 : #include "hccp_common.h"
18 : #include "ra.h"
19 : #include "ra_rs_comm.h"
20 : #include "ra_rs_err.h"
21 : #include "ra_hdc.h"
22 : #include "ra_peer.h"
23 : #include "ra_hdc_async.h"
24 : #include "ra_init.h"
25 :
26 : static unsigned int gSendWrNum = 0;
27 : static void *gRaRdevHandle[RA_MAX_PHY_ID_NUM] = {0};
28 : static RaInstance gRefInstances[RA_MAX_INSTANCES] = {{0, PTHREAD_MUTEX_INITIALIZER}};
29 :
30 6 : HCCP_ATTRI_VISI_DEF int RaIsFirstUsed(int insId)
31 : {
32 6 : int isFirst = 0;
33 :
34 6 : CHK_PRT_RETURN(insId < 0 || insId >= RA_MAX_INSTANCES,
35 : hccp_err("[ra]ins_id(%d) must be in [0, %u)", insId, RA_MAX_INSTANCES), -EINVAL);
36 :
37 4 : pthread_mutex_lock(&gRefInstances[insId].mutex);
38 4 : if (gRefInstances[insId].refCount == 0) {
39 2 : isFirst++;
40 2 : hccp_run_info("[ra]ins_id(%d) is first used", insId);
41 : }
42 :
43 4 : gRefInstances[insId].refCount++;
44 4 : hccp_info("[ra]ins_id[%d] is %d", insId, gRefInstances[insId].refCount);
45 4 : pthread_mutex_unlock(&gRefInstances[insId].mutex);
46 :
47 4 : return isFirst;
48 : }
49 :
50 7 : HCCP_ATTRI_VISI_DEF int RaIsLastUsed(int insId)
51 : {
52 7 : int isLast = 0;
53 :
54 7 : CHK_PRT_RETURN(insId < 0 || insId >= RA_MAX_INSTANCES,
55 : hccp_err("[ra]ins_id(%d) must be in [0, %u)", insId, RA_MAX_INSTANCES), -EINVAL);
56 :
57 5 : pthread_mutex_lock(&gRefInstances[insId].mutex);
58 5 : if (gRefInstances[insId].refCount == 0) {
59 1 : hccp_err("[ra]ins_id %d has not been used", insId);
60 1 : pthread_mutex_unlock(&gRefInstances[insId].mutex);
61 1 : return -EINVAL;
62 : }
63 :
64 4 : if (gRefInstances[insId].refCount == 1) {
65 2 : isLast++;
66 2 : hccp_run_info("[ra]ins_id(%d) is last used", insId);
67 : }
68 :
69 4 : hccp_info("[ra]ins_id[%d] is %d", insId, gRefInstances[insId].refCount);
70 4 : gRefInstances[insId].refCount--;
71 4 : pthread_mutex_unlock(&gRefInstances[insId].mutex);
72 :
73 4 : return isLast;
74 : }
75 :
76 5 : HCCP_ATTRI_VISI_DEF int RaRdevGetHandle(unsigned int phyId, void **rdmaHandle)
77 : {
78 5 : CHK_PRT_RETURN(phyId >= RA_MAX_PHY_ID_NUM,
79 : hccp_err("[get][ra_rdev]phyId(%u) must smaller than %u", phyId, RA_MAX_PHY_ID_NUM), -EINVAL);
80 4 : CHK_PRT_RETURN(rdmaHandle == NULL, hccp_err("[get][ra_rdev]rdma_handle is NULL, phyId(%u)", phyId), -EINVAL);
81 3 : CHK_PRT_RETURN(gRaRdevHandle[phyId] == NULL, hccp_run_info("[get][ra_rdev]handle is NULL, phyId(%u)", phyId),
82 : -ENODEV);
83 :
84 2 : *rdmaHandle = gRaRdevHandle[phyId];
85 2 : return 0;
86 : }
87 :
88 4 : void RaRdevSetHandle(unsigned int phyId, void *rdmaHandle)
89 : {
90 4 : if (phyId >= RA_MAX_PHY_ID_NUM) {
91 0 : hccp_warn("[set][ra_rdev]phyId(%u) must smaller than %u", phyId, RA_MAX_PHY_ID_NUM);
92 0 : return;
93 : }
94 :
95 4 : gRaRdevHandle[phyId] = rdmaHandle;
96 : }
97 :
98 2 : void RaRdevIncSendWrNum(void)
99 : {
100 2 : gSendWrNum++;
101 2 : }
102 :
103 4 : STATIC int RaInitHdc(struct RaInitConfig *config)
104 : {
105 4 : struct ProcessRaSign pRaSign = {0};
106 4 : unsigned int phyId = config->phyId;
107 4 : struct process_sign psign = {0};
108 : int ret;
109 :
110 4 : ret = DlDrvGetProcessSign(&psign);
111 4 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]Get process sign failed, ret(%d) phyId(%u)", ret, phyId), ret);
112 :
113 3 : pRaSign.tgid = psign.tgid;
114 3 : ret = strcpy_s(pRaSign.sign, PROCESS_RA_SIGN_LENGTH, psign.sign);
115 3 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]Invalid pid sign, ret(%d) phyId(%u)", ret, phyId), -ESAFEFUNC);
116 :
117 2 : ret = RaHdcInit(config, pRaSign);
118 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]ra hdc init failed, ret(%d) phyId(%u)", ret, phyId), ret);
119 :
120 1 : RaHdcGetAllOpcodeVersion(phyId);
121 :
122 : // init async hdc session via sync hdc session
123 1 : ret = RaHdcInitAsync(config);
124 1 : if (ret != 0) {
125 0 : hccp_err("[init][ra]ra_hdc_init_async failed, ret(%d) phyId(%u)", ret, phyId);
126 0 : (void)RaHdcDeinit(config);
127 : }
128 :
129 1 : return ret;
130 : }
131 :
132 1 : STATIC int RaInitPeer(struct RaInitConfig *config)
133 : {
134 1 : unsigned int phyId = config->phyId;
135 1 : unsigned int whiteListSwitch = 0;
136 : int ret;
137 :
138 1 : ret = RaSocketGetWhiteListStatus(&whiteListSwitch);
139 1 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]get white_list_status failed, ret(%d) phyId(%u)", ret, phyId), ret);
140 :
141 1 : ret = RaPeerInit(config, whiteListSwitch);
142 1 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]ra_peer_init failed, ret(%d) phyId(%u)", ret, phyId), ret);
143 :
144 1 : return 0;
145 : }
146 :
147 8 : HCCP_ATTRI_VISI_DEF int RaInit(struct RaInitConfig *config)
148 : {
149 : unsigned int phyId;
150 : int ret;
151 :
152 8 : CHK_PRT_RETURN(config == NULL, hccp_err("[init][ra]config is NULL"), ConverReturnCode(HCCP_INIT, -EINVAL));
153 :
154 7 : phyId = config->phyId;
155 7 : CHK_PRT_RETURN(phyId >= RA_MAX_PHY_ID_NUM,
156 : hccp_err("[init][ra]phyId(%u) is invalid! it must greater or "
157 : "equal to 0 and less than %d!",
158 : phyId, RA_MAX_PHY_ID_NUM),
159 : ConverReturnCode(HCCP_INIT, -EINVAL));
160 :
161 6 : if (config->hdcType != HDC_SERVICE_TYPE_RDMA && config->hdcType != HDC_SERVICE_TYPE_RDMA_V2) {
162 1 : hccp_warn("[init][ra]hdc_type(%d) is invalid, set it to default hdcType(%d)", config->hdcType,
163 : HDC_SERVICE_TYPE_RDMA);
164 1 : config->hdcType = HDC_SERVICE_TYPE_RDMA;
165 : }
166 :
167 6 : hccp_run_info("Input parameters: phyId[%u], nicPosition:[%u] hdcType:[%d] enableHdcAsync[%d]", phyId,
168 : config->nicPosition, config->hdcType, config->enableHdcAsync);
169 6 : ret = DlHalInit();
170 6 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]dl_hal_init failed, ret(%d) phyId(%u)", ret, phyId), ret);
171 :
172 6 : if (config->nicPosition == NETWORK_OFFLINE) {
173 4 : ret = RaInitHdc(config);
174 4 : if (ret != 0) {
175 3 : hccp_err("[init][ra]ra_init_hdc failed, ret(%d) phyId(%u)", ret, phyId);
176 3 : goto err;
177 : }
178 2 : } else if (config->nicPosition == NETWORK_PEER_ONLINE) {
179 1 : ret = RaInitPeer(config);
180 1 : if (ret != 0) {
181 0 : hccp_err("[init][ra]ra_init_peer failed, ret(%d) phyId(%u)", ret, phyId);
182 0 : goto err;
183 : }
184 : } else {
185 1 : hccp_err("[init][ra]do not support nic_position(%u) phyId(%u)", config->nicPosition, phyId);
186 1 : ret = -EPROTONOSUPPORT;
187 1 : goto err;
188 : }
189 :
190 2 : return 0;
191 :
192 4 : err:
193 4 : DlHalDeinit();
194 4 : return ConverReturnCode(HCCP_INIT, ret);
195 : }
196 :
197 2 : STATIC int RaDeinitHdc(struct RaInitConfig *config)
198 : {
199 : int ret;
200 :
201 2 : ret = RaHdcDeinitAsync(config->phyId);
202 2 : CHK_PRT_RETURN(ret != 0 && ret != -ENODEV, hccp_err("[deinit][ra]ra_hdc_deinit_async failed, ret(%d)", ret), ret);
203 :
204 2 : ret = RaHdcDeinit(config);
205 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra]ra hdc deinit failed, ret(%d), gSendWrNum(%u)", ret, gSendWrNum),
206 : ret);
207 1 : return ret;
208 : }
209 :
210 6 : HCCP_ATTRI_VISI_DEF int RaDeinit(struct RaInitConfig *config)
211 : {
212 : unsigned int phyId;
213 : int ret;
214 :
215 6 : CHK_PRT_RETURN(config == NULL, hccp_err("[deinit][ra]config is NULL, invalid"),
216 : ConverReturnCode(HCCP_INIT, -EINVAL));
217 :
218 5 : phyId = config->phyId;
219 5 : CHK_PRT_RETURN(phyId >= RA_MAX_PHY_ID_NUM,
220 : hccp_err("[deinit][ra]phyId(%u) is invalid! it must greater or equal to 0 and less than %d!", phyId,
221 : RA_MAX_PHY_ID_NUM),
222 : ConverReturnCode(HCCP_INIT, -EINVAL));
223 :
224 4 : hccp_run_info("Input parameters: phyId[%u], nicPosition:[%u]", phyId, config->nicPosition);
225 :
226 4 : if (config->nicPosition == NETWORK_OFFLINE) {
227 2 : ret = RaDeinitHdc(config);
228 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra]ra_deinit_hdc failed, ret(%d) phyId(%u)", ret, phyId),
229 : ConverReturnCode(HCCP_INIT, ret));
230 2 : } else if (config->nicPosition == NETWORK_PEER_ONLINE) {
231 1 : ret = RaPeerDeinit(config);
232 1 : CHK_PRT_RETURN(ret == -EAGAIN,
233 : hccp_warn("[deinit][ra]ra_peer_deinit unsuccessful, ret(%d) phyId(%u)", ret, phyId),
234 : ConverReturnCode(HCCP_INIT, ret));
235 1 : CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra]ra_peer_deinit failed, ret(%d) phyId(%u)", ret, phyId),
236 : ConverReturnCode(HCCP_INIT, ret));
237 : } else {
238 1 : hccp_err("[deinit][ra]do not support nic_position(%u) phyId(%u)", config->nicPosition, phyId);
239 1 : return ConverReturnCode(HCCP_INIT, -EPROTONOSUPPORT);
240 : }
241 :
242 2 : RaSocketSetWhiteListStatus(WHITE_LIST_DISABLE);
243 2 : gSendWrNum = 0;
244 2 : DlHalDeinit();
245 2 : return 0;
246 : }
247 :
248 1 : STATIC void __attribute__((destructor)) RaUninitAsync(void)
249 : {
250 1 : RaHdcDeinitAsyncAll();
251 1 : }
|