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