|
@@ -563,11 +563,6 @@ void init_dl_task_timer(struct sched_dl_entity *dl_se)
|
|
|
{
|
|
|
struct hrtimer *timer = &dl_se->dl_timer;
|
|
|
|
|
|
- if (hrtimer_active(timer)) {
|
|
|
- hrtimer_try_to_cancel(timer);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
|
|
timer->function = dl_task_timer;
|
|
|
}
|
|
@@ -1610,10 +1605,35 @@ void init_sched_dl_class(void)
|
|
|
|
|
|
#endif /* CONFIG_SMP */
|
|
|
|
|
|
+/*
|
|
|
+ * Ensure p's dl_timer is cancelled. May drop rq->lock for a while.
|
|
|
+ */
|
|
|
+static void cancel_dl_timer(struct rq *rq, struct task_struct *p)
|
|
|
+{
|
|
|
+ struct hrtimer *dl_timer = &p->dl.dl_timer;
|
|
|
+
|
|
|
+ /* Nobody will change task's class if pi_lock is held */
|
|
|
+ lockdep_assert_held(&p->pi_lock);
|
|
|
+
|
|
|
+ if (hrtimer_active(dl_timer)) {
|
|
|
+ int ret = hrtimer_try_to_cancel(dl_timer);
|
|
|
+
|
|
|
+ if (unlikely(ret == -1)) {
|
|
|
+ /*
|
|
|
+ * Note, p may migrate OR new deadline tasks
|
|
|
+ * may appear in rq when we are unlocking it.
|
|
|
+ * A caller of us must be fine with that.
|
|
|
+ */
|
|
|
+ raw_spin_unlock(&rq->lock);
|
|
|
+ hrtimer_cancel(dl_timer);
|
|
|
+ raw_spin_lock(&rq->lock);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void switched_from_dl(struct rq *rq, struct task_struct *p)
|
|
|
{
|
|
|
- if (hrtimer_active(&p->dl.dl_timer) && !dl_policy(p->policy))
|
|
|
- hrtimer_try_to_cancel(&p->dl.dl_timer);
|
|
|
+ cancel_dl_timer(rq, p);
|
|
|
|
|
|
__dl_clear_params(p);
|
|
|
|