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 1 : return SubModuleProcessResponse(tsdEventKey_.deviceId, TSD_QS, tsdEventKey_.hostPid, tsdEventKey_.vfId, eventType);
138 : }
139 :
140 2 : void SubModuleInterface::ReportErrMsgToTsd(const int32_t errCode) const
141 : {
142 2 : BQS_LOG_RUN_WARN("ReportErrorMsg errcode is %d.", errCode);
143 2 : std::string errStr;
144 2 : switch (errCode) {
145 1 : case BqsStatus::BQS_STATUS_ATTACH_GROUP_FALED: {
146 1 : errStr = ERROR_MSG_ATTACH_GROUP_FAILED;
147 1 : break;
148 : }
149 1 : default: {
150 1 : errStr = ERROR_MSG_QS_INIT_FAILED;
151 1 : break;
152 : }
153 : }
154 2 : BQS_LOG_RUN_WARN("ReportErrorMsg msg is %s.", errStr.c_str());
155 2 : (void)TsdReportStartOrStopErrCode(
156 2 : tsdEventKey_.deviceId, TSD_QS, tsdEventKey_.hostPid, tsdEventKey_.vfId, errStr.c_str(),
157 2 : static_cast<uint32_t>(errStr.size()));
158 2 : }
159 :
160 6 : int32_t SubModuleInterface::StartQueueScheduleModule(const struct TsdSubEventInfo* const eventInfo)
161 : {
162 6 : BQS_LOG_RUN_INFO("enter queue schedule sub module start process.");
163 : // set event key
164 6 : SetTsdEventKey(eventInfo);
165 :
166 : // args parse
167 6 : ArgsParser startParams;
168 6 : if (!ParseArgsFromFile(startParams)) {
169 1 : BQS_LOG_ERROR("Read aicpu submodule start paras from file failed");
170 1 : return -1;
171 : }
172 :
173 5 : if (!QsSubModuleAttachGroup(startParams)) {
174 1 : BQS_LOG_ERROR("AttachHostGroup error");
175 1 : ReportErrMsgToTsd(BqsStatus::BQS_STATUS_ATTACH_GROUP_FALED);
176 1 : return -1;
177 : }
178 :
179 4 : auto& qsInterface = QueueScheduleInterface::GetInstance();
180 :
181 4 : bqs::InitQsParams initQsParams = {};
182 4 : QsSubModuleInitQsInitParams(initQsParams, startParams);
183 4 : const auto bsqStatus = qsInterface.InitQueueScheduler(initQsParams);
184 4 : if (bsqStatus != bqs::BQS_STATUS_OK) {
185 1 : BQS_LOG_ERROR("QueueSchedule start failed, ret=%d.", bsqStatus);
186 1 : ReportErrMsgToTsd(bsqStatus);
187 1 : return -1;
188 : }
189 :
190 3 : BQS_LOG_RUN_INFO("QueueSchedule init finished.");
191 :
192 3 : const int32_t rspRet = SendSubModuleRsponse(TSD_EVENT_START_QS_MODULE_RSP);
193 3 : if (rspRet != 0) {
194 1 : BQS_LOG_ERROR("Tsd wait for shut down return not ok, error code[%d].", rspRet);
195 1 : return -1;
196 : }
197 :
198 2 : startFlag_ = true;
199 2 : BQS_LOG_RUN_INFO("queue schedule sub module start success");
200 2 : return rspRet;
201 6 : }
202 :
203 3 : int32_t SubModuleInterface::StopQueueScheduleModule(const struct TsdSubEventInfo* const eventInfo)
204 : {
205 : (void)eventInfo;
206 3 : BQS_LOG_RUN_INFO("enter queue schedule sub module stop process.");
207 3 : if (!startFlag_.load()) {
208 1 : BQS_LOG_RUN_INFO("no need to stop qs submodule.");
209 1 : return 0;
210 : }
211 :
212 2 : auto& qsInterface = QueueScheduleInterface::GetInstance();
213 2 : qsInterface.WaitForStop();
214 2 : (void)qsInterface.Destroy();
215 2 : BQS_LOG_RUN_INFO("queue schedule stopped.");
216 2 : const int32_t rspRet = SendSubModuleRsponse(TSD_EVENT_STOP_QS_MODULE_RSP);
217 2 : if (rspRet != 0) {
218 0 : BQS_LOG_ERROR("queue schedule stop response return not ok, error code[%d].", rspRet);
219 0 : return -1;
220 : }
221 :
222 2 : startFlag_ = false;
223 2 : BQS_LOG_RUN_INFO("queue schedule sub module stop success");
224 2 : return rspRet;
225 : }
226 : } // namespace bqs
227 :
228 : extern "C" {
229 6 : int32_t StartQueueScheduleModule(const struct TsdSubEventInfo* const eventInfo)
230 : {
231 6 : return bqs::SubModuleInterface::GetInstance().StartQueueScheduleModule(eventInfo);
232 : }
233 :
234 3 : int32_t StopQueueScheduleModule(const struct TsdSubEventInfo* const eventInfo)
235 : {
236 3 : return bqs::SubModuleInterface::GetInstance().StopQueueScheduleModule(eventInfo);
237 : }
238 : }
|