From cc64606a535edd9fd96487631f8ef583226fc575 Mon Sep 17 00:00:00 2001 From: Sunny He Date: Wed, 21 Jun 2017 12:08:08 -0700 Subject: gpu: nvgpu: debugfs code to dump HAL functions Prints addresses of device-specific HAL functions to debugfs file hal/gops. The list of functions is produced by dumping the contents of the gpu_ops substruct of the gk20a struct. This interface makes the assumption that there are only function pointers in gpu_ops. Companion Python script nvgpu_debug_hal.py analyzes gk20a.h to determine operation counts and prettyify debugfs interface's output. Jira NVGPU-107 Change-Id: I0910e86638d144979e8630bbc5b330bccfd3ad94 Signed-off-by: Sunny He Reviewed-on: https://git-master.nvidia.com/r/1542990 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/Makefile.nvgpu | 1 + drivers/gpu/nvgpu/common/linux/debug.c | 2 + drivers/gpu/nvgpu/common/linux/debug_hal.c | 95 ++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/common/linux/debug_hal.h | 22 +++++++ drivers/gpu/nvgpu/common/linux/os_linux.h | 1 + drivers/gpu/nvgpu/gk20a/gk20a.h | 5 ++ 6 files changed, 126 insertions(+) create mode 100644 drivers/gpu/nvgpu/common/linux/debug_hal.c create mode 100644 drivers/gpu/nvgpu/common/linux/debug_hal.h (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu index 2aa76497..dab9db92 100644 --- a/drivers/gpu/nvgpu/Makefile.nvgpu +++ b/drivers/gpu/nvgpu/Makefile.nvgpu @@ -129,6 +129,7 @@ nvgpu-$(CONFIG_DEBUG_FS) += \ common/linux/debug_sched.o \ common/linux/debug_mm.o \ common/linux/debug_allocator.o \ + common/linux/debug_hal.o \ common/linux/debug_kmem.o \ common/linux/debug_clk.o diff --git a/drivers/gpu/nvgpu/common/linux/debug.c b/drivers/gpu/nvgpu/common/linux/debug.c index 7dce74d6..abc8b907 100644 --- a/drivers/gpu/nvgpu/common/linux/debug.c +++ b/drivers/gpu/nvgpu/common/linux/debug.c @@ -21,6 +21,7 @@ #include "debug_kmem.h" #include "debug_pmu.h" #include "debug_sched.h" +#include "debug_hal.h" #include "os_linux.h" #include "gk20a/gk20a.h" @@ -386,6 +387,7 @@ void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) gk20a_cde_debugfs_init(g); gk20a_ce_debugfs_init(g); nvgpu_alloc_debugfs_init(g); + nvgpu_hal_debugfs_init(g); gk20a_mm_debugfs_init(g); gk20a_fifo_debugfs_init(g); gk20a_sched_debugfs_init(g); diff --git a/drivers/gpu/nvgpu/common/linux/debug_hal.c b/drivers/gpu/nvgpu/common/linux/debug_hal.c new file mode 100644 index 00000000..031e335e --- /dev/null +++ b/drivers/gpu/nvgpu/common/linux/debug_hal.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that 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. + * + */ + +#include "debug_hal.h" +#include "os_linux.h" + +#include +#include + +/* Format and print a single function pointer to the specified seq_file. */ +static void __hal_print_op(struct seq_file *s, void *op_ptr) +{ + seq_printf(s, "%pF\n", op_ptr); +} + +/* + * Prints an array of function pointer addresses in op_ptrs to the + * specified seq_file + */ +static void __hal_print_ops(struct seq_file *s, void **op_ptrs, int num_ops) +{ + int i; + + for (i = 0; i < num_ops; i++) + __hal_print_op(s, op_ptrs[i]); +} + +/* + * Show file operation, which generates content of the file once. Prints a list + * of gpu operations as defined by gops and the corresponding function pointer + * destination addresses. Relies on no compiler reordering of struct fields and + * assumption that all members are function pointers. + */ +static int __hal_show(struct seq_file *s, void *unused) +{ + struct gpu_ops *gops = s->private; + + __hal_print_ops(s, (void **)gops, sizeof(*gops) / sizeof(void *)); + + return 0; +} + +static int __hal_open(struct inode *inode, struct file *file) +{ + return single_open(file, __hal_show, inode->i_private); +} + +static const struct file_operations __hal_fops = { + .open = __hal_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void nvgpu_hal_debugfs_fini(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (!(l->debugfs_hal == NULL)) + debugfs_remove_recursive(l->debugfs_hal); +} + +void nvgpu_hal_debugfs_init(struct gk20a *g) +{ + struct dentry *d; + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + if (!l->debugfs) + return; + l->debugfs_hal = debugfs_create_dir("hal", l->debugfs); + if (IS_ERR_OR_NULL(l->debugfs_hal)) { + l->debugfs_hal = NULL; + return; + } + + /* Pass along reference to the gpu_ops struct as private data */ + d = debugfs_create_file("gops", S_IRUGO, l->debugfs_hal, + &g->ops, &__hal_fops); + if (!d) { + nvgpu_err(g, "%s: Failed to make debugfs node\n", __func__); + debugfs_remove_recursive(l->debugfs_hal); + return; + } +} diff --git a/drivers/gpu/nvgpu/common/linux/debug_hal.h b/drivers/gpu/nvgpu/common/linux/debug_hal.h new file mode 100644 index 00000000..eee6f234 --- /dev/null +++ b/drivers/gpu/nvgpu/common/linux/debug_hal.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that 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. + * + */ + +#ifndef __NVGPU_DEBUG_HAL_H__ +#define __NVGPU_DEBUG_HAL_H__ + +struct gk20a; +void nvgpu_hal_debugfs_fini(struct gk20a *g); +void nvgpu_hal_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_HAL_H__ */ diff --git a/drivers/gpu/nvgpu/common/linux/os_linux.h b/drivers/gpu/nvgpu/common/linux/os_linux.h index d7fdfa78..ed8364a9 100644 --- a/drivers/gpu/nvgpu/common/linux/os_linux.h +++ b/drivers/gpu/nvgpu/common/linux/os_linux.h @@ -102,6 +102,7 @@ struct nvgpu_os_linux { struct dentry *debugfs_allocators; struct dentry *debugfs_xve; struct dentry *debugfs_kmem; + struct dentry *debugfs_hal; struct dentry *debugfs_force_preemption_cilp; struct dentry *debugfs_force_preemption_gfxp; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 15e81291..121dd962 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -130,6 +130,11 @@ enum gk20a_cbc_op { enum nvgpu_unit; +/* + * gpu_ops should only contain function pointers! Non-function pointer members + * should go in struct gk20a or be implemented with the boolean flag API defined + * in nvgpu/enabled.h + */ struct gpu_ops { struct { int (*determine_L2_size_bytes)(struct gk20a *gk20a); -- cgit v1.2.2