From 5ecc45b5e7f16e00b2407d4259759228ccbdcf4b Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Fri, 21 Dec 2018 10:04:27 +0530 Subject: gpu: nvgpu: add cycle stats to debugger node Add NVGPU_DBG_GPU_IOCTL_CYCLE_STATS to debugger node, to install/uninstall a buffer for cycle stats. Add NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT to debugger node, to attach/flush/detach a buffer for Mode-E streamout. Those ioctls will apply to the first channel in the debug session. Bug 2660206 Bug 200464613 Change-Id: I0b96d9a07c016690140292fa5886fda545697ee6 Signed-off-by: Thomas Fleury Reviewed-on: https://git-master.nvidia.com/r/2002060 (cherry picked from commit 90b0bf98ac01d7fa24c40f6a1f20bfe5fa481d36) Signed-off-by: Gagan Grover Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2092008 Reviewed-by: automaticguardword Reviewed-by: Phoenix Jung Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: Peter Daifuku Tested-by: mobile promotions --- drivers/gpu/nvgpu/os/linux/ioctl_channel.c | 21 ++++--- drivers/gpu/nvgpu/os/linux/ioctl_channel.h | 11 +++- drivers/gpu/nvgpu/os/linux/ioctl_dbg.c | 94 ++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_channel.c b/drivers/gpu/nvgpu/os/linux/ioctl_channel.c index 3c844491..da35b93f 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_channel.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_channel.c @@ -1,7 +1,7 @@ /* * GK20A Graphics channel * - * Copyright (c) 2011-2018, 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, @@ -128,8 +128,7 @@ void gk20a_channel_free_cycle_stats_buffer(struct channel_gk20a *ch) nvgpu_mutex_release(&ch->cyclestate.cyclestate_buffer_mutex); } -static int gk20a_channel_cycle_stats(struct channel_gk20a *ch, - struct nvgpu_cycle_stats_args *args) +int gk20a_channel_cycle_stats(struct channel_gk20a *ch, int dmabuf_fd) { struct dma_buf *dmabuf; void *virtual_address; @@ -139,10 +138,10 @@ static int gk20a_channel_cycle_stats(struct channel_gk20a *ch, if (!nvgpu_is_enabled(ch->g, NVGPU_SUPPORT_CYCLE_STATS)) return -ENOSYS; - if (args->dmabuf_fd && !priv->cyclestate_buffer_handler) { + if (dmabuf_fd && !priv->cyclestate_buffer_handler) { /* set up new cyclestats buffer */ - dmabuf = dma_buf_get(args->dmabuf_fd); + dmabuf = dma_buf_get(dmabuf_fd); if (IS_ERR(dmabuf)) return PTR_ERR(dmabuf); virtual_address = dma_buf_vmap(dmabuf); @@ -154,12 +153,12 @@ static int gk20a_channel_cycle_stats(struct channel_gk20a *ch, ch->cyclestate.cyclestate_buffer_size = dmabuf->size; return 0; - } else if (!args->dmabuf_fd && priv->cyclestate_buffer_handler) { + } else if (!dmabuf_fd && priv->cyclestate_buffer_handler) { gk20a_channel_free_cycle_stats_buffer(ch); return 0; - } else if (!args->dmabuf_fd && !priv->cyclestate_buffer_handler) { - /* no requst from GL */ + } else if (!dmabuf_fd && !priv->cyclestate_buffer_handler) { + /* no request from GL */ return 0; } else { @@ -168,7 +167,7 @@ static int gk20a_channel_cycle_stats(struct channel_gk20a *ch, } } -static int gk20a_flush_cycle_stats_snapshot(struct channel_gk20a *ch) +int gk20a_flush_cycle_stats_snapshot(struct channel_gk20a *ch) { int ret; @@ -182,7 +181,7 @@ static int gk20a_flush_cycle_stats_snapshot(struct channel_gk20a *ch) return ret; } -static int gk20a_attach_cycle_stats_snapshot(struct channel_gk20a *ch, +int gk20a_attach_cycle_stats_snapshot(struct channel_gk20a *ch, u32 dmabuf_fd, u32 perfmon_id_count, u32 *perfmon_id_start) @@ -1280,7 +1279,7 @@ long gk20a_channel_ioctl(struct file *filp, break; } err = gk20a_channel_cycle_stats(ch, - (struct nvgpu_cycle_stats_args *)buf); + ((struct nvgpu_cycle_stats_args *)buf)->dmabuf_fd); gk20a_idle(ch->g); break; #endif diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_channel.h b/drivers/gpu/nvgpu/os/linux/ioctl_channel.h index 48cff1ea..3e802899 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_channel.h +++ b/drivers/gpu/nvgpu/os/linux/ioctl_channel.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, @@ -36,9 +36,16 @@ long gk20a_channel_ioctl(struct file *filp, int gk20a_channel_open_ioctl(struct gk20a *g, struct nvgpu_channel_open_args *args); -int gk20a_channel_free_cycle_stats_snapshot(struct channel_gk20a *ch); +int gk20a_channel_cycle_stats(struct channel_gk20a *ch, int dmabuf_fd); void gk20a_channel_free_cycle_stats_buffer(struct channel_gk20a *ch); +int gk20a_attach_cycle_stats_snapshot(struct channel_gk20a *ch, + u32 dmabuf_fd, + u32 perfmon_id_count, + u32 *perfmon_id_start); +int gk20a_flush_cycle_stats_snapshot(struct channel_gk20a *ch); +int gk20a_channel_free_cycle_stats_snapshot(struct channel_gk20a *ch); + extern const struct file_operations gk20a_channel_ops; u32 nvgpu_get_common_runlist_level(u32 level); diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c index 0c9b10b5..b5a10717 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c @@ -42,6 +42,7 @@ #include "os_linux.h" #include "platform_gk20a.h" #include "ioctl_dbg.h" +#include "ioctl_channel.h" #include "dmabuf_vidmem.h" struct dbg_session_gk20a_linux { @@ -1935,6 +1936,87 @@ static int nvgpu_dbg_gpu_set_sm_exception_type_mask( return err; } +#if defined(CONFIG_GK20A_CYCLE_STATS) +static int nvgpu_dbg_gpu_cycle_stats(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_cycle_stats_args *args) +{ + struct channel_gk20a *ch = NULL; + int err; + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch == NULL) { + return -EINVAL; + } + + err = gk20a_busy(ch->g); + if (err != 0) { + return err; + } + + err = gk20a_channel_cycle_stats(ch, args->dmabuf_fd); + + gk20a_idle(ch->g); + return err; +} + +static int nvgpu_dbg_gpu_cycle_stats_snapshot(struct dbg_session_gk20a *dbg_s, + struct nvgpu_dbg_gpu_cycle_stats_snapshot_args *args) +{ + struct channel_gk20a *ch = NULL; + int err; + + if (!args->dmabuf_fd) { + return -EINVAL; + } + + nvgpu_speculation_barrier(); + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch == NULL) { + return -EINVAL; + } + + /* is it allowed to handle calls for current GPU? */ + if (!nvgpu_is_enabled(ch->g, NVGPU_SUPPORT_CYCLE_STATS_SNAPSHOT)) { + return -ENOSYS; + } + + err = gk20a_busy(ch->g); + if (err != 0) { + return err; + } + + /* handle the command (most frequent cases first) */ + switch (args->cmd) { + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT_CMD_FLUSH: + err = gk20a_flush_cycle_stats_snapshot(ch); + args->extra = 0; + break; + + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT_CMD_ATTACH: + err = gk20a_attach_cycle_stats_snapshot(ch, + args->dmabuf_fd, + args->extra, + &args->extra); + break; + + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT_CMD_DETACH: + err = gk20a_channel_free_cycle_stats_snapshot(ch); + args->extra = 0; + break; + + default: + pr_err("cyclestats: unknown command %u\n", args->cmd); + err = -EINVAL; + break; + } + + gk20a_idle(ch->g); + return err; +} + +#endif + int gk20a_dbg_gpu_dev_open(struct inode *inode, struct file *filp) { struct nvgpu_os_linux *l = container_of(inode->i_cdev, @@ -2096,6 +2178,18 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, (struct nvgpu_dbg_gpu_set_ctx_mmu_debug_mode_args *)buf); break; +#ifdef CONFIG_GK20A_CYCLE_STATS + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS: + err = nvgpu_dbg_gpu_cycle_stats(dbg_s, + (struct nvgpu_dbg_gpu_cycle_stats_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_CYCLE_STATS_SNAPSHOT: + err = nvgpu_dbg_gpu_cycle_stats_snapshot(dbg_s, + (struct nvgpu_dbg_gpu_cycle_stats_snapshot_args *)buf); + break; +#endif + default: nvgpu_err(g, "unrecognized dbg gpu ioctl cmd: 0x%x", -- cgit v1.2.2