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