diff options
Diffstat (limited to 'kernel/sched/deadline.c')
| -rw-r--r-- | kernel/sched/deadline.c | 97 | 
1 files changed, 53 insertions, 44 deletions
| diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index f232305dcefe..1d3c97268ec0 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -43,6 +43,28 @@ static inline int on_dl_rq(struct sched_dl_entity *dl_se)  	return !RB_EMPTY_NODE(&dl_se->rb_node);  } +#ifdef CONFIG_RT_MUTEXES +static inline struct sched_dl_entity *pi_of(struct sched_dl_entity *dl_se) +{ +	return dl_se->pi_se; +} + +static inline bool is_dl_boosted(struct sched_dl_entity *dl_se) +{ +	return pi_of(dl_se) != dl_se; +} +#else +static inline struct sched_dl_entity *pi_of(struct sched_dl_entity *dl_se) +{ +	return dl_se; +} + +static inline bool is_dl_boosted(struct sched_dl_entity *dl_se) +{ +	return false; +} +#endif +  #ifdef CONFIG_SMP  static inline struct dl_bw *dl_bw_of(int i)  { @@ -698,7 +720,7 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se)  	struct dl_rq *dl_rq = dl_rq_of_se(dl_se);  	struct rq *rq = rq_of_dl_rq(dl_rq); -	WARN_ON(dl_se->dl_boosted); +	WARN_ON(is_dl_boosted(dl_se));  	WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline));  	/* @@ -736,21 +758,20 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se)   * could happen are, typically, a entity voluntarily trying to overcome its   * runtime, or it just underestimated it during sched_setattr().   */ -static void replenish_dl_entity(struct sched_dl_entity *dl_se, -				struct sched_dl_entity *pi_se) +static void replenish_dl_entity(struct sched_dl_entity *dl_se)  {  	struct dl_rq *dl_rq = dl_rq_of_se(dl_se);  	struct rq *rq = rq_of_dl_rq(dl_rq); -	BUG_ON(pi_se->dl_runtime <= 0); +	BUG_ON(pi_of(dl_se)->dl_runtime <= 0);  	/*  	 * This could be the case for a !-dl task that is boosted.  	 * Just go with full inherited parameters.  	 */  	if (dl_se->dl_deadline == 0) { -		dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline; -		dl_se->runtime = pi_se->dl_runtime; +		dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline; +		dl_se->runtime = pi_of(dl_se)->dl_runtime;  	}  	if (dl_se->dl_yielded && dl_se->runtime > 0) @@ -763,8 +784,8 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,  	 * arbitrary large.  	 */  	while (dl_se->runtime <= 0) { -		dl_se->deadline += pi_se->dl_period; -		dl_se->runtime += pi_se->dl_runtime; +		dl_se->deadline += pi_of(dl_se)->dl_period; +		dl_se->runtime += pi_of(dl_se)->dl_runtime;  	}  	/* @@ -778,8 +799,8 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,  	 */  	if (dl_time_before(dl_se->deadline, rq_clock(rq))) {  		printk_deferred_once("sched: DL replenish lagged too much\n"); -		dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline; -		dl_se->runtime = pi_se->dl_runtime; +		dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline; +		dl_se->runtime = pi_of(dl_se)->dl_runtime;  	}  	if (dl_se->dl_yielded) @@ -812,8 +833,7 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,   * task with deadline equal to period this is the same of using   * dl_period instead of dl_deadline in the equation above.   */ -static bool dl_entity_overflow(struct sched_dl_entity *dl_se, -			       struct sched_dl_entity *pi_se, u64 t) +static bool dl_entity_overflow(struct sched_dl_entity *dl_se, u64 t)  {  	u64 left, right; @@ -835,9 +855,9 @@ static bool dl_entity_overflow(struct sched_dl_entity *dl_se,  	 * of anything below microseconds resolution is actually fiction  	 * (but still we want to give the user that illusion >;).  	 */ -	left = (pi_se->dl_deadline >> DL_SCALE) * (dl_se->runtime >> DL_SCALE); +	left = (pi_of(dl_se)->dl_deadline >> DL_SCALE) * (dl_se->runtime >> DL_SCALE);  	right = ((dl_se->deadline - t) >> DL_SCALE) * -		(pi_se->dl_runtime >> DL_SCALE); +		(pi_of(dl_se)->dl_runtime >> DL_SCALE);  	return dl_time_before(right, left);  } @@ -922,24 +942,23 @@ static inline bool dl_is_implicit(struct sched_dl_entity *dl_se)   * Please refer to the comments update_dl_revised_wakeup() function to find   * more about the Revised CBS rule.   */ -static void update_dl_entity(struct sched_dl_entity *dl_se, -			     struct sched_dl_entity *pi_se) +static void update_dl_entity(struct sched_dl_entity *dl_se)  {  	struct dl_rq *dl_rq = dl_rq_of_se(dl_se);  	struct rq *rq = rq_of_dl_rq(dl_rq);  	if (dl_time_before(dl_se->deadline, rq_clock(rq)) || -	    dl_entity_overflow(dl_se, pi_se, rq_clock(rq))) { +	    dl_entity_overflow(dl_se, rq_clock(rq))) {  		if (unlikely(!dl_is_implicit(dl_se) &&  			     !dl_time_before(dl_se->deadline, rq_clock(rq)) && -			     !dl_se->dl_boosted)){ +			     !is_dl_boosted(dl_se))) {  			update_dl_revised_wakeup(dl_se, rq);  			return;  		} -		dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline; -		dl_se->runtime = pi_se->dl_runtime; +		dl_se->deadline = rq_clock(rq) + pi_of(dl_se)->dl_deadline; +		dl_se->runtime = pi_of(dl_se)->dl_runtime;  	}  } @@ -1038,7 +1057,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)  	 * The task might have been boosted by someone else and might be in the  	 * boosting/deboosting path, its not throttled.  	 */ -	if (dl_se->dl_boosted) +	if (is_dl_boosted(dl_se))  		goto unlock;  	/* @@ -1066,7 +1085,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)  	 * but do not enqueue -- wait for our wakeup to do that.  	 */  	if (!task_on_rq_queued(p)) { -		replenish_dl_entity(dl_se, dl_se); +		replenish_dl_entity(dl_se);  		goto unlock;  	} @@ -1156,7 +1175,7 @@ static inline void dl_check_constrained_dl(struct sched_dl_entity *dl_se)  	if (dl_time_before(dl_se->deadline, rq_clock(rq)) &&  	    dl_time_before(rq_clock(rq), dl_next_period(dl_se))) { -		if (unlikely(dl_se->dl_boosted || !start_dl_timer(p))) +		if (unlikely(is_dl_boosted(dl_se) || !start_dl_timer(p)))  			return;  		dl_se->dl_throttled = 1;  		if (dl_se->runtime > 0) @@ -1287,7 +1306,7 @@ throttle:  			dl_se->dl_overrun = 1;  		__dequeue_task_dl(rq, curr, 0); -		if (unlikely(dl_se->dl_boosted || !start_dl_timer(curr))) +		if (unlikely(is_dl_boosted(dl_se) || !start_dl_timer(curr)))  			enqueue_task_dl(rq, curr, ENQUEUE_REPLENISH);  		if (!is_leftmost(curr, &rq->dl)) @@ -1481,8 +1500,7 @@ static void __dequeue_dl_entity(struct sched_dl_entity *dl_se)  }  static void -enqueue_dl_entity(struct sched_dl_entity *dl_se, -		  struct sched_dl_entity *pi_se, int flags) +enqueue_dl_entity(struct sched_dl_entity *dl_se, int flags)  {  	BUG_ON(on_dl_rq(dl_se)); @@ -1493,9 +1511,9 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se,  	 */  	if (flags & ENQUEUE_WAKEUP) {  		task_contending(dl_se, flags); -		update_dl_entity(dl_se, pi_se); +		update_dl_entity(dl_se);  	} else if (flags & ENQUEUE_REPLENISH) { -		replenish_dl_entity(dl_se, pi_se); +		replenish_dl_entity(dl_se);  	} else if ((flags & ENQUEUE_RESTORE) &&  		  dl_time_before(dl_se->deadline,  				 rq_clock(rq_of_dl_rq(dl_rq_of_se(dl_se))))) { @@ -1512,19 +1530,7 @@ static void dequeue_dl_entity(struct sched_dl_entity *dl_se)  static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)  { -	struct task_struct *pi_task = rt_mutex_get_top_task(p); -	struct sched_dl_entity *pi_se = &p->dl; - -	/* -	 * Use the scheduling parameters of the top pi-waiter task if: -	 * - we have a top pi-waiter which is a SCHED_DEADLINE task AND -	 * - our dl_boosted is set (i.e. the pi-waiter's (absolute) deadline is -	 *   smaller than our deadline OR we are a !SCHED_DEADLINE task getting -	 *   boosted due to a SCHED_DEADLINE pi-waiter). -	 * Otherwise we keep our runtime and deadline. -	 */ -	if (pi_task && dl_prio(pi_task->normal_prio) && p->dl.dl_boosted) { -		pi_se = &pi_task->dl; +	if (is_dl_boosted(&p->dl)) {  		/*  		 * Because of delays in the detection of the overrun of a  		 * thread's runtime, it might be the case that a thread @@ -1557,7 +1563,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)  		 * the throttle.  		 */  		p->dl.dl_throttled = 0; -		BUG_ON(!p->dl.dl_boosted || flags != ENQUEUE_REPLENISH); +		BUG_ON(!is_dl_boosted(&p->dl) || flags != ENQUEUE_REPLENISH);  		return;  	} @@ -1594,7 +1600,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)  		return;  	} -	enqueue_dl_entity(&p->dl, pi_se, flags); +	enqueue_dl_entity(&p->dl, flags);  	if (!task_current(rq, p) && p->nr_cpus_allowed > 1)  		enqueue_pushable_dl_task(rq, p); @@ -2787,11 +2793,14 @@ void __dl_clear_params(struct task_struct *p)  	dl_se->dl_bw			= 0;  	dl_se->dl_density		= 0; -	dl_se->dl_boosted		= 0;  	dl_se->dl_throttled		= 0;  	dl_se->dl_yielded		= 0;  	dl_se->dl_non_contending	= 0;  	dl_se->dl_overrun		= 0; + +#ifdef CONFIG_RT_MUTEXES +	dl_se->pi_se			= dl_se; +#endif  }  bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr) | 
