LCOV - code coverage report
Current view: top level - aicpu_schedule/core/hwts_kernel - hwts_kernel_queue.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.2 % 146 120
Test Date: 2026-08-12 11:05:02 Functions: 100.0 % 7 7

            Line data    Source code
       1              : 
       2              : 
       3              : /**
       4              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       5              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       6              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       7              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       8              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       9              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
      10              :  * See LICENSE in the root of the software repository for the full text of the License.
      11              :  */
      12              : 
      13              : #include "hwts_kernel_queue.h"
      14              : 
      15              : #include "ascend_hal.h"
      16              : #include "aicpusd_monitor.h"
      17              : #include "aicpusd_drv_manager.h"
      18              : #include "hwts_kernel_common.h"
      19              : 
      20              : namespace AicpuSchedule {
      21              : namespace {
      22              : const std::string CREATE_QUEUE = "CreateQueue";
      23              : const std::string DESTROY_QUEUE = "DestroyQueue";
      24              : constexpr uint64_t TO_US = 1000000UL;
      25              : constexpr GroupShareAttr GROUP_WITH_ALL_ATTR = {1U, 1U, 1U, 1U, 0U}; // admin + read + write + alloc
      26              : } // namespace
      27              : 
      28            2 : int32_t CreateQueueTsKernel::DoQueueSubscrible(const QueueAttr& queAttr, uint32_t* queueId) const
      29              : {
      30            2 :     const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
      31            2 :     auto drvRet = halQueueInit(deviceId);
      32            2 :     if ((drvRet != DRV_ERROR_NONE) && (drvRet != DRV_ERROR_REPEATED_INIT)) {
      33            1 :         aicpusd_err("halQueueInit error, deviceId[%u], drvRet[%d]", deviceId, drvRet);
      34            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
      35              :     }
      36              : 
      37            1 :     drvRet = halQueueCreate(deviceId, &queAttr, queueId);
      38            1 :     if (drvRet != DRV_ERROR_NONE) {
      39            0 :         aicpusd_err("Create buff queue[%s] error, depth[%u], ret[%d]", queAttr.name, queAttr.depth, drvRet);
      40            0 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
      41              :     }
      42              : 
      43            1 :     const int32_t ret = SubscribeEvent(deviceId, *queueId);
      44            1 :     if (ret != AICPU_SCHEDULE_OK) {
      45            0 :         (void)halQueueDestroy(deviceId, *queueId);
      46            0 :         return ret;
      47              :     }
      48              : 
      49            1 :     return AICPU_SCHEDULE_OK;
      50              : }
      51              : 
      52            3 : int32_t CreateQueueTsKernel::Compute(const aicpu::HwtsTsKernel& tsKernelInfo)
      53              : {
      54            3 :     const aicpu::HwtsCceKernel& kernel = tsKernelInfo.kernelBase.cceKernel;
      55              :     // create queue op param : queueId(uint64_t) + queueName(128 char) + queueDepth(uint32_t)
      56            3 :     constexpr size_t len =
      57              :         sizeof(aicpu::AicpuParamHead) + sizeof(uint64_t) + static_cast<size_t>(QUEUE_MAX_STR_LEN) + sizeof(uint32_t);
      58            3 :     size_t offset = sizeof(aicpu::AicpuParamHead);
      59            3 :     const auto baseAddr = PtrToPtr<void, char_t>(ValueToPtr(kernel.paramBase));
      60            3 :     const aicpu::AicpuParamHead* const paramHead = PtrToPtr<char_t, aicpu::AicpuParamHead>(baseAddr);
      61            3 :     if (paramHead == nullptr) {
      62            0 :         aicpusd_err("ParamHead for create queue is nullptr");
      63            0 :         return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
      64              :     }
      65              : 
      66            3 :     if (static_cast<size_t>(paramHead->length) != len) {
      67            0 :         aicpusd_err("Create queue param length[%u] should be [%zu]", paramHead->length, len);
      68            0 :         return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
      69              :     }
      70              : 
      71            3 :     const int32_t ret = CreateGrp();
      72            3 :     if (ret != AICPU_SCHEDULE_OK) {
      73            1 :         aicpusd_err("CreateGrp abnormal, ret = %d.", ret);
      74            1 :         return ret;
      75              :     }
      76              : 
      77            2 :     const uint64_t queueIdAddr = *PtrToPtr<const char_t, const uint64_t>(PtrAdd<const char_t>(baseAddr, len, offset));
      78            2 :     const auto queueId = PtrToPtr<void, uint32_t>(ValueToPtr(queueIdAddr));
      79              : 
      80            2 :     offset += sizeof(uint64_t);
      81            2 :     const auto queueName = PtrAdd<const char_t>(baseAddr, static_cast<size_t>(paramHead->length), offset);
      82              : 
      83            2 :     QueueAttr queAttr = {};
      84            2 :     const auto memcpyRet = memcpy_s(
      85              :         queAttr.name, static_cast<size_t>(QUEUE_MAX_STR_LEN), queueName, static_cast<size_t>(QUEUE_MAX_STR_LEN));
      86            2 :     if (memcpyRet != EOK) {
      87            0 :         aicpusd_err("Memcpy_s failed, ret=%d.", memcpyRet);
      88            0 :         return AICPU_SCHEDULE_ERROR_INNER_ERROR;
      89              :     }
      90              : 
      91            2 :     offset += static_cast<size_t>(QUEUE_MAX_STR_LEN);
      92            2 :     const uint32_t queueDepth = *PtrToPtr<const char_t, const uint32_t>(PtrAdd<const char_t>(baseAddr, len, offset));
      93            2 :     queAttr.depth = queueDepth;
      94            2 :     queAttr.workMode = QUEUE_MODE_PULL;
      95              : 
      96            2 :     return DoQueueSubscrible(queAttr, queueId);
      97              : }
      98              : 
      99            2 : int32_t CreateQueueTsKernel::CreateGrp() const
     100              : {
     101            2 :     const pid_t curPid = drvDeviceGetBareTgid();
     102            2 :     std::map<std::string, GroupShareAttr> buffGrpInfo;
     103            2 :     const auto ret = AicpuDrvManager::GetInstance().QueryProcBuffInfo(static_cast<uint32_t>(curPid), buffGrpInfo);
     104            2 :     if (ret != AICPU_SCHEDULE_OK) {
     105            0 :         aicpusd_err("Fail to get group info of master aicpusd[%d]", curPid);
     106            0 :         return ret;
     107              :     }
     108              :     // 0 group need to create group
     109            2 :     if (buffGrpInfo.size() == 0UL) {
     110            2 :         aicpusd_info("There is no group for master aicpusd[%d]. Create new group", curPid);
     111            2 :         struct timeval tv = {};
     112            2 :         (void)gettimeofday(&tv, nullptr);
     113            2 :         const uint64_t groupNameAddition =
     114            2 :             (static_cast<uint64_t>(tv.tv_sec) * TO_US) + (static_cast<uint64_t>(tv.tv_usec));
     115            2 :         const std::string groupName = "Aicpusd" + std::to_string(groupNameAddition);
     116            2 :         GroupCfg groupConf = {};
     117            2 :         groupConf.privMbufFlag = static_cast<uint32_t>(BUFF_ENABLE_PRIVATE_MBUF);
     118              :         // 1.create group
     119            2 :         auto drvRet = halGrpCreate(groupName.c_str(), &groupConf);
     120            2 :         if (drvRet != DRV_ERROR_NONE) {
     121            0 :             aicpusd_err("Create group failed in aicpusd[%d], result[%d]", curPid, drvRet);
     122            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     123              :         }
     124              : 
     125              :         // 2.add current process to new group
     126            2 :         drvRet = halGrpAddProc(groupName.c_str(), curPid, GROUP_WITH_ALL_ATTR);
     127            2 :         if (drvRet != DRV_ERROR_NONE) {
     128            0 :             aicpusd_err("Add group[%s] for master aicpusd[%d] failed, ret[%d]", groupName.c_str(), curPid, drvRet);
     129            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     130              :         }
     131              : 
     132            2 :         drvRet = halGrpAttach(groupName.c_str(), 0);
     133            2 :         if (drvRet != DRV_ERROR_NONE) {
     134            0 :             aicpusd_err("Attach group[%s] for master aicpusd[%d] failed, ret[%d]", groupName.c_str(), curPid, drvRet);
     135            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     136              :         }
     137              : 
     138              :         // 3.initial process
     139            2 :         BuffCfg buffCfg = {};
     140            2 :         drvRet = halBuffInit(&buffCfg);
     141            2 :         if (drvRet != DRV_ERROR_NONE) {
     142            0 :             aicpusd_err("Buffer initial failed for master aicpusd[%d], ret[%d]", curPid, drvRet);
     143            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     144              :         }
     145            2 :         aicpusd_info("Create new group[%s] for master aicpusd[%d] success", groupName.c_str(), curPid);
     146            2 :     }
     147            2 :     return AICPU_SCHEDULE_OK;
     148            2 : }
     149              : 
     150            5 : int32_t CreateQueueTsKernel::SubscribeEvent(const uint32_t deviceId, const uint32_t queueId) const
     151              : {
     152            5 :     int32_t ret = halQueueSubscribe(deviceId, queueId, 0U, QUEUE_TYPE_SINGLE);
     153            5 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_QUEUE_RE_SUBSCRIBED)) {
     154            1 :         aicpusd_err("Subscribe queue[%u] failed, ret[%d].", queueId, ret);
     155            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     156              :     }
     157              : 
     158            4 :     if ((ret == DRV_ERROR_QUEUE_RE_SUBSCRIBED) && (Resubscribe(deviceId, queueId) != AICPU_SCHEDULE_OK)) {
     159            1 :         aicpusd_err("Resubscribe queue[%u] failed.", queueId);
     160            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     161              :     }
     162              : 
     163            3 :     ret = halQueueSubF2NFEvent(deviceId, queueId, 0U);
     164            3 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_QUEUE_RE_SUBSCRIBED)) {
     165            1 :         aicpusd_err("Subscribe queue[%u] F2NF event failed, ret[%d].", queueId, ret);
     166            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     167              :     }
     168              : 
     169            2 :     if ((ret == DRV_ERROR_QUEUE_RE_SUBSCRIBED) && (ResubscribeF2NF(deviceId, queueId) != AICPU_SCHEDULE_OK)) {
     170            1 :         aicpusd_err("Resubscribe queue[%u] F2NF event failed.", queueId);
     171            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     172              :     }
     173            1 :     return AICPU_SCHEDULE_OK;
     174              : }
     175              : 
     176            4 : int32_t CreateQueueTsKernel::Resubscribe(const uint32_t deviceId, const uint32_t queueId) const
     177              : {
     178            4 :     int32_t queueStatus = halQueueUnsubscribe(deviceId, queueId);
     179            4 :     if ((queueStatus != DRV_ERROR_NONE) && (queueStatus != DRV_ERROR_NOT_EXIST)) {
     180            2 :         aicpusd_err("Unsubscribe queue[%u] failed, ret[%d].", queueId, queueStatus);
     181            2 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     182              :     }
     183              : 
     184            2 :     queueStatus = halQueueSubscribe(deviceId, queueId, 0U, QUEUE_TYPE_SINGLE);
     185            2 :     if (queueStatus != DRV_ERROR_NONE) {
     186            1 :         aicpusd_err("Subscribe queue[%u] failed, ret[%d].", queueId, queueStatus);
     187            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     188              :     }
     189            1 :     return AICPU_SCHEDULE_OK;
     190              : }
     191              : 
     192            4 : int32_t CreateQueueTsKernel::ResubscribeF2NF(const uint32_t deviceId, const uint32_t queueId) const
     193              : {
     194            4 :     int32_t queueStatus = halQueueUnsubF2NFEvent(deviceId, queueId);
     195            4 :     if ((queueStatus != DRV_ERROR_NONE) && (queueStatus != DRV_ERROR_NOT_EXIST)) {
     196            1 :         aicpusd_err("Unsub F2NF event for queue[%u] failed, ret[%d].", queueId, queueStatus);
     197            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     198              :     }
     199              : 
     200            3 :     queueStatus = halQueueSubF2NFEvent(deviceId, queueId, 0U);
     201            3 :     if (queueStatus != DRV_ERROR_NONE) {
     202            2 :         aicpusd_err("Sub F2NF event for queue[%u] failed, ret=%d.", queueId, queueStatus);
     203            2 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     204              :     }
     205            1 :     return AICPU_SCHEDULE_OK;
     206              : }
     207              : 
     208            3 : int32_t DestroyQueueTsKernel::Compute(const aicpu::HwtsTsKernel& tsKernelInfo)
     209              : {
     210            3 :     const aicpu::HwtsCceKernel& kernel = tsKernelInfo.kernelBase.cceKernel;
     211              :     // destroy queue op param : queueId(uint32_t)
     212            3 :     constexpr uint64_t len = sizeof(aicpu::AicpuParamHead) + sizeof(uint32_t);
     213            3 :     constexpr uint64_t offset = sizeof(aicpu::AicpuParamHead);
     214            3 :     const auto baseAddr = PtrToPtr<void, char_t>(ValueToPtr(kernel.paramBase));
     215            3 :     const aicpu::AicpuParamHead* const paramHead = PtrToPtr<char_t, aicpu::AicpuParamHead>(baseAddr);
     216            3 :     if (paramHead == nullptr) {
     217            1 :         aicpusd_err("ParamHead for DumpDataKernel is nullptr");
     218            1 :         return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     219              :     }
     220              : 
     221            2 :     if (paramHead->length != len) {
     222            1 :         aicpusd_err("Destroy queue param length[%u] should be [%lu]", paramHead->length, len);
     223            1 :         return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     224              :     }
     225              : 
     226            1 :     const uint32_t queueId = *PtrToPtr<const char_t, const uint32_t>(PtrAdd<const char_t>(baseAddr, len, offset));
     227            1 :     const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
     228              : 
     229            1 :     int32_t eventRet = AICPU_SCHEDULE_OK;
     230            1 :     int32_t ret = halQueueUnsubscribe(deviceId, queueId);
     231            1 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_NOT_EXIST)) {
     232            0 :         aicpusd_err("Unsubscribe queue[%u] failed, ret[%d].", queueId, ret);
     233            0 :         eventRet = AICPU_SCHEDULE_ERROR_DRV_ERR;
     234              :     }
     235              : 
     236            1 :     ret = halQueueUnsubF2NFEvent(deviceId, queueId);
     237            1 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_NOT_EXIST)) {
     238            0 :         aicpusd_err("Unsubscribe queue[%u] F2NF event failed, ret[%d].", queueId, ret);
     239            0 :         eventRet = AICPU_SCHEDULE_ERROR_DRV_ERR;
     240              :     }
     241              : 
     242            1 :     ret = halQueueDestroy(deviceId, queueId);
     243            1 :     if (ret != DRV_ERROR_NONE) {
     244            0 :         aicpusd_err("Destroy queue[%u] error, ret[%d]", queueId, ret);
     245            0 :         eventRet = AICPU_SCHEDULE_ERROR_DRV_ERR;
     246              :     }
     247              : 
     248            1 :     return eventRet;
     249              : }
     250              : 
     251              : REGISTER_HWTS_KERNEL(CREATE_QUEUE, CreateQueueTsKernel);
     252              : REGISTER_HWTS_KERNEL(DESTROY_QUEUE, DestroyQueueTsKernel);
     253              : } // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1