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