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, hccp_err("[ra]ins_id(%d) must be in [0, %u)",
35 : 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, hccp_err("[ra]ins_id(%d) must be in [0, %u)",
55 : 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, hccp_err("[get][ra_rdev]phyId(%u) must smaller than %u",
79 : 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)",
81 : phyId), -EINVAL);
82 3 : CHK_PRT_RETURN(gRaRdevHandle[phyId] == NULL, hccp_run_info("[get][ra_rdev]handle is NULL, phyId(%u)", phyId),
83 : -ENODEV);
84 :
85 2 : *rdmaHandle = gRaRdevHandle[phyId];
86 2 : return 0;
87 : }
88 :
89 4 : void RaRdevSetHandle(unsigned int phyId, void *rdmaHandle)
90 : {
91 4 : if (phyId >= RA_MAX_PHY_ID_NUM) {
92 0 : hccp_warn("[set][ra_rdev]phyId(%u) must smaller than %u", phyId, RA_MAX_PHY_ID_NUM);
93 0 : return;
94 : }
95 :
96 4 : gRaRdevHandle[phyId] = rdmaHandle;
97 : }
98 :
99 2 : void RaRdevIncSendWrNum(void)
100 : {
101 2 : gSendWrNum++;
102 2 : }
103 :
104 4 : STATIC int RaInitHdc(struct RaInitConfig *config)
105 : {
106 4 : struct ProcessRaSign pRaSign = {0};
107 4 : unsigned int phyId = config->phyId;
108 4 : struct process_sign psign = {0};
109 : int ret;
110 :
111 4 : ret = DlDrvGetProcessSign(&psign);
112 4 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]Get process sign failed, ret(%d) phyId(%u)", ret, phyId), ret);
113 :
114 3 : pRaSign.tgid = psign.tgid;
115 3 : ret = strcpy_s(pRaSign.sign, PROCESS_RA_SIGN_LENGTH, psign.sign);
116 3 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]Invalid pid sign, ret(%d) phyId(%u)", ret, phyId), -ESAFEFUNC);
117 :
118 2 : ret = RaHdcInit(config, pRaSign);
119 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]ra hdc init failed, ret(%d) phyId(%u)", ret, phyId), ret);
120 :
121 1 : RaHdcGetAllOpcodeVersion(phyId);
122 :
123 : // init async hdc session via sync hdc session
124 1 : ret = RaHdcInitAsync(config);
125 1 : if (ret != 0) {
126 0 : hccp_err("[init][ra]ra_hdc_init_async failed, ret(%d) phyId(%u)", ret, phyId);
127 0 : (void)RaHdcDeinit(config);
128 : }
129 :
130 1 : return ret;
131 : }
132 :
133 1 : STATIC int RaInitPeer(struct RaInitConfig *config)
134 : {
135 1 : unsigned int phyId = config->phyId;
136 1 : unsigned int whiteListSwitch = 0;
137 : int ret;
138 :
139 1 : ret = RaSocketGetWhiteListStatus(&whiteListSwitch);
140 1 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]get white_list_status failed, ret(%d) phyId(%u)", ret, phyId), ret);
141 :
142 1 : ret = RaPeerInit(config, whiteListSwitch);
143 1 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]ra_peer_init failed, ret(%d) phyId(%u)", ret, phyId), ret);
144 :
145 1 : return 0;
146 : }
147 :
148 8 : HCCP_ATTRI_VISI_DEF int RaInit(struct RaInitConfig *config)
149 : {
150 : unsigned int phyId;
151 : int ret;
152 :
153 8 : CHK_PRT_RETURN(config == NULL, hccp_err("[init][ra]config is NULL"), ConverReturnCode(HCCP_INIT, -EINVAL));
154 :
155 7 : phyId = config->phyId;
156 7 : CHK_PRT_RETURN(phyId >= RA_MAX_PHY_ID_NUM, hccp_err("[init][ra]phyId(%u) is invalid! it must greater or "
157 : "equal to 0 and less than %d!", phyId, RA_MAX_PHY_ID_NUM), ConverReturnCode(HCCP_INIT, -EINVAL));
158 :
159 6 : if (config->hdcType != HDC_SERVICE_TYPE_RDMA && config->hdcType != HDC_SERVICE_TYPE_RDMA_V2) {
160 1 : hccp_warn("[init][ra]hdc_type(%d) is invalid, set it to default hdcType(%d)",
161 : config->hdcType, HDC_SERVICE_TYPE_RDMA);
162 1 : config->hdcType = HDC_SERVICE_TYPE_RDMA;
163 : }
164 :
165 6 : hccp_run_info("Input parameters: phyId[%u], nicPosition:[%u] hdcType:[%d] enableHdcAsync[%d]",
166 : phyId, config->nicPosition, config->hdcType, config->enableHdcAsync);
167 6 : ret = DlHalInit();
168 6 : CHK_PRT_RETURN(ret != 0, hccp_err("[init][ra]dl_hal_init failed, ret(%d) phyId(%u)", ret, phyId), ret);
169 :
170 6 : if (config->nicPosition == NETWORK_OFFLINE) {
171 4 : ret = RaInitHdc(config);
172 4 : if (ret != 0) {
173 3 : hccp_err("[init][ra]ra_init_hdc failed, ret(%d) phyId(%u)", ret, phyId);
174 3 : goto err;
175 : }
176 2 : } else if (config->nicPosition == NETWORK_PEER_ONLINE) {
177 1 : ret = RaInitPeer(config);
178 1 : if (ret != 0) {
179 0 : hccp_err("[init][ra]ra_init_peer failed, ret(%d) phyId(%u)", ret, phyId);
180 0 : goto err;
181 : }
182 : } else {
183 1 : hccp_err("[init][ra]do not support nic_position(%u) phyId(%u)", config->nicPosition, phyId);
184 1 : ret = -EPROTONOSUPPORT;
185 1 : goto err;
186 : }
187 :
188 2 : return 0;
189 :
190 4 : err:
191 4 : DlHalDeinit();
192 4 : return ConverReturnCode(HCCP_INIT, ret);
193 : }
194 :
195 2 : STATIC int RaDeinitHdc(struct RaInitConfig *config)
196 : {
197 : int ret;
198 :
199 2 : ret = RaHdcDeinitAsync(config->phyId);
200 2 : CHK_PRT_RETURN(ret != 0 && ret != -ENODEV, hccp_err("[deinit][ra]ra_hdc_deinit_async failed, ret(%d)", ret), ret);
201 :
202 2 : ret = RaHdcDeinit(config);
203 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra]ra hdc deinit failed, ret(%d), gSendWrNum(%u)",
204 : ret, gSendWrNum), ret);
205 1 : return ret;
206 : }
207 :
208 6 : HCCP_ATTRI_VISI_DEF int RaDeinit(struct RaInitConfig *config)
209 : {
210 : unsigned int phyId;
211 : int ret;
212 :
213 6 : CHK_PRT_RETURN(config == NULL, hccp_err("[deinit][ra]config is NULL, invalid"),
214 : ConverReturnCode(HCCP_INIT, -EINVAL));
215 :
216 5 : phyId = config->phyId;
217 5 : CHK_PRT_RETURN(phyId >= RA_MAX_PHY_ID_NUM,
218 : hccp_err("[deinit][ra]phyId(%u) is invalid! it must greater or equal to 0 and less than %d!", phyId,
219 : RA_MAX_PHY_ID_NUM), ConverReturnCode(HCCP_INIT, -EINVAL));
220 :
221 4 : hccp_run_info("Input parameters: phyId[%u], nicPosition:[%u]", phyId, config->nicPosition);
222 :
223 4 : if (config->nicPosition == NETWORK_OFFLINE) {
224 2 : ret = RaDeinitHdc(config);
225 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra]ra_deinit_hdc failed, ret(%d) phyId(%u)", ret, phyId),
226 : ConverReturnCode(HCCP_INIT, ret));
227 2 : } else if (config->nicPosition == NETWORK_PEER_ONLINE) {
228 1 : ret = RaPeerDeinit(config);
229 1 : CHK_PRT_RETURN(ret == -EAGAIN, hccp_warn("[deinit][ra]ra_peer_deinit unsuccessful, ret(%d) phyId(%u)",
230 : ret, phyId), ConverReturnCode(HCCP_INIT, ret));
231 1 : CHK_PRT_RETURN(ret != 0, hccp_err("[deinit][ra]ra_peer_deinit failed, ret(%d) phyId(%u)", ret, phyId),
232 : ConverReturnCode(HCCP_INIT, ret));
233 : } else {
234 1 : hccp_err("[deinit][ra]do not support nic_position(%u) phyId(%u)", config->nicPosition, phyId);
235 1 : return ConverReturnCode(HCCP_INIT, -EPROTONOSUPPORT);
236 : }
237 :
238 2 : RaSocketSetWhiteListStatus(WHITE_LIST_DISABLE);
239 2 : gSendWrNum = 0;
240 2 : DlHalDeinit();
241 2 : return 0;
242 : }
243 :
244 1 : STATIC void __attribute__ ((destructor)) RaUninitAsync(void)
245 : {
246 1 : RaHdcDeinitAsyncAll();
247 1 : }
|