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 : #include "aicpusd_drv_manager.h"
11 : #include <sys/time.h>
12 : #include <sstream>
13 : #include "driver/ascend_hal.h"
14 : #include "aicpusd_status.h"
15 : #include "aicpusd_context.h"
16 : #include "aicpusd_resource_manager.h"
17 : #include "securec.h"
18 : #include "type_def.h"
19 : #include "aicpusd_hal_interface_ref.h"
20 : #include "aicpusd_feature_ctrl.h"
21 :
22 : #ifdef __cplusplus
23 : extern "C" {
24 : #endif
25 : #ifdef __cplusplus
26 : }
27 : #endif
28 :
29 : namespace {
30 : // device num
31 : constexpr uint32_t DEVICE_NUM = 64U;
32 : // first array index
33 : constexpr size_t FIRST_INDEX = 0LU;
34 : // max number of eatch device can split
35 : constexpr const uint32_t DEVICE_MAX_SPLIT_NUM = 16U;
36 : // max number of eatch device cpu
37 : constexpr const uint32_t DEVICE_MAX_CPU_NUM = 16U;
38 : // 查询bind信息间隔
39 : constexpr uint32_t QUERY_BIND_HOST_PID_INTERVBALE = 10000U;
40 : // 查询bind超时时间
41 : #ifndef aicpusd_UT
42 : constexpr uint32_t QUERY_BIND_HOST_PID_TIME = 120000000U;
43 : #else
44 : constexpr uint32_t QUERY_BIND_HOST_PID_TIME = 100000U;
45 : #endif
46 : // bind结果的日志输出周期
47 : constexpr uint32_t QUERY_BIND_HOST_PID_LOG_INTERVAL = 1000U;
48 : } // namespace
49 :
50 : namespace AicpuSchedule {
51 2061 : AicpuDrvManager& AicpuDrvManager::GetInstance()
52 : {
53 2061 : static AicpuDrvManager instance;
54 2061 : return instance;
55 : }
56 :
57 59 : int32_t AicpuDrvManager::GetNormalAicpuDCpuInfo(const std::vector<uint32_t>& deviceVec)
58 : {
59 59 : uint32_t deviceIdTmp = deviceVec[FIRST_INDEX];
60 : drvError_t ret;
61 59 : if (FeatureCtrl::IsVfModeDie1(deviceVec[FIRST_INDEX])) {
62 2 : int64_t pfDeviceId = 0;
63 2 : ret = halGetDeviceInfo(deviceVec[FIRST_INDEX], MODULE_TYPE_SYSTEM, INFO_TYPE_PHY_DIE_ID, &pfDeviceId);
64 2 : if (ret != DRV_ERROR_NONE) {
65 1 : aicpusd_err("halGetDeviceInfo get pfDeviceId fail in device[%d], ret[%d]", deviceVec[FIRST_INDEX], ret);
66 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
67 : }
68 1 : deviceIdTmp = static_cast<uint32_t>(pfDeviceId);
69 : }
70 58 : int64_t aicpuNum = 0;
71 58 : int64_t aicpuOsSched = 0;
72 58 : int64_t ccpuNum = 0;
73 58 : int64_t ccpuOsSched = 0;
74 58 : int64_t dcpuNum = 0;
75 58 : int64_t dcpuOsSched = 0;
76 58 : int64_t tsCpuNum = 0;
77 58 : int64_t tsCpuOsSched = 0;
78 : uint32_t retDrv =
79 58 : static_cast<uint32_t>(AicpuGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum));
80 58 : retDrv |=
81 58 : static_cast<uint32_t>(AicpuGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_OS_SCHED, &aicpuOsSched));
82 58 : retDrv |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_CORE_NUM, &ccpuNum));
83 58 : retDrv |=
84 58 : static_cast<uint32_t>(AicpuGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_OS_SCHED, &ccpuOsSched));
85 58 : retDrv |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_CORE_NUM, &dcpuNum));
86 58 : retDrv |=
87 58 : static_cast<uint32_t>(AicpuGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_OS_SCHED, &dcpuOsSched));
88 58 : retDrv |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_CORE_NUM, &tsCpuNum));
89 58 : retDrv |=
90 58 : static_cast<uint32_t>(AicpuGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_OS_SCHED, &tsCpuOsSched));
91 58 : if (retDrv != 0U) {
92 0 : aicpusd_err("AicpuGetDeviceInfo failed, ret[%u]", retDrv);
93 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
94 : }
95 :
96 58 : if (FeatureCtrl::IsAosCore()) {
97 2 : aicpuNumPerDev_ = aicpuNum;
98 2 : if (ccpuOsSched != 0) {
99 1 : aicpuBaseId_ += ccpuNum;
100 : }
101 2 : if (dcpuOsSched != 0) {
102 1 : aicpuBaseId_ += dcpuNum;
103 : }
104 : }
105 : // connot overflow
106 58 : coreNumPerDev_ =
107 58 : (ccpuNum * ccpuOsSched) + (dcpuNum * dcpuOsSched) + (aicpuNum * aicpuOsSched) + (tsCpuNum * tsCpuOsSched);
108 58 : aicpusd_run_info(
109 : "GetNormalAicpuDCpuInfo, deviceId[%u], aicpu_num[%u], aicpu_os_sched[%u], ccpu_num[%u], "
110 : "ccpu_os_sched[%u], dcpu_num[%u], dcpu_os_sched[%u], tscpu_num[%u], tscpu_os_sched[%u].",
111 : deviceIdTmp, aicpuNum, aicpuOsSched, ccpuNum, ccpuOsSched, dcpuNum, dcpuOsSched, tsCpuNum, tsCpuOsSched);
112 58 : dcpuBase_ = (deviceIdTmp * coreNumPerDev_) + ccpuNum;
113 58 : dcpuNum_ = dcpuNum;
114 58 : return AICPU_SCHEDULE_OK;
115 : }
116 728 : int32_t AicpuDrvManager::AicpuGetDeviceInfo(
117 : const uint32_t deviceId, const DEV_MODULE_TYPE moduleType, const DEV_INFO_TYPE infoType, int64_t* value) const
118 : {
119 728 : if (value == nullptr) {
120 0 : aicpusd_err(
121 : "halGetDeviceInfo value is null, deviceId[%u], DEV_MODULE_TYPE[%d], DEV_INFO_TYPE[%d]", deviceId,
122 : static_cast<int32_t>(moduleType), static_cast<int32_t>(infoType));
123 0 : return -1;
124 : }
125 : const auto ret =
126 728 : halGetDeviceInfo(deviceId, static_cast<int32_t>(moduleType), static_cast<int32_t>(infoType), value);
127 728 : if (ret != DRV_ERROR_NONE) {
128 4 : aicpusd_err(
129 : "halGetDeviceInfo failed, ret[%d], deviceId[%u] DEV_MODULE_TYPE[%d], DEV_INFO_TYPE[%d], "
130 : "value[%lld]",
131 : ret, deviceId, static_cast<int32_t>(moduleType), static_cast<int32_t>(infoType), *value);
132 : }
133 728 : return static_cast<int32_t>(ret);
134 : }
135 :
136 66 : int32_t AicpuDrvManager::GetNormalAicpuInfo(const std::vector<uint32_t>& deviceVec)
137 : {
138 66 : int64_t aicpuNum = 0;
139 66 : int64_t aicpuBitMap = 0;
140 66 : int32_t ret = 0;
141 66 : if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceVec[0])) {
142 4 : ret = AicpuGetDeviceInfo(deviceVec[FIRST_INDEX], MODULE_TYPE_AICPU, INFO_TYPE_PF_CORE_NUM, &aicpuNum);
143 4 : if (ret != DRV_ERROR_NONE) {
144 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
145 : }
146 3 : ret = AicpuGetDeviceInfo(deviceVec[FIRST_INDEX], MODULE_TYPE_AICPU, INFO_TYPE_PF_OCCUPY, &aicpuBitMap);
147 3 : if (ret != DRV_ERROR_NONE) {
148 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
149 : }
150 : } else {
151 62 : ret = AicpuGetDeviceInfo(deviceVec[FIRST_INDEX], MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum);
152 62 : if (ret != DRV_ERROR_NONE) {
153 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
154 : }
155 61 : ret = AicpuGetDeviceInfo(deviceVec[FIRST_INDEX], MODULE_TYPE_AICPU, INFO_TYPE_OCCUPY, &aicpuBitMap);
156 61 : if (ret != DRV_ERROR_NONE) {
157 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
158 : }
159 : }
160 :
161 64 : aicpusd_run_info("aicpuBitMap[%lld], aicpuNum[%lld].", aicpuBitMap, aicpuNum);
162 64 : aicpuNumPerDev_ = static_cast<uint32_t>(aicpuNum);
163 64 : aicpuIdVec_.clear();
164 :
165 64 : DeployContext deployCtx = DeployContext::DEVICE;
166 64 : (void)GetAicpuDeployContext(deployCtx);
167 64 : if (deployCtx == DeployContext::HOST) {
168 65 : for (int64_t i = 0; i < aicpuNum; ++i) {
169 64 : aicpuIdVec_.push_back(i);
170 : }
171 1 : return AICPU_SCHEDULE_OK;
172 : }
173 :
174 1071 : for (uint32_t i = 0U; i < DEVICE_MAX_CPU_NUM; i++) {
175 1008 : if ((aicpuBitMap & 0x1LL) != 0LL) {
176 106 : aicpuIdVec_.push_back(i);
177 : }
178 1008 : aicpuBitMap = aicpuBitMap >> 1;
179 : }
180 63 : if (static_cast<uint32_t>(aicpuNum) != aicpuIdVec_.size()) {
181 1 : aicpusd_err("aicpunum bitmap error, aicpuNum[%lld],aicpuIdVecSize[%zu]", aicpuNum, aicpuIdVec_.size());
182 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
183 : }
184 62 : return AICPU_SCHEDULE_OK;
185 : }
186 :
187 58 : int32_t AicpuDrvManager::GetCcpuInfo(const std::vector<uint32_t>& deviceVec)
188 : {
189 58 : int64_t ccpuBitMap = 0;
190 58 : const int32_t ret = AicpuGetDeviceInfo(deviceVec[FIRST_INDEX], MODULE_TYPE_CCPU, INFO_TYPE_OCCUPY, &ccpuBitMap);
191 58 : if (ret != DRV_ERROR_NONE) {
192 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
193 : }
194 58 : aicpusd_run_info("ccpuBitMap[%lld].", ccpuBitMap);
195 986 : for (uint32_t i = 0U; i < DEVICE_MAX_CPU_NUM; i++) {
196 928 : if ((ccpuBitMap & 0x1LL) != 0LL) {
197 57 : ccpuIdVec_.push_back(i);
198 : }
199 928 : ccpuBitMap = ccpuBitMap >> 1;
200 : }
201 58 : return AICPU_SCHEDULE_OK;
202 : }
203 :
204 2 : int32_t AicpuDrvManager::GetThreadVfAicpuDCpuInfo(const std::vector<uint32_t>& deviceVec)
205 : {
206 2 : const uint32_t deviceId = deviceVec[FIRST_INDEX];
207 2 : int64_t aicpuNum = 0L;
208 : uint32_t ret =
209 2 : static_cast<uint32_t>(AicpuGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum));
210 2 : int64_t aicpuOsSched = 0;
211 2 : ret |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_OS_SCHED, &aicpuOsSched));
212 2 : int64_t ccpuNum = 0;
213 2 : ret |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceId, MODULE_TYPE_CCPU, INFO_TYPE_CORE_NUM, &ccpuNum));
214 2 : int64_t ccpuOsSched = 0;
215 2 : ret |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceId, MODULE_TYPE_CCPU, INFO_TYPE_OS_SCHED, &ccpuOsSched));
216 2 : int64_t dcpuNum = 0;
217 2 : ret |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceId, MODULE_TYPE_DCPU, INFO_TYPE_CORE_NUM, &dcpuNum));
218 2 : int64_t dcpuOsSched = 0;
219 2 : ret |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceId, MODULE_TYPE_DCPU, INFO_TYPE_OS_SCHED, &dcpuOsSched));
220 2 : int64_t tsCpuNum = 0;
221 2 : ret |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceId, MODULE_TYPE_TSCPU, INFO_TYPE_CORE_NUM, &tsCpuNum));
222 2 : int64_t tsCpuOsSched = 0;
223 2 : ret |= static_cast<uint32_t>(AicpuGetDeviceInfo(deviceId, MODULE_TYPE_TSCPU, INFO_TYPE_OS_SCHED, &tsCpuOsSched));
224 2 : if (ret != 0U) {
225 0 : aicpusd_err("AicpuGetDeviceInfo failed, ret[%u]", ret);
226 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
227 : }
228 :
229 2 : if (FeatureCtrl::IsAosCore()) {
230 1 : aicpuNumPerDev_ = static_cast<uint32_t>(aicpuNum);
231 1 : if (ccpuOsSched != 0L) {
232 1 : aicpuBaseId_ += static_cast<uint32_t>(ccpuNum);
233 : }
234 1 : if (dcpuOsSched != 0L) {
235 1 : aicpuBaseId_ += static_cast<uint32_t>(dcpuNum);
236 : }
237 : }
238 : // connot overflow
239 2 : coreNumPerDev_ = (static_cast<uint32_t>(ccpuNum) * static_cast<uint32_t>(ccpuOsSched)) +
240 2 : (static_cast<uint32_t>(dcpuNum) * static_cast<uint32_t>(dcpuOsSched)) +
241 2 : (static_cast<uint32_t>(aicpuNum) * static_cast<uint32_t>(aicpuOsSched)) +
242 2 : (static_cast<uint32_t>(tsCpuNum) * static_cast<uint32_t>(tsCpuOsSched));
243 2 : aicpusd_info(
244 : "GetThreadVfAicpuDCpuInfo, deviceId[%u], aicpuNum[%llu], aicpuOsSched[%llu], ccpuNum[%llu], "
245 : "ccpuOsSched[%llu], dcpuNum[%llu], dcpuOsSched[%llu], tsCpuNum[%llu], tsCpuOsSched[%llu].",
246 : deviceId, aicpuNum, aicpuOsSched, ccpuNum, ccpuOsSched, dcpuNum, dcpuOsSched, tsCpuNum, tsCpuOsSched);
247 2 : dcpuBase_ = (deviceVec[FIRST_INDEX] * coreNumPerDev_) + static_cast<uint32_t>(ccpuNum);
248 2 : dcpuNum_ = static_cast<uint32_t>(dcpuNum);
249 2 : return AICPU_SCHEDULE_OK;
250 : }
251 :
252 57 : void AicpuDrvManager::InitDrvMgrCaluniqueVfId(const std::vector<uint32_t>& deviceVec, const uint32_t vfId)
253 : {
254 57 : if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceVec[0])) {
255 1 : uniqueVfId_ = deviceVec[0];
256 : } else {
257 56 : uniqueVfId_ = vfId;
258 56 : if (FeatureCtrl::IsAosCore()) {
259 1 : return;
260 : }
261 55 : if ((!deviceVec.empty()) && (deviceVec[FIRST_INDEX] != 0U) && (vfId != 0U)) {
262 2 : uint32_t maxNumSpDev = 0U;
263 2 : const auto vfMaxRet = halGetDeviceVfMax(deviceVec[FIRST_INDEX], &maxNumSpDev);
264 2 : if ((vfMaxRet != DRV_ERROR_NONE) || (maxNumSpDev > DEVICE_MAX_SPLIT_NUM)) {
265 0 : aicpusd_err("Failed to get device cat vf number, result[%d], max num[%u].", vfMaxRet, maxNumSpDev);
266 0 : return;
267 : }
268 2 : uniqueVfId_ = (maxNumSpDev * deviceVec[FIRST_INDEX]) + vfId;
269 : }
270 : }
271 56 : aicpusd_run_info("InitDrvMgr uniqueVfId=%u, deviceId=%u", uniqueVfId_, deviceVec[0]);
272 : }
273 :
274 60 : void AicpuDrvManager::InitSocType(const uint32_t deviceId)
275 : {
276 60 : DeployContext deployCtx = DeployContext::DEVICE;
277 60 : (void)GetAicpuDeployContext(deployCtx);
278 60 : if (deployCtx == DeployContext::HOST) {
279 0 : return;
280 : }
281 :
282 60 : int64_t hardwareVersion = 0L;
283 60 : const int32_t ret = AicpuGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &hardwareVersion);
284 60 : if (ret != AICPU_SCHEDULE_OK) {
285 2 : aicpusd_err("Get device info failed, deviceId=%u", deviceId);
286 2 : return;
287 : }
288 :
289 58 : FeatureCtrl::Init(hardwareVersion, deviceId);
290 :
291 58 : return;
292 : }
293 :
294 60 : int32_t AicpuDrvManager::InitDrvMgr(
295 : const std::vector<uint32_t>& deviceVec, const pid_t hostPid, const uint32_t vfId, const bool hasThread,
296 : const aicpu::AicpuRunMode runMode, const std::string& hostProcName)
297 : {
298 60 : if (deviceVec.size() == 0LU) {
299 1 : aicpusd_err("deviceList is empty, deviceNum[%zu]", deviceVec.size());
300 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
301 : }
302 :
303 59 : InitSocType(deviceVec[0U]);
304 :
305 59 : auto ret = 0;
306 59 : if (!FeatureCtrl::IsAosCore()) {
307 59 : ret = GetNormalAicpuInfo(deviceVec);
308 59 : if (ret != 0) {
309 1 : aicpusd_err("GetNormalAicpuInfo error, ret[%d]", ret);
310 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
311 : }
312 58 : ret = GetCcpuInfo(deviceVec);
313 58 : if (ret != 0) {
314 1 : aicpusd_err("GetCcpuInfo error, ret[%d]", ret);
315 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
316 : }
317 : }
318 :
319 57 : deviceNum_ = deviceVec.size();
320 114 : for (size_t i = 0LU; i < deviceNum_; i++) {
321 58 : if (deviceVec[i] >= DEVICE_NUM) {
322 1 : aicpusd_err("invalid device id[%u]", deviceVec[i]);
323 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
324 : }
325 : }
326 :
327 56 : if ((runMode == aicpu::AicpuRunMode::THREAD_MODE) && (vfId > 0)) {
328 0 : ret = GetThreadVfAicpuDCpuInfo(deviceVec);
329 : } else {
330 56 : ret = GetNormalAicpuDCpuInfo(deviceVec);
331 : }
332 56 : if (ret != AICPU_SCHEDULE_OK) {
333 0 : aicpusd_err("get cpu info failed, ret[%d], vfId[%u], runMode[%u]", ret, vfId, runMode);
334 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
335 : }
336 :
337 56 : InitDrvMgrCaluniqueVfId(deviceVec, vfId);
338 56 : aicpusd_run_info(
339 : "host pid[%d], host proc name[%s], vf id[%u], first aicpu index[%u], aicpu num[%u],"
340 : " dcpu base index[%u], dcpu num[%u].",
341 : hostPid, hostProcName.c_str(), vfId, aicpuBaseId_, aicpuNumPerDev_, dcpuBase_, dcpuNum_);
342 :
343 56 : deviceVec_ = deviceVec;
344 56 : hostPid_ = hostPid;
345 56 : vfId_ = vfId;
346 56 : hasThread_ = hasThread;
347 56 : isInit_ = true;
348 56 : hostProcName_ = hostProcName;
349 :
350 56 : return AICPU_SCHEDULE_OK;
351 : }
352 :
353 3 : void AicpuDrvManager::DettachAllDevice(const size_t deviceIndex) const
354 : {
355 6 : for (size_t i = 0LU; i <= deviceIndex; i++) {
356 3 : (void)halEschedDettachDevice(deviceVec_[i]);
357 : }
358 3 : }
359 :
360 15 : int32_t AicpuDrvManager::InitDrvSchedModule(const uint32_t grpId, const std::map<EVENT_ID, SCHEDULE_PRIORITY>& priority)
361 : {
362 : // use driver event means has thread
363 15 : hasThread_ = true;
364 15 : int32_t ret = InitDrvZone();
365 15 : if (ret != DRV_ERROR_NONE) {
366 0 : aicpusd_err("Failed to init the drv zone, ret[%d].", ret);
367 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
368 : }
369 24 : for (size_t i = 0LU; i < deviceNum_; i++) {
370 14 : aicpusd_info("Attach device[%u] to drv scheduler", deviceVec_[i]);
371 14 : ret = halEschedAttachDevice(deviceVec_[i]);
372 14 : if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_PROCESS_REPEAT_ADD)) {
373 2 : aicpusd_err("Failed to attach device in drv, result[%d], device[%u].", ret, deviceVec_[i]);
374 5 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
375 : }
376 :
377 12 : GROUP_TYPE cpuGrpType = GRP_TYPE_BIND_DP_CPU;
378 12 : DeployContext deployCtx = DeployContext::DEVICE;
379 12 : const StatusCode status = GetAicpuDeployContext(deployCtx);
380 12 : if (status != AICPU_SCHEDULE_OK) {
381 0 : aicpusd_err("Get current deploy ctx failed.");
382 0 : return status;
383 : }
384 12 : const uint32_t aicpuNum = GetAicpuNumPerDevice();
385 12 : if ((deployCtx == DeployContext::HOST) || (aicpuNum == 0U)) {
386 0 : cpuGrpType = GRP_TYPE_BIND_CP_CPU;
387 : }
388 12 : aicpusd_info("Create group[%u], device[%d], type[%d]", grpId, deviceVec_[i], cpuGrpType);
389 12 : ret = halEschedCreateGrp(deviceVec_[i], grpId, cpuGrpType);
390 12 : if (ret != DRV_ERROR_NONE) {
391 2 : (void)DettachAllDevice(i);
392 2 : aicpusd_err(
393 : "Failed to create group in drv, result[%d], group[%u], device[%d], type[%d].", ret, grpId,
394 : deviceVec_[i], cpuGrpType);
395 2 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
396 : }
397 91 : for (const auto& item : priority) {
398 82 : ret = halEschedSetEventPriority(deviceVec_[i], item.first, item.second);
399 82 : if (ret != DRV_ERROR_NONE) {
400 1 : (void)DettachAllDevice(i);
401 1 : aicpusd_err("Failed to set event[%d] priority, result[%d].", item.first, ret);
402 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
403 : }
404 81 : aicpusd_info("Set event[%d] priority[%d] success.", item.first, item.second);
405 : }
406 :
407 9 : if (FeatureCtrl::ShouldInitDrvThread() && (deployCtx == DeployContext::DEVICE) &&
408 : (&halDrvEventThreadInit != nullptr)) {
409 : // call driver interface
410 0 : ret = halDrvEventThreadInit(deviceVec_[i]);
411 0 : aicpusd_run_info("Enable process drv queue msg on ccpu, ret is %d.", static_cast<int32_t>(ret));
412 : }
413 : }
414 10 : return AICPU_SCHEDULE_OK;
415 : }
416 :
417 16 : int32_t AicpuDrvManager::InitDrvZone() const
418 : {
419 : // init bufManager/eventManager
420 16 : if (hasThread_) {
421 15 : (void)BufManager::GetInstance().InitBufManager();
422 15 : (void)EventWaitManager::NotifyWaitManager(MAX_NOTIFY_COUNT);
423 15 : (void)EventWaitManager::EndGraphWaitManager(MAX_MODEL_COUNT);
424 15 : (void)ModelStreamManager::GetInstance();
425 15 : (void)EventWaitManager::QueueNotEmptyWaitManager(DEFAULT_QUEUE_COUNT);
426 15 : (void)EventWaitManager::QueueNotFullWaitManager(DEFAULT_QUEUE_COUNT);
427 15 : (void)EventWaitManager::PrepareMemWaitManager(MAX_MODEL_COUNT);
428 15 : (void)EventWaitManager::AnyQueNotEmptyWaitManager(MAX_MODEL_COUNT);
429 15 : (void)EventWaitManager::TableUnlockWaitManager(MAX_MODEL_COUNT);
430 : }
431 16 : return AICPU_SCHEDULE_OK;
432 : }
433 :
434 9 : int32_t AicpuDrvManager::SubscribeQueueNotEmptyEvent(const uint32_t queueId) const
435 : {
436 9 : const uint32_t deviceId = GetDeviceId();
437 9 : aicpusd_info(
438 : "Begin to subscribe non-empty event, deviceId[%u], queueId[%u], groupId[%u].", deviceId, queueId, groupId_);
439 9 : const drvError_t ret = halQueueSubscribe(deviceId, queueId, groupId_, QUEUE_TYPE_SINGLE);
440 9 : if (ret != DRV_ERROR_NONE) {
441 1 : aicpusd_err("Failed to subscribe event for queue[%u], ret[%d].", queueId, ret);
442 1 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
443 : }
444 :
445 8 : aicpusd_info(
446 : "End to subscribe non-empty event, deviceId[%u], queueId[%u], groupId[%u].", deviceId, queueId, groupId_);
447 8 : return AICPU_SCHEDULE_OK;
448 : }
449 :
450 5 : int32_t AicpuDrvManager::UnSubscribeQueueNotEmptyEvent(const uint32_t queueId) const
451 : {
452 5 : const uint32_t deviceId = GetDeviceId();
453 5 : aicpusd_info("Begin to unsubscribe non-empty event, deviceId[%u], queueId[%u].", deviceId, queueId);
454 5 : const drvError_t ret = halQueueUnsubscribe(deviceId, queueId);
455 5 : if (ret != DRV_ERROR_NONE) {
456 1 : aicpusd_warn("Failed to unsubscribe event for queue[%u], ret[%d].", queueId, ret);
457 1 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
458 : }
459 :
460 4 : aicpusd_info("End to unsubscribe non-empty event, deviceId[%u], queueId[%u].", deviceId, queueId);
461 4 : return AICPU_SCHEDULE_OK;
462 : }
463 :
464 5 : int32_t AicpuDrvManager::SubscribeQueueNotFullEvent(const uint32_t queueId) const
465 : {
466 5 : const uint32_t deviceId = GetDeviceId();
467 5 : aicpusd_info(
468 : "Begin to subscribe not full event, deviceId[%u], queueId[%u], groupId[%u].", deviceId, queueId, groupId_);
469 5 : const drvError_t ret = halQueueSubF2NFEvent(deviceId, queueId, groupId_);
470 5 : if (ret != DRV_ERROR_NONE) {
471 1 : aicpusd_err("Failed to subscribe the event of output queue[%u], ret[%d].", queueId, ret);
472 1 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
473 : }
474 4 : aicpusd_info(
475 : "End to subscribe not full event, deviceId[%u], queueId[%u], groupId[%u].", deviceId, queueId, groupId_);
476 4 : return AICPU_SCHEDULE_OK;
477 : }
478 :
479 4 : int32_t AicpuDrvManager::UnSubscribeQueueNotFullEvent(const uint32_t queueId) const
480 : {
481 4 : const uint32_t deviceId = GetDeviceId();
482 4 : aicpusd_info("Begin to unsubscribe not full event, deviceId[%u], queueId[%u].", deviceId, queueId);
483 4 : const drvError_t ret = halQueueUnsubF2NFEvent(deviceId, queueId);
484 4 : if (ret != DRV_ERROR_NONE) {
485 1 : aicpusd_warn("Failed to unsubscribe not full event for queue[%u], ret[%d].", queueId, ret);
486 1 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
487 : }
488 3 : aicpusd_info("End to unsubscribe not full event, deviceId[%u], queueId[%u].", deviceId, queueId);
489 3 : return AICPU_SCHEDULE_OK;
490 : }
491 :
492 14 : int32_t AicpuDrvManager::BindHostPid(
493 : const std::string& signStr, const int32_t mode, const uint32_t vfId, const enum devdrv_process_type cpType) const
494 : {
495 14 : aicpusd_info(
496 : "Begin to bind host pid, device id[%u], host pid[%d], mode[%d], vfId[%u], cp type[%d]", deviceVec_[FIRST_INDEX],
497 : hostPid_, mode, vfId, cpType);
498 14 : if (mode >= static_cast<int32_t>(AicpuPlat::AICPU_MAX_PLAT)) {
499 1 : aicpusd_err("plat mode[%d] should less than %d", mode, AicpuPlat::AICPU_MAX_PLAT);
500 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
501 : }
502 :
503 13 : if (cpType >= DEVDRV_PROCESS_CPTYPE_MAX) {
504 1 : aicpusd_err("cp type[%d] should less than %d", cpType, DEVDRV_PROCESS_CPTYPE_MAX);
505 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
506 : }
507 :
508 12 : struct drvBindHostpidInfo para = {};
509 23 : for (size_t i = 0LU; i < deviceNum_; i++) {
510 12 : para.host_pid = hostPid_;
511 12 : para.vfid = vfId;
512 12 : para.len = static_cast<uint32_t>(PROCESS_SIGN_LENGTH);
513 12 : para.mode = mode;
514 12 : para.cp_type = cpType;
515 12 : para.chip_id = deviceVec_[i];
516 12 : const errno_t memRet = strcpy_s(para.sign, static_cast<size_t>(PROCESS_SIGN_LENGTH), signStr.c_str());
517 12 : if (memRet != EOK) {
518 0 : aicpusd_err(
519 : "memcpy ret[%d], pid[%d], device id[%u], cp type[%d], mode[%d]", memRet, hostPid_, deviceVec_[i],
520 : cpType, mode);
521 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
522 : }
523 :
524 12 : const drvError_t drvRet = drvBindHostPid(para);
525 12 : if (drvRet != DRV_ERROR_NONE) {
526 1 : aicpusd_err(
527 : "Call drvBindHostPid failed, ret[%d] device id[%u], host pid[%d], mode[%d], cp type[%d],"
528 : " vf id[%u]",
529 : drvRet, deviceVec_[i], hostPid_, mode, cpType, vfId);
530 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
531 : }
532 : }
533 :
534 11 : aicpusd_run_info("Bind host pid success, hostPid=%u, vfId=%u, mode=%d", hostPid_, vfId, mode);
535 11 : return AICPU_SCHEDULE_OK;
536 : }
537 :
538 5 : int32_t AicpuDrvManager::CheckBindHostPid() const
539 : {
540 5 : aicpusd_run_info("Start query process host pid");
541 5 : if (&drvQueryProcessHostPid == nullptr) {
542 0 : aicpusd_run_info("drvQueryProcessHostPid does not exist");
543 0 : return AICPU_SCHEDULE_OK;
544 : }
545 5 : drvError_t ret = DRV_ERROR_NONE;
546 5 : unsigned int hostpid = 0;
547 5 : unsigned int cpType = DEVDRV_PROCESS_CPTYPE_MAX;
548 5 : const int pid = static_cast<int>(getpid());
549 16 : for (uint32_t i = 0; i < QUERY_BIND_HOST_PID_TIME / QUERY_BIND_HOST_PID_INTERVBALE; i++) {
550 15 : ret = drvQueryProcessHostPid(pid, nullptr, nullptr, &hostpid, &cpType);
551 15 : if ((i % QUERY_BIND_HOST_PID_LOG_INTERVAL) == 0U) {
552 5 : aicpusd_run_info(
553 : "Query process host pid end, ret=%d, hostpid=%u, expect=%u, cpType=%u", static_cast<int32_t>(ret),
554 : hostpid, hostPid_, cpType);
555 : }
556 15 : if (ret == DRV_ERROR_NO_PROCESS) {
557 11 : aicpusd_info("call drvQueryProcessHostPid try again");
558 11 : (void)usleep(QUERY_BIND_HOST_PID_INTERVBALE);
559 11 : continue;
560 : }
561 :
562 4 : if (ret != DRV_ERROR_NONE) {
563 2 : aicpusd_err("call drvQueryProcessHostPid failed, ret[%d]", static_cast<int32_t>(ret));
564 2 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
565 : }
566 :
567 2 : aicpusd_info("call drvQueryProcessHostPid result, hostpid[%d], cpType[%d]", hostpid, cpType);
568 2 : if (hostPid_ == static_cast<pid_t>(hostpid)) {
569 1 : aicpusd_run_info("call drvQueryProcessHostPid successfully, hostpid[%d], cpType[%d].", hostpid, cpType);
570 1 : return AICPU_SCHEDULE_OK;
571 : } else {
572 1 : aicpusd_err(
573 : "CheckBindHostPid failed, hostpid not right. ret[%d], pid[%d], hostpid[%d], cpType[%d]",
574 : static_cast<int32_t>(ret), pid, hostpid, cpType);
575 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
576 : }
577 : }
578 1 : aicpusd_err(
579 : "CheckBindHostPid failed, try timeout. ret[%d], pid[%d], hostpid[%d], cpType[%d]", static_cast<int32_t>(ret),
580 : pid, hostpid, cpType);
581 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
582 : }
583 :
584 70 : uint32_t AicpuDrvManager::GetAicpuNum() const
585 : {
586 70 : aicpusd_info("Get aicpu core num[%u], device num[%zu]", aicpuNumPerDev_, deviceNum_);
587 70 : return aicpuNumPerDev_ * static_cast<uint32_t>(deviceNum_);
588 : }
589 :
590 34 : std::vector<uint32_t> AicpuDrvManager::GetDeviceList() const
591 : {
592 34 : aicpusd_info("Get device list");
593 34 : return deviceVec_;
594 : }
595 :
596 60 : uint32_t AicpuDrvManager::GetAicpuNumPerDevice() const
597 : {
598 60 : aicpusd_info("Get aicpu core num[%u]", aicpuNumPerDev_);
599 60 : return aicpuNumPerDev_;
600 : }
601 :
602 27 : int32_t AicpuDrvManager::QueryProcBuffInfo(uint32_t procId, std::map<std::string, GroupShareAttr>& buffGrpInfo) const
603 : {
604 27 : std::unique_ptr<GroupQueryOutput> groupInfoPtr(new (std::nothrow) GroupQueryOutput());
605 27 : if (groupInfoPtr == nullptr) {
606 0 : aicpusd_err("groupInfoPtr malloc failed.");
607 0 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
608 : }
609 27 : GroupQueryOutput& groupInfo = *(groupInfoPtr.get());
610 27 : uint32_t groupInfoLen = 0U;
611 27 : const auto drvRet = halGrpQuery(
612 : GRP_QUERY_GROUPS_OF_PROCESS, &procId, static_cast<uint32_t>(sizeof(procId)),
613 : PtrToPtr<GroupQueryOutput, void>(&groupInfo), &groupInfoLen);
614 27 : if (drvRet != DRV_ERROR_NONE) {
615 2 : aicpusd_err("Get group info of process[%u] failed, ret[%d]", procId, drvRet);
616 2 : return drvRet;
617 : }
618 25 : if ((static_cast<size_t>(groupInfoLen) % sizeof(groupInfo.grpQueryGroupsOfProcInfo[0])) != 0UL) {
619 1 : aicpusd_err("Output buffer size[%d] in halGrpQuery is invalid", groupInfoLen);
620 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
621 : }
622 24 : const size_t groupNum = static_cast<size_t>(groupInfoLen) / sizeof(groupInfo.grpQueryGroupsOfProcInfo[0]);
623 24 : if (groupNum == 0UL) {
624 12 : buffGrpInfo.clear();
625 12 : aicpusd_info("Query proc[%u] buff succ, group number[%zu]", procId, groupNum);
626 12 : return AICPU_SCHEDULE_OK;
627 : }
628 31 : for (size_t i = 0UL; i < groupNum; ++i) {
629 19 : const std::string grpName(groupInfo.grpQueryGroupsOfProcInfo[i].groupName);
630 19 : if (!IsSvmShareGrp(grpName)) {
631 19 : buffGrpInfo[grpName] = groupInfo.grpQueryGroupsOfProcInfo[i].attr;
632 : }
633 19 : }
634 12 : aicpusd_info("Query proc[%u] buff succ, group number[%zu], size[%lu]", procId, groupNum, buffGrpInfo.size());
635 12 : return AICPU_SCHEDULE_OK;
636 27 : }
637 :
638 128 : uint32_t AicpuDrvManager::GetAicpuPhysIndex(const uint32_t aicpuLogIndex, const uint32_t deviceId) const
639 : {
640 128 : if (FeatureCtrl::IsAosCore()) {
641 : // connot overflow
642 8 : return ((aicpuBaseId_ + aicpuNumPerDev_) * deviceId) + aicpuBaseId_ + aicpuLogIndex;
643 : }
644 120 : if (FeatureCtrl::BindCpuOnlyOneDevice()) {
645 : // 只有一个device,vf切分到同一容器时会产生多个deviceId。
646 0 : return aicpuIdVec_[aicpuLogIndex];
647 : }
648 120 : return (coreNumPerDev_ * deviceId) + aicpuIdVec_[aicpuLogIndex];
649 : }
650 :
651 13 : std::vector<uint32_t> AicpuDrvManager::GetAicpuPhysIndexs(const uint32_t deviceId)
652 : {
653 13 : if (!aicpuPhyIds_.empty()) {
654 11 : return aicpuPhyIds_;
655 : }
656 :
657 2 : const uint32_t aicpuNum = GetAicpuNum();
658 5 : for (uint32_t i = 0U; i < aicpuNum; ++i) {
659 3 : const uint32_t aicpuLogicIdx = i % aicpuNumPerDev_;
660 3 : aicpuPhyIds_.emplace_back(GetAicpuPhysIndex(aicpuLogicIdx, deviceId));
661 : }
662 :
663 2 : return aicpuPhyIds_;
664 : }
665 :
666 19 : bool AicpuDrvManager::IsSvmShareGrp(const std::string& grpName) const
667 : {
668 19 : return grpName.find("svm_share_grp") != std::string::npos;
669 : }
670 : } // namespace AicpuSchedule
|