diff options
author | Seema Khowala <seemaj@nvidia.com> | 2018-05-04 13:29:14 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-05-17 12:33:04 -0400 |
commit | 4654d9abd176043e69d548d53d516e78e4054d9e (patch) | |
tree | c6c33636d9154d1cf35fb1bc7bafe2bb996d02cd | |
parent | 4d63729ac8aa8fecf66bd066178e317f07560534 (diff) |
gpu: nvgpu: runlist_lock released before preempt timeout recovery
Release runlist_lock and then initiate recovery if preempt
timed out. Also do not issue preempt if ch, tsg or runlist
id is invalid. tsgid could be invalid for below call trace
gk20a_prepare_poweroff->gk20a_channel_suspend->
*_fifo_preempt_channel->*_fifo_preempt_tsg
Bug 2065990
Bug 2043838
Change-Id: Ia1e3c134f06743e1258254a4a6f7256831706185
Signed-off-by: Seema Khowala <seemaj@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1662656
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 22 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/fifo_gv11b.c | 16 |
3 files changed, 29 insertions, 12 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index aada3065..22dc1d60 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -2721,7 +2721,7 @@ int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, | |||
2721 | return ret; | 2721 | return ret; |
2722 | } | 2722 | } |
2723 | 2723 | ||
2724 | void __locked_fifo_preempt_timeout_rc(struct gk20a *g, u32 id, | 2724 | void gk20a_fifo_preempt_timeout_rc(struct gk20a *g, u32 id, |
2725 | unsigned int id_type) | 2725 | unsigned int id_type) |
2726 | { | 2726 | { |
2727 | if (id_type == ID_TYPE_TSG) { | 2727 | if (id_type == ID_TYPE_TSG) { |
@@ -2764,7 +2764,7 @@ int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) | |||
2764 | int ret; | 2764 | int ret; |
2765 | unsigned int id_type; | 2765 | unsigned int id_type; |
2766 | 2766 | ||
2767 | nvgpu_log_fn(g, "%d", id); | 2767 | nvgpu_log_fn(g, "id: %d is_tsg: %d", id, is_tsg); |
2768 | 2768 | ||
2769 | /* issue preempt */ | 2769 | /* issue preempt */ |
2770 | gk20a_fifo_issue_preempt(g, id, is_tsg); | 2770 | gk20a_fifo_issue_preempt(g, id, is_tsg); |
@@ -2774,10 +2774,6 @@ int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg) | |||
2774 | /* wait for preempt */ | 2774 | /* wait for preempt */ |
2775 | ret = g->ops.fifo.is_preempt_pending(g, id, id_type, | 2775 | ret = g->ops.fifo.is_preempt_pending(g, id, id_type, |
2776 | PREEMPT_TIMEOUT_RC); | 2776 | PREEMPT_TIMEOUT_RC); |
2777 | |||
2778 | if (ret) | ||
2779 | __locked_fifo_preempt_timeout_rc(g, id, id_type); | ||
2780 | |||
2781 | return ret; | 2777 | return ret; |
2782 | } | 2778 | } |
2783 | 2779 | ||
@@ -2789,7 +2785,9 @@ int gk20a_fifo_preempt_channel(struct gk20a *g, u32 chid) | |||
2789 | u32 mutex_ret = 0; | 2785 | u32 mutex_ret = 0; |
2790 | u32 i; | 2786 | u32 i; |
2791 | 2787 | ||
2792 | nvgpu_log_fn(g, "%d", chid); | 2788 | nvgpu_log_fn(g, "chid: %d", chid); |
2789 | if (chid == FIFO_INVAL_CHANNEL_ID) | ||
2790 | return 0; | ||
2793 | 2791 | ||
2794 | /* we have no idea which runlist we are using. lock all */ | 2792 | /* we have no idea which runlist we are using. lock all */ |
2795 | for (i = 0; i < g->fifo.max_runlists; i++) | 2793 | for (i = 0; i < g->fifo.max_runlists; i++) |
@@ -2805,6 +2803,9 @@ int gk20a_fifo_preempt_channel(struct gk20a *g, u32 chid) | |||
2805 | for (i = 0; i < g->fifo.max_runlists; i++) | 2803 | for (i = 0; i < g->fifo.max_runlists; i++) |
2806 | nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); | 2804 | nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); |
2807 | 2805 | ||
2806 | if (ret) | ||
2807 | gk20a_fifo_preempt_timeout_rc(g, chid, false); | ||
2808 | |||
2808 | return ret; | 2809 | return ret; |
2809 | } | 2810 | } |
2810 | 2811 | ||
@@ -2816,7 +2817,9 @@ int gk20a_fifo_preempt_tsg(struct gk20a *g, u32 tsgid) | |||
2816 | u32 mutex_ret = 0; | 2817 | u32 mutex_ret = 0; |
2817 | u32 i; | 2818 | u32 i; |
2818 | 2819 | ||
2819 | nvgpu_log_fn(g, "%d", tsgid); | 2820 | nvgpu_log_fn(g, "tsgid: %d", tsgid); |
2821 | if (tsgid == FIFO_INVAL_TSG_ID) | ||
2822 | return 0; | ||
2820 | 2823 | ||
2821 | /* we have no idea which runlist we are using. lock all */ | 2824 | /* we have no idea which runlist we are using. lock all */ |
2822 | for (i = 0; i < g->fifo.max_runlists; i++) | 2825 | for (i = 0; i < g->fifo.max_runlists; i++) |
@@ -2832,6 +2835,9 @@ int gk20a_fifo_preempt_tsg(struct gk20a *g, u32 tsgid) | |||
2832 | for (i = 0; i < g->fifo.max_runlists; i++) | 2835 | for (i = 0; i < g->fifo.max_runlists; i++) |
2833 | nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); | 2836 | nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); |
2834 | 2837 | ||
2838 | if (ret) | ||
2839 | gk20a_fifo_preempt_timeout_rc(g, tsgid, true); | ||
2840 | |||
2835 | return ret; | 2841 | return ret; |
2836 | } | 2842 | } |
2837 | 2843 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 7216302c..5866dd1b 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | |||
@@ -44,6 +44,7 @@ enum { | |||
44 | #define FIFO_INVAL_ENGINE_ID ((u32)~0) | 44 | #define FIFO_INVAL_ENGINE_ID ((u32)~0) |
45 | #define FIFO_INVAL_CHANNEL_ID ((u32)~0) | 45 | #define FIFO_INVAL_CHANNEL_ID ((u32)~0) |
46 | #define FIFO_INVAL_TSG_ID ((u32)~0) | 46 | #define FIFO_INVAL_TSG_ID ((u32)~0) |
47 | #define FIFO_INVAL_RUNLIST_ID ((u32)~0) | ||
47 | 48 | ||
48 | #define ID_TYPE_CHANNEL 0 | 49 | #define ID_TYPE_CHANNEL 0 |
49 | #define ID_TYPE_TSG 1 | 50 | #define ID_TYPE_TSG 1 |
@@ -374,7 +375,7 @@ u32 gk20a_fifo_intr_0_error_mask(struct gk20a *g); | |||
374 | int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, unsigned int id_type, | 375 | int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, unsigned int id_type, |
375 | unsigned int timeout_rc_type); | 376 | unsigned int timeout_rc_type); |
376 | int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg); | 377 | int __locked_fifo_preempt(struct gk20a *g, u32 id, bool is_tsg); |
377 | void __locked_fifo_preempt_timeout_rc(struct gk20a *g, u32 id, | 378 | void gk20a_fifo_preempt_timeout_rc(struct gk20a *g, u32 id, |
378 | unsigned int id_type); | 379 | unsigned int id_type); |
379 | int gk20a_fifo_setup_ramfc(struct channel_gk20a *c, | 380 | int gk20a_fifo_setup_ramfc(struct channel_gk20a *c, |
380 | u64 gpfifo_base, u32 gpfifo_entries, | 381 | u64 gpfifo_base, u32 gpfifo_entries, |
diff --git a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c index 9843c7de..30e03092 100644 --- a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c | |||
@@ -757,6 +757,9 @@ int gv11b_fifo_preempt_channel(struct gk20a *g, u32 chid) | |||
757 | struct fifo_gk20a *f = &g->fifo; | 757 | struct fifo_gk20a *f = &g->fifo; |
758 | u32 tsgid; | 758 | u32 tsgid; |
759 | 759 | ||
760 | if (chid == FIFO_INVAL_CHANNEL_ID) | ||
761 | return 0; | ||
762 | |||
760 | tsgid = f->channel[chid].tsgid; | 763 | tsgid = f->channel[chid].tsgid; |
761 | nvgpu_log_info(g, "chid:%d tsgid:%d", chid, tsgid); | 764 | nvgpu_log_info(g, "chid:%d tsgid:%d", chid, tsgid); |
762 | 765 | ||
@@ -813,10 +816,14 @@ int gv11b_fifo_preempt_tsg(struct gk20a *g, u32 tsgid) | |||
813 | u32 mutex_ret = 0; | 816 | u32 mutex_ret = 0; |
814 | u32 runlist_id; | 817 | u32 runlist_id; |
815 | 818 | ||
816 | nvgpu_log_fn(g, "%d", tsgid); | 819 | nvgpu_log_fn(g, "tsgid: %d", tsgid); |
820 | if (tsgid == FIFO_INVAL_TSG_ID) | ||
821 | return 0; | ||
817 | 822 | ||
818 | runlist_id = f->tsg[tsgid].runlist_id; | 823 | runlist_id = f->tsg[tsgid].runlist_id; |
819 | nvgpu_log_fn(g, "runlist_id %d", runlist_id); | 824 | nvgpu_log_fn(g, "runlist_id: %d", runlist_id); |
825 | if (runlist_id == FIFO_INVAL_RUNLIST_ID) | ||
826 | return 0; | ||
820 | 827 | ||
821 | nvgpu_mutex_acquire(&f->runlist_info[runlist_id].runlist_lock); | 828 | nvgpu_mutex_acquire(&f->runlist_info[runlist_id].runlist_lock); |
822 | 829 | ||
@@ -829,6 +836,9 @@ int gv11b_fifo_preempt_tsg(struct gk20a *g, u32 tsgid) | |||
829 | 836 | ||
830 | nvgpu_mutex_release(&f->runlist_info[runlist_id].runlist_lock); | 837 | nvgpu_mutex_release(&f->runlist_info[runlist_id].runlist_lock); |
831 | 838 | ||
839 | if (ret) | ||
840 | gk20a_fifo_preempt_timeout_rc(g, tsgid, true); | ||
841 | |||
832 | return ret; | 842 | return ret; |
833 | } | 843 | } |
834 | 844 | ||
@@ -888,7 +898,7 @@ static int __locked_fifo_preempt_ch_tsg(struct gk20a *g, u32 id, | |||
888 | timeout_rc_type); | 898 | timeout_rc_type); |
889 | 899 | ||
890 | if (ret && (timeout_rc_type == PREEMPT_TIMEOUT_RC)) | 900 | if (ret && (timeout_rc_type == PREEMPT_TIMEOUT_RC)) |
891 | __locked_fifo_preempt_timeout_rc(g, id, id_type); | 901 | gk20a_fifo_preempt_timeout_rc(g, id, id_type); |
892 | 902 | ||
893 | return ret; | 903 | return ret; |
894 | } | 904 | } |