diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-06-13 11:27:30 -0400 |
---|---|---|
committer | Deepak Nibade <dnibade@nvidia.com> | 2016-06-14 07:50:56 -0400 |
commit | 1409d216e536f742700f1ef23a17481509024799 (patch) | |
tree | 0a27b81bd0fb71ea1e6f32075568fc4937fbe8f1 /drivers/gpu/nvgpu/gk20a | |
parent | edd080b05ab118307c7c7b01426ea1e7c1cc9be7 (diff) |
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 <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/1163440
GVS: Gerrit_Virtual_Submit
Tested-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/debug_gk20a.c | 40 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/debug_gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 2 |
3 files changed, 23 insertions, 21 deletions
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) | |||
165 | { | 165 | { |
166 | struct fifo_gk20a *f = &g->fifo; | 166 | struct fifo_gk20a *f = &g->fifo; |
167 | u32 chid; | 167 | u32 chid; |
168 | int i, err; | 168 | int i; |
169 | 169 | ||
170 | struct ch_state **ch_state; | 170 | struct ch_state **ch_state; |
171 | 171 | ||
172 | err = gk20a_busy(g->dev); | ||
173 | if (err) { | ||
174 | gk20a_debug_output(o, "failed to power on gpu: %d\n", err); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | for (i = 0; i < fifo_pbdma_status__size_1_v(); i++) { | 172 | for (i = 0; i < fifo_pbdma_status__size_1_v(); i++) { |
179 | u32 status = gk20a_readl(g, fifo_pbdma_status_r(i)); | 173 | u32 status = gk20a_readl(g, fifo_pbdma_status_r(i)); |
180 | u32 chan_status = fifo_pbdma_status_chan_status_v(status); | 174 | 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) | |||
227 | * f->num_channels, GFP_KERNEL); | 221 | * f->num_channels, GFP_KERNEL); |
228 | if (!ch_state) { | 222 | if (!ch_state) { |
229 | gk20a_debug_output(o, "cannot alloc memory for channels\n"); | 223 | gk20a_debug_output(o, "cannot alloc memory for channels\n"); |
230 | goto done; | 224 | return; |
231 | } | 225 | } |
232 | 226 | ||
233 | for (chid = 0; chid < f->num_channels; chid++) { | 227 | 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) | |||
262 | } | 256 | } |
263 | } | 257 | } |
264 | kfree(ch_state); | 258 | kfree(ch_state); |
265 | done: | ||
266 | gk20a_idle(g->dev); | ||
267 | } | 259 | } |
268 | 260 | ||
269 | static int gk20a_gr_dump_regs(struct device *dev, | 261 | static int gk20a_gr_dump_regs(struct device *dev, |
@@ -271,18 +263,9 @@ static int gk20a_gr_dump_regs(struct device *dev, | |||
271 | { | 263 | { |
272 | struct gk20a_platform *platform = gk20a_get_platform(dev); | 264 | struct gk20a_platform *platform = gk20a_get_platform(dev); |
273 | struct gk20a *g = platform->g; | 265 | struct gk20a *g = platform->g; |
274 | int err; | ||
275 | |||
276 | err = gk20a_busy(dev); | ||
277 | if (err) { | ||
278 | gk20a_err(dev, "failed to power on gpu: %d\n", err); | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | 266 | ||
282 | gr_gk20a_elpg_protected_call(g, g->ops.gr.dump_gr_regs(g, o)); | 267 | gr_gk20a_elpg_protected_call(g, g->ops.gr.dump_gr_regs(g, o)); |
283 | 268 | ||
284 | gk20a_idle(dev); | ||
285 | |||
286 | return 0; | 269 | return 0; |
287 | } | 270 | } |
288 | 271 | ||
@@ -304,9 +287,18 @@ static int gk20a_gr_debug_show(struct seq_file *s, void *unused) | |||
304 | .fn = gk20a_debug_write_to_seqfile, | 287 | .fn = gk20a_debug_write_to_seqfile, |
305 | .ctx = s, | 288 | .ctx = s, |
306 | }; | 289 | }; |
290 | int err; | ||
291 | |||
292 | err = gk20a_busy(dev); | ||
293 | if (err) { | ||
294 | gk20a_err(dev, "failed to power on gpu: %d", err); | ||
295 | return -EINVAL; | ||
296 | } | ||
307 | 297 | ||
308 | gk20a_gr_dump_regs(dev, &o); | 298 | gk20a_gr_dump_regs(dev, &o); |
309 | 299 | ||
300 | gk20a_idle(dev); | ||
301 | |||
310 | return 0; | 302 | return 0; |
311 | } | 303 | } |
312 | 304 | ||
@@ -334,11 +326,21 @@ static int gk20a_debug_show(struct seq_file *s, void *unused) | |||
334 | .ctx = s, | 326 | .ctx = s, |
335 | }; | 327 | }; |
336 | struct gk20a *g; | 328 | struct gk20a *g; |
329 | int err; | ||
337 | 330 | ||
338 | g = gk20a_get_platform(dev)->g; | 331 | g = gk20a_get_platform(dev)->g; |
332 | |||
333 | err = gk20a_busy(g->dev); | ||
334 | if (err) { | ||
335 | gk20a_err(g->dev, "failed to power on gpu: %d", err); | ||
336 | return -EFAULT; | ||
337 | } | ||
338 | |||
339 | /* HAL only initialized after 1st power-on */ | 339 | /* HAL only initialized after 1st power-on */ |
340 | if (g->ops.debug.show_dump) | 340 | if (g->ops.debug.show_dump) |
341 | g->ops.debug.show_dump(g, &o); | 341 | g->ops.debug.show_dump(g, &o); |
342 | |||
343 | gk20a_idle(g->dev); | ||
342 | return 0; | 344 | return 0; |
343 | } | 345 | } |
344 | 346 | ||
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); | |||
37 | int gk20a_gr_debug_dump(struct device *pdev); | 37 | int gk20a_gr_debug_dump(struct device *pdev); |
38 | void gk20a_debug_init(struct device *dev); | 38 | void gk20a_debug_init(struct device *dev); |
39 | void gk20a_init_debug_ops(struct gpu_ops *gops); | 39 | void gk20a_init_debug_ops(struct gpu_ops *gops); |
40 | void gk20a_debug_dump_device(void *dev); | ||
41 | |||
40 | 42 | ||
41 | #endif | 43 | #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, | |||
1099 | struct class *class); | 1099 | struct class *class); |
1100 | void gk20a_user_deinit(struct device *dev, struct class *class); | 1100 | void gk20a_user_deinit(struct device *dev, struct class *class); |
1101 | 1101 | ||
1102 | void gk20a_debug_dump_device(void *dev); | ||
1103 | |||
1104 | static inline u32 ptimer_scalingfactor10x(u32 ptimer_src_freq) | 1102 | static inline u32 ptimer_scalingfactor10x(u32 ptimer_src_freq) |
1105 | { | 1103 | { |
1106 | return (u32)(((u64)(PTIMER_REF_FREQ_HZ * 10)) / ptimer_src_freq); | 1104 | return (u32)(((u64)(PTIMER_REF_FREQ_HZ * 10)) / ptimer_src_freq); |