From 2a2c16af5f9f1ccfc93a13e820d5381e5c881e92 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Wed, 18 Apr 2018 12:59:00 -0700 Subject: gpu: nvgpu: Move Linux files away from common Move all Linux source code files to drivers/gpu/nvgpu/os/linux from drivers/gpu/nvgpu/common/linux. This changes the meaning of common to be OS independent. JIRA NVGPU-598 JIRA NVGPU-601 Change-Id: Ib7f2a43d3688bb0d0b7dcc48469a6783fd988ce9 Signed-off-by: Terje Bergstrom Reviewed-on: https://git-master.nvidia.com/r/1747714 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/ioctl_tsg.c | 677 ----------------------------- 1 file changed, 677 deletions(-) delete mode 100644 drivers/gpu/nvgpu/common/linux/ioctl_tsg.c (limited to 'drivers/gpu/nvgpu/common/linux/ioctl_tsg.c') diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c b/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c deleted file mode 100644 index 4ef99ded..00000000 --- a/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "gk20a/gk20a.h" -#include "gk20a/tsg_gk20a.h" -#include "gv11b/fifo_gv11b.h" -#include "platform_gk20a.h" -#include "ioctl_tsg.h" -#include "ioctl_channel.h" -#include "os_linux.h" - -struct tsg_private { - struct gk20a *g; - struct tsg_gk20a *tsg; -}; - -static int gk20a_tsg_bind_channel_fd(struct tsg_gk20a *tsg, int ch_fd) -{ - struct channel_gk20a *ch; - int err; - - ch = gk20a_get_channel_from_file(ch_fd); - if (!ch) - return -EINVAL; - - err = ch->g->ops.fifo.tsg_bind_channel(tsg, ch); - - gk20a_channel_put(ch); - return err; -} - -static int gk20a_tsg_ioctl_bind_channel_ex(struct gk20a *g, - struct tsg_gk20a *tsg, struct nvgpu_tsg_bind_channel_ex_args *arg) -{ - struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); - struct gk20a_sched_ctrl *sched = &l->sched_ctrl; - struct channel_gk20a *ch; - struct gr_gk20a *gr = &g->gr; - int err = 0; - - nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid); - - nvgpu_mutex_acquire(&sched->control_lock); - if (sched->control_locked) { - err = -EPERM; - goto mutex_release; - } - err = gk20a_busy(g); - if (err) { - nvgpu_err(g, "failed to power on gpu"); - goto mutex_release; - } - - ch = gk20a_get_channel_from_file(arg->channel_fd); - if (!ch) { - err = -EINVAL; - goto idle; - } - - if (arg->tpc_pg_enabled && (!tsg->tpc_num_initialized)) { - if ((arg->num_active_tpcs > gr->max_tpc_count) || - !(arg->num_active_tpcs)) { - nvgpu_err(g, "Invalid num of active TPCs"); - err = -EINVAL; - goto ch_put; - } - tsg->tpc_num_initialized = true; - tsg->num_active_tpcs = arg->num_active_tpcs; - tsg->tpc_pg_enabled = true; - } else { - tsg->tpc_pg_enabled = false; nvgpu_log(g, gpu_dbg_info, "dynamic TPC-PG not enabled"); - } - - if (arg->subcontext_id < g->fifo.max_subctx_count) { - ch->subctx_id = arg->subcontext_id; - } else { - err = -EINVAL; - goto ch_put; - } - - nvgpu_log(g, gpu_dbg_info, "channel id : %d : subctx: %d", - ch->chid, ch->subctx_id); - - /* Use runqueue selector 1 for all ASYNC ids */ - if (ch->subctx_id > CHANNEL_INFO_VEID0) - ch->runqueue_sel = 1; - - err = ch->g->ops.fifo.tsg_bind_channel(tsg, ch); -ch_put: - gk20a_channel_put(ch); -idle: - gk20a_idle(g); -mutex_release: - nvgpu_mutex_release(&sched->control_lock); - return err; -} - -static int gk20a_tsg_unbind_channel_fd(struct tsg_gk20a *tsg, int ch_fd) -{ - struct channel_gk20a *ch; - int err = 0; - - ch = gk20a_get_channel_from_file(ch_fd); - if (!ch) - return -EINVAL; - - if (ch->tsgid != tsg->tsgid) { - err = -EINVAL; - goto out; - } - - err = gk20a_tsg_unbind_channel(ch); - - /* - * Mark the channel timedout since channel unbound from TSG - * has no context of its own so it can't serve any job - */ - ch->has_timedout = true; - -out: - gk20a_channel_put(ch); - return err; -} - -static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg, - unsigned int event_id, - struct gk20a_event_id_data **event_id_data) -{ - struct gk20a_event_id_data *local_event_id_data; - bool event_found = false; - - nvgpu_mutex_acquire(&tsg->event_id_list_lock); - nvgpu_list_for_each_entry(local_event_id_data, &tsg->event_id_list, - gk20a_event_id_data, event_id_node) { - if (local_event_id_data->event_id == event_id) { - event_found = true; - break; - } - } - nvgpu_mutex_release(&tsg->event_id_list_lock); - - if (event_found) { - *event_id_data = local_event_id_data; - return 0; - } else { - return -1; - } -} - -/* - * Convert common event_id of the form NVGPU_EVENT_ID_* to Linux specific - * event_id of the form NVGPU_IOCTL_CHANNEL_EVENT_ID_* which is used in IOCTLs - */ -static u32 nvgpu_event_id_to_ioctl_channel_event_id(u32 event_id) -{ - switch (event_id) { - case NVGPU_EVENT_ID_BPT_INT: - return NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT; - case NVGPU_EVENT_ID_BPT_PAUSE: - return NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE; - case NVGPU_EVENT_ID_BLOCKING_SYNC: - return NVGPU_IOCTL_CHANNEL_EVENT_ID_BLOCKING_SYNC; - case NVGPU_EVENT_ID_CILP_PREEMPTION_STARTED: - return NVGPU_IOCTL_CHANNEL_EVENT_ID_CILP_PREEMPTION_STARTED; - case NVGPU_EVENT_ID_CILP_PREEMPTION_COMPLETE: - return NVGPU_IOCTL_CHANNEL_EVENT_ID_CILP_PREEMPTION_COMPLETE; - case NVGPU_EVENT_ID_GR_SEMAPHORE_WRITE_AWAKEN: - return NVGPU_IOCTL_CHANNEL_EVENT_ID_GR_SEMAPHORE_WRITE_AWAKEN; - } - - return NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX; -} - -void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg, - int __event_id) -{ - struct gk20a_event_id_data *event_id_data; - u32 event_id; - int err = 0; - struct gk20a *g = tsg->g; - - event_id = nvgpu_event_id_to_ioctl_channel_event_id(__event_id); - if (event_id >= NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX) - return; - - err = gk20a_tsg_get_event_data_from_id(tsg, event_id, - &event_id_data); - if (err) - return; - - nvgpu_mutex_acquire(&event_id_data->lock); - - nvgpu_log_info(g, - "posting event for event_id=%d on tsg=%d\n", - event_id, tsg->tsgid); - event_id_data->event_posted = true; - - nvgpu_cond_broadcast_interruptible(&event_id_data->event_id_wq); - - nvgpu_mutex_release(&event_id_data->lock); -} - -static unsigned int gk20a_event_id_poll(struct file *filep, poll_table *wait) -{ - unsigned int mask = 0; - struct gk20a_event_id_data *event_id_data = filep->private_data; - struct gk20a *g = event_id_data->g; - u32 event_id = event_id_data->event_id; - struct tsg_gk20a *tsg = g->fifo.tsg + event_id_data->id; - - nvgpu_log(g, gpu_dbg_fn | gpu_dbg_info, " "); - - poll_wait(filep, &event_id_data->event_id_wq.wq, wait); - - nvgpu_mutex_acquire(&event_id_data->lock); - - if (event_id_data->event_posted) { - nvgpu_log_info(g, - "found pending event_id=%d on TSG=%d\n", - event_id, tsg->tsgid); - mask = (POLLPRI | POLLIN); - event_id_data->event_posted = false; - } - - nvgpu_mutex_release(&event_id_data->lock); - - return mask; -} - -static int gk20a_event_id_release(struct inode *inode, struct file *filp) -{ - struct gk20a_event_id_data *event_id_data = filp->private_data; - struct gk20a *g = event_id_data->g; - struct tsg_gk20a *tsg = g->fifo.tsg + event_id_data->id; - - nvgpu_mutex_acquire(&tsg->event_id_list_lock); - nvgpu_list_del(&event_id_data->event_id_node); - nvgpu_mutex_release(&tsg->event_id_list_lock); - - nvgpu_mutex_destroy(&event_id_data->lock); - gk20a_put(g); - nvgpu_kfree(g, event_id_data); - filp->private_data = NULL; - - return 0; -} - -const struct file_operations gk20a_event_id_ops = { - .owner = THIS_MODULE, - .poll = gk20a_event_id_poll, - .release = gk20a_event_id_release, -}; - -static int gk20a_tsg_event_id_enable(struct tsg_gk20a *tsg, - int event_id, - int *fd) -{ - int err = 0; - int local_fd; - struct file *file; - char name[64]; - struct gk20a_event_id_data *event_id_data; - struct gk20a *g; - - g = gk20a_get(tsg->g); - if (!g) - return -ENODEV; - - err = gk20a_tsg_get_event_data_from_id(tsg, - event_id, &event_id_data); - if (err == 0) { - /* We already have event enabled */ - err = -EINVAL; - goto free_ref; - } - - err = get_unused_fd_flags(O_RDWR); - if (err < 0) - goto free_ref; - local_fd = err; - - snprintf(name, sizeof(name), "nvgpu-event%d-fd%d", - event_id, local_fd); - - file = anon_inode_getfile(name, &gk20a_event_id_ops, - NULL, O_RDWR); - if (IS_ERR(file)) { - err = PTR_ERR(file); - goto clean_up; - } - - event_id_data = nvgpu_kzalloc(tsg->g, sizeof(*event_id_data)); - if (!event_id_data) { - err = -ENOMEM; - goto clean_up_file; - } - event_id_data->g = g; - event_id_data->id = tsg->tsgid; - event_id_data->event_id = event_id; - - nvgpu_cond_init(&event_id_data->event_id_wq); - err = nvgpu_mutex_init(&event_id_data->lock); - if (err) - goto clean_up_free; - - nvgpu_init_list_node(&event_id_data->event_id_node); - - nvgpu_mutex_acquire(&tsg->event_id_list_lock); - nvgpu_list_add_tail(&event_id_data->event_id_node, &tsg->event_id_list); - nvgpu_mutex_release(&tsg->event_id_list_lock); - - fd_install(local_fd, file); - file->private_data = event_id_data; - - *fd = local_fd; - - return 0; - -clean_up_free: - nvgpu_kfree(g, event_id_data); -clean_up_file: - fput(file); -clean_up: - put_unused_fd(local_fd); -free_ref: - gk20a_put(g); - return err; -} - -static int gk20a_tsg_event_id_ctrl(struct gk20a *g, struct tsg_gk20a *tsg, - struct nvgpu_event_id_ctrl_args *args) -{ - int err = 0; - int fd = -1; - - if (args->event_id >= NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX) - return -EINVAL; - - switch (args->cmd) { - case NVGPU_IOCTL_CHANNEL_EVENT_ID_CMD_ENABLE: - err = gk20a_tsg_event_id_enable(tsg, args->event_id, &fd); - if (!err) - args->event_fd = fd; - break; - - default: - nvgpu_err(tsg->g, "unrecognized tsg event id cmd: 0x%x", - args->cmd); - err = -EINVAL; - break; - } - - return err; -} - -int nvgpu_ioctl_tsg_open(struct gk20a *g, struct file *filp) -{ - struct tsg_private *priv; - struct tsg_gk20a *tsg; - struct device *dev; - int err; - - g = gk20a_get(g); - if (!g) - return -ENODEV; - - dev = dev_from_gk20a(g); - - nvgpu_log(g, gpu_dbg_fn, "tsg: %s", dev_name(dev)); - - priv = nvgpu_kmalloc(g, sizeof(*priv)); - if (!priv) { - err = -ENOMEM; - goto free_ref; - } - - tsg = gk20a_tsg_open(g, nvgpu_current_pid(g)); - if (!tsg) { - nvgpu_kfree(g, priv); - err = -ENOMEM; - goto free_ref; - } - - priv->g = g; - priv->tsg = tsg; - filp->private_data = priv; - - gk20a_sched_ctrl_tsg_added(g, tsg); - - return 0; - -free_ref: - gk20a_put(g); - return err; -} - -int nvgpu_ioctl_tsg_dev_open(struct inode *inode, struct file *filp) -{ - struct nvgpu_os_linux *l; - struct gk20a *g; - int ret; - - l = container_of(inode->i_cdev, - struct nvgpu_os_linux, tsg.cdev); - g = &l->g; - - nvgpu_log_fn(g, " "); - - ret = gk20a_busy(g); - if (ret) { - nvgpu_err(g, "failed to power on, %d", ret); - return ret; - } - - ret = nvgpu_ioctl_tsg_open(&l->g, filp); - - gk20a_idle(g); - nvgpu_log_fn(g, "done"); - return ret; -} - -void nvgpu_ioctl_tsg_release(struct nvgpu_ref *ref) -{ - struct tsg_gk20a *tsg = container_of(ref, struct tsg_gk20a, refcount); - struct gk20a *g = tsg->g; - - gk20a_sched_ctrl_tsg_removed(g, tsg); - - gk20a_tsg_release(ref); - gk20a_put(g); -} - -int nvgpu_ioctl_tsg_dev_release(struct inode *inode, struct file *filp) -{ - struct tsg_private *priv = filp->private_data; - struct tsg_gk20a *tsg = priv->tsg; - - nvgpu_ref_put(&tsg->refcount, nvgpu_ioctl_tsg_release); - nvgpu_kfree(tsg->g, priv); - return 0; -} - -static int gk20a_tsg_ioctl_set_runlist_interleave(struct gk20a *g, - struct tsg_gk20a *tsg, struct nvgpu_runlist_interleave_args *arg) -{ - struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); - struct gk20a_sched_ctrl *sched = &l->sched_ctrl; - u32 level = arg->level; - int err; - - nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid); - - nvgpu_mutex_acquire(&sched->control_lock); - if (sched->control_locked) { - err = -EPERM; - goto done; - } - err = gk20a_busy(g); - if (err) { - nvgpu_err(g, "failed to power on gpu"); - goto done; - } - - level = nvgpu_get_common_runlist_level(level); - err = gk20a_tsg_set_runlist_interleave(tsg, level); - - gk20a_idle(g); -done: - nvgpu_mutex_release(&sched->control_lock); - return err; -} - -static int gk20a_tsg_ioctl_set_timeslice(struct gk20a *g, - struct tsg_gk20a *tsg, struct nvgpu_timeslice_args *arg) -{ - struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); - struct gk20a_sched_ctrl *sched = &l->sched_ctrl; - int err; - - nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid); - - nvgpu_mutex_acquire(&sched->control_lock); - if (sched->control_locked) { - err = -EPERM; - goto done; - } - err = gk20a_busy(g); - if (err) { - nvgpu_err(g, "failed to power on gpu"); - goto done; - } - err = gk20a_tsg_set_timeslice(tsg, arg->timeslice_us); - gk20a_idle(g); -done: - nvgpu_mutex_release(&sched->control_lock); - return err; -} - -static int gk20a_tsg_ioctl_get_timeslice(struct gk20a *g, - struct tsg_gk20a *tsg, struct nvgpu_timeslice_args *arg) -{ - arg->timeslice_us = gk20a_tsg_get_timeslice(tsg); - return 0; -} - -long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - struct tsg_private *priv = filp->private_data; - struct tsg_gk20a *tsg = priv->tsg; - struct gk20a *g = tsg->g; - u8 __maybe_unused buf[NVGPU_TSG_IOCTL_MAX_ARG_SIZE]; - int err = 0; - - nvgpu_log_fn(g, "start %d", _IOC_NR(cmd)); - - if ((_IOC_TYPE(cmd) != NVGPU_TSG_IOCTL_MAGIC) || - (_IOC_NR(cmd) == 0) || - (_IOC_NR(cmd) > NVGPU_TSG_IOCTL_LAST) || - (_IOC_SIZE(cmd) > NVGPU_TSG_IOCTL_MAX_ARG_SIZE)) - return -EINVAL; - - memset(buf, 0, sizeof(buf)); - if (_IOC_DIR(cmd) & _IOC_WRITE) { - if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) - return -EFAULT; - } - - if (!g->sw_ready) { - err = gk20a_busy(g); - if (err) - return err; - - gk20a_idle(g); - } - - switch (cmd) { - case NVGPU_TSG_IOCTL_BIND_CHANNEL: - { - int ch_fd = *(int *)buf; - if (ch_fd < 0) { - err = -EINVAL; - break; - } - err = gk20a_tsg_bind_channel_fd(tsg, ch_fd); - break; - } - - case NVGPU_TSG_IOCTL_BIND_CHANNEL_EX: - { - err = gk20a_tsg_ioctl_bind_channel_ex(g, tsg, - (struct nvgpu_tsg_bind_channel_ex_args *)buf); - break; - } - - case NVGPU_TSG_IOCTL_UNBIND_CHANNEL: - { - int ch_fd = *(int *)buf; - - if (ch_fd < 0) { - err = -EINVAL; - break; - } - err = gk20a_busy(g); - if (err) { - nvgpu_err(g, - "failed to host gk20a for ioctl cmd: 0x%x", cmd); - break; - } - err = gk20a_tsg_unbind_channel_fd(tsg, ch_fd); - gk20a_idle(g); - break; - } - - case NVGPU_IOCTL_TSG_ENABLE: - { - err = gk20a_busy(g); - if (err) { - nvgpu_err(g, - "failed to host gk20a for ioctl cmd: 0x%x", cmd); - return err; - } - g->ops.fifo.enable_tsg(tsg); - gk20a_idle(g); - break; - } - - case NVGPU_IOCTL_TSG_DISABLE: - { - err = gk20a_busy(g); - if (err) { - nvgpu_err(g, - "failed to host gk20a for ioctl cmd: 0x%x", cmd); - return err; - } - g->ops.fifo.disable_tsg(tsg); - gk20a_idle(g); - break; - } - - case NVGPU_IOCTL_TSG_PREEMPT: - { - err = gk20a_busy(g); - if (err) { - nvgpu_err(g, - "failed to host gk20a for ioctl cmd: 0x%x", cmd); - return err; - } - /* preempt TSG */ - err = g->ops.fifo.preempt_tsg(g, tsg->tsgid); - gk20a_idle(g); - break; - } - - case NVGPU_IOCTL_TSG_EVENT_ID_CTRL: - { - err = gk20a_tsg_event_id_ctrl(g, tsg, - (struct nvgpu_event_id_ctrl_args *)buf); - break; - } - - case NVGPU_IOCTL_TSG_SET_RUNLIST_INTERLEAVE: - err = gk20a_tsg_ioctl_set_runlist_interleave(g, tsg, - (struct nvgpu_runlist_interleave_args *)buf); - break; - - case NVGPU_IOCTL_TSG_SET_TIMESLICE: - { - err = gk20a_tsg_ioctl_set_timeslice(g, tsg, - (struct nvgpu_timeslice_args *)buf); - break; - } - case NVGPU_IOCTL_TSG_GET_TIMESLICE: - { - err = gk20a_tsg_ioctl_get_timeslice(g, tsg, - (struct nvgpu_timeslice_args *)buf); - break; - } - - default: - nvgpu_err(g, "unrecognized tsg gpu ioctl cmd: 0x%x", - cmd); - err = -ENOTTY; - break; - } - - if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ)) - err = copy_to_user((void __user *)arg, - buf, _IOC_SIZE(cmd)); - - return err; -} -- cgit v1.2.2