diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 1bf38080..306f05a7 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -2743,6 +2743,17 @@ void gk20a_fifo_issue_preempt(struct gk20a *g, u32 id, bool is_tsg) | |||
2743 | fifo_preempt_type_channel_f()); | 2743 | fifo_preempt_type_channel_f()); |
2744 | } | 2744 | } |
2745 | 2745 | ||
2746 | static u32 gk20a_fifo_get_preempt_timeout(struct gk20a *g) | ||
2747 | { | ||
2748 | /* Use fifo_eng_timeout converted to ms for preempt | ||
2749 | * polling. gr_idle_timeout i.e 3000 ms is and not appropriate | ||
2750 | * for polling preempt done as context switch timeout gets | ||
2751 | * triggered every 100 ms and context switch recovery | ||
2752 | * happens every 3000 ms */ | ||
2753 | |||
2754 | return g->fifo_eng_timeout_us / 1000; | ||
2755 | } | ||
2756 | |||
2746 | int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, | 2757 | int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, |
2747 | unsigned int id_type) | 2758 | unsigned int id_type) |
2748 | { | 2759 | { |
@@ -2750,7 +2761,7 @@ int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, | |||
2750 | u32 delay = GR_IDLE_CHECK_DEFAULT; | 2761 | u32 delay = GR_IDLE_CHECK_DEFAULT; |
2751 | int ret = -EBUSY; | 2762 | int ret = -EBUSY; |
2752 | 2763 | ||
2753 | nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g), | 2764 | nvgpu_timeout_init(g, &timeout, gk20a_fifo_get_preempt_timeout(g), |
2754 | NVGPU_TIMER_CPU_TIMER); | 2765 | NVGPU_TIMER_CPU_TIMER); |
2755 | do { | 2766 | do { |
2756 | if (!(gk20a_readl(g, fifo_preempt_r()) & | 2767 | if (!(gk20a_readl(g, fifo_preempt_r()) & |
@@ -2761,8 +2772,12 @@ int gk20a_fifo_is_preempt_pending(struct gk20a *g, u32 id, | |||
2761 | 2772 | ||
2762 | nvgpu_usleep_range(delay, delay * 2); | 2773 | nvgpu_usleep_range(delay, delay * 2); |
2763 | delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); | 2774 | delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); |
2764 | } while (!nvgpu_timeout_expired_msg(&timeout, "preempt timeout")); | 2775 | } while (!nvgpu_timeout_expired(&timeout)); |
2765 | 2776 | ||
2777 | if (ret) { | ||
2778 | nvgpu_err(g, "preempt timeout: id: %u id_type: %d ", | ||
2779 | id, id_type); | ||
2780 | } | ||
2766 | return ret; | 2781 | return ret; |
2767 | } | 2782 | } |
2768 | 2783 | ||
@@ -2848,8 +2863,16 @@ int gk20a_fifo_preempt_channel(struct gk20a *g, u32 chid) | |||
2848 | for (i = 0; i < g->fifo.max_runlists; i++) | 2863 | for (i = 0; i < g->fifo.max_runlists; i++) |
2849 | nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); | 2864 | nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); |
2850 | 2865 | ||
2851 | if (ret) | 2866 | if (ret) { |
2852 | gk20a_fifo_preempt_timeout_rc(g, chid, false); | 2867 | if (nvgpu_platform_is_silicon(g)) { |
2868 | nvgpu_err(g, "preempt timed out for chid: %u, " | ||
2869 | "ctxsw timeout will trigger recovery if needed", chid); | ||
2870 | } else { | ||
2871 | gk20a_fifo_preempt_timeout_rc(g, chid, false); | ||
2872 | } | ||
2873 | } | ||
2874 | |||
2875 | |||
2853 | 2876 | ||
2854 | return ret; | 2877 | return ret; |
2855 | } | 2878 | } |
@@ -2880,8 +2903,14 @@ int gk20a_fifo_preempt_tsg(struct gk20a *g, u32 tsgid) | |||
2880 | for (i = 0; i < g->fifo.max_runlists; i++) | 2903 | for (i = 0; i < g->fifo.max_runlists; i++) |
2881 | nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); | 2904 | nvgpu_mutex_release(&f->runlist_info[i].runlist_lock); |
2882 | 2905 | ||
2883 | if (ret) | 2906 | if (ret) { |
2884 | gk20a_fifo_preempt_timeout_rc(g, tsgid, true); | 2907 | if (nvgpu_platform_is_silicon(g)) { |
2908 | nvgpu_err(g, "preempt timed out for tsgid: %u, " | ||
2909 | "ctxsw timeout will trigger recovery if needed", tsgid); | ||
2910 | } else { | ||
2911 | gk20a_fifo_preempt_timeout_rc(g, tsgid, true); | ||
2912 | } | ||
2913 | } | ||
2885 | 2914 | ||
2886 | return ret; | 2915 | return ret; |
2887 | } | 2916 | } |
@@ -3121,6 +3150,11 @@ int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id) | |||
3121 | delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); | 3150 | delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); |
3122 | } while (!nvgpu_timeout_expired(&timeout)); | 3151 | } while (!nvgpu_timeout_expired(&timeout)); |
3123 | 3152 | ||
3153 | if (ret) { | ||
3154 | nvgpu_err(g, "runlist wait timeout: runlist id: %u", | ||
3155 | runlist_id); | ||
3156 | } | ||
3157 | |||
3124 | return ret; | 3158 | return ret; |
3125 | } | 3159 | } |
3126 | 3160 | ||