From 1409d216e536f742700f1ef23a17481509024799 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 13 Jun 2016 08:27:30 -0700 Subject: gpu: nvgpu: Fix gk20a_busy() in debug dump When debug dump is called from an interrupt thread, we do not want to call gk20a_busy() because it causes race in case rail gating is being engaged at the same time. It has to be called from all debugfs paths. Bug 200198908 Bug 1770522 Change-Id: I7eda7d029b0a59cce0320ecc1b750dc2f4d7ccf0 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/1163440 GVS: Gerrit_Virtual_Submit Tested-by: Deepak Nibade Reviewed-by: Bharat Nihalani --- drivers/gpu/nvgpu/gk20a/debug_gk20a.c | 40 ++++++++++++++++++----------------- drivers/gpu/nvgpu/gk20a/debug_gk20a.h | 2 ++ drivers/gpu/nvgpu/gk20a/gk20a.h | 2 -- 3 files changed, 23 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/gk20a/debug_gk20a.c b/drivers/gpu/nvgpu/gk20a/debug_gk20a.c index c02e9760..f1e1f98a 100644 --- a/drivers/gpu/nvgpu/gk20a/debug_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/debug_gk20a.c @@ -165,16 +165,10 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o) { struct fifo_gk20a *f = &g->fifo; u32 chid; - int i, err; + int i; struct ch_state **ch_state; - err = gk20a_busy(g->dev); - if (err) { - gk20a_debug_output(o, "failed to power on gpu: %d\n", err); - return; - } - for (i = 0; i < fifo_pbdma_status__size_1_v(); i++) { u32 status = gk20a_readl(g, fifo_pbdma_status_r(i)); u32 chan_status = fifo_pbdma_status_chan_status_v(status); @@ -227,7 +221,7 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o) * f->num_channels, GFP_KERNEL); if (!ch_state) { gk20a_debug_output(o, "cannot alloc memory for channels\n"); - goto done; + return; } for (chid = 0; chid < f->num_channels; chid++) { @@ -262,8 +256,6 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o) } } kfree(ch_state); -done: - gk20a_idle(g->dev); } static int gk20a_gr_dump_regs(struct device *dev, @@ -271,18 +263,9 @@ static int gk20a_gr_dump_regs(struct device *dev, { struct gk20a_platform *platform = gk20a_get_platform(dev); struct gk20a *g = platform->g; - int err; - - err = gk20a_busy(dev); - if (err) { - gk20a_err(dev, "failed to power on gpu: %d\n", err); - return -EINVAL; - } gr_gk20a_elpg_protected_call(g, g->ops.gr.dump_gr_regs(g, o)); - gk20a_idle(dev); - return 0; } @@ -304,9 +287,18 @@ static int gk20a_gr_debug_show(struct seq_file *s, void *unused) .fn = gk20a_debug_write_to_seqfile, .ctx = s, }; + int err; + + err = gk20a_busy(dev); + if (err) { + gk20a_err(dev, "failed to power on gpu: %d", err); + return -EINVAL; + } gk20a_gr_dump_regs(dev, &o); + gk20a_idle(dev); + return 0; } @@ -334,11 +326,21 @@ static int gk20a_debug_show(struct seq_file *s, void *unused) .ctx = s, }; struct gk20a *g; + int err; g = gk20a_get_platform(dev)->g; + + err = gk20a_busy(g->dev); + if (err) { + gk20a_err(g->dev, "failed to power on gpu: %d", err); + return -EFAULT; + } + /* HAL only initialized after 1st power-on */ if (g->ops.debug.show_dump) g->ops.debug.show_dump(g, &o); + + gk20a_idle(g->dev); return 0; } diff --git a/drivers/gpu/nvgpu/gk20a/debug_gk20a.h b/drivers/gpu/nvgpu/gk20a/debug_gk20a.h index 1044f881..e83076b8 100644 --- a/drivers/gpu/nvgpu/gk20a/debug_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/debug_gk20a.h @@ -37,5 +37,7 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o); int gk20a_gr_debug_dump(struct device *pdev); void gk20a_debug_init(struct device *dev); void gk20a_init_debug_ops(struct gpu_ops *gops); +void gk20a_debug_dump_device(void *dev); + #endif diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 1c129743..4ede8982 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -1099,8 +1099,6 @@ int gk20a_user_init(struct device *dev, const char *interface_name, struct class *class); void gk20a_user_deinit(struct device *dev, struct class *class); -void gk20a_debug_dump_device(void *dev); - static inline u32 ptimer_scalingfactor10x(u32 ptimer_src_freq) { return (u32)(((u64)(PTIMER_REF_FREQ_HZ * 10)) / ptimer_src_freq); -- cgit v1.2.2