return tl;
 }
 
+static const char *repr_timer(const struct timer_list *t)
+{
+       if (!READ_ONCE(t->expires))
+               return "inactive";
+
+       if (timer_pending(t))
+               return "active";
+
+       return "expired";
+}
+
 static void intel_engine_print_registers(struct intel_engine_cs *engine,
                                         struct drm_printer *m)
 {
                unsigned int idx;
                u8 read, write;
 
-               drm_printf(m, "\tExeclist status: 0x%08x %08x, entries %u\n",
-                          ENGINE_READ(engine, RING_EXECLIST_STATUS_LO),
-                          ENGINE_READ(engine, RING_EXECLIST_STATUS_HI),
-                          num_entries);
+               drm_printf(m, "\tExeclist tasklet queued? %s (%s), timeslice? %s\n",
+                          yesno(test_bit(TASKLET_STATE_SCHED,
+                                         &engine->execlists.tasklet.state)),
+                          enableddisabled(!atomic_read(&engine->execlists.tasklet.count)),
+                          repr_timer(&engine->execlists.timer));
 
                read = execlists->csb_head;
                write = READ_ONCE(*execlists->csb_write);
 
-               drm_printf(m, "\tExeclist CSB read %d, write %d, tasklet queued? %s (%s)\n",
-                          read, write,
-                          yesno(test_bit(TASKLET_STATE_SCHED,
-                                         &engine->execlists.tasklet.state)),
-                          enableddisabled(!atomic_read(&engine->execlists.tasklet.count)));
+               drm_printf(m, "\tExeclist status: 0x%08x %08x; CSB read:%d, write:%d, entries:%d\n",
+                          ENGINE_READ(engine, RING_EXECLIST_STATUS_LO),
+                          ENGINE_READ(engine, RING_EXECLIST_STATUS_HI),
+                          read, write, num_entries);
+
                if (read >= num_entries)
                        read = 0;
                if (write >= num_entries)
 
                        last->hw_context->lrc_desc |= CTX_DESC_FORCE_RESTORE;
                        last = NULL;
                } else if (need_timeslice(engine, last) &&
-                          !timer_pending(&engine->execlists.timer)) {
+                          timer_expired(&engine->execlists.timer)) {
                        GEM_TRACE("%s: expired last=%llx:%lld, prio=%d, hint=%d\n",
                                  engine->name,
                                  last->fence.context,
 
                        if (enable_timeslice(execlists))
                                mod_timer(&execlists->timer, jiffies + 1);
+                       else
+                               cancel_timer(&execlists->timer);
 
                        WRITE_ONCE(execlists->pending[0], NULL);
                } else {
 
 static void execlists_park(struct intel_engine_cs *engine)
 {
-       del_timer(&engine->execlists.timer);
+       cancel_timer(&engine->execlists.timer);
 }
 
 void intel_execlists_set_default_submission(struct intel_engine_cs *engine)
 
        return test_bit(TASKLET_STATE_SCHED, &t->state);
 }
 
+static inline void cancel_timer(struct timer_list *t)
+{
+       if (!READ_ONCE(t->expires))
+               return;
+
+       del_timer(t);
+       WRITE_ONCE(t->expires, 0);
+}
+
+static inline bool timer_expired(const struct timer_list *t)
+{
+       return READ_ONCE(t->expires) && !timer_pending(t);
+}
+
 #endif /* __I915_GEM_H__ */