diff options
Diffstat (limited to 'kernel/sched/deadline.c')
| -rw-r--r-- | kernel/sched/deadline.c | 17 | 
1 files changed, 13 insertions, 4 deletions
| diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index fc8f01083527..8b0a15e285f9 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -668,8 +668,15 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)  	 * Queueing this task back might have overloaded rq, check if we need  	 * to kick someone away.  	 */ -	if (has_pushable_dl_tasks(rq)) +	if (has_pushable_dl_tasks(rq)) { +		/* +		 * Nothing relies on rq->lock after this, so its safe to drop +		 * rq->lock. +		 */ +		lockdep_unpin_lock(&rq->lock);  		push_dl_task(rq); +		lockdep_pin_lock(&rq->lock); +	}  #endif  unlock: @@ -1066,8 +1073,9 @@ select_task_rq_dl(struct task_struct *p, int cpu, int sd_flag, int flags)  		int target = find_later_rq(p);  		if (target != -1 && -				dl_time_before(p->dl.deadline, -					cpu_rq(target)->dl.earliest_dl.curr)) +				(dl_time_before(p->dl.deadline, +					cpu_rq(target)->dl.earliest_dl.curr) || +				(cpu_rq(target)->dl.dl_nr_running == 0)))  			cpu = target;  	}  	rcu_read_unlock(); @@ -1417,7 +1425,8 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq)  		later_rq = cpu_rq(cpu); -		if (!dl_time_before(task->dl.deadline, +		if (later_rq->dl.dl_nr_running && +		    !dl_time_before(task->dl.deadline,  					later_rq->dl.earliest_dl.curr)) {  			/*  			 * Target rq has tasks of equal or earlier deadline, |