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