summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2019-07-17 07:53:42 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2019-08-02 10:12:00 -0400
commit47f6bc0c2e85d0a8ff943b88c81108ca1bfc588e (patch)
tree8cafdce8c9eeb4d7d3b8127d69a0763f3a968e70 /drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c
parent9fdb446b472c7a299b10365ddc91fc86a8e6788f (diff)
gpu: nvgpu: Fix the race between runtime PM and L2 flush
gk20a_mm_l2_flush flushes the L2 cache when "struct gk20a->power_on" is true. But it doesn't acquire power lock when doing that, which creates a race that runtime PM might suspend the GPU in the middle of L2 flush. The FB flush looks having the same issue with L2 flushing. This patch fixes that by calling pm_runtime_get_if_in_use at the beginning of the ioctl. This API from PM does a compare and add to the usage count. If the device was not in use, it simply returns without incrementing the usage count as its unnecessary to wake up the GPU(using e.g. a call to gk20a_busy()) as the caches are flushed when the device would be resumed anyways. Bug 2643951 Change-Id: I2417f7ca3223c722dcb4d9057d32a7e065b9e574 Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2151532 GVS: Gerrit_Virtual_Submit Reviewed-by: Mark Zhang <markz@nvidia.com> Reviewed-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c')
-rw-r--r--drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c
index 227a7d57..3ccc6b0a 100644
--- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c
+++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c
@@ -568,19 +568,28 @@ static int gk20a_ctrl_get_fbp_l2_masks(
568static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g, 568static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g,
569 struct nvgpu_gpu_l2_fb_args *args) 569 struct nvgpu_gpu_l2_fb_args *args)
570{ 570{
571 int err = 0; 571 int ret = 0;
572 572
573 if ((!args->l2_flush && !args->fb_flush) || 573 if ((!args->l2_flush && !args->fb_flush) ||
574 (!args->l2_flush && args->l2_invalidate)) 574 (!args->l2_flush && args->l2_invalidate))
575 return -EINVAL; 575 return -EINVAL;
576 576
577 ret = gk20a_busy_try_noresume(g);
578
579 /* return if device is already powered off */
580 if (ret == 0)
581 return 0;
582
577 if (args->l2_flush) 583 if (args->l2_flush)
578 g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false); 584 g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false);
579 585
580 if (args->fb_flush) 586 if (args->fb_flush)
581 g->ops.mm.fb_flush(g); 587 g->ops.mm.fb_flush(g);
582 588
583 return err; 589 if (ret > 0)
590 gk20a_idle_nosuspend(g);
591
592 return 0;
584} 593}
585 594
586static int nvgpu_gpu_ioctl_set_mmu_debug_mode( 595static int nvgpu_gpu_ioctl_set_mmu_debug_mode(