aff95158创建于 2025年12月23日历史提交
/**

 * Copyright (c) 2025 Huawei Technologies Co., Ltd.

 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of

 * CANN Open Software License Agreement Version 2.0 (the "License").

 * Please refer to the License for details. You may not use this file except in compliance with the License.

 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,

 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.

 * See LICENSE in the root of the software repository for the full text of the License.

 */

#include <fcntl.h>

#include <sys/ioctl.h>

#include <sys/types.h>

#include <pthread.h>



#include "securec.h"

#include "ascend_hal.h"

#include "davinci_interface.h"

#include "dp_proc_mng_ioctl.h"

#include "dp_adapt.h"

#include "dp_proc_mng.h"



static THREAD int g_dp_proc_mng_fd = -1;

static THREAD int g_dp_proc_mng_pid = -1;



#ifdef EMU_ST

int dp_proc_fie_open(const char *pathname, int flags);

int dp_proc_file_close(int fd);

int dp_proc_ioctl(int fd, unsigned long cmd, void *para);

int dp_proc_get_pid(void);

#else

#define dp_proc_fie_open open

#define dp_proc_file_close close

#define dp_proc_ioctl(fd, cmd, ...) ioctl((fd), (unsigned int)(cmd), ##__VA_ARGS__)

#define dp_proc_get_pid getpid

#endif



static int dp_proc_mng_open_dev(void)

{

    struct davinci_intf_open_arg arg = {0};

    int ret, fd, flags;



    ret = strcpy_s(arg.module_name, DAVINIC_MODULE_NAME_MAX, DAVINCI_DP_PROC_MNG_SUB_MODULE_NAME);

    if (ret != 0) {

        DP_PROC_MNG_ERR("strcpy_s failed. (ret=%d)\n", ret);

        return -1;

    }



    fd = dp_proc_fie_open(davinci_intf_get_dev_path(), O_RDWR | O_SYNC | O_CLOEXEC);

    if (fd < 0) {

        DP_PROC_MNG_ERR("open dev=%d.\n", fd);

        return fd;

    }



    flags = fcntl(fd, F_GETFD);

    flags = (int)((unsigned int)flags | FD_CLOEXEC);

    (void)fcntl(fd, F_SETFD, flags);



    ret = dp_proc_ioctl(fd, DAVINCI_INTF_IOCTL_OPEN, &arg);

    if (ret != 0) {

        DP_PROC_MNG_ERR("DAVINCI_INTF_IOCTL_OPEN failed. (ret=%d)\n", ret);

        (void)dp_proc_file_close(fd);

        return -1;

    }



    return fd;

}



STATIC void dp_proc_mng_close_dev(void)

{

#ifndef EMU_ST

    struct davinci_intf_close_arg arg = {0};

    int ret;



    ret = strcpy_s(arg.module_name, DAVINIC_MODULE_NAME_MAX, DAVINCI_DP_PROC_MNG_SUB_MODULE_NAME);

    if (ret != 0) {

        DP_PROC_MNG_ERR("strcpy_s failed. (ret=%d)\n", ret);

        (void)dp_proc_file_close(g_dp_proc_mng_fd);

        return;

    }



    ret = dp_proc_ioctl(g_dp_proc_mng_fd, DAVINCI_INTF_IOCTL_CLOSE, &arg);

    if (ret != 0) {

        DP_PROC_MNG_ERR("DAVINCI_INTF_IOCTL_CLOSE failed. (ret=%d)\n", ret);

    }



    (void)dp_proc_file_close(g_dp_proc_mng_fd);

    g_dp_proc_mng_fd = -1;

#endif

}



int dp_proc_mng_get_fd_inner(void)

{

    static pthread_mutex_t dp_fd_mutex = PTHREAD_MUTEX_INITIALIZER;



    (void)pthread_mutex_lock(&dp_fd_mutex);

    if ((g_dp_proc_mng_fd > 0) && (g_dp_proc_mng_pid == dp_proc_get_pid())) {

        (void)pthread_mutex_unlock(&dp_fd_mutex);

        return g_dp_proc_mng_fd;

    }



    if (g_dp_proc_mng_fd > 0) {

        dp_proc_mng_close_dev();

    }



    g_dp_proc_mng_fd = dp_proc_mng_open_dev();

    if (g_dp_proc_mng_fd < 0) {

        DP_PROC_MNG_ERR("Open dev file failed. (errno=%d)\n", errno);

    } else {

        g_dp_proc_mng_pid = dp_proc_get_pid();

    }

    (void)pthread_mutex_unlock(&dp_fd_mutex);



    return g_dp_proc_mng_fd;

}



drvError_t dp_proc_mng_ioctl(unsigned int cmd, void *para)

{

    int fd = dp_proc_mng_get_fd_inner();

    int ret;



    if (fd < 0) {

        DP_PROC_MNG_ERR("DpProcMng fd not init.\n");

        return DRV_ERROR_INVALID_DEVICE;

    }



    ret = dp_proc_ioctl(fd, cmd, para);

    if (ret != 0) {

        DP_PROC_MNG_ERR("ioctl failed. (cmd=%x; error=%d) \n", cmd, errno);

        return DRV_ERROR_IOCRL_FAIL;

    }



    return DRV_ERROR_NONE;

}



drvError_t __attribute__((weak)) halBindCgroup(BIND_CGROUP_TYPE bindType)

{

    struct dp_proc_mng_ioctl_arg dp_arg = {0};

    drvError_t ret_val;



    if (!dp_proc_support_bind_cgroup()) {

        DP_PROC_MNG_INFO("Not support yet.\n");

        return DRV_ERROR_NOT_SUPPORT;

    }



    if (bindType >= BIND_CGROUP_MAX_TYPE) {

        DP_PROC_MNG_INFO("Not support bind Cgroup this type. (type=%u)\n", bindType);

        return DRV_ERROR_NOT_SUPPORT;

    }



    dp_arg.data.bind_cgroup_para.bind_type = bindType;

    ret_val = dp_proc_mng_ioctl(DP_PROC_MNG_BIND_CGROUP, &dp_arg);

    if (ret_val != DRV_ERROR_NONE) {

        DP_PROC_MNG_ERR("Bind Cgroup failed. (ret=%d)\n", ret_val);

    }



    return ret_val;

}