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 "msprof_manager.h"
12 :
13 : #include <memory>
14 : #include <unordered_map>
15 : #include "securec.h"
16 :
17 : namespace bqs {
18 : namespace {
19 : const std::string PROFILING_RESULT_DIR = "/var/log/npu/profiling/";
20 : }
21 :
22 114 : BqsMsprofManager &BqsMsprofManager::GetInstance()
23 : {
24 114 : static BqsMsprofManager instance;
25 114 : return instance;
26 : }
27 :
28 18 : void BqsMsprofManager::InitBqsMsprofManager(const bool initFlag, const std::string &cfgData)
29 : {
30 18 : if (!initFlag) {
31 3 : DGW_LOG_RUN_INFO("[Prof]Profiling flag set to false, will not start.");
32 3 : return;
33 : }
34 :
35 15 : if (!BqsMsprofApiAdapter::GetInstance().IsSoLoad()) {
36 0 : DGW_LOG_ERROR("[Prof]Profiling flag set to true but so load failed.");
37 0 : return;
38 : }
39 :
40 15 : ProfStatus ret = RegProfCallback();
41 15 : if (ret != ProfStatus::PROF_SUCCESS) {
42 0 : DGW_LOG_ERROR("[Prof]Regist profiling callback failed, ret=%d", static_cast<int32_t>(ret));
43 0 : return;
44 : }
45 :
46 15 : ret = InitProf(cfgData);
47 15 : if (ret != ProfStatus::PROF_SUCCESS) {
48 0 : DGW_LOG_ERROR("[Prof]Init msprof failed, ret=%d, cfgData=%s.", static_cast<int32_t>(ret), cfgData.c_str());
49 0 : return;
50 : }
51 :
52 15 : ret = RegProfType();
53 15 : if (ret != ProfStatus::PROF_SUCCESS) {
54 0 : DGW_LOG_ERROR("[Prof]Regist profiling type failed, ret=%d", static_cast<int32_t>(ret));
55 0 : return;
56 : }
57 :
58 15 : DGW_LOG_RUN_INFO("[Prof]Queue schedule profiling init success, cfgData=%s.", cfgData.c_str());
59 :
60 15 : return;
61 : }
62 :
63 15 : ProfStatus BqsMsprofManager::RegProfCallback() const
64 : {
65 15 : const ProfStatus ret = BqsMsprofApiAdapter::GetInstance().MsprofRegisterCallback(AICPU, &ProfCallback);
66 15 : if (ret != ProfStatus::PROF_SUCCESS) {
67 0 : DGW_LOG_ERROR("[Prof]Regist profiling callback failed, ret=%d.", static_cast<int32_t>(ret));
68 0 : return ret;
69 : }
70 :
71 15 : DGW_LOG_RUN_INFO("[Prof]Regist profiling callback success.");
72 :
73 15 : return ret;
74 : }
75 :
76 15 : ProfStatus BqsMsprofManager::InitProf(const std::string &cfgData)
77 : {
78 15 : std::shared_ptr<MsprofCommandHandleParams> profCfg = std::make_shared<MsprofCommandHandleParams>();
79 15 : if (profCfg == nullptr) {
80 0 : DGW_LOG_ERROR("[Prof]Malloc profiling config struct failed.");
81 0 : return ProfStatus::PROF_FAIL;
82 : }
83 :
84 15 : int32_t ret = memset_s(profCfg.get(), sizeof(*profCfg), 0, sizeof(*profCfg));
85 15 : if (ret != EOK) {
86 0 : DGW_LOG_ERROR("[Prof]Memset profiling config struct failed, ret=%d.", ret);
87 0 : return ProfStatus::PROF_FAIL;
88 : }
89 :
90 15 : const uint32_t cfgDataLen = cfgData.length();
91 15 : const uint32_t pathLen = PROFILING_RESULT_DIR.length();
92 15 : ret = strncpy_s(profCfg->profData, sizeof(profCfg->profData), cfgData.c_str(), cfgDataLen);
93 15 : ret |= strncpy_s(profCfg->path, sizeof(profCfg->path), PROFILING_RESULT_DIR.c_str(), pathLen);
94 15 : if (ret != EOK) {
95 0 : DGW_LOG_ERROR("[Prof]Copy data to profiling config failed, cfgDataLen=%u, pathLen=%u.", cfgDataLen, pathLen);
96 0 : return ProfStatus::PROF_FAIL;
97 : }
98 :
99 15 : profCfg->profDataLen = cfgDataLen;
100 15 : profCfg->pathLen = pathLen;
101 15 : profCfg->storageLimit = UINT32_MAX;
102 :
103 30 : ProfStatus profRet = BqsMsprofApiAdapter::GetInstance().MsprofInit(
104 : static_cast<uint32_t>(MSPROF_CTRL_INIT_PURE_CPU),
105 15 : profCfg.get(), sizeof(*profCfg));
106 15 : if (profRet != ProfStatus::PROF_SUCCESS) {
107 0 : DGW_LOG_ERROR("[Prof]Init msprof failed, ret=%d, profData=%s, profPath=%s, storageLimit=%u.",
108 : static_cast<int32_t>(profRet), profCfg->profData, profCfg->path, profCfg->storageLimit);
109 0 : return profRet;
110 : }
111 :
112 15 : isInitMsprof_ = true;
113 :
114 15 : DGW_LOG_RUN_INFO("[Prof]Init msprof success, profData=%s, profPath=%s, storageLimit=%u.",
115 : profCfg->profData, profCfg->path, profCfg->storageLimit);
116 :
117 15 : return ProfStatus::PROF_SUCCESS;
118 15 : }
119 :
120 15 : ProfStatus BqsMsprofManager::RegProfType() const
121 : {
122 : const std::unordered_map<std::string, DgwProfInfoType> namesToProfTypes = {
123 0 : {"FlowGwHcclTransData", DgwProfInfoType::HCCL_TRANS_DATA},
124 0 : {"FlowGwAlloMbuf", DgwProfInfoType::ALLOC_MBUF},
125 0 : {"FlowGwEnqueueData", DgwProfInfoType::ENQUEUE_DATA},
126 75 : };
127 :
128 60 : for (const auto &name_pair : namesToProfTypes) {
129 45 : const ProfStatus ret = BqsMsprofApiAdapter::GetInstance().MsprofRegTypeInfo(
130 : static_cast<uint16_t>(MSPROF_REPORT_MODEL_LEVEL),
131 45 : static_cast<int32_t>(name_pair.second),
132 : name_pair.first.c_str());
133 45 : if (ret != ProfStatus::PROF_SUCCESS) {
134 0 : DGW_LOG_ERROR("[Prof]Regist profiling type failed, ret=%d, typeId=%d, typeName=%s.",
135 : static_cast<int32_t>(ret), static_cast<int32_t>(name_pair.second), name_pair.first.c_str());
136 0 : return ProfStatus::PROF_FAIL;
137 : }
138 : }
139 :
140 15 : DGW_LOG_RUN_INFO("[Prof]Regist profiling type success.");
141 :
142 15 : return ProfStatus::PROF_SUCCESS;
143 30 : }
144 :
145 14 : int32_t BqsMsprofManager::ProfCallback(uint32_t type, void *data, uint32_t dataLen)
146 : {
147 14 : DGW_LOG_RUN_INFO("[Prof]Queue schedule start process profiling callback, type=%u.", type);
148 :
149 14 : if ((data == nullptr) || (dataLen < sizeof(MsprofCommandHandle))) {
150 1 : DGW_LOG_ERROR("[Prof]Prorfiling callback data is nullptr or dataLen is invalid, dataLen=%u.", dataLen);
151 1 : return static_cast<int32_t>(ProfStatus::PROF_INVALID_PARA);
152 : }
153 :
154 13 : const MsprofCommandHandle *const profCmdHandle = static_cast<MsprofCommandHandle *>(data);
155 13 : ProfStatus ret = ProfStatus::PROF_SUCCESS;
156 13 : switch (type) {
157 10 : case static_cast<uint32_t>(PROF_CTRL_SWITCH):
158 10 : ret = BqsMsprofManager::GetInstance().HandleCtrlSwitch(*profCmdHandle);
159 10 : break;
160 1 : case static_cast<uint32_t>(PROF_CTRL_REPORTER):
161 1 : ret = BqsMsprofManager::GetInstance().HandelCtrlReporter(*profCmdHandle);
162 1 : break;
163 1 : case static_cast<uint32_t>(PROF_CTRL_STEPINFO):
164 1 : ret = BqsMsprofManager::GetInstance().HandleCtrlStepInfo(*profCmdHandle);
165 1 : break;
166 1 : default:
167 1 : DGW_LOG_INFO("[Prof]Get unknown ctrl type, type=%u.", type);
168 1 : break;
169 : }
170 :
171 13 : return static_cast<int32_t>(ret);
172 : }
173 :
174 10 : ProfStatus BqsMsprofManager::HandleCtrlSwitch(const MsprofCommandHandle &profCmdHandle)
175 : {
176 10 : const uint32_t type = profCmdHandle.type;
177 10 : DGW_LOG_INFO("[Prof]Start process prof ctrl switch, type=%u.", type);
178 10 : switch (type) {
179 3 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_START):
180 3 : isRun_ = true;
181 3 : DGW_LOG_RUN_INFO("[Prof]Start queue schedule profiling.");
182 3 : break;
183 :
184 4 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_STOP):
185 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_FINALIZE):
186 4 : isRun_ = false;
187 4 : DGW_LOG_RUN_INFO("[Prof]Stop queue schedule profiling.");
188 4 : break;
189 :
190 3 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_INIT):
191 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_MODEL_SUBSCRIBE):
192 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_MODEL_UNSUBSCRIBE):
193 : default:
194 3 : break;
195 : }
196 :
197 10 : return ProfStatus::PROF_SUCCESS;
198 : }
199 :
200 1 : ProfStatus BqsMsprofManager::HandelCtrlReporter(const MsprofCommandHandle &profCmdHandle) const
201 : {
202 : (void)profCmdHandle;
203 1 : DGW_LOG_INFO("[Prof]Start process prof ctrl reporter.");
204 1 : return ProfStatus::PROF_SUCCESS;
205 : }
206 :
207 1 : ProfStatus BqsMsprofManager::HandleCtrlStepInfo(const MsprofCommandHandle &profCmdHandle) const
208 : {
209 : (void)profCmdHandle;
210 1 : DGW_LOG_INFO("[Prof]Start process prof ctrl step info.");
211 1 : return ProfStatus::PROF_SUCCESS;
212 : }
213 :
214 27 : void BqsMsprofManager::ReportApiPerf(const ProfInfo &profData) const
215 : {
216 27 : if (!isRun_) {
217 22 : return;
218 : }
219 :
220 5 : MsprofApi reportData;
221 5 : reportData.level = static_cast<uint16_t>(MSPROF_REPORT_MODEL_LEVEL);
222 5 : reportData.type = profData.type;
223 5 : reportData.threadId = GetTid();
224 5 : reportData.reserve = 0UL;
225 5 : reportData.beginTime = profData.timeStamp;
226 5 : reportData.endTime = GetTimeStamp();
227 5 : reportData.itemId = profData.itemId;
228 :
229 5 : const ProfStatus ret = BqsMsprofApiAdapter::GetInstance().MsprofReportApi(agingFlag_, &reportData);
230 5 : if (ret != ProfStatus::PROF_SUCCESS) {
231 0 : DGW_LOG_ERROR("[Prof]Report api failed, ret=%d, itemId=%lu", static_cast<int32_t>(ret), profData.itemId);
232 : }
233 :
234 5 : DGW_LOG_INFO("[Prof]Send api perf success, itemId=%lu, beginTime=%lu.", reportData.itemId, reportData.beginTime);
235 :
236 5 : return;
237 : }
238 :
239 2 : void BqsMsprofManager::ReportEventPerf(const ProfInfo &profData)
240 : {
241 2 : if (!isRun_) {
242 1 : return;
243 : }
244 :
245 1 : ++requestId_;
246 1 : MsprofEvent reportData;
247 1 : reportData.level = static_cast<uint16_t>(MSPROF_REPORT_MODEL_LEVEL);
248 1 : reportData.type = profData.type;
249 1 : reportData.threadId = GetTid();
250 1 : reportData.requestId = requestId_.load();
251 1 : reportData.timeStamp = profData.timeStamp;
252 1 : reportData.itemId = profData.itemId;
253 :
254 1 : const ProfStatus ret = BqsMsprofApiAdapter::GetInstance().MsprofReportEvent(agingFlag_, &reportData);
255 1 : if (ret != ProfStatus::PROF_SUCCESS) {
256 0 : DGW_LOG_ERROR("[Prof]Report event failed, ret=%d, requestId=%u, itemId=%lu.",
257 : static_cast<int32_t>(ret), reportData.requestId, reportData.itemId);
258 : }
259 :
260 1 : DGW_LOG_INFO("[Prof]Send event perf success, requestId=%u, itemId=%lu, timeStamp=%lu.",
261 : reportData.requestId, reportData.itemId, reportData.timeStamp);
262 :
263 1 : return;
264 : }
265 :
266 : } // namespace bqs
|