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-07-28 10:54:05 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 = sizeof(aicpu::AicpuParamHead) + sizeof(uint64_t) +
      57              :                            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(queAttr.name, static_cast<size_t>(QUEUE_MAX_STR_LEN),
      85              :                                     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]",
     129              :                 groupName.c_str(), curPid, drvRet);
     130            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     131              :         }
     132              : 
     133            2 :         drvRet = halGrpAttach(groupName.c_str(), 0);
     134            2 :         if (drvRet != DRV_ERROR_NONE) {
     135            0 :             aicpusd_err("Attach group[%s] for master aicpusd[%d] failed, ret[%d]",
     136              :                 groupName.c_str(), curPid, drvRet);
     137            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     138              :         }
     139              : 
     140              :         // 3.initial process
     141            2 :         BuffCfg buffCfg = {};
     142            2 :         drvRet = halBuffInit(&buffCfg);
     143            2 :         if (drvRet != DRV_ERROR_NONE) {
     144            0 :             aicpusd_err("Buffer initial failed for master aicpusd[%d], ret[%d]", curPid, drvRet);
     145            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     146              :         }
     147            2 :         aicpusd_info("Create new group[%s] for master aicpusd[%d] success", groupName.c_str(), curPid);
     148            2 :     }
     149            2 :     return AICPU_SCHEDULE_OK;
     150            2 : }
     151              : 
     152            5 : int32_t CreateQueueTsKernel::SubscribeEvent(const uint32_t deviceId, const uint32_t queueId) const
     153              : {
     154            5 :     int32_t ret = halQueueSubscribe(deviceId, queueId, 0U, QUEUE_TYPE_SINGLE);
     155            5 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_QUEUE_RE_SUBSCRIBED)) {
     156            1 :         aicpusd_err("Subscribe queue[%u] failed, ret[%d].", queueId, ret);
     157            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     158              :     }
     159              : 
     160            4 :     if ((ret == DRV_ERROR_QUEUE_RE_SUBSCRIBED) && (Resubscribe(deviceId, queueId) != AICPU_SCHEDULE_OK)) {
     161            1 :         aicpusd_err("Resubscribe queue[%u] failed.", queueId);
     162            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     163              :     }
     164              : 
     165            3 :     ret = halQueueSubF2NFEvent(deviceId, queueId, 0U);
     166            3 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_QUEUE_RE_SUBSCRIBED)) {
     167            1 :         aicpusd_err("Subscribe queue[%u] F2NF event failed, ret[%d].", queueId, ret);
     168            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     169              :     }
     170              : 
     171            2 :     if ((ret == DRV_ERROR_QUEUE_RE_SUBSCRIBED) && (ResubscribeF2NF(deviceId, queueId) != AICPU_SCHEDULE_OK)) {
     172            1 :         aicpusd_err("Resubscribe queue[%u] F2NF event failed.", queueId);
     173            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     174              :     }
     175            1 :     return AICPU_SCHEDULE_OK;
     176              : }
     177              : 
     178            4 : int32_t CreateQueueTsKernel::Resubscribe(const uint32_t deviceId, const uint32_t queueId) const
     179              : {
     180            4 :     int32_t queueStatus = halQueueUnsubscribe(deviceId, queueId);
     181            4 :     if ((queueStatus != DRV_ERROR_NONE) && (queueStatus != DRV_ERROR_NOT_EXIST)) {
     182            2 :         aicpusd_err("Unsubscribe queue[%u] failed, ret[%d].", queueId, queueStatus);
     183            2 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     184              :     }
     185              : 
     186            2 :     queueStatus = halQueueSubscribe(deviceId, queueId, 0U, QUEUE_TYPE_SINGLE);
     187            2 :     if (queueStatus != DRV_ERROR_NONE) {
     188            1 :         aicpusd_err("Subscribe queue[%u] failed, ret[%d].", queueId, queueStatus);
     189            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     190              :     }
     191            1 :     return AICPU_SCHEDULE_OK;
     192              : }
     193              : 
     194            4 : int32_t CreateQueueTsKernel::ResubscribeF2NF(const uint32_t deviceId, const uint32_t queueId) const
     195              : {
     196            4 :     int32_t queueStatus = halQueueUnsubF2NFEvent(deviceId, queueId);
     197            4 :     if ((queueStatus != DRV_ERROR_NONE) && (queueStatus != DRV_ERROR_NOT_EXIST)) {
     198            1 :         aicpusd_err("Unsub F2NF event for queue[%u] failed, ret[%d].", queueId, queueStatus);
     199            1 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     200              :     }
     201              : 
     202            3 :     queueStatus = halQueueSubF2NFEvent(deviceId, queueId, 0U);
     203            3 :     if (queueStatus != DRV_ERROR_NONE) {
     204            2 :         aicpusd_err("Sub F2NF event for queue[%u] failed, ret=%d.", queueId, queueStatus);
     205            2 :         return AICPU_SCHEDULE_ERROR_DRV_ERR;
     206              :     }
     207            1 :     return AICPU_SCHEDULE_OK;
     208              : }
     209              : 
     210            3 : int32_t DestroyQueueTsKernel::Compute(const aicpu::HwtsTsKernel &tsKernelInfo)
     211              : {
     212            3 :     const aicpu::HwtsCceKernel &kernel = tsKernelInfo.kernelBase.cceKernel;
     213              :     // destroy queue op param : queueId(uint32_t)
     214            3 :     constexpr uint64_t len =  sizeof(aicpu::AicpuParamHead) + sizeof(uint32_t);
     215            3 :     constexpr uint64_t offset = sizeof(aicpu::AicpuParamHead);
     216            3 :     const auto baseAddr = PtrToPtr<void, char_t>(ValueToPtr(kernel.paramBase));
     217            3 :     const aicpu::AicpuParamHead * const paramHead = PtrToPtr<char_t, aicpu::AicpuParamHead>(baseAddr);
     218            3 :     if (paramHead == nullptr) {
     219            1 :         aicpusd_err("ParamHead for DumpDataKernel is nullptr");
     220            1 :         return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     221              :     }
     222              : 
     223            2 :     if (paramHead->length != len) {
     224            1 :         aicpusd_err("Destroy queue param length[%u] should be [%lu]", paramHead->length, len);
     225            1 :         return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     226              :     }
     227              : 
     228            1 :     const uint32_t queueId = *PtrToPtr<const char_t, const uint32_t>(PtrAdd<const char_t>(baseAddr, len, offset));
     229            1 :     const uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
     230              : 
     231            1 :     int32_t eventRet = AICPU_SCHEDULE_OK;
     232            1 :     int32_t ret = halQueueUnsubscribe(deviceId, queueId);
     233            1 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_NOT_EXIST)) {
     234            0 :         aicpusd_err("Unsubscribe queue[%u] failed, ret[%d].", queueId, ret);
     235            0 :         eventRet = AICPU_SCHEDULE_ERROR_DRV_ERR;
     236              :     }
     237              : 
     238            1 :     ret = halQueueUnsubF2NFEvent(deviceId, queueId);
     239            1 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_NOT_EXIST)) {
     240            0 :         aicpusd_err("Unsubscribe queue[%u] F2NF event failed, ret[%d].", queueId, ret);
     241            0 :         eventRet = AICPU_SCHEDULE_ERROR_DRV_ERR;
     242              :     }
     243              : 
     244            1 :     ret = halQueueDestroy(deviceId, queueId);
     245            1 :     if (ret != DRV_ERROR_NONE) {
     246            0 :         aicpusd_err("Destroy queue[%u] error, ret[%d]", queueId, ret);
     247            0 :         eventRet = AICPU_SCHEDULE_ERROR_DRV_ERR;
     248              :     }
     249              : 
     250            1 :     return eventRet;
     251              : }
     252              : 
     253              : REGISTER_HWTS_KERNEL(CREATE_QUEUE, CreateQueueTsKernel);
     254              : REGISTER_HWTS_KERNEL(DESTROY_QUEUE, DestroyQueueTsKernel);
     255              : }  // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1