mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: create device/context profiler dev nodes
Create new dev nodes for device and context profilers. Example of dev nodes on iGPU /dev/nvhost-prof-dev-gpu - device scope profiler /dev/nvhost-prof-ctx-gpu - context scope profiler Add below APIs to open/close above dev nodes : nvgpu_prof_dev_fops_open() nvgpu_prof_ctx_fops_open() nvgpu_prof_fops_release() Add common API nvgpu_prof_fops_ioctl() to handle IOCTL call on these dev nodes. Add IOCTL NVGPU_PROFILER_IOCTL_BIND_CONTEXT to bind the TSG to profiler objects. Add nvgpu_tsg_get_from_file() to retrieve TSG struct pointer from file descriptor. Also store profiler object pointer into TSG struct. Enable NVGPU_SUPPORT_PROFILER_V2_DEVICE capability on gv11b and tu104. Note that this is not yet enabled for vGPU. Keep NVGPU_SUPPORT_PROFILER_V2_CONTEXT capabiity disabled since this will take longer to support. Add new IOCTL NVGPU_PROFILER_IOCTL_UNBIND_CONTEXT so that userspace can explicitly unbind the context and release the resources before closing the profiler descriptor. Add context_init flag to profiler object for book keeping. Bug 2510974 Jira NVGPU-5360 Change-Id: Ie07e0cfd5a9da9d80008f79c955c7ef93b4bc60f Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2384354 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Alex Waterman
parent
fb95b7efa7
commit
969b901999
@@ -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 ]
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#include <nvgpu/gr/ctx.h>
|
||||
#include <nvgpu/runlist.h>
|
||||
#include <nvgpu/static_analysis.h>
|
||||
#ifdef CONFIG_NVGPU_PROFILER
|
||||
#include <nvgpu/profiler.h>
|
||||
#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;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <nvgpu/atomic.h>
|
||||
#include <nvgpu/log.h>
|
||||
#include <nvgpu/kmem.h>
|
||||
#include <nvgpu/tsg.h>
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
229
drivers/gpu/nvgpu/os/linux/ioctl_prof.c
Normal file
229
drivers/gpu/nvgpu/os/linux/ioctl_prof.c
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <uapi/linux/nvgpu.h>
|
||||
|
||||
#include <nvgpu/kmem.h>
|
||||
#include <nvgpu/log.h>
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/nvgpu_init.h>
|
||||
#include <nvgpu/profiler.h>
|
||||
#include <nvgpu/pm_reservation.h>
|
||||
#include <nvgpu/tsg.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
29
drivers/gpu/nvgpu/os/linux/ioctl_prof.h
Normal file
29
drivers/gpu/nvgpu/os/linux/ioctl_prof.h
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LINUX_IOCTL_PROF_H
|
||||
#define LINUX_IOCTL_PROF_H
|
||||
|
||||
#include <nvgpu/types.h>
|
||||
|
||||
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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user