From e93a4ca50b6b24d3db1f8fdc0e5030fecb5ea8d2 Mon Sep 17 00:00:00 2001 From: Nitin Kumbhar Date: Tue, 4 Sep 2018 16:19:47 +0530 Subject: gpu: nvgpu: move fecs trace debugfs to linux Add fecs trace debugfs initialization as an os op. The debugfs nodes are set up for gpu versions which call gk20a_fecs_trace_init(). JIRA NVGPU-602 Change-Id: I606ec31acbf04f633500be4c342db32f3f537794 Signed-off-by: Nitin Kumbhar Reviewed-on: https://git-master.nvidia.com/r/1812449 Reviewed-by: Deepak Nibade GVS: Gerrit_Virtual_Submit Reviewed-by: svc-misra-checker Reviewed-by: Alex Waterman Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c | 154 ++++++++++++++++++++++++++ drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h | 30 +++++ drivers/gpu/nvgpu/os/linux/module.c | 8 ++ drivers/gpu/nvgpu/os/linux/os_linux.h | 4 + drivers/gpu/nvgpu/os/linux/os_ops.c | 4 + drivers/gpu/nvgpu/os/linux/os_ops_gp106.c | 5 + drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c | 5 + drivers/gpu/nvgpu/os/linux/os_ops_gv100.c | 5 + drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c | 30 +++++ drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h | 24 ++++ 10 files changed, 269 insertions(+) create mode 100644 drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c create mode 100644 drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h create mode 100644 drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c create mode 100644 drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h (limited to 'drivers/gpu/nvgpu/os') diff --git a/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c b/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c new file mode 100644 index 00000000..9e72d2ce --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2018, 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 "os_linux.h" + +/* + * The sequence iterator functions. We simply use the count of the + * next line as our internal position. + */ +static void *gk20a_fecs_trace_debugfs_ring_seq_start( + struct seq_file *s, loff_t *pos) +{ + if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) + return NULL; + + return pos; +} + +static void *gk20a_fecs_trace_debugfs_ring_seq_next( + struct seq_file *s, void *v, loff_t *pos) +{ + ++(*pos); + if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) + return NULL; + return pos; +} + +static void gk20a_fecs_trace_debugfs_ring_seq_stop( + struct seq_file *s, void *v) +{ +} + +static int gk20a_fecs_trace_debugfs_ring_seq_show( + struct seq_file *s, void *v) +{ + loff_t *pos = (loff_t *) v; + struct gk20a *g = *(struct gk20a **)s->private; + struct gk20a_fecs_trace_record *r = + gk20a_fecs_trace_get_record(g, *pos); + int i; + const u32 invalid_tag = gk20a_fecs_trace_record_ts_tag_invalid_ts_v(); + u32 tag; + u64 timestamp; + + seq_printf(s, "record #%lld (%p)\n", *pos, r); + seq_printf(s, "\tmagic_lo=%08x\n", r->magic_lo); + seq_printf(s, "\tmagic_hi=%08x\n", r->magic_hi); + if (gk20a_fecs_trace_is_valid_record(r)) { + seq_printf(s, "\tcontext_ptr=%08x\n", r->context_ptr); + seq_printf(s, "\tcontext_id=%08x\n", r->context_id); + seq_printf(s, "\tnew_context_ptr=%08x\n", r->new_context_ptr); + seq_printf(s, "\tnew_context_id=%08x\n", r->new_context_id); + for (i = 0; i < gk20a_fecs_trace_num_ts(); i++) { + tag = gk20a_fecs_trace_record_ts_tag_v(r->ts[i]); + if (tag == invalid_tag) + continue; + timestamp = gk20a_fecs_trace_record_ts_timestamp_v(r->ts[i]); + timestamp <<= GK20A_FECS_TRACE_PTIMER_SHIFT; + seq_printf(s, "\ttag=%02x timestamp=%012llx\n", tag, timestamp); + } + } + return 0; +} + +/* + * Tie them all together into a set of seq_operations. + */ +static const struct seq_operations gk20a_fecs_trace_debugfs_ring_seq_ops = { + .start = gk20a_fecs_trace_debugfs_ring_seq_start, + .next = gk20a_fecs_trace_debugfs_ring_seq_next, + .stop = gk20a_fecs_trace_debugfs_ring_seq_stop, + .show = gk20a_fecs_trace_debugfs_ring_seq_show +}; + +/* + * Time to set up the file operations for our /proc file. In this case, + * all we need is an open function which sets up the sequence ops. + */ + +static int gk20a_ctxsw_debugfs_ring_open(struct inode *inode, + struct file *file) +{ + struct gk20a **p; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + p = __seq_open_private(file, &gk20a_fecs_trace_debugfs_ring_seq_ops, + sizeof(struct gk20a *)); + if (!p) + return -ENOMEM; + + *p = (struct gk20a *)inode->i_private; + return 0; +}; + +/* + * The file operations structure contains our open function along with + * set of the canned seq_ ops. + */ +static const struct file_operations gk20a_fecs_trace_debugfs_ring_fops = { + .owner = THIS_MODULE, + .open = gk20a_ctxsw_debugfs_ring_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private +}; + +static int gk20a_fecs_trace_debugfs_read(void *arg, u64 *val) +{ + *val = gk20a_fecs_trace_get_read_index((struct gk20a *)arg); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_read_fops, + gk20a_fecs_trace_debugfs_read, NULL, "%llu\n"); + +static int gk20a_fecs_trace_debugfs_write(void *arg, u64 *val) +{ + *val = gk20a_fecs_trace_get_write_index((struct gk20a *)arg); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_write_fops, + gk20a_fecs_trace_debugfs_write, NULL, "%llu\n"); + +int nvgpu_fecs_trace_init_debugfs(struct gk20a *g) +{ + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + + debugfs_create_file("ctxsw_trace_read", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_read_fops); + debugfs_create_file("ctxsw_trace_write", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_write_fops); + debugfs_create_file("ctxsw_trace_ring", 0600, l->debugfs, g, + &gk20a_fecs_trace_debugfs_ring_fops); + + return 0; +} diff --git a/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h b/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h new file mode 100644 index 00000000..a545f2db --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/debug_fecs_trace.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, 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_DEBUG_FECS_TRACE_H +#define LINUX_DEBUG_FECS_TRACE_H + +struct gk20a; + +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_GK20A_CTXSW_TRACE) +int nvgpu_fecs_trace_init_debugfs(struct gk20a *g); +#else +int nvgpu_fecs_trace_init_debugfs(struct gk20a *g) +{ + return 0; +} +#endif +#endif diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 85439b88..ff4d9a4c 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -216,6 +216,14 @@ int nvgpu_finalize_poweron_linux(struct nvgpu_os_linux *l) } } + if (l->ops.fecs_trace.init_debugfs) { + err = l->ops.fecs_trace.init_debugfs(g); + if (err) { + nvgpu_err(g, "failed to init linux fecs trace debugfs"); + return err; + } + } + err = nvgpu_pmgr_init_debugfs_linux(l); if (err) { nvgpu_err(g, "failed to init linux pmgr debugfs"); diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h index ff871fe5..a9a9ebb6 100644 --- a/drivers/gpu/nvgpu/os/linux/os_linux.h +++ b/drivers/gpu/nvgpu/os/linux/os_linux.h @@ -46,6 +46,10 @@ struct nvgpu_os_linux_ops { struct { int (*init_debugfs)(struct gk20a *g); } therm; + + struct { + int (*init_debugfs)(struct gk20a *g); + } fecs_trace; }; struct nvgpu_os_linux { diff --git a/drivers/gpu/nvgpu/os/linux/os_ops.c b/drivers/gpu/nvgpu/os/linux/os_ops.c index 5c2eb25c..f1ab4b15 100644 --- a/drivers/gpu/nvgpu/os/linux/os_ops.c +++ b/drivers/gpu/nvgpu/os/linux/os_ops.c @@ -19,6 +19,7 @@ #include "os_ops_gm20b.h" #include "os_ops_gp10b.h" #include "os_ops_gp106.h" +#include "os_ops_gv11b.h" #include "os_ops_gv100.h" #if defined(CONFIG_TEGRA_GPU_NEXT) @@ -44,6 +45,9 @@ int nvgpu_init_os_linux_ops(struct nvgpu_os_linux *l) case NVGPU_GPUID_GV100: nvgpu_gv100_init_os_ops(l); break; + case NVGPU_GPUID_GV11B: + nvgpu_gv11b_init_os_ops(l); + break; #if defined(CONFIG_TEGRA_GPU_NEXT) case NVGPU_GPUID_NEXT: NVGPU_NEXT_INIT_OS_OPS(l); diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c b/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c index 662f4551..14f1b004 100644 --- a/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gp106.c @@ -18,6 +18,7 @@ #include "debug_clk_gp106.h" #include "debug_therm_gp106.h" +#include "debug_fecs_trace.h" static struct nvgpu_os_linux_ops gp106_os_linux_ops = { .clk = { @@ -26,10 +27,14 @@ static struct nvgpu_os_linux_ops gp106_os_linux_ops = { .therm = { .init_debugfs = gp106_therm_init_debugfs, }, + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, }; void nvgpu_gp106_init_os_ops(struct nvgpu_os_linux *l) { l->ops.clk = gp106_os_linux_ops.clk; l->ops.therm = gp106_os_linux_ops.therm; + l->ops.fecs_trace = gp106_os_linux_ops.fecs_trace; } diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c b/drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c index 984dcdc0..e2891f73 100644 --- a/drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gp10b.c @@ -17,6 +17,7 @@ #include "os_linux.h" #include "cde_gp10b.h" +#include "debug_fecs_trace.h" static struct nvgpu_os_linux_ops gp10b_os_linux_ops = { #ifdef CONFIG_NVGPU_SUPPORT_CDE @@ -26,6 +27,9 @@ static struct nvgpu_os_linux_ops gp10b_os_linux_ops = { .populate_scatter_buffer = gp10b_populate_scatter_buffer, }, #endif + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, }; void nvgpu_gp10b_init_os_ops(struct nvgpu_os_linux *l) @@ -33,4 +37,5 @@ void nvgpu_gp10b_init_os_ops(struct nvgpu_os_linux *l) #ifdef CONFIG_NVGPU_SUPPORT_CDE l->ops.cde = gp10b_os_linux_ops.cde; #endif + l->ops.fecs_trace = gp10b_os_linux_ops.fecs_trace; } diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c b/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c index 7a5174a4..f5c5a604 100644 --- a/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gv100.c @@ -18,6 +18,7 @@ #include "debug_clk_gp106.h" #include "debug_therm_gp106.h" +#include "debug_fecs_trace.h" static struct nvgpu_os_linux_ops gv100_os_linux_ops = { .clk = { @@ -26,10 +27,14 @@ static struct nvgpu_os_linux_ops gv100_os_linux_ops = { .therm = { .init_debugfs = gp106_therm_init_debugfs, }, + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, }; void nvgpu_gv100_init_os_ops(struct nvgpu_os_linux *l) { l->ops.clk = gv100_os_linux_ops.clk; l->ops.therm = gv100_os_linux_ops.therm; + l->ops.fecs_trace = gv100_os_linux_ops.fecs_trace; } diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c b/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c new file mode 100644 index 00000000..a82ad0ab --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, 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 "os_linux.h" + +#include "debug_fecs_trace.h" + +static struct nvgpu_os_linux_ops gv11b_os_linux_ops = { + .fecs_trace = { + .init_debugfs = nvgpu_fecs_trace_init_debugfs, + }, +}; + +void nvgpu_gv11b_init_os_ops(struct nvgpu_os_linux *l) +{ + l->ops.fecs_trace = gv11b_os_linux_ops.fecs_trace; +} diff --git a/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h b/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h new file mode 100644 index 00000000..eef6c4ac --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/os_ops_gv11b.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018, 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_OS_OPS_GV11B_H +#define LINUX_OS_OPS_GV11B_H + +struct nvgpu_os_linux; + +void nvgpu_gv11b_init_os_ops(struct nvgpu_os_linux *l); + +#endif -- cgit v1.2.2