]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu: nvgpu: restart timer instead of cancel
authorDeepak Nibade <dnibade@nvidia.com>
Mon, 12 Oct 2015 12:39:43 +0000 (18:09 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Thu, 5 Nov 2015 07:23:19 +0000 (23:23 -0800)
In gk20a_fifo_handle_sched_error(), we currently cancel
the timeout on all the channels
But this could cause us to miss one of stuck channel

hence, instead of cancelling, restart the timeout of channel
on which it is already active

Bug 200133289

Change-Id: I40e7e0e5394911fc110ab6fde39592b885dfaf7d
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/816133
(cherry picked from commit 7d249416f79e708f4825c9a7265becec0b8c6100)
Reviewed-on: http://git-master/r/820161
Signed-off-by: Thomas Fleury <tfleury@nvidia.com>
Reviewed-on: http://git-master/r/825508
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
drivers/gpu/nvgpu/gk20a/channel_gk20a.c
drivers/gpu/nvgpu/gk20a/channel_gk20a.h
drivers/gpu/nvgpu/gk20a/fifo_gk20a.c

index 02cac21ff69e9ec3d442bea5eed54aedca2868ee..54ebc6792895657aa6b74f770644100047c1d67f 100644 (file)
@@ -1588,7 +1588,7 @@ static void gk20a_channel_timeout_stop(struct channel_gk20a *ch)
        mutex_unlock(&ch->timeout.lock);
 }
 
-void gk20a_channel_timeout_stop_all_channels(struct gk20a *g)
+void gk20a_channel_timeout_restart_all_channels(struct gk20a *g)
 {
        u32 chid;
        struct fifo_gk20a *f = &g->fifo;
@@ -1597,7 +1597,20 @@ void gk20a_channel_timeout_stop_all_channels(struct gk20a *g)
                struct channel_gk20a *ch = &f->channel[chid];
 
                if (gk20a_channel_get(ch)) {
-                       gk20a_channel_timeout_stop(ch);
+                       mutex_lock(&ch->timeout.lock);
+                       if (!ch->timeout.initialized) {
+                               mutex_unlock(&ch->timeout.lock);
+                               gk20a_channel_put(ch);
+                               continue;
+                       }
+                       mutex_unlock(&ch->timeout.lock);
+
+                       cancel_delayed_work_sync(&ch->timeout.wq);
+                       if (!ch->has_timedout)
+                               schedule_delayed_work(&ch->timeout.wq,
+                                      msecs_to_jiffies(
+                                      gk20a_get_channel_watchdog_timeout(ch)));
+
                        gk20a_channel_put(ch);
                }
        }
index 261fc74fd10aa687b94e0dfef713b0ecbe1c63d3..35a6187af611e754f7e07f27329587baf59f3182 100644 (file)
@@ -259,5 +259,5 @@ void channel_gk20a_free_inst(struct gk20a *g, struct channel_gk20a *ch);
 int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
                        u64 gpfifo_base, u32 gpfifo_entries);
 void channel_gk20a_enable(struct channel_gk20a *ch);
-void gk20a_channel_timeout_stop_all_channels(struct gk20a *g);
+void gk20a_channel_timeout_restart_all_channels(struct gk20a *g);
 #endif /* CHANNEL_GK20A_H */
index 0c8e9d06e10744954151c231007091664c372b62..cc252d56ad6aab3712b0bde35266e275a89b40ad 100644 (file)
@@ -1412,7 +1412,7 @@ static bool gk20a_fifo_handle_sched_error(struct gk20a *g)
                struct channel_gk20a *ch = &f->channel[id];
 
                if (is_tsg) {
-                       gk20a_channel_timeout_stop_all_channels(g);
+                       gk20a_channel_timeout_restart_all_channels(g);
                        gk20a_fifo_recover(g, BIT(engine_id), id, true, true);
                        ret = true;
                        goto err;
@@ -1433,7 +1433,7 @@ static bool gk20a_fifo_handle_sched_error(struct gk20a *g)
                         * Cancel all channels' timeout since SCHED error might
                         * trigger multiple watchdogs at a time
                         */
-                       gk20a_channel_timeout_stop_all_channels(g);
+                       gk20a_channel_timeout_restart_all_channels(g);
                        gk20a_fifo_recover(g, BIT(engine_id), id, false,
                                ch->timeout_debug_dump);
                        ret = true;