aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Gustafsson <harald.gustafsson@ericsson.com>2013-11-07 08:43:40 -0500
committerIngo Molnar <mingo@kernel.org>2014-01-13 07:41:09 -0500
commit755378a47192a3d1f7c3a8ca6c15c1cf76de0af2 (patch)
treeb5154fe4b499081b76958894bae2c6fa696c1925
parent239be4a982154ea0c979fca5846349bb68973aed (diff)
sched/deadline: Add period support for SCHED_DEADLINE tasks
Make it possible to specify a period (different or equal than deadline) for -deadline tasks. Relative deadlines (D_i) are used on task arrivals to generate new scheduling (absolute) deadlines as "d = t + D_i", and periods (P_i) to postpone the scheduling deadlines as "d = d + P_i" when the budget is zero. This is in general useful to model (and schedule) tasks that have slow activation rates (long periods), but have to be scheduled soon once activated (short deadlines). Signed-off-by: Harald Gustafsson <harald.gustafsson@ericsson.com> Signed-off-by: Dario Faggioli <raistlin@linux.it> Signed-off-by: Juri Lelli <juri.lelli@gmail.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1383831828-15501-7-git-send-email-juri.lelli@gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--include/linux/sched.h1
-rw-r--r--kernel/sched/core.c10
-rw-r--r--kernel/sched/deadline.c10
3 files changed, 16 insertions, 5 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index cc66f2615a6d..158f4c2dd852 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1102,6 +1102,7 @@ struct sched_dl_entity {
1102 */ 1102 */
1103 u64 dl_runtime; /* maximum runtime for each instance */ 1103 u64 dl_runtime; /* maximum runtime for each instance */
1104 u64 dl_deadline; /* relative deadline of each instance */ 1104 u64 dl_deadline; /* relative deadline of each instance */
1105 u64 dl_period; /* separation of two instances (period) */
1105 1106
1106 /* 1107 /*
1107 * Actual scheduling parameters. Initialized with the values above, 1108 * Actual scheduling parameters. Initialized with the values above,
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 548cc04aee45..069230b5c3fb 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1723,6 +1723,7 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
1723 hrtimer_init(&p->dl.dl_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 1723 hrtimer_init(&p->dl.dl_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1724 p->dl.dl_runtime = p->dl.runtime = 0; 1724 p->dl.dl_runtime = p->dl.runtime = 0;
1725 p->dl.dl_deadline = p->dl.deadline = 0; 1725 p->dl.dl_deadline = p->dl.deadline = 0;
1726 p->dl.dl_period = 0;
1726 p->dl.flags = 0; 1727 p->dl.flags = 0;
1727 1728
1728 INIT_LIST_HEAD(&p->rt.run_list); 1729 INIT_LIST_HEAD(&p->rt.run_list);
@@ -3026,6 +3027,7 @@ __setparam_dl(struct task_struct *p, const struct sched_attr *attr)
3026 init_dl_task_timer(dl_se); 3027 init_dl_task_timer(dl_se);
3027 dl_se->dl_runtime = attr->sched_runtime; 3028 dl_se->dl_runtime = attr->sched_runtime;
3028 dl_se->dl_deadline = attr->sched_deadline; 3029 dl_se->dl_deadline = attr->sched_deadline;
3030 dl_se->dl_period = attr->sched_period ?: dl_se->dl_deadline;
3029 dl_se->flags = attr->sched_flags; 3031 dl_se->flags = attr->sched_flags;
3030 dl_se->dl_throttled = 0; 3032 dl_se->dl_throttled = 0;
3031 dl_se->dl_new = 1; 3033 dl_se->dl_new = 1;
@@ -3067,19 +3069,23 @@ __getparam_dl(struct task_struct *p, struct sched_attr *attr)
3067 attr->sched_priority = p->rt_priority; 3069 attr->sched_priority = p->rt_priority;
3068 attr->sched_runtime = dl_se->dl_runtime; 3070 attr->sched_runtime = dl_se->dl_runtime;
3069 attr->sched_deadline = dl_se->dl_deadline; 3071 attr->sched_deadline = dl_se->dl_deadline;
3072 attr->sched_period = dl_se->dl_period;
3070 attr->sched_flags = dl_se->flags; 3073 attr->sched_flags = dl_se->flags;
3071} 3074}
3072 3075
3073/* 3076/*
3074 * This function validates the new parameters of a -deadline task. 3077 * This function validates the new parameters of a -deadline task.
3075 * We ask for the deadline not being zero, and greater or equal 3078 * We ask for the deadline not being zero, and greater or equal
3076 * than the runtime. 3079 * than the runtime, as well as the period of being zero or
3080 * greater than deadline.
3077 */ 3081 */
3078static bool 3082static bool
3079__checkparam_dl(const struct sched_attr *attr) 3083__checkparam_dl(const struct sched_attr *attr)
3080{ 3084{
3081 return attr && attr->sched_deadline != 0 && 3085 return attr && attr->sched_deadline != 0 &&
3082 (s64)(attr->sched_deadline - attr->sched_runtime) >= 0; 3086 (attr->sched_period == 0 ||
3087 (s64)(attr->sched_period - attr->sched_deadline) >= 0) &&
3088 (s64)(attr->sched_deadline - attr->sched_runtime ) >= 0;
3083} 3089}
3084 3090
3085/* 3091/*
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 21f58d261134..3958bc576d67 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -289,7 +289,7 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se)
289 * arbitrary large. 289 * arbitrary large.
290 */ 290 */
291 while (dl_se->runtime <= 0) { 291 while (dl_se->runtime <= 0) {
292 dl_se->deadline += dl_se->dl_deadline; 292 dl_se->deadline += dl_se->dl_period;
293 dl_se->runtime += dl_se->dl_runtime; 293 dl_se->runtime += dl_se->dl_runtime;
294 } 294 }
295 295
@@ -329,9 +329,13 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se)
329 * 329 *
330 * This function returns true if: 330 * This function returns true if:
331 * 331 *
332 * runtime / (deadline - t) > dl_runtime / dl_deadline , 332 * runtime / (deadline - t) > dl_runtime / dl_period ,
333 * 333 *
334 * IOW we can't recycle current parameters. 334 * IOW we can't recycle current parameters.
335 *
336 * Notice that the bandwidth check is done against the period. For
337 * task with deadline equal to period this is the same of using
338 * dl_deadline instead of dl_period in the equation above.
335 */ 339 */
336static bool dl_entity_overflow(struct sched_dl_entity *dl_se, u64 t) 340static bool dl_entity_overflow(struct sched_dl_entity *dl_se, u64 t)
337{ 341{
@@ -355,7 +359,7 @@ static bool dl_entity_overflow(struct sched_dl_entity *dl_se, u64 t)
355 * of anything below microseconds resolution is actually fiction 359 * of anything below microseconds resolution is actually fiction
356 * (but still we want to give the user that illusion >;). 360 * (but still we want to give the user that illusion >;).
357 */ 361 */
358 left = (dl_se->dl_deadline >> 10) * (dl_se->runtime >> 10); 362 left = (dl_se->dl_period >> 10) * (dl_se->runtime >> 10);
359 right = ((dl_se->deadline - t) >> 10) * (dl_se->dl_runtime >> 10); 363 right = ((dl_se->deadline - t) >> 10) * (dl_se->dl_runtime >> 10);
360 364
361 return dl_time_before(right, left); 365 return dl_time_before(right, left);