diff --git a/arch/nvgpu-linux.yaml b/arch/nvgpu-linux.yaml index 098a644fa..654a92064 100644 --- a/arch/nvgpu-linux.yaml +++ b/arch/nvgpu-linux.yaml @@ -117,6 +117,8 @@ ioctl: os/linux/ioctl_ctrl.h, os/linux/ioctl_dbg.c, os/linux/ioctl_dbg.h, + os/linux/ioctl_prof.c, + os/linux/ioctl_prof.h, os/linux/ioctl_tsg.c, os/linux/ioctl_tsg.h ] diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index c62f674d1..eabee16a2 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -377,6 +377,7 @@ nvgpu-y += \ os/linux/ioctl_channel.o \ os/linux/ioctl_tsg.o \ os/linux/ioctl_dbg.o \ + os/linux/ioctl_prof.o \ os/linux/ioctl_clk_arb.o \ os/linux/cond.o \ os/linux/nvgpu_mem.o \ diff --git a/drivers/gpu/nvgpu/common/fifo/tsg.c b/drivers/gpu/nvgpu/common/fifo/tsg.c index 692499099..eff615b79 100644 --- a/drivers/gpu/nvgpu/common/fifo/tsg.c +++ b/drivers/gpu/nvgpu/common/fifo/tsg.c @@ -34,6 +34,9 @@ #include #include #include +#ifdef CONFIG_NVGPU_PROFILER +#include +#endif void nvgpu_tsg_disable(struct nvgpu_tsg *tsg) { @@ -808,6 +811,12 @@ void nvgpu_tsg_release_common(struct gk20a *g, struct nvgpu_tsg *tsg) g->ops.tsg.deinit_eng_method_buffers(g, tsg); } +#ifdef CONFIG_NVGPU_PROFILER + if (tsg->prof != NULL) { + nvgpu_profiler_unbind_context(tsg->prof); + } +#endif + if (tsg->vm != NULL) { nvgpu_vm_put(tsg->vm); tsg->vm = NULL; diff --git a/drivers/gpu/nvgpu/common/profiler/profiler.c b/drivers/gpu/nvgpu/common/profiler/profiler.c index 19f51b9c4..4d4428648 100644 --- a/drivers/gpu/nvgpu/common/profiler/profiler.c +++ b/drivers/gpu/nvgpu/common/profiler/profiler.c @@ -26,6 +26,7 @@ #include #include #include +#include static nvgpu_atomic_t unique_id = NVGPU_ATOMIC_INIT(0); static int generate_unique_id(void) @@ -68,10 +69,61 @@ void nvgpu_profiler_free(struct nvgpu_profiler_object *prof) nvgpu_log(g, gpu_dbg_prof, "Free profiler handle %u", prof->prof_handle); + nvgpu_profiler_unbind_context(prof); + nvgpu_list_del(&prof->prof_obj_entry); nvgpu_kfree(g, prof); } +int nvgpu_profiler_bind_context(struct nvgpu_profiler_object *prof, + struct nvgpu_tsg *tsg) +{ + struct gk20a *g = prof->g; + + nvgpu_log(g, gpu_dbg_prof, "Request to bind tsgid %u with profiler handle %u", + tsg->tsgid, prof->prof_handle); + + if (tsg->prof != NULL) { + nvgpu_err(g, "TSG %u is already bound", tsg->tsgid); + return -EINVAL; + } + + if (prof->tsg != NULL) { + nvgpu_err(g, "Profiler object %u already bound!", prof->prof_handle); + return -EINVAL; + } + + prof->tsg = tsg; + tsg->prof = prof; + + nvgpu_log(g, gpu_dbg_prof, "Bind tsgid %u with profiler handle %u successful", + tsg->tsgid, prof->prof_handle); + + prof->context_init = true; + return 0; +} + +int nvgpu_profiler_unbind_context(struct nvgpu_profiler_object *prof) +{ + struct gk20a *g = prof->g; + struct nvgpu_tsg *tsg = prof->tsg; + + if (!prof->context_init) { + return -EINVAL; + } + + if (tsg != NULL) { + tsg->prof = NULL; + prof->tsg = NULL; + + nvgpu_log(g, gpu_dbg_prof, "Unbind profiler handle %u and tsgid %u", + prof->prof_handle, tsg->tsgid); + } + + prof->context_init = false; + return 0; +} + int nvgpu_profiler_pm_resource_reserve(struct nvgpu_profiler_object *prof, enum nvgpu_profiler_pm_resource_type pm_resource) { diff --git a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c index 140fd5a18..d9d186074 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c @@ -1611,6 +1611,10 @@ int gv11b_init_hal(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_FECS_CTXSW_TRACE, true); #endif +#ifdef CONFIG_NVGPU_PROFILER + nvgpu_set_enabled(g, NVGPU_SUPPORT_PROFILER_V2_DEVICE, true); + nvgpu_set_enabled(g, NVGPU_SUPPORT_PROFILER_V2_CONTEXT, false); +#endif nvgpu_set_enabled(g, NVGPU_SUPPORT_MULTIPLE_WPR, false); #ifdef CONFIG_NVGPU_GRAPHICS diff --git a/drivers/gpu/nvgpu/hal/init/hal_tu104.c b/drivers/gpu/nvgpu/hal/init/hal_tu104.c index 1f2776812..e49323f1f 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_tu104.c +++ b/drivers/gpu/nvgpu/hal/init/hal_tu104.c @@ -1733,6 +1733,10 @@ int tu104_init_hal(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_FECS_TRACE_VA, true); nvgpu_set_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_FECS_CTXSW_TRACE, true); +#endif +#ifdef CONFIG_NVGPU_PROFILER + nvgpu_set_enabled(g, NVGPU_SUPPORT_PROFILER_V2_DEVICE, true); + nvgpu_set_enabled(g, NVGPU_SUPPORT_PROFILER_V2_CONTEXT, false); #endif nvgpu_set_enabled(g, NVGPU_SUPPORT_SEC2_RTOS, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_PMU_RTOS_FBQ, true); diff --git a/drivers/gpu/nvgpu/include/nvgpu/profiler.h b/drivers/gpu/nvgpu/include/nvgpu/profiler.h index 00861d526..bab004940 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/profiler.h +++ b/drivers/gpu/nvgpu/include/nvgpu/profiler.h @@ -30,6 +30,7 @@ struct gk20a; struct nvgpu_channel; +struct nvgpu_tsg; struct nvgpu_profiler_object { struct gk20a *g; @@ -49,6 +50,13 @@ struct nvgpu_profiler_object { */ struct nvgpu_tsg *tsg; + /* + * If context has been bound by userspace. + * For objects with device scope, userspace should still trigger + * BIND_CONTEXT IOCTL/DEVCTL with tsg_fd = -1 for consistency. + */ + bool context_init; + /* If profiler object has reservation for each resource. */ bool reserved[NVGPU_PROFILER_PM_RESOURCE_TYPE_COUNT]; @@ -74,6 +82,10 @@ int nvgpu_profiler_alloc(struct gk20a *g, enum nvgpu_profiler_pm_reservation_scope scope); void nvgpu_profiler_free(struct nvgpu_profiler_object *prof); +int nvgpu_profiler_bind_context(struct nvgpu_profiler_object *prof, + struct nvgpu_tsg *tsg); +int nvgpu_profiler_unbind_context(struct nvgpu_profiler_object *prof); + int nvgpu_profiler_pm_resource_reserve(struct nvgpu_profiler_object *prof, enum nvgpu_profiler_pm_resource_type pm_resource); int nvgpu_profiler_pm_resource_release(struct nvgpu_profiler_object *prof, diff --git a/drivers/gpu/nvgpu/include/nvgpu/tsg.h b/drivers/gpu/nvgpu/include/nvgpu/tsg.h index f1b189799..16f930b86 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/tsg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/tsg.h @@ -52,6 +52,7 @@ struct gk20a; struct nvgpu_channel; struct nvgpu_gr_ctx; struct nvgpu_channel_hw_state; +struct nvgpu_profiler_object; #ifdef CONFIG_NVGPU_CHANNEL_TSG_CONTROL enum nvgpu_event_id_type; @@ -193,6 +194,11 @@ struct nvgpu_tsg { u32 sm_exception_mask_type; struct nvgpu_mutex sm_exception_mask_lock; #endif + +#ifdef CONFIG_NVGPU_PROFILER + /** Pointer of profiler object to which this TSG is bound */ + struct nvgpu_profiler_object *prof; +#endif }; int nvgpu_tsg_open_common(struct gk20a *g, struct nvgpu_tsg *tsg, pid_t pid); diff --git a/drivers/gpu/nvgpu/os/linux/ioctl.c b/drivers/gpu/nvgpu/os/linux/ioctl.c index 1efd7e671..33aa8c5d9 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl.c @@ -1,7 +1,7 @@ /* * NVGPU IOCTLs * - * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2020, 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, @@ -26,6 +26,7 @@ #include "ioctl_as.h" #include "ioctl_tsg.h" #include "ioctl_dbg.h" +#include "ioctl_prof.h" #include "module.h" #include "os_linux.h" #include "fecs_trace_linux.h" @@ -91,7 +92,27 @@ static const struct file_operations gk20a_prof_ops = { #endif }; -static const struct file_operations gk20a_tsg_ops = { +static const struct file_operations gk20a_prof_dev_ops = { + .owner = THIS_MODULE, + .release = nvgpu_prof_fops_release, + .open = nvgpu_prof_dev_fops_open, + .unlocked_ioctl = nvgpu_prof_fops_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = nvgpu_prof_fops_ioctl, +#endif +}; + +static const struct file_operations gk20a_prof_ctx_ops = { + .owner = THIS_MODULE, + .release = nvgpu_prof_fops_release, + .open = nvgpu_prof_ctx_fops_open, + .unlocked_ioctl = nvgpu_prof_fops_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = nvgpu_prof_fops_ioctl, +#endif +}; + +const struct file_operations gk20a_tsg_ops = { .owner = THIS_MODULE, .release = nvgpu_ioctl_tsg_dev_release, .open = nvgpu_ioctl_tsg_dev_open, @@ -195,6 +216,16 @@ void gk20a_user_deinit(struct device *dev, struct class *class) cdev_del(&l->prof.cdev); } + if (l->prof_dev.node) { + device_destroy(class, l->prof_dev.cdev.dev); + cdev_del(&l->prof_dev.cdev); + } + + if (l->prof_ctx.node) { + device_destroy(class, l->prof_ctx.cdev.dev); + cdev_del(&l->prof_ctx.cdev); + } + if (l->tsg.node) { device_destroy(class, l->tsg.cdev.dev); cdev_del(&l->tsg.cdev); @@ -264,6 +295,20 @@ int gk20a_user_init(struct device *dev, const char *interface_name, if (err) goto fail; + err = gk20a_create_device(dev, devno++, interface_name, "-prof-dev", + &l->prof_dev.cdev, &l->prof_dev.node, + &gk20a_prof_dev_ops, + class); + if (err) + goto fail; + + err = gk20a_create_device(dev, devno++, interface_name, "-prof-ctx", + &l->prof_ctx.cdev, &l->prof_ctx.node, + &gk20a_prof_ctx_ops, + class); + if (err) + goto fail; + err = gk20a_create_device(dev, devno++, interface_name, "-tsg", &l->tsg.cdev, &l->tsg.node, &gk20a_tsg_ops, diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index c22f4ea6c..2069678fb 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -411,6 +411,7 @@ gk20a_ctrl_ioctl_gpu_characteristics( gpu.as_ioctl_nr_last = NVGPU_AS_IOCTL_LAST; gpu.event_ioctl_nr_last = NVGPU_EVENT_IOCTL_LAST; gpu.ctxsw_ioctl_nr_last = NVGPU_CTXSW_IOCTL_LAST; + gpu.prof_ioctl_nr_last = NVGPU_PROFILER_IOCTL_LAST; gpu.gpu_va_bit_count = 40; strlcpy(gpu.chipname, g->name, sizeof(gpu.chipname)); diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_prof.c b/drivers/gpu/nvgpu/os/linux/ioctl_prof.c new file mode 100644 index 000000000..67b09bf0c --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/ioctl_prof.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2020, 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 +#include + +#include "os_linux.h" +#include "ioctl_prof.h" +#include "ioctl_tsg.h" + +struct nvgpu_profiler_object_priv { + struct nvgpu_profiler_object *prof; + struct gk20a *g; +}; + +static int nvgpu_prof_fops_open(struct gk20a *g, struct file *filp, + enum nvgpu_profiler_pm_reservation_scope scope) +{ + struct nvgpu_profiler_object_priv *prof_priv; + struct nvgpu_profiler_object *prof; + int err; + + nvgpu_log(g, gpu_dbg_prof, "Request to open profiler session with scope %u", + scope); + + prof_priv = nvgpu_kzalloc(g, sizeof(*prof_priv)); + if (prof_priv == NULL) { + return -ENOMEM; + } + + err = nvgpu_profiler_alloc(g, &prof, scope); + if (err != 0) { + nvgpu_kfree(g, prof_priv); + return -ENOMEM; + } + + prof_priv->g = g; + prof_priv->prof = prof; + filp->private_data = prof_priv; + + nvgpu_log(g, gpu_dbg_prof, + "Profiler session with scope %u created successfully with profiler handle %u", + scope, prof->prof_handle); + + return 0; +} + +int nvgpu_prof_dev_fops_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l = container_of(inode->i_cdev, + struct nvgpu_os_linux, prof_dev.cdev); + struct gk20a *g; + int err; + + g = nvgpu_get(&l->g); + if (!g) { + return -ENODEV; + } + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_PROFILER_V2_DEVICE)) { + nvgpu_put(g); + return -EINVAL; + } + + err = nvgpu_prof_fops_open(g, filp, + NVGPU_PROFILER_PM_RESERVATION_SCOPE_DEVICE); + if (err != 0) { + nvgpu_put(g); + } + + return err; +} + +int nvgpu_prof_ctx_fops_open(struct inode *inode, struct file *filp) +{ + struct nvgpu_os_linux *l = container_of(inode->i_cdev, + struct nvgpu_os_linux, prof_ctx.cdev); + struct gk20a *g; + int err; + + g = nvgpu_get(&l->g); + if (!g) { + return -ENODEV; + } + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_PROFILER_V2_CONTEXT)) { + nvgpu_put(g); + return -EINVAL; + } + + err = nvgpu_prof_fops_open(g, filp, + NVGPU_PROFILER_PM_RESERVATION_SCOPE_CONTEXT); + if (err != 0) { + nvgpu_put(g); + } + + return err; +} + +int nvgpu_prof_fops_release(struct inode *inode, struct file *filp) +{ + struct nvgpu_profiler_object_priv *prof_priv = filp->private_data; + struct nvgpu_profiler_object *prof = prof_priv->prof; + struct gk20a *g = prof_priv->g; + + nvgpu_log(g, gpu_dbg_prof, + "Request to close profiler session with scope %u and profiler handle %u", + prof->scope, prof->prof_handle); + + nvgpu_profiler_free(prof); + nvgpu_kfree(g, prof_priv); + nvgpu_put(g); + + nvgpu_log(g, gpu_dbg_prof, "Profiler session closed successfully"); + + return 0; +} + +static int nvgpu_prof_ioctl_bind_context(struct nvgpu_profiler_object *prof, + struct nvgpu_profiler_bind_context_args *args) +{ + int tsg_fd = args->tsg_fd; + struct nvgpu_tsg *tsg; + struct gk20a *g = prof->g; + + if (prof->context_init) { + nvgpu_err(g, "Context info is already initialized"); + return -EINVAL; + } + + if (tsg_fd < 0) { + if (prof->scope == NVGPU_PROFILER_PM_RESERVATION_SCOPE_DEVICE) { + prof->context_init = true; + return 0; + } + return -EINVAL; + } + + tsg = nvgpu_tsg_get_from_file(tsg_fd); + if (tsg == NULL) { + nvgpu_err(g, "invalid TSG fd %d", tsg_fd); + return -EINVAL; + } + + return nvgpu_profiler_bind_context(prof, tsg); +} + +static int nvgpu_prof_ioctl_unbind_context(struct nvgpu_profiler_object *prof) +{ + return nvgpu_profiler_unbind_context(prof); +} + +long nvgpu_prof_fops_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct nvgpu_profiler_object_priv *prof_priv = filp->private_data; + struct nvgpu_profiler_object *prof = prof_priv->prof; + struct gk20a *g = prof_priv->g; + u8 __maybe_unused buf[NVGPU_PROFILER_IOCTL_MAX_ARG_SIZE]; + int err = 0; + + if ((_IOC_TYPE(cmd) != NVGPU_PROFILER_IOCTL_MAGIC) || + (_IOC_NR(cmd) == 0) || + (_IOC_NR(cmd) > NVGPU_PROFILER_IOCTL_LAST) || + (_IOC_SIZE(cmd) > NVGPU_PROFILER_IOCTL_MAX_ARG_SIZE)) { + return -EINVAL; + } + + (void) memset(buf, 0, sizeof(buf)); + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) { + return -EFAULT; + } + } + + nvgpu_log(g, gpu_dbg_prof, "Profiler handle %u received IOCTL cmd %u", + prof->prof_handle, cmd); + + nvgpu_speculation_barrier(); + + switch (cmd) { + case NVGPU_PROFILER_IOCTL_BIND_CONTEXT: + err = nvgpu_prof_ioctl_bind_context(prof, + (struct nvgpu_profiler_bind_context_args *)buf); + break; + + case NVGPU_PROFILER_IOCTL_UNBIND_CONTEXT: + err = nvgpu_prof_ioctl_unbind_context(prof); + break; + + default: + nvgpu_err(g, "unrecognized profiler 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)); + + nvgpu_log(g, gpu_dbg_prof, "Profiler handle %u IOCTL err = %d", + prof->prof_handle, err); + + return err; +} diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_prof.h b/drivers/gpu/nvgpu/os/linux/ioctl_prof.h new file mode 100644 index 000000000..8180f9db6 --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/ioctl_prof.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020, 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 . + */ +#ifndef LINUX_IOCTL_PROF_H +#define LINUX_IOCTL_PROF_H + +#include + +struct inode; +struct file; + +int nvgpu_prof_dev_fops_open(struct inode *inode, struct file *filp); +int nvgpu_prof_ctx_fops_open(struct inode *inode, struct file *filp); +int nvgpu_prof_fops_release(struct inode *inode, struct file *filp); +long nvgpu_prof_fops_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); +#endif /* LINUX_IOCTL_PROF_H */ diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c index e455f38d6..67f3acf16 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c @@ -44,6 +44,29 @@ struct tsg_private { struct nvgpu_tsg *tsg; }; +extern const struct file_operations gk20a_tsg_ops; + +struct nvgpu_tsg *nvgpu_tsg_get_from_file(int fd) +{ + struct nvgpu_tsg *tsg; + struct tsg_private *priv; + struct file *f = fget(fd); + + if (!f) { + return NULL; + } + + if (f->f_op != &gk20a_tsg_ops) { + fput(f); + return NULL; + } + + priv = (struct tsg_private *)f->private_data; + tsg = priv->tsg; + fput(f); + return tsg; +} + static int nvgpu_tsg_bind_channel_fd(struct nvgpu_tsg *tsg, int ch_fd) { struct nvgpu_channel *ch; diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.h b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.h index 67399fd48..2809eadec 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.h +++ b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, 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, @@ -18,6 +18,8 @@ struct file; struct gk20a; struct nvgpu_ref; +struct nvgpu_tsg *nvgpu_tsg_get_from_file(int fd); + int nvgpu_ioctl_tsg_dev_release(struct inode *inode, struct file *filp); int nvgpu_ioctl_tsg_dev_open(struct inode *inode, struct file *filp); int nvgpu_ioctl_tsg_open(struct gk20a *g, struct file *filp); diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h index 8f1ff5dd2..d833773ec 100644 --- a/drivers/gpu/nvgpu/os/linux/os_linux.h +++ b/drivers/gpu/nvgpu/os/linux/os_linux.h @@ -103,6 +103,16 @@ struct nvgpu_os_linux { struct device *node; } prof; + struct { + struct cdev cdev; + struct device *node; + } prof_dev; + + struct { + struct cdev cdev; + struct device *node; + } prof_ctx; + struct { struct cdev cdev; struct device *node; diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h index a2a1b723e..abd176b6b 100644 --- a/include/uapi/linux/nvgpu.h +++ b/include/uapi/linux/nvgpu.h @@ -315,7 +315,8 @@ struct nvgpu_gpu_characteristics { __u32 max_css_buffer_size; __s16 ctxsw_ioctl_nr_last; - __u8 reserved2[6]; + __s16 prof_ioctl_nr_last; + __u8 reserved2[4]; __u32 max_ctxsw_ring_buffer_size; __u32 reserved3; @@ -1624,10 +1625,12 @@ struct nvgpu_profiler_exec_reg_ops_args { _IOWR(NVGPU_PROFILER_IOCTL_MAGIC, 8, struct nvgpu_profiler_pma_stream_update_get_put_args) #define NVGPU_PROFILER_IOCTL_EXEC_REG_OPS \ _IOWR(NVGPU_PROFILER_IOCTL_MAGIC, 9, struct nvgpu_profiler_exec_reg_ops_args) +#define NVGPU_PROFILER_IOCTL_UNBIND_CONTEXT \ + _IO(NVGPU_PROFILER_IOCTL_MAGIC, 10) #define NVGPU_PROFILER_IOCTL_MAX_ARG_SIZE \ sizeof(struct nvgpu_profiler_alloc_pma_stream_args) #define NVGPU_PROFILER_IOCTL_LAST \ - _IOC_NR(NVGPU_PROFILER_IOCTL_EXEC_REG_OPS) + _IOC_NR(NVGPU_PROFILER_IOCTL_UNBIND_CONTEXT) /*