summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2017-04-11 02:40:30 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-04-11 12:57:16 -0400
commit6de456f8407ba7230410175f1aff90541137d19b (patch)
tree1ba58f9b7effe006516d471b35966ca0bf550c4d
parenta100422df5a7ab799d979a383d9bfb963d82e45a (diff)
gpu: nvgpu: wait for engine idle in shutdown
In gk20a_pm_shutdown(), we do not check return value of gk20a_pm_prepare_poweroff In some cases it is possible that gk20a_pm_prepare_poweroff() returns -EBUSY (this could happen if engines are busy) so we don't clean up s/w state and directly trigger GPU railgate In case some interrupt is triggered simultaneously we try to access a register while GPU is already railgated This leads to a hard hang in nvgpu shutdown path Make below changes in shutdown sequence to fix this: - check return value of gk20a_wait_for_idle() - disable activity on all engines with gk20a_fifo_disable_all_engine_activity() - ensure engines are idle with gk20a_fifo_wait_engine_idle() - check return value of gk20a_pm_prepare_poweroff() - check return value of gk20a_pm_railgate() Add a print when we bail out early in case GPU is already railgated Move to use new nvgpu_info/err() log messages instead of dev_*() messages Bug 200281010 Change-Id: I2856f9be6cd2de9b0d3ae12955cb1f0a2b6c29be Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1454658 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index d7446484..5fc57494 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -732,32 +732,60 @@ static int gk20a_pm_unrailgate(struct device *dev)
732static void gk20a_pm_shutdown(struct platform_device *pdev) 732static void gk20a_pm_shutdown(struct platform_device *pdev)
733{ 733{
734 struct gk20a_platform *platform = platform_get_drvdata(pdev); 734 struct gk20a_platform *platform = platform_get_drvdata(pdev);
735 struct gk20a *g = platform->g;
736 int err;
735 737
736 dev_info(&pdev->dev, "shutting down"); 738 nvgpu_info(g, "shutting down");
737 739
738 gk20a_driver_start_unload(platform->g); 740 gk20a_driver_start_unload(g);
739 741
740 /* If GPU is already railgated, 742 /* If GPU is already railgated,
741 * just prevent more requests, and return */ 743 * just prevent more requests, and return */
742 if (platform->is_railgated && platform->is_railgated(&pdev->dev)) { 744 if (platform->is_railgated && platform->is_railgated(&pdev->dev)) {
743 __pm_runtime_disable(&pdev->dev, false); 745 __pm_runtime_disable(&pdev->dev, false);
746 nvgpu_info(g, "already railgated, shut down complete");
744 return; 747 return;
745 } 748 }
746 749
747 /* Prevent more requests by disabling Runtime PM */ 750 /* Prevent more requests by disabling Runtime PM */
748 __pm_runtime_disable(&pdev->dev, false); 751 __pm_runtime_disable(&pdev->dev, false);
749 752
750 gk20a_wait_for_idle(&pdev->dev); 753 err = gk20a_wait_for_idle(&pdev->dev);
754 if (err) {
755 nvgpu_err(g, "failed to idle GPU, err=%d", err);
756 goto finish;
757 }
758
759 err = gk20a_fifo_disable_all_engine_activity(g, true);
760 if (err) {
761 nvgpu_err(g, "failed to disable engine activity, err=%d",
762 err);
763 goto finish;
764 }
765
766 err = gk20a_fifo_wait_engine_idle(g);
767 if (err) {
768 nvgpu_err(g, "failed to idle engines, err=%d",
769 err);
770 goto finish;
771 }
751 772
752 /* Be ready for rail-gate after this point */
753 if (gk20a_gpu_is_virtual(&pdev->dev)) 773 if (gk20a_gpu_is_virtual(&pdev->dev))
754 vgpu_pm_prepare_poweroff(&pdev->dev); 774 err = vgpu_pm_prepare_poweroff(&pdev->dev);
755 else 775 else
756 gk20a_pm_prepare_poweroff(&pdev->dev); 776 err = gk20a_pm_prepare_poweroff(&pdev->dev);
777 if (err) {
778 nvgpu_err(g, "failed to prepare for poweroff, err=%d",
779 err);
780 goto finish;
781 }
757 782
758 gk20a_pm_railgate(&pdev->dev); 783 err = gk20a_pm_railgate(&pdev->dev);
784 if (err)
785 nvgpu_err(g, "failed to railgate, err=%d", err);
759 786
760 dev_info(&pdev->dev, "shut down complete\n"); 787finish:
788 nvgpu_info(g, "shut down complete\n");
761} 789}
762 790
763#ifdef CONFIG_PM 791#ifdef CONFIG_PM