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 226 : AicpuDrvManager& AicpuDrvManager::GetInstance()
49 : {
50 226 : static AicpuDrvManager instance;
51 226 : 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 15 : int32_t AicpuDrvManager::InitDrvMgr(
89 : const uint32_t deviceId, const pid_t hostPid, const uint32_t vfId, const bool hasThread)
90 : {
91 15 : if (deviceId >= DEVICE_NUM) {
92 2 : aicpusd_err("invalid device id[%u]", deviceId);
93 2 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
94 : }
95 13 : SetSafeVerifyFlag(deviceId);
96 13 : InitSocType(deviceId);
97 : int32_t ret;
98 13 : if (!FeatureCtrl::IsAosCore()) {
99 10 : ret = GetNormalAicpuInfo(deviceId);
100 10 : if (ret != 0) {
101 1 : aicpusd_err("GetNormalAicpuInfo error, ret[%d]", ret);
102 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
103 : }
104 9 : GetCcpuInfo(deviceId);
105 : }
106 :
107 12 : uint32_t deviceIdTmp = deviceId;
108 12 : if (FeatureCtrl::IsVfModeDie1(deviceId)) {
109 2 : int64_t pfDeviceId = 0;
110 2 : ret = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_PHY_DIE_ID, &pfDeviceId);
111 2 : if (ret != DRV_ERROR_NONE) {
112 1 : aicpusd_err("halGetDeviceInfo get pfDeviceId fail in device[%d], ret[%d]", deviceId, ret);
113 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
114 : }
115 1 : deviceIdTmp = static_cast<uint32_t>(pfDeviceId);
116 : }
117 :
118 11 : int64_t aicpuNum = 0;
119 11 : int64_t aicpuOsSched = 0;
120 11 : int64_t ccpuNum = 0;
121 11 : int64_t ccpuOsSched = 0;
122 11 : int64_t dcpuNum = 0;
123 11 : int64_t dcpuOsSched = 0;
124 11 : int64_t tsCpuNum = 0;
125 11 : int64_t tsCpuOsSched = 0;
126 : uint32_t retDrv =
127 11 : static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuNum));
128 11 : retDrv |=
129 11 : static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_AICPU, INFO_TYPE_OS_SCHED, &aicpuOsSched));
130 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_CORE_NUM, &ccpuNum));
131 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_CCPU, INFO_TYPE_OS_SCHED, &ccpuOsSched));
132 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_CORE_NUM, &dcpuNum));
133 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_DCPU, INFO_TYPE_OS_SCHED, &dcpuOsSched));
134 11 : retDrv |= static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_CORE_NUM, &tsCpuNum));
135 11 : retDrv |=
136 11 : static_cast<uint32_t>(halGetDeviceInfo(deviceIdTmp, MODULE_TYPE_TSCPU, INFO_TYPE_OS_SCHED, &tsCpuOsSched));
137 11 : if (retDrv != 0U) {
138 0 : aicpusd_err("halGetDeviceInfo failed, ret[%u]", retDrv);
139 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
140 : }
141 11 : if (FeatureCtrl::IsAosCore()) {
142 2 : aicpuNum_ = aicpuNum;
143 2 : if (ccpuOsSched != 0) {
144 1 : aicpuBaseId_ += ccpuNum;
145 : }
146 2 : if (dcpuOsSched != 0) {
147 1 : aicpuBaseId_ += dcpuNum;
148 : }
149 : }
150 : // connot overflow
151 11 : coreNumPerDev_ =
152 11 : (ccpuNum * ccpuOsSched) + (dcpuNum * dcpuOsSched) + (aicpuNum * aicpuOsSched) + (tsCpuNum * tsCpuOsSched);
153 11 : dcpuBase_ = (deviceIdTmp * coreNumPerDev_) + ccpuNum;
154 11 : dcpuNum_ = dcpuNum;
155 11 : aicpusd_run_info(
156 : "device id[%u], host pid[%d], first aicpu index[%u], aicpu num[%u],"
157 : " dcpu base index[%u], dcpu num[%u], vf id[%u]",
158 : deviceIdTmp, hostPid, aicpuBaseId_, aicpuNum_, dcpuBase_, dcpuNum_, vfId);
159 11 : deviceId_ = deviceId;
160 11 : hostPid_ = hostPid;
161 11 : vfId_ = vfId;
162 11 : hasThread_ = hasThread;
163 11 : isInit_ = true;
164 :
165 11 : if (FeatureCtrl::IsVfModeCheckedByDeviceId(deviceId)) {
166 2 : uniqueVfId_ = deviceId;
167 : } else {
168 9 : uniqueVfId_ = vfId;
169 9 : if (FeatureCtrl::IsAosCore()) {
170 1 : return AICPU_SCHEDULE_OK;
171 : }
172 8 : if ((deviceId != 0U) && (vfId != 0U)) {
173 1 : uint32_t maxNumSpDev = 0U;
174 1 : const auto vfMaxRet = halGetDeviceVfMax(deviceId, &maxNumSpDev);
175 1 : if ((vfMaxRet != DRV_ERROR_NONE) || (maxNumSpDev > DEVICE_MAX_SPLIT_NUM)) {
176 0 : aicpusd_err("Failed to get device cat vf number, result[%d], max num[%u].", vfMaxRet, maxNumSpDev);
177 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
178 : }
179 1 : uniqueVfId_ = maxNumSpDev * deviceId + vfId;
180 : }
181 : }
182 :
183 10 : return AICPU_SCHEDULE_OK;
184 : }
185 :
186 14 : void AicpuDrvManager::InitSocType(const uint32_t deviceId)
187 : {
188 14 : int64_t hardwareVersion = 0L;
189 14 : const int32_t ret = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &hardwareVersion);
190 14 : if (ret != DRV_ERROR_NONE) {
191 2 : aicpusd_err("Get device info failed, deviceId=%u", deviceId);
192 2 : return;
193 : }
194 :
195 12 : FeatureCtrl::Init(hardwareVersion, deviceId);
196 12 : return;
197 : }
198 :
199 7 : int32_t AicpuDrvManager::InitDrvSchedModule(const uint32_t grpId)
200 : {
201 : // use driver event means has thread
202 7 : hasThread_ = true;
203 7 : aicpusd_info("Attach device[%u] to drv scheduler.", deviceId_);
204 7 : int32_t ret = halEschedAttachDevice(deviceId_);
205 7 : if (ret != DRV_ERROR_NONE) {
206 1 : aicpusd_err("Failed to attach device in drv, result[%d].", ret);
207 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
208 : }
209 :
210 6 : aicpusd_info("Create group[%u], type[%d]", grpId, GRP_TYPE_BIND_DP_CPU);
211 6 : ret = halEschedCreateGrp(deviceId_, grpId, GRP_TYPE_BIND_DP_CPU);
212 6 : if (ret != DRV_ERROR_NONE) {
213 1 : (void)halEschedDettachDevice(deviceId_);
214 1 : aicpusd_err("Failed to attach device in drv, result[%d].", ret);
215 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
216 : }
217 5 : if (FeatureCtrl::ShouldInitDrvThread() && (&halDrvEventThreadInit != nullptr)) {
218 5 : ret = halDrvEventThreadInit(deviceId_);
219 5 : aicpusd_run_info("Enable process drv queue msg on ccpu, ret is %d.", static_cast<int32_t>(ret));
220 : }
221 :
222 5 : return AICPU_SCHEDULE_OK;
223 : }
224 :
225 5 : int32_t AicpuDrvManager::CheckBindHostPid() const
226 : {
227 5 : aicpusd_run_info("Start query process host pid");
228 5 : if (&drvQueryProcessHostPid == nullptr) {
229 0 : aicpusd_run_info("drvQueryProcessHostPid does not exist");
230 0 : return AICPU_SCHEDULE_OK;
231 : }
232 5 : drvError_t ret = DRV_ERROR_NONE;
233 5 : unsigned int hostpid = 0;
234 5 : unsigned int cpType = DEVDRV_PROCESS_CPTYPE_MAX;
235 5 : const int pid = static_cast<int>(getpid());
236 16 : for (uint32_t i = 0; i < QUERY_BIND_HOST_PID_TIME / QUERY_BIND_HOST_PID_INTERVBALE; i++) {
237 15 : ret = drvQueryProcessHostPid(pid, nullptr, nullptr, &hostpid, &cpType);
238 15 : if ((i % QUERY_BIND_HOST_PID_LOG_INTERVAL) == 0U) {
239 5 : aicpusd_run_info(
240 : "Query process host pid end, ret=%d, hostpid=%u, expect=%u, cpType=%u", static_cast<int32_t>(ret),
241 : hostpid, hostPid_, cpType);
242 : }
243 15 : if (ret == DRV_ERROR_NO_PROCESS) {
244 11 : aicpusd_info("call drvQueryProcessHostPid try again");
245 11 : (void)usleep(QUERY_BIND_HOST_PID_INTERVBALE);
246 11 : continue;
247 : }
248 :
249 4 : if (ret != DRV_ERROR_NONE) {
250 2 : aicpusd_err("call drvQueryProcessHostPid failed, ret[%d]", static_cast<int32_t>(ret));
251 2 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
252 : }
253 :
254 2 : aicpusd_info("call drvQueryProcessHostPid result, hostpid[%d], cpType[%d]", hostpid, cpType);
255 2 : if (hostPid_ == static_cast<pid_t>(hostpid)) {
256 1 : aicpusd_run_info("call drvQueryProcessHostPid success, hostpid[%d], cpType[%d]", hostpid, cpType);
257 1 : return AICPU_SCHEDULE_OK;
258 : } else {
259 1 : aicpusd_err(
260 : "CheckBindHostPid failed, hostpid not right. ret[%d], pid[%d], hostpid[%d], cpType[%d]",
261 : static_cast<int32_t>(ret), pid, hostpid, cpType);
262 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
263 : }
264 : }
265 1 : aicpusd_err(
266 : "CheckBindHostPid failed, try timeout. ret[%d], pid[%d], hostpid[%d], cpType[%d]", static_cast<int32_t>(ret),
267 : pid, hostpid, cpType);
268 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
269 : }
270 :
271 29 : uint32_t AicpuDrvManager::GetAicpuNum() const
272 : {
273 29 : aicpusd_info("Get aicpu core num[%u]", aicpuNum_);
274 29 : return aicpuNum_;
275 : }
276 :
277 12 : int32_t AicpuDrvManager::GetCcpuInfo(const uint32_t deviceId)
278 : {
279 12 : int64_t ccpuBitMap = 0;
280 12 : const int32_t ret = halGetDeviceInfo(deviceId, MODULE_TYPE_CCPU, INFO_TYPE_OCCUPY, &ccpuBitMap);
281 12 : if (ret != DRV_ERROR_NONE) {
282 1 : aicpusd_err("halGetDeviceInfo failed, devid:%u, ret[%d]", deviceId, ret);
283 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
284 : }
285 11 : aicpusd_run_info("ccpuBitMap[%lld].", ccpuBitMap);
286 187 : for (uint32_t i = 0U; i < DEVICE_MAX_CPU_NUM; i++) {
287 176 : if ((ccpuBitMap & 0x1LL) != 0LL) {
288 9 : ccpuIdVec_.push_back(i);
289 : }
290 176 : ccpuBitMap = ccpuBitMap >> 1;
291 : }
292 11 : return AICPU_SCHEDULE_OK;
293 : }
294 :
295 14 : void AicpuDrvManager::SetSafeVerifyFlag(const uint32_t deviceId)
296 : {
297 14 : int64_t verifyFlag = 0;
298 14 : const auto drvRet = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_CUST_OP_ENHANCE, &verifyFlag);
299 14 : if (drvRet == DRV_ERROR_NOT_SUPPORT) {
300 1 : aicpusd_info("safe flag is not supported");
301 3 : return;
302 : }
303 13 : if (drvRet != DRV_ERROR_NONE) {
304 2 : aicpusd_run_warn("get device info by halGetDeviceInfo failed, errorCode[%d] deviceId[%u]", drvRet, deviceId);
305 2 : return;
306 : }
307 11 : if (verifyFlag == SAFE_VERIFY_OPEN) {
308 10 : needSafeVerify_ = false;
309 10 : aicpusd_info("set verify flag to false");
310 : }
311 : }
312 : } // namespace AicpuSchedule
|