diff options
Diffstat (limited to 'kernel/sched/core.c')
| -rw-r--r-- | kernel/sched/core.c | 37 | 
1 files changed, 30 insertions, 7 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f3f08bf94355..44e00abece09 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3195,17 +3195,40 @@ __getparam_dl(struct task_struct *p, struct sched_attr *attr)   * We ask for the deadline not being zero, and greater or equal   * than the runtime, as well as the period of being zero or   * greater than deadline. Furthermore, we have to be sure that - * user parameters are above the internal resolution (1us); we - * check sched_runtime only since it is always the smaller one. + * user parameters are above the internal resolution of 1us (we + * check sched_runtime only since it is always the smaller one) and + * below 2^63 ns (we have to check both sched_deadline and + * sched_period, as the latter can be zero).   */  static bool  __checkparam_dl(const struct sched_attr *attr)  { -	return attr && attr->sched_deadline != 0 && -		(attr->sched_period == 0 || -		(s64)(attr->sched_period   - attr->sched_deadline) >= 0) && -		(s64)(attr->sched_deadline - attr->sched_runtime ) >= 0  && -		attr->sched_runtime >= (2 << (DL_SCALE - 1)); +	/* deadline != 0 */ +	if (attr->sched_deadline == 0) +		return false; + +	/* +	 * Since we truncate DL_SCALE bits, make sure we're at least +	 * that big. +	 */ +	if (attr->sched_runtime < (1ULL << DL_SCALE)) +		return false; + +	/* +	 * Since we use the MSB for wrap-around and sign issues, make +	 * sure it's not set (mind that period can be equal to zero). +	 */ +	if (attr->sched_deadline & (1ULL << 63) || +	    attr->sched_period & (1ULL << 63)) +		return false; + +	/* runtime <= deadline <= period (if period != 0) */ +	if ((attr->sched_period != 0 && +	     attr->sched_period < attr->sched_deadline) || +	    attr->sched_deadline < attr->sched_runtime) +		return false; + +	return true;  }  /*  | 
