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 <sys/prctl.h>
12 : #include <pthread.h>
13 : #include "user_log.h"
14 : #include "dl_hal_function.h"
15 : #include "hccp_msg.h"
16 : #include "hccp_common.h"
17 : #include "ra_rs_err.h"
18 : #include "rs_ub.h"
19 : #include "rs_esched.h"
20 :
21 : struct RsEschedInfo gRsEschedInfo = {0};
22 :
23 2 : STATIC void RsEschedJettyDestroy(struct rs_cb *rscb, TsUbTaskReportT *taskInfo)
24 : {
25 : unsigned int dieId, funcId, ueInfo;
26 : int ret, i;
27 :
28 4 : for (i = 0; i < taskInfo->num; i++) {
29 2 : dieId = taskInfo->array[i].udieId;
30 2 : funcId = taskInfo->array[i].functionId;
31 2 : ueInfo = RsGenerateUeInfo(dieId, funcId);
32 2 : ret = RsUbCtxJettyFree(rscb, ueInfo, taskInfo->array[i].jettyId);
33 2 : if (ret != 0) {
34 1 : hccp_run_warn("rs_ub_ctx_jetty_free unsuccessful, ret[%d] task_index[%d] logicId[%u] dieId[%u] "
35 : "funcId[%u] jettyId[%u]", ret, i, rscb->logicId, dieId, funcId, taskInfo->array[i].jettyId);
36 1 : continue;
37 : }
38 :
39 1 : hccp_info("jetty destroy task success, task_index[%d] logicId[%u] dieId[%u] funcId[%u] jettyId[%u]",
40 : i, rscb->logicId, dieId, funcId, taskInfo->array[i].jettyId);
41 : }
42 2 : return;
43 : }
44 :
45 3 : STATIC int RsEschedExecByCmdType(struct rs_cb *rscb, struct TagTsHccpMsg *msg)
46 : {
47 3 : int ret = 0;
48 :
49 3 : switch (msg->cmdType) {
50 2 : case 0: // UB force kill
51 2 : RsEschedJettyDestroy(rscb, &msg->u.ubTaskInfo);
52 2 : break;
53 1 : default:
54 1 : hccp_run_warn("tag_ts_hccp_msg unsupported cmd type[%u]", msg->cmdType);
55 1 : ret = -EINVAL;
56 1 : break;
57 : }
58 3 : return ret;
59 : }
60 :
61 1 : STATIC void RsEschedCleanAllResource(struct rs_cb *rscb)
62 : {
63 1 : struct RsUbDevCb *devCbCurr = NULL;
64 1 : struct RsUbDevCb *devCbNext = NULL;
65 :
66 1 : RS_PTHREAD_MUTEX_LOCK(&rscb->mutex);
67 :
68 1 : RS_LIST_GET_HEAD_ENTRY(devCbCurr, devCbNext, &rscb->udevList, list, struct RsUbDevCb);
69 2 : for (; (&devCbCurr->list) != &rscb->udevList;
70 1 : devCbCurr = devCbNext,
71 1 : devCbNext = list_entry(devCbNext->list.next, struct RsUbDevCb, list)) {
72 1 : hccp_info("logicId[%u] devIndex[%u] start clean", rscb->logicId, devCbCurr->index);
73 1 : RsUbFreeJettyCbList(devCbCurr, &devCbCurr->jettyList, &devCbCurr->rjettyList);
74 : }
75 :
76 1 : RS_PTHREAD_MUTEX_ULOCK(&rscb->mutex);
77 1 : return;
78 : }
79 :
80 6 : STATIC int RsEschedProcessEvent(struct rs_cb *rscb, struct event_info *eventData)
81 : {
82 6 : unsigned int subeventId = eventData->comm.subevent_id;
83 : struct TagTsHccpMsg *msg;
84 : uint16_t isAppExit;
85 6 : int ret = 0;
86 :
87 6 : CHK_PRT_RETURN(eventData->priv.msg_len != sizeof(struct TagTsHccpMsg),
88 : hccp_err("event invalid, msg_len[%u] != [%u], event_id[%d] subeventId[%u]",
89 : eventData->priv.msg_len, sizeof(struct TagTsHccpMsg), eventData->comm.event_id, subeventId), -EINVAL);
90 :
91 5 : msg = (struct TagTsHccpMsg *)eventData->priv.msg;
92 5 : isAppExit = msg->isAppExit;
93 5 : switch (isAppExit) {
94 3 : case 0: // host app alive, exec by cmd_type
95 3 : ret = RsEschedExecByCmdType(rscb, msg);
96 3 : break;
97 1 : case 1: // host app exit, clean all resource
98 1 : RsEschedCleanAllResource(rscb);
99 1 : break;
100 1 : default:
101 1 : hccp_run_warn("tag_ts_hccp_msg unsupported is_app_exit status[%u]", isAppExit);
102 1 : ret = -EINVAL;
103 1 : break;
104 : }
105 :
106 5 : return ret;
107 : }
108 :
109 1 : STATIC void RsEschedAckEvent(struct rs_cb *rscb, struct event_info *eventData)
110 : {
111 1 : struct event_summary ackEvent = {0};
112 1 : int ret = 0;
113 :
114 1 : ackEvent.pid = eventData->comm.pid;
115 1 : ackEvent.grp_id = eventData->comm.grp_id;
116 1 : ackEvent.event_id = EVENT_HCCP_MSG;
117 1 : ackEvent.subevent_id = TOPIC_KILL_DONE_MSG;
118 1 : ackEvent.msg_len = eventData->priv.msg_len;
119 1 : ackEvent.msg = eventData->priv.msg;
120 1 : ackEvent.dst_engine = CCPU_DEVICE;
121 1 : ackEvent.policy = ONLY;
122 1 : ret = DlHalEschedSubmitEvent(rscb->logicId, &ackEvent);
123 1 : if (ret != 0) {
124 0 : hccp_run_warn("DlHalEschedSubmitEvent unsuccessful, ret[%d] logicId[%u]", ret, rscb->logicId);
125 : }
126 :
127 1 : return;
128 : }
129 :
130 1 : STATIC void RsEschedHandleEvent(struct rs_cb *rscb)
131 : {
132 1 : struct event_info event = {0};
133 : int ret;
134 :
135 1 : ret = DlHalEschedWaitEvent(rscb->logicId, ESCHED_GRP_TS_HCCP, ESCHED_THREAD_ID_TS_HCCP, 0, &event);
136 1 : if (ret == -DRV_ERROR_SCHED_WAIT_TIMEOUT || ret == -DRV_ERROR_NO_EVENT) {
137 1 : return;
138 : }
139 :
140 1 : if (ret != DRV_ERROR_NONE) {
141 1 : hccp_run_warn("DlHalEschedWaitEvent unsuccessful, ret[%d] logicId[%u]", ret, rscb->logicId);
142 1 : return;
143 : }
144 :
145 0 : hccp_info("wait event success, event_id[%d] subeventId[%u]", event.comm.event_id, event.comm.subevent_id);
146 0 : ret = RsEschedProcessEvent(rscb, &event);
147 0 : if (ret != 0) {
148 0 : hccp_run_warn("rs_esched_process_event unsuccessful, ret[%d] logicId[%u]", ret, rscb->logicId);
149 : }
150 :
151 0 : RsEschedAckEvent(rscb, &event);
152 : }
153 :
154 0 : STATIC void *RsEschedHandle(void *arg)
155 : {
156 0 : struct rs_cb *rscb = (struct rs_cb *)arg;
157 : int ret;
158 :
159 0 : ret = pthread_detach(pthread_self());
160 0 : CHK_PRT_RETURN(ret, hccp_err("pthread detach failed ret %d", ret), NULL);
161 0 : (void)prctl(PR_SET_NAME, (uintptr_t)"hccp_rs_esched", 0, 0, 0);
162 0 : gRsEschedInfo.threadStatus = THREAD_RUNNING;
163 :
164 : while (1) {
165 0 : if (gRsEschedInfo.threadStatus == THREAD_DESTROYING) {
166 0 : break;
167 : }
168 :
169 0 : RsEschedHandleEvent(rscb);
170 0 : usleep(ESCHED_THREAD_USLEEP_TIME);
171 : }
172 :
173 0 : hccp_run_info("rs esched handle thread exit success, logic_devid[%u]", rscb->logicId);
174 0 : gRsEschedInfo.threadStatus = THREAD_HALT;
175 0 : return NULL;
176 : }
177 :
178 0 : int RsEschedInit(struct rs_cb *rscb)
179 : {
180 : pthread_t rsEschedTid;
181 0 : int ret = 0;
182 :
183 0 : if (rscb->protocol != PROTOCOL_UDMA) {
184 0 : return 0;
185 : }
186 :
187 0 : ret = DlHalEschedAttachDevice(rscb->logicId);
188 0 : CHK_PRT_RETURN(ret != 0, hccp_err("halEschedSubscribeEvent failed, ret[%d] logicId[%u]",
189 : ret, rscb->logicId), ret);
190 :
191 0 : ret = DlHalEschedCreateGrp(rscb->logicId, ESCHED_GRP_TS_HCCP, GRP_TYPE_BIND_CP_CPU);
192 0 : CHK_PRT_RETURN(ret != 0, hccp_err("DlHalEschedCreateGrp failed, ret[%d] logicId[%u]",
193 : ret, rscb->logicId), ret);
194 :
195 0 : ret = DlHalEschedSubscribeEvent(rscb->logicId, ESCHED_GRP_TS_HCCP, ESCHED_THREAD_ID_TS_HCCP,
196 : (1UL << EVENT_HCCP_MSG));
197 0 : CHK_PRT_RETURN(ret != 0, hccp_err("DlHalEschedSubscribeEvent failed, ret[%d] logicId[%u]",
198 : ret, rscb->logicId), ret);
199 :
200 0 : ret = pthread_create(&rsEschedTid, NULL, RsEschedHandle, (void *)rscb);
201 0 : CHK_PRT_RETURN(ret != 0, hccp_err("pthread create failed, ret[%d] logicId[%u]", ret, rscb->logicId), -ESYSFUNC);
202 :
203 0 : return 0;
204 : }
205 :
206 0 : void RsEschedDeinit(enum ProtocolTypeT protocol)
207 : {
208 : int tryAgain;
209 :
210 0 : if (protocol != PROTOCOL_UDMA) {
211 0 : return;
212 : }
213 :
214 0 : if (gRsEschedInfo.threadStatus == THREAD_HALT) {
215 0 : return;
216 : }
217 :
218 : // not need to use mutex, because rs_esched thread can only be created once when rs_init exec in hccp process
219 0 : gRsEschedInfo.threadStatus = THREAD_DESTROYING;
220 :
221 0 : tryAgain = ESCHED_THREAD_TRY_TIME;
222 0 : while ((gRsEschedInfo.threadStatus != THREAD_HALT) && tryAgain != 0) {
223 0 : usleep(ESCHED_THREAD_USLEEP_TIME);
224 0 : tryAgain--;
225 : }
226 :
227 0 : if (tryAgain <= 0) {
228 0 : hccp_warn("rs_esched_handle thread quit timeout");
229 : }
230 0 : return;
231 : }
|