LCOV - code coverage report
Current view: top level - aicpu_schedule/execute - main.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.9 % 229 215
Test Date: 2026-08-12 11:05:02 Functions: 100.0 % 12 12

            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 <string>
      11              : #include <vector>
      12              : #include <sstream>
      13              : #include <unistd.h>
      14              : #include <dlfcn.h>
      15              : #include <sys/file.h>
      16              : #include <sys/ioctl.h>
      17              : #include <exception>
      18              : #include "core/aicpusd_interface_process.h"
      19              : #include "core/aicpusd_event_process.h"
      20              : #include "core/aicpusd_event_manager.h"
      21              : #include "core/aicpusd_resource_limit.h"
      22              : #include "core/aicpusd_worker.h"
      23              : #include "aicpusd_profiler.h"
      24              : #include "aicpusd_lastword.h"
      25              : #include "common/aicpusd_args_parser.h"
      26              : #include "aicpusd_util.h"
      27              : #include "aicpusd_status.h"
      28              : #include "aicpusd_common.h"
      29              : #include "securec.h"
      30              : #include "tsd.h"
      31              : #include "aicpusd_weak_log.h"
      32              : #include "driver/ascend_hal.h"
      33              : #include "common/aicpusd_context.h"
      34              : #include "aicpusd_mc2_maintenance_thread_api.h"
      35              : #include "aicpusd_feature_ctrl.h"
      36              : #include "aicpusd_cust_dump_process.h"
      37              : #include "aicpusd_send_platform_Info_to_custom.h"
      38              : 
      39              : namespace AicpuSchedule {
      40              : namespace {
      41              : constexpr int32_t SUCCESS_VALUE = 0;
      42              : const std::string ERROR_MSG_INVALID_PARAM = "E39001";
      43              : const std::string ERROR_MSG_DRV_ERROR = "E39002";
      44              : const std::string ERROR_MSG_CGROUP_FAILED = "E30007";
      45              : const std::string ERROR_MSG_AICPU_INIT_FAILED = "E39004";
      46              : const std::string QUEUE_SCHEDULE_SO_NAME = "libqueue_schedule.so";
      47              : void* g_qslibHandle = nullptr;
      48              : 
      49           26 : void SetLogLevel(AicpuSchedule::ArgsParser& startParams)
      50              : {
      51           26 :     if (&dlog_setlevel != nullptr) {
      52           26 :         if (dlog_setlevel(-1, startParams.GetLogLevel(), startParams.GetEventLevel()) != SUCCESS_VALUE) {
      53            4 :             aicpusd_warn("Set log level failed");
      54              :         }
      55           26 :         if ((startParams.GetCcecpuLogLevel() >= DEBUG_LOG) && (startParams.GetCcecpuLogLevel() <= ERROR_LOG)) {
      56            0 :             if (dlog_setlevel(CCECPU, startParams.GetCcecpuLogLevel(), startParams.GetEventLevel()) != SUCCESS_VALUE) {
      57            0 :                 aicpusd_warn("Set ccecpu log level failed");
      58              :             }
      59              :         }
      60           26 :         if ((startParams.GetAicpuLogLevel() >= DEBUG_LOG) && (startParams.GetAicpuLogLevel() <= ERROR_LOG)) {
      61            0 :             if (dlog_setlevel(AICPU, startParams.GetAicpuLogLevel(), startParams.GetEventLevel()) != SUCCESS_VALUE) {
      62            0 :                 aicpusd_warn("Set aicpu log level failed");
      63              :             }
      64              :         }
      65              :     }
      66           26 :     LogAttr logAttr = {};
      67           26 :     logAttr.type = APPLICATION;
      68           26 :     logAttr.pid = startParams.GetHostPid();
      69           26 :     logAttr.deviceId = startParams.GetDeviceId();
      70           26 :     logAttr.mode = 0;
      71           26 :     if (DlogSetAttrAicpu(logAttr) != SUCCESS_VALUE) {
      72            1 :         aicpusd_warn("Set log attr failed");
      73              :     }
      74           26 : }
      75              : /**
      76              :  * attach host group based on parameters send by tsd.
      77              :  * @param  grpNameListStr group name list
      78              :  * @param  grpNameNum group name number
      79              :  * @return true:success, false:failed
      80              :  */
      81           20 : bool AttachHostGroup(const std::vector<std::string>& groupNameVec, const uint32_t grpNameNum)
      82              : {
      83           20 :     if (grpNameNum == 0U) {
      84            4 :         aicpusd_info("There is not group need to be attached");
      85            4 :         return true;
      86              :     }
      87           16 :     if (groupNameVec.empty()) {
      88            1 :         aicpusd_err("Aicpu start failed. Wrong parameters of groupNum[%d] with empty group name", grpNameNum);
      89            1 :         return false;
      90              :     }
      91           15 :     if (static_cast<uint32_t>(groupNameVec.size()) != grpNameNum) {
      92            1 :         aicpusd_err(
      93              :             "Aicpu start failed. parse group name num[%d] is consistence with num[%u] in parameter",
      94              :             groupNameVec.size(), grpNameNum);
      95            1 :         return false;
      96              :     }
      97              : 
      98           37 :     for (size_t i = 0UL; i < groupNameVec.size(); ++i) {
      99           24 :         const auto drvRet = halGrpAttach(groupNameVec[i].c_str(), -1);
     100           24 :         if (drvRet != DRV_ERROR_NONE) {
     101            1 :             aicpusd_err("halGrpAttach group[%s] failed. ret[%d]", groupNameVec[i].c_str(), drvRet);
     102            1 :             return false;
     103              :         }
     104           23 :         aicpusd_run_info("halGrpAttach group[%s] successfully.", groupNameVec[i].c_str());
     105              :     }
     106           13 :     return true;
     107              : }
     108              : 
     109            9 : void ReportErrorMsg(const int32_t errCode, const uint32_t deviceId, const uint32_t hostPid, const uint32_t vfId)
     110              : {
     111            9 :     std::string errStr;
     112            9 :     switch (errCode) {
     113            1 :         case AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID: {
     114            1 :             errStr = ERROR_MSG_INVALID_PARAM;
     115            1 :             break;
     116              :         }
     117            3 :         case AICPU_SCHEDULE_ERROR_DRV_ERR: {
     118            3 :             errStr = ERROR_MSG_DRV_ERROR;
     119            3 :             break;
     120              :         }
     121            1 :         case AICPU_SCHEDULE_ERROR_CGROUP_FAILED: {
     122            1 :             errStr = ERROR_MSG_CGROUP_FAILED;
     123            1 :             break;
     124              :         }
     125            1 :         case AICPU_SCHEDULE_ERROR_INIT_FAILED: {
     126            1 :             errStr = ERROR_MSG_AICPU_INIT_FAILED;
     127            1 :             break;
     128              :         }
     129            3 :         default: {
     130            3 :             errStr = ERROR_MSG_AICPU_INIT_FAILED;
     131            3 :             break;
     132              :         }
     133              :     }
     134            9 :     DlogFlushAicpu();
     135            9 :     sleep(1); // sleep 1s to avoid log loss
     136            9 :     const int32_t ret = TsdReportStartOrStopErrCode(
     137            9 :         deviceId, TSD_COMPUTE, hostPid, vfId, errStr.c_str(), static_cast<uint32_t>(errStr.size()));
     138            9 :     if (ret != 0) {
     139            1 :         aicpusd_err("TsdReportStartOrStopErrCode failed. ret[%d]", ret);
     140            1 :         sleep(1); // sleep 1s to avoid log loss
     141              :     }
     142              : 
     143            9 :     DlogFlushAicpu();
     144            9 : }
     145              : 
     146           17 : void SendPidQosMsgToTsd(const uint32_t pidQos, const uint32_t deviceId, const uint32_t hostPid, const uint32_t vfId)
     147              : {
     148              :     TsdCapabilityMsgInfo qosPidMsg;
     149           17 :     qosPidMsg.subCapabityType = TSD_EVENT_GET_CAPABILITY;
     150           17 :     qosPidMsg.resultInfo = pidQos;
     151           17 :     ReportMsgToTsd(deviceId, TSD_COMPUTE, hostPid, vfId, reinterpret_cast<const char_t* const>(&qosPidMsg));
     152           17 : }
     153              : 
     154           17 : void RegQueueScheduleModuleCallBack()
     155              : {
     156           17 :     g_qslibHandle = dlopen(QUEUE_SCHEDULE_SO_NAME.c_str(), RTLD_LAZY);
     157           17 :     if (g_qslibHandle == nullptr) {
     158            9 :         aicpusd_warn("cannot open %s", QUEUE_SCHEDULE_SO_NAME.c_str());
     159            9 :         return;
     160              :     }
     161              : 
     162              :     const SubProcEventCallBackFuncInfo startQsFunc =
     163            8 :         reinterpret_cast<SubProcEventCallBackFuncInfo>(dlsym(g_qslibHandle, "StartQueueScheduleModule"));
     164            8 :     if (startQsFunc == nullptr) {
     165            1 :         aicpusd_err("cannot find StartQueueScheduleModule");
     166            1 :         (void)dlclose(g_qslibHandle);
     167            1 :         g_qslibHandle = nullptr;
     168            1 :         return;
     169              :     }
     170              : 
     171              :     SubProcEventCallBackInfo startCallBackInfo;
     172            7 :     startCallBackInfo.callBackFunc = startQsFunc;
     173            7 :     startCallBackInfo.eventType = TSD_EVENT_START_QS_MODULE;
     174            7 :     int32_t ret = RegEventMsgCallBackFunc(&startCallBackInfo);
     175            7 :     if (ret != 0) {
     176            2 :         aicpusd_err("reg StartQueueScheduleModule failed");
     177            2 :         (void)dlclose(g_qslibHandle);
     178            2 :         g_qslibHandle = nullptr;
     179            2 :         return;
     180              :     }
     181              : 
     182              :     const SubProcEventCallBackFuncInfo stopQsFunc =
     183            5 :         reinterpret_cast<SubProcEventCallBackFuncInfo>(dlsym(g_qslibHandle, "StopQueueScheduleModule"));
     184            5 :     if (stopQsFunc == nullptr) {
     185            1 :         UnRegEventMsgCallBackFunc(TSD_EVENT_START_QS_MODULE);
     186            1 :         aicpusd_err("cannot find StopQueueScheduleModule");
     187            1 :         (void)dlclose(g_qslibHandle);
     188            1 :         g_qslibHandle = nullptr;
     189            1 :         return;
     190              :     }
     191              : 
     192              :     SubProcEventCallBackInfo stopCallBackInfo;
     193            4 :     stopCallBackInfo.callBackFunc = stopQsFunc;
     194            4 :     stopCallBackInfo.eventType = TSD_EVENT_STOP_QS_MODULE;
     195              : 
     196            4 :     ret = RegEventMsgCallBackFunc(&stopCallBackInfo);
     197            4 :     if (ret != 0) {
     198            1 :         UnRegEventMsgCallBackFunc(TSD_EVENT_START_QS_MODULE);
     199            1 :         aicpusd_err("reg StopQueueScheduleModule failed");
     200            1 :         (void)dlclose(g_qslibHandle);
     201            1 :         g_qslibHandle = nullptr;
     202            1 :         return;
     203              :     }
     204              : 
     205            3 :     aicpusd_run_info("Register queue schedule module callback successfully.");
     206            3 :     return;
     207              : }
     208              : 
     209           17 : void RegCreateMc2MantenanceThreadCallBack()
     210              : {
     211           17 :     SubProcEventCallBackInfo createMc2MantenanceThreadInfo = {};
     212           17 :     createMc2MantenanceThreadInfo.callBackFunc = CreateMc2MantenanceThread;
     213           17 :     createMc2MantenanceThreadInfo.eventType = TSD_EVENT_START_MC2_THREAD;
     214           17 :     int32_t ret = RegEventMsgCallBackFunc(&createMc2MantenanceThreadInfo);
     215           17 :     if (ret != 0) {
     216            3 :         aicpusd_err("reg Create Mc2 Maintenance Thread failed");
     217            3 :         return;
     218              :     }
     219              : }
     220              : 
     221           17 : void RegCreateDatadumpThreadCallBack()
     222              : {
     223           17 :     SubProcEventCallBackInfo createDatadumpThreadInfo = {};
     224           17 :     createDatadumpThreadInfo.callBackFunc = CreateDatadumpThread;
     225           17 :     createDatadumpThreadInfo.eventType = TSD_EVENT_START_UDF_DATADUMP_THREAD;
     226           17 :     int32_t ret = RegEventMsgCallBackFunc(&createDatadumpThreadInfo);
     227           17 :     if (ret != 0) {
     228            3 :         aicpusd_err("reg Create datadump Thread failed");
     229            3 :         return;
     230              :     }
     231              : }
     232              : 
     233           17 : void RegCustProcessLoadPlatformCallBack()
     234              : {
     235           17 :     SubProcEventCallBackInfo sendLoadPlatformInfoToCustInfo = {};
     236           17 :     sendLoadPlatformInfoToCustInfo.callBackFunc = SendLoadPlatformInfoToCust;
     237           17 :     sendLoadPlatformInfoToCustInfo.eventType = TSD_EVENT_LOAD_PLATFORM_TO_CUST;
     238           17 :     int32_t ret = RegEventMsgCallBackFunc(&sendLoadPlatformInfoToCustInfo);
     239           17 :     if (ret != 0) {
     240            3 :         aicpusd_err("reg send load platform to cust failed");
     241            3 :         return;
     242              :     }
     243              : }
     244              : 
     245           16 : void StopQsSubModuleInAicpu(const uint32_t deviceId, const uint32_t hostPid, const uint32_t vfId)
     246              : {
     247           16 :     if (g_qslibHandle == nullptr) {
     248           13 :         aicpusd_warn("cannot open so %s", QUEUE_SCHEDULE_SO_NAME.c_str());
     249           14 :         return;
     250              :     }
     251            3 :     TsdSubEventInfo eventInfo = {};
     252            3 :     eventInfo.deviceId = deviceId;
     253            3 :     eventInfo.hostPid = hostPid;
     254            3 :     eventInfo.vfId = vfId;
     255              :     const SubProcEventCallBackFuncInfo stopQsFunc =
     256            3 :         reinterpret_cast<SubProcEventCallBackFuncInfo>(dlsym(g_qslibHandle, "StopQueueScheduleModule"));
     257            3 :     if (stopQsFunc == nullptr) {
     258            1 :         aicpusd_err("cannot find StopQueueScheduleModule");
     259            1 :         (void)dlclose(g_qslibHandle);
     260            1 :         g_qslibHandle = nullptr;
     261            1 :         return;
     262              :     }
     263            2 :     const int32_t ret = stopQsFunc(&eventInfo);
     264            2 :     if (ret != 0) {
     265            0 :         aicpusd_err("StopQueueScheduleModule fail");
     266              :     }
     267            2 :     (void)dlclose(g_qslibHandle);
     268            2 :     g_qslibHandle = nullptr;
     269              : }
     270              : 
     271           32 : bool SendVfMsgToDrv(const uint32_t cmd, const uint32_t deviceId, const uint32_t vfId)
     272              : {
     273           32 :     if (FeatureCtrl::IsVfMode(deviceId, vfId)) {
     274            6 :         const int32_t fd = open("/dev/qos", O_RDWR);
     275            6 :         if (fd < 0) {
     276            4 :             aicpusd_warn("no such file. error[%s],errorno[%d]", strerror(errno), errno);
     277            4 :             return false;
     278              :         }
     279              :         VfMsgInfo vfMsg;
     280            2 :         vfMsg.deviceId = deviceId;
     281            2 :         vfMsg.vfId = vfId;
     282            2 :         const auto ret = ioctl(fd, cmd, PtrToPtr<VfMsgInfo, void>(&vfMsg));
     283            2 :         if (ret != 0) {
     284            0 :             aicpusd_warn("ioctl failed, error[%s],errorno[%d]", strerror(errno), errno);
     285            0 :             (void)close(fd);
     286            0 :             return false;
     287              :         }
     288            2 :         (void)close(fd);
     289              :     }
     290           28 :     return true;
     291              : }
     292              : 
     293            1 : void CloseQslibHandle()
     294              : {
     295            1 :     if (g_qslibHandle != nullptr) {
     296            0 :         (void)dlclose(g_qslibHandle);
     297            0 :         g_qslibHandle = nullptr;
     298            0 :         return;
     299              :     }
     300              : }
     301              : } // namespace
     302              : } // namespace AicpuSchedule
     303              : 
     304              : /**
     305              :  * main of compute process.
     306              :  * @param  argc argv length
     307              :  * @param  argv arg values
     308              :  * @return 0:success, other:failed
     309              :  */
     310              : #ifndef aicpusd_UT
     311              : int32_t main(int32_t argc, char* argv[])
     312              : #else
     313           39 : int32_t ComputeProcessMain(int32_t argc, char* argv[])
     314              : #endif
     315              : {
     316              :     try {
     317           39 :         AicpuSchedule::ArgsParser startParams;
     318           39 :         if (!startParams.ParseArgs(argc, argv)) {
     319           13 :             return -1;
     320              :         }
     321           26 :         AicpuSchedule::SetLogLevel(startParams);
     322           26 :         aicpusd_run_info("Start parameter. %s", startParams.GetParaParsedStr().c_str());
     323              : 
     324           26 :         const uint32_t vfId = startParams.GetVfId();
     325           26 :         const pid_t pid = startParams.GetHostPid();
     326           26 :         const uint32_t deviceId = startParams.GetDeviceId();
     327           26 :         const uint32_t aicpuProcNum = startParams.GetAicpuProcNum();
     328           26 :         AicpuSchedule::AicpuScheduleInterface::GetInstance().SetBatchLoadMode(aicpuProcNum);
     329           26 :         if (!AicpuSchedule::AddToCgroup(deviceId, vfId)) {
     330            1 :             AicpuSchedule::ReportErrorMsg(
     331              :                 AicpuSchedule::AICPU_SCHEDULE_ERROR_CGROUP_FAILED, deviceId, static_cast<uint32_t>(pid), vfId);
     332            1 :             return -1;
     333              :         }
     334              :         // Make sure AicpusdLastword are created first,to ensure the last exit
     335           25 :         AicpuSchedule::AicpusdLastword::GetInstance();
     336           25 :         AicpuSchedule::AicpuProfiler::ProfilerAgentInit();
     337           25 :         AicpuSchedule::AicpuEventManager::GetInstance().InitEventMgr(false, true, 0U);
     338           25 :         std::vector<uint32_t> deviceVec(1, deviceId);
     339              : 
     340           75 :         int32_t ret = AicpuSchedule::AicpuScheduleInterface::GetInstance().InitAICPUScheduler(
     341           50 :             deviceVec, pid, startParams.GetPidSign(), startParams.GetProfilingMode(), vfId, true,
     342           50 :             startParams.GetHostProcName());
     343           25 :         if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     344            5 :             aicpusd_err("Aicpu scheduler start failed, ret=%d", ret);
     345            5 :             AicpuSchedule::ReportErrorMsg(ret, deviceId, static_cast<uint32_t>(pid), vfId);
     346            5 :             (void)AicpuSchedule::AicpuScheduleInterface::GetInstance().StopAICPUScheduler(deviceVec, pid);
     347            5 :             return -1;
     348              :         }
     349              : 
     350           20 :         std::string libPath = "";
     351           20 :         (void)AicpuSchedule::AicpuUtil::GetEnvVal(AicpuSchedule::ENV_NAME_LD_LIBRARY_PATH, libPath);
     352           20 :         aicpusd_run_info("Aicpu schedule start successfully, LD_LIBRARY_PATH=%s", libPath.c_str());
     353              : 
     354              :         // start attach and init process.
     355              :         // Attach group before send success to make sure aicpusd own the authority to access mbuff send by RTS
     356           20 :         if (!AicpuSchedule::AttachHostGroup(startParams.GetGrpNameList(), startParams.GetGrpNameNum())) {
     357            3 :             aicpusd_err("AttachHostGroup execute failed.");
     358            3 :             AicpuSchedule::ReportErrorMsg(
     359              :                 AicpuSchedule::AICPU_SCHEDULE_ERROR_DRV_ERR, deviceId, static_cast<uint32_t>(pid), vfId);
     360            3 :             return -1;
     361              :         }
     362              : 
     363           17 :         aicpusd_run_info("Aicpu schedule attach and init successfully.");
     364              :         // send pid qos to tsd current send default value 0 to tsd
     365           17 :         AicpuSchedule::SendPidQosMsgToTsd(
     366              :             static_cast<uint32_t>(PRIORITY_LEVEL1), deviceId, static_cast<uint32_t>(pid), vfId);
     367              : 
     368              :         // reg queue schedule start and stop callback func
     369           17 :         AicpuSchedule::RegQueueScheduleModuleCallBack();
     370           17 :         AicpuSchedule::RegCreateMc2MantenanceThreadCallBack();
     371           17 :         AicpuSchedule::RegCreateDatadumpThreadCallBack();
     372           17 :         AicpuSchedule::RegCustProcessLoadPlatformCallBack();
     373              : 
     374           17 :         const int32_t rspRet = StartupResponse(deviceVec[0U], TSD_COMPUTE, static_cast<uint32_t>(pid), vfId);
     375           17 :         if (rspRet != AicpuSchedule::SUCCESS_VALUE) {
     376            1 :             aicpusd_err("Aicpu startup response return not ok, error code[%d].", rspRet);
     377            1 :             AicpuSchedule::CloseQslibHandle();
     378            1 :             return -1;
     379              :         }
     380           16 :         aicpusd_run_info("Aicpu startup response return successfully.");
     381              : 
     382           16 :         (void)AicpuSchedule::SendVfMsgToDrv(VM_QOS_PROCESS_STARTUP, deviceId, vfId);
     383              : 
     384              :         // wait for shutdown
     385           16 :         const int32_t waitRet = WaitForShutDown(deviceVec[0U]);
     386           16 :         if (waitRet != AicpuSchedule::SUCCESS_VALUE) {
     387            1 :             aicpusd_err("wait for shut down return not ok return not ok, error code[%d].", waitRet);
     388            1 :             ret = -1;
     389              :         } else {
     390           15 :             aicpusd_info("wait for shut down return successfully.");
     391           15 :             ret = 0;
     392              :         }
     393              : 
     394           16 :         AicpuSchedule::StopQsSubModuleInAicpu(deviceId, static_cast<uint32_t>(pid), vfId);
     395           16 :         (void)AicpuSchedule::AicpuScheduleInterface::GetInstance().StopAICPUScheduler(deviceVec, pid);
     396           16 :         aicpusd_run_info("Aicpu schedule stopped");
     397              : 
     398           16 :         (void)AicpuSchedule::SendVfMsgToDrv(VM_QOS_PROCESS_SUSPEND, deviceId, vfId);
     399              :         // flush cache log to slogd
     400           16 :         DlogFlushAicpu();
     401           16 :         return ret;
     402           39 :     } catch (const std::exception& e) {
     403            0 :         aicpusd_err("Execute main failed, reason=%s", e.what());
     404            0 :         return -1;
     405            0 :     }
     406              : }
        

Generated by: LCOV version 2.0-1