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 :
12 : #include <map>
13 : #include <sys/time.h>
14 : #include "driver/ascend_hal.h"
15 : #include "aicpusd_status.h"
16 : #include "securec.h"
17 : #include "aicpusd_common.h"
18 : #include "aicpusd_hal_interface_ref.h"
19 :
20 : #ifdef __cplusplus
21 : extern "C" {
22 : #endif
23 : #ifdef __cplusplus
24 : }
25 : #endif
26 :
27 : namespace {
28 : constexpr const uint32_t DEVICE_NUM = 64U;
29 : // max number of eatch device can split
30 : constexpr const uint32_t DEVICE_MAX_SPLIT_NUM = 16U;
31 : // max number of eatch device cpu
32 : constexpr const uint32_t DEVICE_MAX_CPU_NUM = 16U;
33 : // 查询bind信息间隔
34 : constexpr uint32_t QUERY_BIND_HOST_PID_INTERVBALE = 10000U;
35 : // 查询bind超时时间
36 : #ifndef aicpusd_UT
37 : constexpr uint32_t QUERY_BIND_HOST_PID_TIME = 120000000U;
38 : #else
39 : constexpr uint32_t QUERY_BIND_HOST_PID_TIME = 100000U;
40 : #endif
41 : // bind结果的日志输出周期
42 : constexpr uint32_t QUERY_BIND_HOST_PID_LOG_INTERVAL = 1000U;
43 : // 特权开关打开为1
44 : constexpr int64_t SAFE_VERIFY_OPEN = 1;
45 : } // namespace
46 :
47 : namespace AicpuSchedule {
48 268 : AicpuDrvManager& AicpuDrvManager::GetInstance()
49 : {
50 268 : static AicpuDrvManager instance;
51 268 : return instance;
52 : }
53 :
54 10 : int32_t AicpuDrvManager::GetNormalAicpuInfo(const uint32_t deviceId)
55 : {
56 10 : int64_t aicpuNum = 0;
57 10 : int64_t aicpuBitMap = 0;
58 10 : int32_t ret = 0;
59 10 : if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceId)) {
60 2 : ret = halGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_PF_CORE_NUM, &aicpuNum) +
61 2 : halGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_PF_OCCUPY, &aicpuBitMap);
62 : } else {
63 8 : ret = halGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum) +
64 8 : halGetDeviceInfo(deviceId, MODULE_TYPE_AICPU, INFO_TYPE_OCCUPY, &aicpuBitMap);
65 : }
66 10 : if (ret != DRV_ERROR_NONE) {
67 1 : aicpusd_err(
68 : "halGetDeviceInfo failed, ret[%d], deviceId[%u], DEV_MODULE_TYPE[%d], DEV_INFO_TYPE[%d]", ret, deviceId,
69 : static_cast<int32_t>(MODULE_TYPE_AICPU), static_cast<int32_t>(INFO_TYPE_PF_OCCUPY));
70 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
71 : }
72 9 : aicpusd_run_info("aicpuBitMap[%lld], aicpuNum[%lld]", aicpuBitMap, aicpuNum);
73 9 : aicpuNum_ = static_cast<uint32_t>(aicpuNum);
74 9 : aicpuIdVec_.clear();
75 153 : for (uint32_t i = 0U; i < DEVICE_MAX_CPU_NUM; i++) {
76 144 : if ((static_cast<uint64_t>(aicpuBitMap) & 0x1UL) != 0) {
77 9 : aicpuIdVec_.push_back(i);
78 : }
79 144 : aicpuBitMap = aicpuBitMap >> 1;
80 : }
81 9 : if (static_cast<uint32_t>(aicpuNum) != aicpuIdVec_.size()) {
82 0 : aicpusd_err("aicpunum bitmap error, aicpuNum[%lld],aicpuIdVecSize[%u]", aicpuNum, aicpuIdVec_.size());
83 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
84 : }
85 9 : return AICPU_SCHEDULE_OK;
86 : }
87 :
88 16 : int32_t AicpuDrvManager::InitDrvMgr(
89 : const uint32_t deviceId, const pid_t hostPid, const uint32_t vfId, const bool hasThread)
90 : {
91 16 : if (deviceId >= DEVICE_NUM) {
92 2 : aicpusd_err("invalid device id[%u]", deviceId);
93 2 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
94 : }
95 14 : SetSafeVerifyFlag(deviceId);
96 14 : InitSocType(deviceId);
97 : int32_t ret;
98 14 : if (!FeatureCtrl::IsAosCore()) {
99 11 : ret = GetNormalAicpuInfo(deviceId);
100 11 : if (ret != 0) {
101 1 : aicpusd_err("GetNormalAicpuInfo error, ret[%d]", ret);
102 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
103 : }
104 10 : ret = GetCcpuInfo(deviceId);
105 10 : if ((ret != AICPU_SCHEDULE_OK) && (GetAicpuNum() == 0U)) {
106 1 : aicpusd_err("GetCcpuInfo error, ret[%d]", ret);
107 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
108 : }
109 : }
110 :
111 12 : uint32_t deviceIdTmp = deviceId;
112 12 : if (FeatureCtrl::IsVfModeDie1(deviceId)) {
113 2 : int64_t pfDeviceId = 0;
114 2 : ret = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_PHY_DIE_ID, &pfDeviceId);
115 2 : if (ret != DRV_ERROR_NONE) {
116 1 : aicpusd_err("halGetDeviceInfo get pfDeviceId fail in device[%d], ret[%d]", deviceId, ret);
117 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
118 : }
119 1 : deviceIdTmp = static_cast<uint32_t>(pfDeviceId);
120 : }
121 :
122 11 : int64_t aicpuNum = 0;
123 11 : int64_t aicpuOsSched = 0;
124 11 : int64_t ccpuNum = 0;
125 11 : int64_t ccpuOsSched = 0;
126 11 : int64_t dcpuNum = 0;
127 11 : int64_t dcpuOsSched = 0;
128 11 : int64_t tsCpuNum = 0;
129 11 : int64_t tsCpuOsSched = 0;
130 : uint32_t retDrv =
131 11 : static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum));
132 11 : retDrv |=
133 11 : static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_OS_SCHED, &aicpuOsSched));
134 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_CORE_NUM, &ccpuNum));
135 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_OS_SCHED, &ccpuOsSched));
136 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_CORE_NUM, &dcpuNum));
137 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_OS_SCHED, &dcpuOsSched));
138 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_CORE_NUM, &tsCpuNum));
139 11 : retDrv |=
140 11 : static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_OS_SCHED, &tsCpuOsSched));
141 11 : if (retDrv != 0U) {
142 0 : aicpusd_err("halGetDeviceInfo failed, ret[%u]", retDrv);
143 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
144 : }
145 11 : if (FeatureCtrl::IsAosCore()) {
146 2 : aicpuNum_ = aicpuNum;
147 2 : if (ccpuOsSched != 0) {
148 1 : aicpuBaseId_ += ccpuNum;
149 : }
150 2 : if (dcpuOsSched != 0) {
151 1 : aicpuBaseId_ += dcpuNum;
152 : }
153 : }
154 : // connot overflow
155 11 : coreNumPerDev_ =
156 11 : (ccpuNum * ccpuOsSched) + (dcpuNum * dcpuOsSched) + (aicpuNum * aicpuOsSched) + (tsCpuNum * tsCpuOsSched);
157 11 : dcpuBase_ = (deviceIdTmp * coreNumPerDev_) + ccpuNum;
158 11 : dcpuNum_ = dcpuNum;
159 11 : aicpusd_run_info(
160 : "device id[%u], host pid[%d], first aicpu index[%u], aicpu num[%u],"
161 : " dcpu base index[%u], dcpu num[%u], vf id[%u]",
162 : deviceIdTmp, hostPid, aicpuBaseId_, aicpuNum_, dcpuBase_, dcpuNum_, vfId);
163 11 : deviceId_ = deviceId;
164 11 : hostPid_ = hostPid;
165 11 : vfId_ = vfId;
166 11 : hasThread_ = hasThread;
167 11 : isInit_ = true;
168 :
169 11 : if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceId)) {
170 2 : uniqueVfId_ = deviceId;
171 : } else {
172 9 : uniqueVfId_ = vfId;
173 9 : if (FeatureCtrl::IsAosCore()) {
174 1 : return AICPU_SCHEDULE_OK;
175 : }
176 8 : if ((deviceId != 0U) && (vfId != 0U)) {
177 1 : uint32_t maxNumSpDev = 0U;
178 1 : const auto vfMaxRet = halGetDeviceVfMax(deviceId, &maxNumSpDev);
179 1 : if ((vfMaxRet != DRV_ERROR_NONE) || (maxNumSpDev > DEVICE_MAX_SPLIT_NUM)) {
180 0 : aicpusd_err("Failed to get device cat vf number, result[%d], max num[%u].", vfMaxRet, maxNumSpDev);
181 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
182 : }
183 1 : uniqueVfId_ = maxNumSpDev * deviceId + vfId;
184 : }
185 : }
186 :
187 10 : return AICPU_SCHEDULE_OK;
188 : }
189 :
190 15 : void AicpuDrvManager::InitSocType(const uint32_t deviceId)
191 : {
192 15 : int64_t hardwareVersion = 0L;
193 15 : const int32_t ret = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &hardwareVersion);
194 15 : if (ret != DRV_ERROR_NONE) {
195 2 : aicpusd_err("Get device info failed, deviceId=%u", deviceId);
196 2 : return;
197 : }
198 :
199 13 : FeatureCtrl::Init(hardwareVersion, deviceId);
200 13 : return;
201 : }
202 :
203 8 : int32_t AicpuDrvManager::InitDrvSchedModule(const uint32_t grpId)
204 : {
205 : // use driver event means has thread
206 8 : hasThread_ = true;
207 8 : aicpusd_info("Attach device[%u] to drv scheduler.", deviceId_);
208 8 : int32_t ret = halEschedAttachDevice(deviceId_);
209 8 : if (ret != DRV_ERROR_NONE) {
210 1 : aicpusd_err("Failed to attach device in drv, result[%d].", ret);
211 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
212 : }
213 :
214 7 : const GROUP_TYPE cpuGrpType = (GetAicpuNum() == 0U) ? GRP_TYPE_BIND_CP_CPU : GRP_TYPE_BIND_DP_CPU;
215 7 : aicpusd_info("Create group[%u], type[%d]", grpId, cpuGrpType);
216 7 : ret = halEschedCreateGrp(deviceId_, grpId, cpuGrpType);
217 7 : if (ret != DRV_ERROR_NONE) {
218 1 : (void)halEschedDettachDevice(deviceId_);
219 1 : aicpusd_err("Failed to attach device in drv, result[%d].", ret);
220 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
221 : }
222 6 : if (FeatureCtrl::ShouldInitDrvThread() && (&halDrvEventThreadInit != nullptr)) {
223 6 : ret = halDrvEventThreadInit(deviceId_);
224 6 : aicpusd_run_info("Enable process drv queue msg on ccpu, ret is %d.", static_cast<int32_t>(ret));
225 : }
226 :
227 6 : return AICPU_SCHEDULE_OK;
228 : }
229 :
230 5 : int32_t AicpuDrvManager::CheckBindHostPid() const
231 : {
232 5 : aicpusd_run_info("Start query process host pid");
233 5 : if (&drvQueryProcessHostPid == nullptr) {
234 0 : aicpusd_run_info("drvQueryProcessHostPid does not exist");
235 0 : return AICPU_SCHEDULE_OK;
236 : }
237 5 : drvError_t ret = DRV_ERROR_NONE;
238 5 : unsigned int hostpid = 0;
239 5 : unsigned int cpType = DEVDRV_PROCESS_CPTYPE_MAX;
240 5 : const int pid = static_cast<int>(getpid());
241 16 : for (uint32_t i = 0; i < QUERY_BIND_HOST_PID_TIME / QUERY_BIND_HOST_PID_INTERVBALE; i++) {
242 15 : ret = drvQueryProcessHostPid(pid, nullptr, nullptr, &hostpid, &cpType);
243 15 : if ((i % QUERY_BIND_HOST_PID_LOG_INTERVAL) == 0U) {
244 5 : aicpusd_run_info(
245 : "Query process host pid end, ret=%d, hostpid=%u, expect=%u, cpType=%u", static_cast<int32_t>(ret),
246 : hostpid, hostPid_, cpType);
247 : }
248 15 : if (ret == DRV_ERROR_NO_PROCESS) {
249 11 : aicpusd_info("call drvQueryProcessHostPid try again");
250 11 : (void)usleep(QUERY_BIND_HOST_PID_INTERVBALE);
251 11 : continue;
252 : }
253 :
254 4 : if (ret != DRV_ERROR_NONE) {
255 2 : aicpusd_err("call drvQueryProcessHostPid failed, ret[%d]", static_cast<int32_t>(ret));
256 2 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
257 : }
258 :
259 2 : aicpusd_info("call drvQueryProcessHostPid result, hostpid[%d], cpType[%d]", hostpid, cpType);
260 2 : if (hostPid_ == static_cast<pid_t>(hostpid)) {
261 1 : aicpusd_run_info("call drvQueryProcessHostPid success, hostpid[%d], cpType[%d]", hostpid, cpType);
262 1 : return AICPU_SCHEDULE_OK;
263 : } else {
264 1 : aicpusd_err(
265 : "CheckBindHostPid failed, hostpid not right. ret[%d], pid[%d], hostpid[%d], cpType[%d]",
266 : static_cast<int32_t>(ret), pid, hostpid, cpType);
267 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
268 : }
269 : }
270 1 : aicpusd_err(
271 : "CheckBindHostPid failed, try timeout. ret[%d], pid[%d], hostpid[%d], cpType[%d]", static_cast<int32_t>(ret),
272 : pid, hostpid, cpType);
273 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
274 : }
275 :
276 43 : uint32_t AicpuDrvManager::GetAicpuNum() const
277 : {
278 43 : aicpusd_info("Get aicpu core num[%u]", aicpuNum_);
279 43 : return aicpuNum_;
280 : }
281 :
282 12 : int32_t AicpuDrvManager::GetCcpuInfo(const uint32_t deviceId)
283 : {
284 12 : int64_t ccpuBitMap = 0;
285 12 : const int32_t ret = halGetDeviceInfo(deviceId, MODULE_TYPE_CCPU, INFO_TYPE_OCCUPY, &ccpuBitMap);
286 12 : if (ret != DRV_ERROR_NONE) {
287 1 : aicpusd_err("halGetDeviceInfo failed, devid:%u, ret[%d]", deviceId, ret);
288 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
289 : }
290 11 : aicpusd_run_info("ccpuBitMap[%lld].", ccpuBitMap);
291 187 : for (uint32_t i = 0U; i < DEVICE_MAX_CPU_NUM; i++) {
292 176 : if ((ccpuBitMap & 0x1LL) != 0LL) {
293 9 : ccpuIdVec_.push_back(i);
294 : }
295 176 : ccpuBitMap = ccpuBitMap >> 1;
296 : }
297 11 : return AICPU_SCHEDULE_OK;
298 : }
299 :
300 15 : void AicpuDrvManager::SetSafeVerifyFlag(const uint32_t deviceId)
301 : {
302 15 : int64_t verifyFlag = 0;
303 15 : const auto drvRet = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_CUST_OP_ENHANCE, &verifyFlag);
304 15 : if (drvRet == DRV_ERROR_NOT_SUPPORT) {
305 1 : aicpusd_info("safe flag is not supported");
306 3 : return;
307 : }
308 14 : if (drvRet != DRV_ERROR_NONE) {
309 2 : aicpusd_run_warn("get device info by halGetDeviceInfo failed, errorCode[%d] deviceId[%u]", drvRet, deviceId);
310 2 : return;
311 : }
312 12 : if (verifyFlag == SAFE_VERIFY_OPEN) {
313 11 : needSafeVerify_ = false;
314 11 : aicpusd_info("set verify flag to false");
315 : }
316 : }
317 : } // namespace AicpuSchedule
|