mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 09:57:08 +03:00
gpu: nvgpu: add TSG support to channel event id
Add NVGPU_IOCTL_TSG_EVENT_ID_CTRL API for channel event id support to TSGs This API will accept an event_id (like BPT.INT or BPT.PAUSE), a command to enable the event, and return a file descriptor on which we can raise the event (if cmd=enable) Events generated for TSGs will reuse file operations "gk20a_event_id_ops" Bug 200089620 Change-Id: I2f563c6d3a0988eb670caac2d3c7c6795724792c Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1030776 (cherry picked from commit 72b61fa266279038f013e582be80c21808e1038d) Reviewed-on: http://git-master/r/1120319 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
This commit is contained in:
committed by
Terje Bergstrom
parent
e87ba53235
commit
5f10073540
@@ -2506,7 +2506,13 @@ unsigned int gk20a_event_id_poll(struct file *filep, poll_table *wait)
|
|||||||
|
|
||||||
mutex_lock(&event_id_data->lock);
|
mutex_lock(&event_id_data->lock);
|
||||||
|
|
||||||
if (!event_id_data->is_tsg) {
|
if (event_id_data->is_tsg) {
|
||||||
|
struct tsg_gk20a *tsg = g->fifo.tsg + event_id_data->id;
|
||||||
|
|
||||||
|
gk20a_dbg_info(
|
||||||
|
"found pending event_id=%d on TSG=%d\n",
|
||||||
|
event_id, tsg->tsgid);
|
||||||
|
} else {
|
||||||
struct channel_gk20a *ch = g->fifo.channel
|
struct channel_gk20a *ch = g->fifo.channel
|
||||||
+ event_id_data->id;
|
+ event_id_data->id;
|
||||||
|
|
||||||
@@ -2526,7 +2532,13 @@ int gk20a_event_id_release(struct inode *inode, struct file *filp)
|
|||||||
struct gk20a_event_id_data *event_id_data = filp->private_data;
|
struct gk20a_event_id_data *event_id_data = filp->private_data;
|
||||||
struct gk20a *g = event_id_data->g;
|
struct gk20a *g = event_id_data->g;
|
||||||
|
|
||||||
if (!event_id_data->is_tsg) {
|
if (event_id_data->is_tsg) {
|
||||||
|
struct tsg_gk20a *tsg = g->fifo.tsg + event_id_data->id;
|
||||||
|
|
||||||
|
mutex_lock(&tsg->event_id_list_lock);
|
||||||
|
list_del_init(&event_id_data->event_id_node);
|
||||||
|
mutex_unlock(&tsg->event_id_list_lock);
|
||||||
|
} else {
|
||||||
struct channel_gk20a *ch = g->fifo.channel + event_id_data->id;
|
struct channel_gk20a *ch = g->fifo.channel + event_id_data->id;
|
||||||
|
|
||||||
mutex_lock(&ch->event_id_list_lock);
|
mutex_lock(&ch->event_id_list_lock);
|
||||||
@@ -2540,7 +2552,7 @@ int gk20a_event_id_release(struct inode *inode, struct file *filp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations gk20a_event_id_ops = {
|
const struct file_operations gk20a_event_id_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.poll = gk20a_event_id_poll,
|
.poll = gk20a_event_id_poll,
|
||||||
.release = gk20a_event_id_release,
|
.release = gk20a_event_id_release,
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ struct gk20a_fence;
|
|||||||
#include "gr_gk20a.h"
|
#include "gr_gk20a.h"
|
||||||
#include "fence_gk20a.h"
|
#include "fence_gk20a.h"
|
||||||
|
|
||||||
|
extern const struct file_operations gk20a_event_id_ops;
|
||||||
|
|
||||||
struct notification {
|
struct notification {
|
||||||
struct {
|
struct {
|
||||||
u32 nanoseconds[2];
|
u32 nanoseconds[2];
|
||||||
|
|||||||
@@ -153,6 +153,9 @@ int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid)
|
|||||||
INIT_LIST_HEAD(&tsg->ch_list);
|
INIT_LIST_HEAD(&tsg->ch_list);
|
||||||
mutex_init(&tsg->ch_list_lock);
|
mutex_init(&tsg->ch_list_lock);
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&tsg->event_id_list);
|
||||||
|
mutex_init(&tsg->event_id_list_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +187,122 @@ static int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg,
|
||||||
|
int event_id,
|
||||||
|
struct gk20a_event_id_data **event_id_data)
|
||||||
|
{
|
||||||
|
struct gk20a_event_id_data *local_event_id_data;
|
||||||
|
bool event_found = false;
|
||||||
|
|
||||||
|
mutex_lock(&tsg->event_id_list_lock);
|
||||||
|
list_for_each_entry(local_event_id_data, &tsg->event_id_list,
|
||||||
|
event_id_node) {
|
||||||
|
if (local_event_id_data->event_id == event_id) {
|
||||||
|
event_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&tsg->event_id_list_lock);
|
||||||
|
|
||||||
|
if (event_found) {
|
||||||
|
*event_id_data = local_event_id_data;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
struct gk20a_event_id_data *event_id_data;
|
||||||
|
|
||||||
|
err = gk20a_tsg_get_event_data_from_id(tsg,
|
||||||
|
event_id, &event_id_data);
|
||||||
|
if (err == 0) /* We already have event enabled */
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
err = get_unused_fd_flags(O_RDWR);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
local_fd = err;
|
||||||
|
|
||||||
|
name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d",
|
||||||
|
event_id, local_fd);
|
||||||
|
|
||||||
|
file = anon_inode_getfile(name, &gk20a_event_id_ops,
|
||||||
|
NULL, O_RDWR);
|
||||||
|
kfree(name);
|
||||||
|
if (IS_ERR(file)) {
|
||||||
|
err = PTR_ERR(file);
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_id_data = kzalloc(sizeof(*event_id_data), GFP_KERNEL);
|
||||||
|
if (!event_id_data) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto clean_up_file;
|
||||||
|
}
|
||||||
|
event_id_data->g = tsg->g;
|
||||||
|
event_id_data->id = tsg->tsgid;
|
||||||
|
event_id_data->is_tsg = true;
|
||||||
|
event_id_data->event_id = event_id;
|
||||||
|
|
||||||
|
init_waitqueue_head(&event_id_data->event_id_wq);
|
||||||
|
mutex_init(&event_id_data->lock);
|
||||||
|
INIT_LIST_HEAD(&event_id_data->event_id_node);
|
||||||
|
|
||||||
|
mutex_lock(&tsg->event_id_list_lock);
|
||||||
|
list_add_tail(&event_id_data->event_id_node, &tsg->event_id_list);
|
||||||
|
mutex_unlock(&tsg->event_id_list_lock);
|
||||||
|
|
||||||
|
fd_install(local_fd, file);
|
||||||
|
file->private_data = event_id_data;
|
||||||
|
|
||||||
|
*fd = local_fd;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
clean_up_file:
|
||||||
|
fput(file);
|
||||||
|
clean_up:
|
||||||
|
put_unused_fd(local_fd);
|
||||||
|
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 < 0 ||
|
||||||
|
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:
|
||||||
|
gk20a_err(dev_from_gk20a(tsg->g),
|
||||||
|
"unrecognized tsg event id cmd: 0x%x",
|
||||||
|
args->cmd);
|
||||||
|
err = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg)
|
static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg)
|
||||||
{
|
{
|
||||||
mutex_lock(&f->tsg_inuse_mutex);
|
mutex_lock(&f->tsg_inuse_mutex);
|
||||||
@@ -372,6 +491,13 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case NVGPU_IOCTL_TSG_EVENT_ID_CTRL:
|
||||||
|
{
|
||||||
|
err = gk20a_tsg_event_id_ctrl(g, tsg,
|
||||||
|
(struct nvgpu_event_id_ctrl_args *)buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gk20a_err(dev_from_gk20a(g),
|
gk20a_err(dev_from_gk20a(g),
|
||||||
"unrecognized tsg gpu ioctl cmd: 0x%x",
|
"unrecognized tsg gpu ioctl cmd: 0x%x",
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ struct tsg_gk20a {
|
|||||||
struct vm_gk20a *vm;
|
struct vm_gk20a *vm;
|
||||||
|
|
||||||
u32 interleave_level;
|
u32 interleave_level;
|
||||||
|
|
||||||
|
struct list_head event_id_list;
|
||||||
|
struct mutex event_id_list_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
int gk20a_enable_tsg(struct tsg_gk20a *tsg);
|
int gk20a_enable_tsg(struct tsg_gk20a *tsg);
|
||||||
|
|||||||
@@ -448,11 +448,15 @@ struct nvgpu_gpu_get_cpu_time_correlation_info_args {
|
|||||||
_IO(NVGPU_TSG_IOCTL_MAGIC, 5)
|
_IO(NVGPU_TSG_IOCTL_MAGIC, 5)
|
||||||
#define NVGPU_IOCTL_TSG_SET_PRIORITY \
|
#define NVGPU_IOCTL_TSG_SET_PRIORITY \
|
||||||
_IOW(NVGPU_TSG_IOCTL_MAGIC, 6, struct nvgpu_set_priority_args)
|
_IOW(NVGPU_TSG_IOCTL_MAGIC, 6, struct nvgpu_set_priority_args)
|
||||||
|
#define NVGPU_IOCTL_TSG_EVENT_ID_CTRL \
|
||||||
|
_IOWR(NVGPU_TSG_IOCTL_MAGIC, 7, struct nvgpu_event_id_ctrl_args)
|
||||||
|
|
||||||
#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \
|
#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \
|
||||||
sizeof(struct nvgpu_set_priority_args)
|
sizeof(struct nvgpu_event_id_ctrl_args)
|
||||||
#define NVGPU_TSG_IOCTL_LAST \
|
#define NVGPU_TSG_IOCTL_LAST \
|
||||||
_IOC_NR(NVGPU_IOCTL_TSG_SET_PRIORITY)
|
_IOC_NR(NVGPU_IOCTL_TSG_EVENT_ID_CTRL)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* /dev/nvhost-dbg-gpu device
|
* /dev/nvhost-dbg-gpu device
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user