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 <errno.h>
12 : #include <sys/prctl.h>
13 : #include "securec.h"
14 : #include "dl_hal_function.h"
15 : #include "hccp_common.h"
16 : #include "ra_rs_err.h"
17 : #include "rs.h"
18 : #include "ra_rs_err.h"
19 : #include "rs_inner.h"
20 : #include "rs_epoll.h"
21 : #include "rs_socket.h"
22 : #include "rs_ping_inner.h"
23 : #include "rs_ping_roce.h"
24 : #include "rs_ping_urma.h"
25 : #ifndef HNS_ROCE_LLT
26 : #include "dlog_pub.h"
27 : #endif
28 : #include "rs_ping.h"
29 :
30 : struct RsPthreadInfo gPingThreadInfo = {0};
31 :
32 23 : int RsEpollEventPingHandle(struct rs_cb *rsCb, int fd)
33 : {
34 23 : struct RsPingCtxCb *pingCb = &rsCb->pingCb;
35 23 : struct timeval timestamp2 = {0};
36 23 : int polledCnt = 0;
37 23 : int ret = -ENODEV;
38 :
39 : // thread not running, no need to handle ping
40 23 : if (pingCb->threadStatus != RS_PING_THREAD_RUNNING || pingCb->pingPongOps == NULL) {
41 18 : return ret;
42 : }
43 :
44 : // ping rq: receive detect packet
45 5 : if (pingCb->pingPongOps->checkPingFd(pingCb, fd)) {
46 2 : RS_PTHREAD_MUTEX_LOCK(&rsCb->pingCb.devMutex);
47 2 : if (pingCb->initCnt == 0) {
48 0 : goto free_dev_mutex;
49 : }
50 2 : ret = pingCb->pingPongOps->pingPollRcq(pingCb, &polledCnt, ×tamp2);
51 2 : if (ret != 0) {
52 0 : hccp_err("ping_poll_rcq failed, polledCnt:%d", polledCnt);
53 0 : goto free_dev_mutex;
54 : }
55 2 : pingCb->pingPongOps->pongHandleSend(pingCb, polledCnt, ×tamp2);
56 2 : goto free_dev_mutex;
57 : }
58 :
59 : // pong rq: receive response packet
60 3 : if (pingCb->pingPongOps->checkPongFd(pingCb, fd)) {
61 3 : RS_PTHREAD_MUTEX_LOCK(&rsCb->pingCb.devMutex);
62 3 : if (pingCb->initCnt == 0) {
63 1 : goto free_dev_mutex;
64 : }
65 2 : pingCb->pingPongOps->pongPollRcq(pingCb);
66 2 : ret = 0;
67 2 : goto free_dev_mutex;
68 : }
69 :
70 0 : return ret;
71 :
72 5 : free_dev_mutex:
73 5 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->pingCb.devMutex);
74 5 : return ret;
75 : }
76 :
77 2 : STATIC void *RsPingHandle(void *arg)
78 : {
79 2 : struct RsPingTargetInfo *targetNext = NULL;
80 2 : struct RsPingTargetInfo *targetCurr = NULL;
81 2 : struct rs_cb *rsCb = NULL;
82 : int ret;
83 :
84 2 : RS_CHECK_POINTER_NULL_RETURN_NULL(arg);
85 :
86 2 : hccp_info("<PING> thread begin! thread_id:%lu, pid:%d, ppid:%d", pthread_self(), getpid(), getppid());
87 2 : CHK_PRT_RETURN(pthread_detach(pthread_self()) != 0,
88 : hccp_err("pthread_detach failed! thread_id:%lu, errno:%d", pthread_self(), errno), NULL);
89 :
90 2 : (void)prctl(PR_SET_NAME, (uintptr_t) "hccp_ping", 0, 0, 0);
91 :
92 2 : rsCb = (struct rs_cb *)arg;
93 :
94 2 : RsGetCurTime(&gPingThreadInfo.lastCheckTime);
95 2 : ret = strncpy_s((char *)gPingThreadInfo.pthreadName, sizeof(gPingThreadInfo.pthreadName), "ping_pthread",
96 : strlen("ping_pthread"));
97 2 : CHK_PRT_RETURN(ret != 0, hccp_err("strncpy_s pthread name failed, ret[%d]", ret), NULL);
98 :
99 2 : hccp_run_info("pthread[%s] is alive!", gPingThreadInfo.pthreadName);
100 : while (1) {
101 3 : if (rsCb->pingCb.threadStatus != RS_PING_THREAD_RUNNING) {
102 2 : break;
103 : }
104 :
105 1 : RsHeartbeatAlivePrint(&gPingThreadInfo);
106 1 : if (rsCb->pingCb.taskStatus != RS_PING_TASK_RUNNING || rsCb->pingCb.taskAttr.packetCnt == 0) {
107 0 : usleep(RS_PING_PERIOD_TIME_USEC);
108 0 : continue;
109 : }
110 1 : if (RsListEmpty(&rsCb->pingCb.pingList)) {
111 0 : usleep(RS_PING_PERIOD_TIME_USEC);
112 0 : continue;
113 : }
114 :
115 1 : RS_LIST_GET_HEAD_ENTRY(targetCurr, targetNext, &rsCb->pingCb.pingList, list, struct RsPingTargetInfo);
116 2 : for (; rsCb->pingCb.taskStatus == RS_PING_TASK_RUNNING && (&targetCurr->list) != &rsCb->pingCb.pingList;
117 1 : targetCurr = targetNext, targetNext = list_entry(targetNext->list.next, struct RsPingTargetInfo, list)) {
118 1 : if (targetCurr->state != RS_PING_PONG_TARGET_READY) {
119 0 : usleep(rsCb->pingCb.taskAttr.packetInterval * RS_PING_MSEC_TO_USEC);
120 0 : continue;
121 : }
122 :
123 1 : ret = rsCb->pingCb.pingPongOps->pingPostSend(&rsCb->pingCb, targetCurr);
124 1 : if (ret != 0) {
125 1 : hccp_warn("ping_post_send unsuccessful, ret:%d", ret);
126 1 : usleep(rsCb->pingCb.taskAttr.packetInterval * RS_PING_MSEC_TO_USEC);
127 1 : continue;
128 : }
129 :
130 0 : if (rsCb->pingCb.taskAttr.packetCnt == 1 && targetCurr->state == RS_PING_PONG_TARGET_READY) {
131 0 : targetCurr->state = RS_PING_PONG_TARGET_FINISH;
132 : }
133 : // make sure thread will exit
134 0 : usleep(rsCb->pingCb.taskAttr.packetInterval * RS_PING_MSEC_TO_USEC);
135 :
136 : // ping poll scq
137 0 : ret = rsCb->pingCb.pingPongOps->pingPollScq(&rsCb->pingCb, targetCurr);
138 0 : if (ret != 0) {
139 0 : continue;
140 : }
141 0 : targetCurr->resultSummary.sendCnt++;
142 : }
143 :
144 : // update task attr & status
145 1 : rsCb->pingCb.taskAttr.packetCnt--;
146 1 : if (rsCb->pingCb.taskAttr.packetCnt == 0) {
147 1 : rsCb->pingCb.taskStatus = RS_PING_TASK_RESET;
148 : }
149 : }
150 :
151 2 : RS_PTHREAD_MUTEX_LOCK(&rsCb->pingCb.pingMutex);
152 2 : rsCb->pingCb.threadStatus = RS_PING_THREAD_FINISH;
153 2 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->pingCb.pingMutex);
154 2 : hccp_info("<PING> QUIT thread_id:%lu, pid:%d", pthread_self(), getpid());
155 2 : return NULL;
156 : }
157 :
158 5 : STATIC int RsPingCbInitMutex(struct RsPingCtxCb *pingCb)
159 : {
160 : int ret;
161 :
162 5 : ret = pthread_mutex_init(&pingCb->pingMutex, NULL);
163 5 : if (ret != 0) {
164 1 : hccp_err("pthread_mutex_init ping_mutex failed ret %d", ret);
165 1 : goto ping_mutex_init_failed;
166 : }
167 4 : ret = pthread_mutex_init(&pingCb->pongMutex, NULL);
168 4 : if (ret != 0) {
169 1 : hccp_err("pthread_mutex_init pong_mutex failed ret %d", ret);
170 1 : goto pong_mutex_init_failed;
171 : }
172 3 : ret = pthread_mutex_init(&pingCb->devMutex, NULL);
173 3 : if (ret != 0) {
174 1 : hccp_err("pthread_mutex_init dev_mutex failed ret %d", ret);
175 1 : goto dev_mutex_init_failed;
176 : }
177 :
178 2 : RS_PTHREAD_MUTEX_LOCK(&pingCb->pingMutex);
179 2 : RS_INIT_LIST_HEAD(&pingCb->pingList);
180 2 : RS_PTHREAD_MUTEX_ULOCK(&pingCb->pingMutex);
181 2 : RS_PTHREAD_MUTEX_LOCK(&pingCb->pongMutex);
182 2 : RS_INIT_LIST_HEAD(&pingCb->pongList);
183 2 : RS_PTHREAD_MUTEX_ULOCK(&pingCb->pongMutex);
184 :
185 2 : return 0;
186 :
187 1 : dev_mutex_init_failed:
188 1 : (void)pthread_mutex_destroy(&pingCb->pongMutex);
189 2 : pong_mutex_init_failed:
190 2 : (void)pthread_mutex_destroy(&pingCb->pingMutex);
191 3 : ping_mutex_init_failed:
192 3 : return -ESYSFUNC;
193 : }
194 :
195 4 : RS_ATTRI_VISI_DEF int RsPingHandleInit(unsigned int chipId, int hdcType, unsigned int whiteListStatus)
196 : {
197 4 : struct rs_cb *rsCb = NULL;
198 : int ret;
199 :
200 4 : if (hdcType != HDC_SERVICE_TYPE_RDMA_V2 && whiteListStatus != WHITE_LIST_DISABLE) {
201 1 : return 0;
202 : }
203 :
204 3 : ret = RsDev2rscb(chipId, &rsCb, false);
205 3 : CHK_PRT_RETURN(ret != 0, hccp_err("get rs_cb failed, ret:%d, chipId:%u", ret, chipId), -ENODEV);
206 :
207 2 : ret = RsPingCbInitMutex(&rsCb->pingCb);
208 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_ping_cb_init_mutex failed, ret %d", ret), ret);
209 :
210 2 : rsCb->pingCb.threadStatus = RS_PING_THREAD_RUNNING;
211 2 : ret = pthread_create(&rsCb->pingCb.tid, NULL, (void *)RsPingHandle, (void *)rsCb);
212 2 : if (ret != 0) {
213 1 : hccp_err("Create pthread failed, ret(%d) ", ret);
214 1 : rsCb->pingCb.threadStatus = RS_PING_THREAD_RESET;
215 1 : (void)pthread_mutex_destroy(&rsCb->pingCb.pingMutex);
216 1 : (void)pthread_mutex_destroy(&rsCb->pingCb.pongMutex);
217 1 : (void)pthread_mutex_destroy(&rsCb->pingCb.devMutex);
218 1 : return -ESYSFUNC;
219 : }
220 :
221 1 : return 0;
222 : }
223 :
224 4 : RS_ATTRI_VISI_DEF int RsPingHandleDeinit(unsigned int chipId)
225 : {
226 : #define THREAD_STATUS_CHANGE_TIMEOUT 100
227 4 : struct rs_cb *rsCb = NULL;
228 : int ret;
229 : int i;
230 :
231 4 : ret = RsDev2rscb(chipId, &rsCb, false);
232 4 : CHK_PRT_RETURN(ret != 0, hccp_err("get rs_cb failed, ret:%d, chipId:%u", ret, chipId), -ENODEV);
233 :
234 3 : if (rsCb->pingCb.threadStatus != RS_PING_THREAD_RUNNING) {
235 1 : return 0;
236 : }
237 :
238 2 : RS_PTHREAD_MUTEX_LOCK(&rsCb->pingCb.pingMutex);
239 2 : rsCb->pingCb.threadStatus = RS_PING_THREAD_RESET;
240 2 : rsCb->pingCb.taskStatus = RS_PING_TASK_RESET;
241 2 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->pingCb.pingMutex);
242 :
243 : // wait thread change to finish running status, wait 100 times(total cost: 1s) until timeout
244 103 : for (i = 0; i < THREAD_STATUS_CHANGE_TIMEOUT && rsCb->pingCb.threadStatus != RS_PING_THREAD_FINISH; i++) {
245 101 : usleep(RS_PING_PERIOD_TIME_USEC);
246 : }
247 :
248 : // thread not in finish running status, report timeout
249 2 : if (rsCb->pingCb.threadStatus != RS_PING_THREAD_FINISH) {
250 1 : hccp_run_info("<PING> wait thread tid:%lu finish running timeout, thread status:%d", rsCb->pingCb.tid,
251 : rsCb->pingCb.threadStatus);
252 : }
253 :
254 2 : (void)pthread_mutex_destroy(&rsCb->pingCb.pingMutex);
255 2 : (void)pthread_mutex_destroy(&rsCb->pingCb.pongMutex);
256 2 : (void)pthread_mutex_destroy(&rsCb->pingCb.devMutex);
257 2 : return 0;
258 : }
259 :
260 4 : STATIC int RsPingInitProtocolOps(struct RsPingCtxCb *pingCb, enum ProtocolTypeT protocol)
261 : {
262 4 : pingCb->protocol = protocol;
263 :
264 4 : switch (protocol) {
265 3 : case PROTOCOL_RDMA:
266 3 : pingCb->pingPongOps = RsPingRoceGetOps();
267 3 : pingCb->pingPongDfx = RsPingRoceGetDfx();
268 3 : break;
269 1 : case PROTOCOL_UDMA:
270 1 : pingCb->pingPongOps = RsPingUrmaGetOps();
271 1 : pingCb->pingPongDfx = RsPingUrmaGetDfx();
272 1 : break;
273 0 : default:
274 0 : hccp_err("unsupported protocol:%u", protocol);
275 0 : return -EINVAL;
276 : }
277 :
278 4 : if (pingCb->pingPongOps == NULL || pingCb->pingPongOps->initPingCb == NULL || pingCb->pingPongDfx == NULL) {
279 0 : hccp_err("pingCb->pingPongOps or init_ping_cb or pingCb->ping_pong_dfx is NULL, protocol:%u", protocol);
280 0 : return -ENOTSUPP;
281 : }
282 4 : return 0;
283 : }
284 :
285 9 : RS_ATTRI_VISI_DEF int RsPingInit(struct PingInitAttr *attr, struct PingInitInfo *info, unsigned int *devIndex)
286 : {
287 9 : struct RsPingCtxCb *pingCb = NULL;
288 9 : struct rs_cb *rscb = NULL;
289 : unsigned int phyId;
290 9 : int ret = 0;
291 :
292 9 : CHK_PRT_RETURN(attr == NULL || info == NULL || devIndex == NULL,
293 : hccp_err("param error, attr or info or devIndex is NULL"), -EINVAL);
294 :
295 8 : phyId = (attr->protocol == PROTOCOL_RDMA) ? attr->dev.rdma.phyId : attr->ub.phyId;
296 8 : ret = RsGetRsCb(phyId, &rscb);
297 8 : CHK_PRT_RETURN(ret != 0, hccp_err("RsGetRsCb failed, phyId[%u] invalid, ret %d", phyId, ret), ret);
298 :
299 7 : pingCb = &rscb->pingCb;
300 7 : RS_PTHREAD_MUTEX_LOCK(&pingCb->devMutex);
301 7 : if (rscb->pingCb.initCnt != 0) {
302 1 : hccp_err("init_cnt:%u != 0", rscb->pingCb.initCnt);
303 1 : ret = -EEXIST;
304 1 : goto free_dev_mutex;
305 : }
306 :
307 6 : ret = rsGetLocalDevIDByHostDevID(phyId, &pingCb->logicDevid);
308 6 : if (ret != 0) {
309 1 : hccp_err("rsGetLocalDevIDByHostDevID failed, phyId(%u), ret(%d)", phyId, ret);
310 1 : goto free_dev_mutex;
311 : }
312 :
313 : #ifdef CUSTOM_INTERFACE
314 5 : if (RsIsCustomInterfaceSupported()) {
315 : // setup sharemem for pingmesh
316 5 : ret = RsSetupSharemem(rscb, false, phyId);
317 5 : if (ret != 0) {
318 1 : hccp_err("RsSetupSharemem failed, phyId(%u), ret(%d)", phyId, ret);
319 1 : goto free_dev_mutex;
320 : }
321 : }
322 : #endif
323 :
324 4 : ret = RsPingInitProtocolOps(pingCb, attr->protocol);
325 4 : if (ret != 0) {
326 0 : hccp_err("rs_ping_init_protocol_ops failed, phyId:%u ret:%d", phyId, ret);
327 0 : goto free_dev_mutex;
328 : }
329 :
330 4 : ret = pingCb->pingPongOps->initPingCb(phyId, attr, info, devIndex, pingCb);
331 4 : if (ret != 0) {
332 2 : hccp_err("init_ping_cb failed, phyId:%u ret:%d", phyId, ret);
333 2 : goto free_dev_mutex;
334 : }
335 :
336 2 : pingCb->initCnt++;
337 2 : pingCb->pingPongDfx->initPingCbSuccess(phyId, attr, *devIndex);
338 :
339 7 : free_dev_mutex:
340 7 : RS_PTHREAD_MUTEX_ULOCK(&pingCb->devMutex);
341 7 : return ret;
342 : }
343 :
344 2 : STATIC int RsGetPingCb(struct RaRsDevInfo *rdev, struct RsPingCtxCb **pingCb)
345 : {
346 2 : unsigned int phyId = rdev->phyId;
347 2 : struct rs_cb *rsCb = NULL;
348 : int ret;
349 :
350 2 : ret = RsGetRsCb(phyId, &rsCb);
351 2 : CHK_PRT_RETURN(ret != 0, hccp_err("RsGetRsCb failed, phyId[%u] invalid, ret %d", phyId, ret), ret);
352 :
353 1 : CHK_PRT_RETURN(rdev->devIndex != rsCb->pingCb.devIndex,
354 : hccp_err("param error, devIndex:%u != pingCb.devIndex:%u", rdev->devIndex, rsCb->pingCb.devIndex), -ENODEV);
355 :
356 1 : CHK_PRT_RETURN(rsCb->pingCb.threadStatus != RS_PING_THREAD_RUNNING,
357 : hccp_err("thread_status:%d is not running", rsCb->pingCb.threadStatus), -ESRCH);
358 :
359 1 : *pingCb = &rsCb->pingCb;
360 :
361 1 : return 0;
362 : }
363 :
364 11 : RS_ATTRI_VISI_DEF int RsPingTargetAdd(struct RaRsDevInfo *rdev, struct PingTargetInfo *target)
365 : {
366 11 : struct RsPingTargetInfo *targetInfo = NULL;
367 11 : struct RsPingCtxCb *pingCb = NULL;
368 : int ret;
369 :
370 11 : CHK_PRT_RETURN(rdev == NULL || target == NULL, hccp_err("param error, rdev is NULL or target is NULL"), -EINVAL);
371 10 : CHK_PRT_RETURN(target->payload.size > PING_USER_PAYLOAD_MAX_SIZE,
372 : hccp_err("param error, size:%u > max_size:%u", target->payload.size, PING_USER_PAYLOAD_MAX_SIZE), -EINVAL);
373 :
374 9 : ret = RsGetPingCb(rdev, &pingCb);
375 9 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_ping_cb failed, ret=%d phyId:%u", ret, rdev->phyId), ret);
376 :
377 8 : if (pingCb->taskStatus != RS_PING_TASK_RESET) {
378 1 : hccp_err("task_status:%d disallow to add target phyId:%u", pingCb->taskStatus, rdev->phyId);
379 1 : return -EEXIST;
380 : }
381 :
382 7 : ret = pingCb->pingPongOps->pingFindTargetNode(pingCb, &target->remoteInfo.qpInfo, &targetInfo);
383 7 : if (ret == 0) {
384 1 : hccp_info("target node exist! phyId:%u", rdev->phyId);
385 1 : ret = -EEXIST;
386 1 : goto out;
387 : }
388 :
389 6 : ret = pingCb->pingPongOps->pingAllocTargetNode(pingCb, target, &targetInfo);
390 6 : if (ret != 0) {
391 3 : hccp_err("rs_ping_alloc_target_node failed, ret:%d phyId:%u", ret, rdev->phyId);
392 3 : return ret;
393 : }
394 :
395 3 : RS_PTHREAD_MUTEX_LOCK(&pingCb->pingMutex);
396 3 : targetInfo->uuid = (uint64_t)pingCb->pingNum;
397 3 : RsListAddTail(&targetInfo->list, &pingCb->pingList);
398 3 : pingCb->pingNum++;
399 3 : RS_PTHREAD_MUTEX_ULOCK(&pingCb->pingMutex);
400 :
401 2 : out:
402 4 : pingCb->pingPongDfx->addTargetSuccess(target, targetInfo);
403 4 : return ret;
404 : }
405 :
406 4 : RS_ATTRI_VISI_DEF int RsPingTaskStart(struct RaRsDevInfo *rdev, struct PingTaskAttr *attr)
407 : {
408 4 : struct RsPingTargetInfo *targetNext = NULL;
409 4 : struct RsPingTargetInfo *targetCurr = NULL;
410 4 : struct RsPingCtxCb *pingCb = NULL;
411 4 : unsigned int targetCnt = 0;
412 : int ret;
413 :
414 4 : CHK_PRT_RETURN(rdev == NULL || attr == NULL, hccp_err("param error, rdev is NULL or attr is NULL"), -EINVAL);
415 3 : ret = RsGetPingCb(rdev, &pingCb);
416 3 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_ping_cb failed, ret=%d phyId:%u", ret, rdev->phyId), ret);
417 :
418 2 : if (pingCb->taskStatus != RS_PING_TASK_RESET) {
419 1 : hccp_warn("task_status:%d disallow to start ping task, phyId:%u", pingCb->taskStatus, rdev->phyId);
420 1 : return -EEXIST;
421 : }
422 1 : CHK_PRT_RETURN(attr->packetCnt == 0 || attr->packetInterval == 0 || attr->timeoutInterval == 0,
423 : hccp_err("param error, packetCnt:%u or packetInterval:%u or timeoutInterval:%u is 0", attr->packetCnt,
424 : attr->packetInterval, attr->timeoutInterval),
425 : -EINVAL);
426 :
427 1 : pingCb->pingPongOps->resetRecvBuffer(pingCb);
428 :
429 1 : RS_PTHREAD_MUTEX_LOCK(&pingCb->pingMutex);
430 1 : pingCb->taskId++;
431 1 : (void)memcpy_s(&pingCb->taskAttr, sizeof(struct PingTaskAttr), attr, sizeof(struct PingTaskAttr));
432 1 : RS_LIST_GET_HEAD_ENTRY(targetCurr, targetNext, &pingCb->pingList, list, struct RsPingTargetInfo);
433 2 : for (; (&targetCurr->list) != &pingCb->pingList;
434 1 : targetCurr = targetNext, targetNext = list_entry(targetNext->list.next, struct RsPingTargetInfo, list)) {
435 1 : (void)memset_s(&targetCurr->resultSummary, sizeof(struct PingResultSummary), 0,
436 : sizeof(struct PingResultSummary));
437 1 : (void)memcpy_s(&targetCurr->resultSummary.taskAttr, sizeof(struct PingTaskAttr), attr,
438 : sizeof(struct PingTaskAttr));
439 1 : targetCurr->resultSummary.rttMin = ~0;
440 1 : targetCurr->resultSummary.taskId = pingCb->taskId;
441 1 : targetCurr->state = RS_PING_PONG_TARGET_READY;
442 1 : targetCnt++;
443 : }
444 :
445 1 : pingCb->taskStatus = RS_PING_TASK_RUNNING;
446 1 : RS_PTHREAD_MUTEX_ULOCK(&pingCb->pingMutex);
447 :
448 1 : hccp_info("target_cnt:%u packet_cnt:%u packet_interval:%u timeout_interval:%u task_id:%u start success", targetCnt,
449 : attr->packetCnt, attr->packetInterval, attr->timeoutInterval, pingCb->taskId);
450 1 : return 0;
451 : }
452 :
453 8 : RS_ATTRI_VISI_DEF int RsPingGetResults(struct RaRsDevInfo *rdev, struct PingTargetCommInfo target[], unsigned int *num,
454 : struct PingResultInfo result[])
455 : {
456 8 : struct RsPingCtxCb *pingCb = NULL;
457 : unsigned int expectedNum;
458 : unsigned int i;
459 : int ret;
460 :
461 8 : CHK_PRT_RETURN(rdev == NULL || num == NULL || target == NULL || result == NULL,
462 : hccp_err("param error, rdev is NULL or num is NULL or result/target is NULL"), -EINVAL);
463 7 : expectedNum = *num;
464 7 : *num = 0;
465 7 : ret = RsGetPingCb(rdev, &pingCb);
466 7 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_ping_cb failed, ret=%d phyId:%u", ret, rdev->phyId), ret);
467 :
468 : // caller needs to retry, degrade log level
469 6 : if (pingCb->taskStatus == RS_PING_TASK_RUNNING) {
470 1 : hccp_warn("task_status:%d disallow to get ping results phyId:%u", pingCb->taskStatus, rdev->phyId);
471 1 : return -EAGAIN;
472 : }
473 :
474 7 : for (i = 0; i < expectedNum; i++) {
475 5 : ret = pingCb->pingPongOps->getTargetResult(pingCb, &target[i], &result[i]);
476 5 : if (ret != 0) {
477 3 : hccp_err("rs_ping_get_target_result node i:%d failed phyId:%u", i, rdev->phyId);
478 3 : i = (i > 0) ? (i - 1U) : 0;
479 3 : goto out;
480 : }
481 : }
482 :
483 2 : out:
484 5 : *num = i;
485 5 : return ret;
486 : }
487 :
488 3 : RS_ATTRI_VISI_DEF int RsPingTaskStop(struct RaRsDevInfo *rdev)
489 : {
490 3 : struct RsPingCtxCb *pingCb = NULL;
491 : int ret;
492 :
493 3 : CHK_PRT_RETURN(rdev == NULL, hccp_err("param error, rdev is NULL"), -EINVAL);
494 2 : ret = RsGetPingCb(rdev, &pingCb);
495 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_ping_cb failed, ret=%d phyId:%u", ret, rdev->phyId), ret);
496 :
497 1 : hccp_info("task_status:%d modify to %d, phyId:%u", pingCb->taskStatus, RS_PING_TASK_RESET, rdev->phyId);
498 :
499 1 : RS_PTHREAD_MUTEX_LOCK(&pingCb->pingMutex);
500 1 : pingCb->taskStatus = RS_PING_TASK_RESET;
501 1 : RS_PTHREAD_MUTEX_ULOCK(&pingCb->pingMutex);
502 :
503 1 : return 0;
504 : }
505 :
506 7 : RS_ATTRI_VISI_DEF int RsPingTargetDel(struct RaRsDevInfo *rdev, struct PingTargetCommInfo target[], unsigned int *num)
507 : {
508 7 : struct RsPingTargetInfo *targetInfo = NULL;
509 7 : struct RsPingCtxCb *pingCb = NULL;
510 : unsigned int expectedNum;
511 : unsigned int i;
512 : int ret;
513 :
514 7 : CHK_PRT_RETURN(rdev == NULL || target == NULL || num == NULL,
515 : hccp_err("param error, rdev or target or num is NULL"), -EINVAL);
516 6 : ret = RsGetPingCb(rdev, &pingCb);
517 6 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_ping_cb failed, ret=%d phyId:%u", ret, rdev->phyId), ret);
518 :
519 5 : if (pingCb->taskStatus != RS_PING_TASK_RESET) {
520 1 : hccp_err("task_status:%d disallow to delete target phyId:%u", pingCb->taskStatus, rdev->phyId);
521 1 : return -EEXIST;
522 : }
523 :
524 4 : expectedNum = *num;
525 6 : for (i = 0; i < expectedNum; i++) {
526 4 : ret = pingCb->pingPongOps->pingFindTargetNode(pingCb, &target[i].qpInfo, &targetInfo);
527 4 : if (ret != 0) {
528 2 : pingCb->pingPongDfx->pingCannotFindTargetNode(i, ret, target[i], rdev->phyId);
529 2 : goto out;
530 : }
531 :
532 2 : pingCb->pingPongOps->pingFreeTargetNode(pingCb, targetInfo);
533 2 : (void)pthread_mutex_destroy(&targetInfo->tripMutex);
534 2 : free(targetInfo);
535 2 : targetInfo = NULL;
536 : }
537 :
538 2 : out:
539 4 : *num = i;
540 4 : return ret;
541 : }
542 :
543 5 : RS_ATTRI_VISI_DEF int RsPingDeinit(struct RaRsDevInfo *rdev)
544 : {
545 5 : struct RsPingCtxCb *pingCb = NULL;
546 5 : int ret = 0;
547 :
548 5 : CHK_PRT_RETURN(rdev == NULL, hccp_err("param error, rdev is NULL"), -EINVAL);
549 4 : ret = RsGetPingCb(rdev, &pingCb);
550 4 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_ping_cb failed, ret=%d phyId:%u", ret, rdev->phyId), ret);
551 :
552 3 : RS_PTHREAD_MUTEX_LOCK(&pingCb->devMutex);
553 3 : if (pingCb->initCnt == 0) {
554 1 : hccp_err("init_cnt is 0");
555 1 : ret = -ENODEV;
556 1 : goto free_dev_mutex;
557 : }
558 :
559 2 : pingCb->pingPongOps->deinitPingCb(rdev->phyId, pingCb);
560 2 : pingCb->initCnt--;
561 2 : hccp_run_info("pingCb deinit success, phyId:%u, devIndex:%u", rdev->phyId, rdev->devIndex);
562 :
563 3 : free_dev_mutex:
564 3 : RS_PTHREAD_MUTEX_ULOCK(&pingCb->devMutex);
565 3 : return ret;
566 : }
|