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 <fstream>
12 : #include <algorithm>
13 : #include <sstream>
14 : #include <unistd.h>
15 : #include "bqs_util.h"
16 : #include "queue_schedule_sub_module_interface.h"
17 : #include "bqs_log.h"
18 : #include "driver/ascend_hal.h"
19 : #include "queue_schedule/qs_client.h"
20 : #include "qs_interface_process.h"
21 :
22 : namespace bqs {
23 : namespace {
24 : constexpr uint32_t MAX_PARAM_NUM = 12U;
25 : const std::string ENV_NAME_REG_ASCEND_MONITOR = "REGISTER_TO_ASCENDMONITOR";
26 : } // namespace
27 :
28 6 : void SubModuleInterface::SetTsdEventKey(const struct TsdSubEventInfo * const eventInfo)
29 : {
30 6 : tsdEventKey_.deviceId = eventInfo->deviceId;
31 6 : tsdEventKey_.hostPid = eventInfo->hostPid;
32 6 : tsdEventKey_.vfId = eventInfo->vfId;
33 6 : }
34 :
35 1 : std::string SubModuleInterface::BuildArgsFilePath() const
36 : {
37 1 : const uint32_t curPid = static_cast<uint32_t>(getpid());
38 2 : const std::string fileName = "queue_schedule_start_param_" + std::to_string(tsdEventKey_.deviceId) +
39 3 : "_" + std::to_string(tsdEventKey_.vfId) + "_" + std::to_string(curPid);
40 1 : std::string pathFreFix = "/home/HwHiAiUser/";
41 1 : std::string inputStr;
42 1 : GetEnvVal(ENV_NAME_REG_ASCEND_MONITOR, inputStr);
43 1 : if (inputStr == "0") {
44 1 : pathFreFix = "/home/mdc/";
45 : }
46 :
47 2 : return pathFreFix.append(fileName);
48 1 : }
49 :
50 6 : void SubModuleInterface::DeleteArgsFile(const std::string &argsFilePath)
51 : {
52 6 : const int32_t ret = remove(argsFilePath.c_str());
53 6 : if (ret != 0) {
54 4 : BQS_LOG_ERROR("Remove file[%s] failed, ret=%d, reason=%s", argsFilePath.c_str(), ret, strerror(errno));
55 4 : return;
56 : }
57 :
58 2 : BQS_LOG_RUN_INFO("Remove file[%s] success", argsFilePath.c_str());
59 : }
60 :
61 2 : bool SubModuleInterface::ParseArgsFromFile(ArgsParser &startParams) const
62 : {
63 2 : const std::string argsFilePath = BuildArgsFilePath();
64 4 : ScopeGuard fileDelGuard([&argsFilePath] () { DeleteArgsFile(argsFilePath); });
65 :
66 2 : std::ifstream argsFile;
67 2 : argsFile.open(argsFilePath, std::ifstream::in);
68 2 : if (!argsFile.is_open()) {
69 1 : BQS_LOG_ERROR("Start file[%s] open failed, reason=%s", argsFilePath.c_str(), strerror(errno));
70 1 : return false;
71 : }
72 2 : ScopeGuard fileCloseGuard([&argsFile] () { argsFile.close(); });
73 :
74 1 : uint32_t item = 0U;
75 1 : std::vector<std::string> fileLines;
76 1 : std::string tempParam;
77 2 : while ((item < MAX_PARAM_NUM) && (getline(argsFile, tempParam))) {
78 1 : fileLines.emplace_back(tempParam);
79 1 : ++item;
80 : }
81 :
82 1 : return startParams.ParseArgs(fileLines);
83 2 : }
84 :
85 4 : bool SubModuleInterface::QsSubModuleAttachGroup(const ArgsParser &startParams)
86 : {
87 4 : BQS_LOG_INFO("Begin to attach group.");
88 4 : if (!startParams.GetWithGroupName()) {
89 1 : BQS_LOG_INFO("withGroupName is false, no need attach now.");
90 1 : return true;
91 : }
92 :
93 3 : std::string groupNameList = startParams.GetGroupName();
94 3 : if (groupNameList.empty()) {
95 1 : BQS_LOG_INFO("grpName is empty.");
96 1 : return true;
97 : }
98 2 : std::stringstream grpNameStream(groupNameList);
99 2 : std::string grpNameElement;
100 2 : std::vector<std::string> groupNameVec;
101 6 : while (getline(grpNameStream, grpNameElement, ',')) {
102 4 : groupNameVec.emplace_back(grpNameElement);
103 : }
104 : // if run context is host, halGrpAttach time out cannot be 0
105 2 : const int32_t halTimeOut = (bqs::GetRunContext() == bqs::RunContext::HOST) ? 3000 : -1;
106 4 : for (const auto &grpName : groupNameVec) {
107 3 : const auto drvRet = halGrpAttach(grpName.c_str(), halTimeOut);
108 3 : if (drvRet != DRV_ERROR_NONE) {
109 1 : BQS_LOG_ERROR("halGrpAttach group[%s] failed. ret[%d]", grpName.c_str(), drvRet);
110 1 : return false;
111 : }
112 2 : BQS_LOG_RUN_INFO("halGrpAttach group[%s] success.", grpName.c_str());
113 : }
114 1 : return true;
115 3 : }
116 :
117 4 : void SubModuleInterface::QsSubModuleInitQsInitParams(InitQsParams &initQsParams, const ArgsParser &startParams)
118 : {
119 4 : initQsParams.deviceId = startParams.GetDeviceId();
120 4 : initQsParams.enqueGroupId = EventGroupId::ENQUEUE_GROUP_ID;
121 4 : initQsParams.f2nfGroupId = EventGroupId::F2NF_GROUP_ID;
122 4 : initQsParams.reschedInterval = static_cast<uint32_t>(startParams.GetReschedInterval());
123 4 : initQsParams.runMode = startParams.GetDeployMode();
124 4 : initQsParams.pid = startParams.GetHostPid();
125 4 : initQsParams.vfId = startParams.GetVfId();
126 4 : initQsParams.pidSign = startParams.GetPidSign();
127 4 : initQsParams.qsInitGrpName = startParams.GetGroupName();
128 4 : initQsParams.schedPolicy = startParams.GetSchedPolicy();
129 4 : initQsParams.starter = startParams.GetStarter();
130 4 : initQsParams.profCfgData = startParams.GetProfCfgData();
131 4 : initQsParams.profFlag = startParams.GetProfFlag();
132 4 : initQsParams.abnormalInterVal = static_cast<uint32_t>(startParams.GetAbnormalInterval());
133 4 : }
134 :
135 1 : int32_t SubModuleInterface::SendSubModuleRsponse(const uint32_t eventType) const
136 : {
137 2 : return SubModuleProcessResponse(tsdEventKey_.deviceId, TSD_QS, tsdEventKey_.hostPid,
138 1 : tsdEventKey_.vfId, eventType);
139 : }
140 :
141 2 : void SubModuleInterface::ReportErrMsgToTsd(const int32_t errCode) const
142 : {
143 2 : BQS_LOG_RUN_WARN("ReportErrorMsg errcode is %d.", errCode);
144 2 : std::string errStr;
145 2 : switch (errCode) {
146 1 : case BqsStatus::BQS_STATUS_ATTACH_GROUP_FALED: {
147 1 : errStr = ERROR_MSG_ATTACH_GROUP_FAILED;
148 1 : break;
149 : }
150 1 : default: {
151 1 : errStr = ERROR_MSG_QS_INIT_FAILED;
152 1 : break;
153 : }
154 : }
155 2 : BQS_LOG_RUN_WARN("ReportErrorMsg msg is %s.", errStr.c_str());
156 2 : (void) TsdReportStartOrStopErrCode(tsdEventKey_.deviceId, TSD_QS, tsdEventKey_.hostPid,
157 2 : tsdEventKey_.vfId, errStr.c_str(),
158 2 : static_cast<uint32_t>(errStr.size()));
159 2 : }
160 :
161 6 : int32_t SubModuleInterface::StartQueueScheduleModule(const struct TsdSubEventInfo * const eventInfo)
162 : {
163 6 : BQS_LOG_RUN_INFO("enter queue schedule sub module start process.");
164 : // set event key
165 6 : SetTsdEventKey(eventInfo);
166 :
167 : // args parse
168 6 : ArgsParser startParams;
169 6 : if (!ParseArgsFromFile(startParams)) {
170 1 : BQS_LOG_ERROR("Read aicpu submodule start paras from file failed");
171 1 : return -1;
172 : }
173 :
174 5 : if (!QsSubModuleAttachGroup(startParams)) {
175 1 : BQS_LOG_ERROR("AttachHostGroup error");
176 1 : ReportErrMsgToTsd(BqsStatus::BQS_STATUS_ATTACH_GROUP_FALED);
177 1 : return -1;
178 : }
179 :
180 4 : auto& qsInterface = QueueScheduleInterface::GetInstance();
181 :
182 4 : bqs::InitQsParams initQsParams = {};
183 4 : QsSubModuleInitQsInitParams(initQsParams, startParams);
184 4 : const auto bsqStatus = qsInterface.InitQueueScheduler(initQsParams);
185 4 : if (bsqStatus != bqs::BQS_STATUS_OK) {
186 1 : BQS_LOG_ERROR("QueueSchedule start failed, ret=%d.", bsqStatus);
187 1 : ReportErrMsgToTsd(bsqStatus);
188 1 : return -1;
189 : }
190 :
191 3 : BQS_LOG_RUN_INFO("QueueSchedule init finished.");
192 :
193 3 : const int32_t rspRet = SendSubModuleRsponse(TSD_EVENT_START_QS_MODULE_RSP);
194 3 : if (rspRet != 0) {
195 1 : BQS_LOG_ERROR("Tsd wait for shut down return not ok, error code[%d].", rspRet);
196 1 : return -1;
197 : }
198 :
199 2 : startFlag_ = true;
200 2 : BQS_LOG_RUN_INFO("queue schedule sub module start success");
201 2 : return rspRet;
202 6 : }
203 :
204 3 : int32_t SubModuleInterface::StopQueueScheduleModule(const struct TsdSubEventInfo * const eventInfo)
205 : {
206 : (void)eventInfo;
207 3 : BQS_LOG_RUN_INFO("enter queue schedule sub module stop process.");
208 3 : if (!startFlag_.load()) {
209 1 : BQS_LOG_RUN_INFO("no need to stop qs submodule.");
210 1 : return 0;
211 : }
212 :
213 2 : auto& qsInterface = QueueScheduleInterface::GetInstance();
214 2 : qsInterface.WaitForStop();
215 2 : (void)qsInterface.Destroy();
216 2 : BQS_LOG_RUN_INFO("queue schedule stopped.");
217 2 : const int32_t rspRet = SendSubModuleRsponse(TSD_EVENT_STOP_QS_MODULE_RSP);
218 2 : if (rspRet != 0) {
219 0 : BQS_LOG_ERROR("queue schedule stop response return not ok, error code[%d].", rspRet);
220 0 : return -1;
221 : }
222 :
223 2 : startFlag_ = false;
224 2 : BQS_LOG_RUN_INFO("queue schedule sub module stop success");
225 2 : return rspRet;
226 : }
227 : } // namespace bqs
228 :
229 : extern "C" {
230 6 : int32_t StartQueueScheduleModule(const struct TsdSubEventInfo *const eventInfo)
231 : {
232 6 : return bqs::SubModuleInterface::GetInstance().StartQueueScheduleModule(eventInfo);
233 : }
234 :
235 3 : int32_t StopQueueScheduleModule(const struct TsdSubEventInfo *const eventInfo)
236 : {
237 3 : return bqs::SubModuleInterface::GetInstance().StopQueueScheduleModule(eventInfo);
238 : }
239 : }
|