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 "aicpusd_model_err_process.h"
12 : #include "aicpusd_model_execute.h"
13 : #include "aicpusd_drv_manager.h"
14 : #include "securec.h"
15 : #include "ts_api.h"
16 : #include "type_def.h"
17 :
18 : namespace {
19 : constexpr uint32_t ERRLOG_MAXNUM = 16U;
20 : constexpr uint32_t ERRLOG_UNIT_MAXLEN = 256U;
21 : constexpr uint32_t ERRLOG_TOTAL_MAXLEN = 4096U;
22 : }
23 :
24 : namespace AicpuSchedule {
25 9 : AicpuModelErrProc::AicpuModelErrProc()
26 : {
27 27 : for (uint32_t i = 0U; i < ERRLOG_TS_MAXNUM; i++) {
28 18 : buffBaseAddr_[i] = 0ULL;
29 18 : buffLen_[i] = 0U;
30 18 : isBuffValid_[i] = false;
31 : }
32 9 : }
33 :
34 70 : AicpuModelErrProc &AicpuModelErrProc::GetInstance()
35 : {
36 70 : static AicpuModelErrProc instance;
37 70 : return instance;
38 : }
39 :
40 8 : void AicpuModelErrProc::ProcessLogBuffCfgMsg(const aicpu::AicpuConfigMsg &cfgInfo)
41 : {
42 8 : const uint32_t tsId = cfgInfo.tsId;
43 8 : const aicpu::AicpuConfigMsgType msgType = static_cast<aicpu::AicpuConfigMsgType>(cfgInfo.msgType);
44 8 : aicpusd_info("Begin to ProcessLogBuffCfgMsg, tsId[%u], msgType[%u].",
45 : tsId, msgType);
46 :
47 8 : if (tsId >= ERRLOG_TS_MAXNUM) {
48 1 : aicpusd_err("Invalid input tsId, tsId[%u].", tsId);
49 1 : return;
50 : }
51 :
52 7 : switch (msgType) {
53 2 : case aicpu::AicpuConfigMsgType::AICPU_CONFIG_MSG_TYPE_BUF_FREE:
54 2 : SetLogBuffInvalid(tsId);
55 2 : break;
56 :
57 1 : case aicpu::AicpuConfigMsgType::AICPU_CONFIG_MSG_TYPE_BUF_RESET:
58 1 : SetUnitLogEmpy(tsId, cfgInfo.offset);
59 1 : break;
60 :
61 3 : case aicpu::AicpuConfigMsgType::AICPU_CONFIG_MSG_TYPE_BUF_SET_ADDR:
62 3 : SetLogBuffAddr(tsId, cfgInfo.bufAddr, cfgInfo.bufLen);
63 3 : break;
64 :
65 1 : default:
66 1 : aicpusd_err("Invalid msgType of ProcessLogBuffCfgMsg, msgType[%d].", msgType);
67 1 : break;
68 : }
69 :
70 7 : return;
71 : }
72 :
73 2 : void AicpuModelErrProc::SetLogBuffInvalid(const uint32_t tsId)
74 : {
75 2 : lockBuff_.Lock();
76 4 : const ScopeGuard lockGuard([&] () { lockBuff_.Unlock(); });
77 :
78 2 : isBuffValid_[tsId] = false;
79 4 : return;
80 2 : }
81 :
82 5 : void AicpuModelErrProc::SetUnitLogEmpy(const uint32_t tsId, const uint32_t offset)
83 : {
84 5 : if ((offset >= ERRLOG_TOTAL_MAXLEN) || ((offset % ERRLOG_UNIT_MAXLEN) != 0U)) {
85 1 : aicpusd_err("Invalid input offset, offset[%u].", offset);
86 1 : return;
87 : }
88 :
89 4 : lockBuff_.Lock();
90 8 : const ScopeGuard lockGuard([&] () { lockBuff_.Unlock(); });
91 :
92 4 : if (!isBuffValid_[tsId]) {
93 1 : return;
94 : }
95 :
96 3 : char_t * const errType = PtrToPtr<void, char_t>(ValueToPtr(buffBaseAddr_[tsId] + offset));
97 3 : *errType = static_cast<char_t>(aicpu::AicpuErrMsgType::ERR_MSG_TYPE_NULL);
98 :
99 3 : return;
100 4 : }
101 :
102 10 : void AicpuModelErrProc::SetLogBuffAddr(const uint32_t tsId, const uint64_t buffAddr, const uint16_t buffLen)
103 : {
104 10 : lockBuff_.Lock();
105 20 : const ScopeGuard lockGuard([&] () { lockBuff_.Unlock(); });
106 :
107 10 : buffBaseAddr_[tsId] = buffAddr;
108 10 : buffLen_[tsId] = buffLen;
109 10 : isBuffValid_[tsId] = true;
110 :
111 20 : return;
112 10 : }
113 :
114 9 : uint32_t AicpuModelErrProc::GetEmptLogOffset(const uint32_t tsId)
115 : {
116 9 : if (!isBuffValid_[tsId]) {
117 1 : return UINT32_MAX;
118 : }
119 :
120 24 : for (uint32_t i = 0U; i < ERRLOG_MAXNUM; i++) {
121 23 : const uint32_t offset = i * ERRLOG_UNIT_MAXLEN;
122 23 : if (offset >= ERRLOG_TOTAL_MAXLEN) {
123 0 : return UINT32_MAX;
124 23 : } else if (CheckLogIsEmpt(tsId, offset)) {
125 7 : return offset;
126 : } else {
127 : (void)i;
128 : }
129 : }
130 1 : return UINT32_MAX;
131 : }
132 :
133 24 : bool AicpuModelErrProc::CheckLogIsEmpt(const uint32_t tsId, const uint32_t offset) const
134 : {
135 24 : if (offset >= ERRLOG_TOTAL_MAXLEN) {
136 1 : return false;
137 : }
138 23 : const char_t * const errType = PtrToPtr<void, char_t>(ValueToPtr(buffBaseAddr_[tsId] + offset));
139 23 : if ((*errType) == static_cast<char_t>(aicpu::AicpuErrMsgType::ERR_MSG_TYPE_NULL)) {
140 7 : return true;
141 : }
142 16 : return false;
143 : }
144 :
145 4 : uint32_t AicpuModelErrProc::AddErrLog(const aicpu::AicoreErrMsgInfo &errLog, const uint32_t tsId, uint32_t &offset)
146 : {
147 4 : lockBuff_.Lock();
148 8 : const ScopeGuard lockGuard([&]() { lockBuff_.Unlock(); });
149 :
150 4 : offset = GetEmptLogOffset(tsId);
151 4 : if (offset == UINT32_MAX) {
152 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
153 : }
154 3 : char_t * const baseAddr = PtrToPtr<void, char_t>(ValueToPtr(buffBaseAddr_[tsId]));
155 3 : char_t * const wrAddr = baseAddr + offset;
156 3 : const errno_t eRet = memcpy_s(wrAddr, ERRLOG_UNIT_MAXLEN, &errLog, sizeof(aicpu::AicoreErrMsgInfo));
157 3 : if (eRet != EOK) {
158 1 : aicpusd_err("Failed to memcpy AicpuModelErrProc, ret[%d].", eRet);
159 1 : return AICPU_SCHEDULE_ERROR_SAFE_FUNCTION_ERR;
160 : }
161 :
162 2 : return AICPU_SCHEDULE_OK;
163 4 : }
164 :
165 5 : uint32_t AicpuModelErrProc::AddErrLog(const aicpu::AicpuErrMsgInfo &errLog, const uint32_t tsId, uint32_t &offset)
166 : {
167 5 : lockBuff_.Lock();
168 10 : const ScopeGuard lockGuard([&]() { lockBuff_.Unlock(); });
169 :
170 5 : offset = GetEmptLogOffset(tsId);
171 5 : if (offset == UINT32_MAX) {
172 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
173 : }
174 4 : char_t * const baseAddr = PtrToPtr<void, char_t>(ValueToPtr(buffBaseAddr_[tsId]));
175 4 : char_t * const wrAddr = baseAddr + offset;
176 :
177 4 : const errno_t eRet = memcpy_s(wrAddr, ERRLOG_UNIT_MAXLEN, &errLog, sizeof(aicpu::AicpuErrMsgInfo));
178 4 : if (eRet != EOK) {
179 1 : aicpusd_err("Failed to memcpy AicpuModelErrProc, ret[%d].", eRet);
180 1 : return AICPU_SCHEDULE_ERROR_SAFE_FUNCTION_ERR;
181 : }
182 :
183 3 : return AICPU_SCHEDULE_OK;
184 5 : }
185 :
186 13 : void AicpuModelErrProc::RecordAicoreOpErrLog(const AicpuSqeAdapter::AicpuTaskReportInfo &info,
187 : AicpuSqeAdapter &aicpuSqeAdapter)
188 : {
189 13 : if (static_cast<int32_t>(info.result_code) == AICPU_SCHEDULE_OK) {
190 5 : return;
191 : }
192 :
193 8 : aicpusd_err("Aicpu start report aic/aiv result to ts. modelId=%hu, streamId=%hu, taskId=%hu, ret=%hu",
194 : info.model_id, info.stream_id, info.task_id, info.result_code);
195 :
196 8 : const auto model = AicpuModelManager::GetInstance().GetModel(static_cast<uint32_t>(info.model_id));
197 8 : if (model == nullptr) {
198 1 : aicpusd_err("Model[%u] is not found.", static_cast<uint32_t>(info.model_id));
199 1 : return;
200 : }
201 :
202 7 : const uint32_t tsId = model->GetModelTsId();
203 7 : if (tsId >= ERRLOG_TS_MAXNUM) {
204 2 : aicpusd_err("Invalid input tsId, tsId[%u].", tsId);
205 2 : return;
206 : }
207 :
208 5 : aicpu::AicoreErrMsgInfo aicLogInfo = {};
209 5 : aicLogInfo.errType = static_cast<uint8_t>(aicpu::AicpuErrMsgType::ERR_MSG_TYPE_AICORE);
210 5 : aicLogInfo.version = static_cast<uint8_t>(ModelErrRptVer::LOG_ERROR_VERSION_1);
211 5 : aicLogInfo.errorCode = info.result_code;
212 5 : aicLogInfo.modelId = static_cast<uint32_t>(info.model_id);
213 5 : aicLogInfo.taskId = info.task_id;
214 5 : aicLogInfo.streamId = info.stream_id;
215 5 : aicLogInfo.transactionId = 0UL;
216 :
217 5 : uint32_t offset = UINT32_MAX;
218 5 : const uint32_t ret = AddErrLog(aicLogInfo, tsId, offset);
219 5 : if (ret != AICPU_SCHEDULE_OK) {
220 1 : aicpusd_warn("Failed to add AicoreErrLog, offset[%u], ret[%d].", offset, ret);
221 1 : return;
222 : }
223 :
224 4 : ErrLogRptInfo reportInfo = {};
225 4 : reportInfo.offset = offset;
226 4 : reportInfo.errCode = info.result_code;
227 4 : reportInfo.streamId = info.stream_id;
228 4 : reportInfo.taskId = info.task_id;
229 4 : reportInfo.modelId = static_cast<uint32_t>(info.model_id);
230 4 : reportInfo.tsId = tsId;
231 4 : if (ReportErrLog(reportInfo, aicpuSqeAdapter) != AICPU_SCHEDULE_OK) {
232 1 : aicpusd_err("Failed to report AicoreErrLog, offset[%u].", offset);
233 1 : SetUnitLogEmpy(tsId, offset);
234 : }
235 :
236 4 : return;
237 : }
238 :
239 4 : void AicpuModelErrProc::RecordAicpuOpErrLog(const RunContext &taskContext, const AicpuTaskInfo &kernelTaskInfo,
240 : const uint32_t resultCode)
241 : {
242 4 : const auto kernelName = PtrToPtr<const void, const char_t>(ValueToPtr(kernelTaskInfo.kernelName));
243 4 : aicpusd_err("Aicpu report aicpu error to ts. modelId=%u, streamId=%u, taskId=%u, kernelType=%u, ret=%u,"
244 : "kernelName=%s", taskContext.modelId, taskContext.streamId, kernelTaskInfo.taskID,
245 : kernelTaskInfo.kernelType, resultCode, kernelName);
246 :
247 4 : const auto model = AicpuModelManager::GetInstance().GetModel(taskContext.modelId);
248 4 : if (model == nullptr) {
249 1 : aicpusd_err("Model[%u] is not found.", taskContext.modelId);
250 1 : return;
251 : }
252 :
253 3 : const uint32_t tsId = model->GetModelTsId();
254 3 : if (tsId >= ERRLOG_TS_MAXNUM) {
255 1 : aicpusd_err("Invalid input tsId, tsId[%u].", tsId);
256 1 : return;
257 : }
258 :
259 2 : aicpu::AicpuErrMsgInfo cpuLogInfo = {};
260 2 : cpuLogInfo.errType = static_cast<uint8_t>(aicpu::AicpuErrMsgType::ERR_MSG_TYPE_AICPU);
261 2 : cpuLogInfo.version = static_cast<uint8_t>(ModelErrRptVer::LOG_ERROR_VERSION_1);
262 2 : cpuLogInfo.errorCode = resultCode;
263 2 : cpuLogInfo.modelId = taskContext.modelId;
264 2 : cpuLogInfo.streamId = taskContext.streamId;
265 2 : cpuLogInfo.transactionId = 0UL;
266 2 : const auto kernelNameLen = strnlen(kernelName, (sizeof(cpuLogInfo.opName) - 1UL));
267 2 : if (memcpy_s(cpuLogInfo.opName, sizeof(cpuLogInfo.opName), kernelName, kernelNameLen) != EOK) {
268 0 : aicpusd_err("Failed to memcpy opName, len[%u].", kernelNameLen);
269 0 : return;
270 : }
271 :
272 2 : const std::string errDesc("AICPU Stream Ops ERROR");
273 2 : if (memcpy_s(cpuLogInfo.errDesc, sizeof(cpuLogInfo.errDesc), errDesc.c_str(), errDesc.length()) != EOK) {
274 0 : aicpusd_err("Failed to memcpy errDesc, len[%u].", errDesc.length());
275 0 : return;
276 : }
277 :
278 2 : uint32_t offset = UINT32_MAX;
279 2 : const uint32_t ret = AddErrLog(cpuLogInfo, tsId, offset);
280 2 : if (ret != AICPU_SCHEDULE_OK) {
281 0 : aicpusd_warn("Failed to add AicpuModelErrProc, offset[%u], ret[%d].", offset, ret);
282 0 : return;
283 : }
284 :
285 2 : ErrLogRptInfo reportInfo = {};
286 2 : reportInfo.offset = offset;
287 2 : reportInfo.errCode = resultCode;
288 2 : reportInfo.streamId = model->GetReportStmId();
289 2 : reportInfo.taskId = kernelTaskInfo.taskID;
290 2 : reportInfo.modelId = taskContext.modelId;
291 2 : reportInfo.tsId = tsId;
292 2 : if (ReportErrLog(reportInfo) != AICPU_SCHEDULE_OK) {
293 1 : aicpusd_err("Failed to report AicpuErrLog, offset[%u].", offset);
294 1 : SetUnitLogEmpy(tsId, offset);
295 : }
296 2 : return;
297 2 : }
298 :
299 9 : uint32_t AicpuModelErrProc::ReportErrLog(const ErrLogRptInfo &reportInfo, AicpuSqeAdapter &aicpuSqeAdapterPtr) const
300 : {
301 9 : aicpusd_info("Begin to report log, tsId[%u], modelId[%u], streamId[%u], taskId[%u], offset[%u].",
302 : reportInfo.tsId, reportInfo.modelId, reportInfo.streamId, reportInfo.taskId, reportInfo.offset);
303 9 : AicpuSqeAdapter::ErrMsgRspInfo errMsgRspInfo(reportInfo.offset, reportInfo.errCode, reportInfo.streamId,
304 9 : reportInfo.taskId, reportInfo.modelId, reportInfo.tsId);
305 9 : AicpuSqeAdapter aicpuSqeAdapter(FeatureCtrl::GetTsMsgVersion());
306 9 : const int32_t ret = aicpuSqeAdapterPtr.ErrorMsgResponseToTs(errMsgRspInfo);
307 9 : aicpusd_info("Finished to send logmsg report information, ret[%d].", ret);
308 9 : return ret;
309 9 : }
310 :
311 3 : uint32_t AicpuModelErrProc::ReportErrLog(const ErrLogRptInfo &reportInfo) const
312 : {
313 3 : AicpuSqeAdapter aicpuSqeAdapter(FeatureCtrl::GetTsMsgVersion());
314 6 : return ReportErrLog(reportInfo, aicpuSqeAdapter);
315 3 : }
316 : } // namespace AicpuSchedule
|