aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_rt.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2008-01-25 15:08:29 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-25 15:08:29 -0500
commitfa85ae2418e6843953107cd6a06f645752829bc0 (patch)
tree004130ac471247a29d3f6adfbfe61c474e725779 /kernel/sched_rt.c
parent8f4d37ec073c17e2d4aa8851df5837d798606d6f (diff)
sched: rt time limit
Very simple time limit on the realtime scheduling classes. Allow the rq's realtime class to consume sched_rt_ratio of every sched_rt_period slice. If the class exceeds this quota the fair class will preempt the realtime class. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched_rt.c')
-rw-r--r--kernel/sched_rt.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 83fbbcb8019e..fd10d965aa06 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -45,6 +45,50 @@ static void update_rt_migration(struct rq *rq)
45} 45}
46#endif /* CONFIG_SMP */ 46#endif /* CONFIG_SMP */
47 47
48static int sched_rt_ratio_exceeded(struct rq *rq, struct rt_rq *rt_rq)
49{
50 u64 period, ratio;
51
52 if (sysctl_sched_rt_ratio == SCHED_RT_FRAC)
53 return 0;
54
55 if (rt_rq->rt_throttled)
56 return 1;
57
58 period = (u64)sysctl_sched_rt_period * NSEC_PER_MSEC;
59 ratio = (period * sysctl_sched_rt_ratio) >> SCHED_RT_FRAC_SHIFT;
60
61 if (rt_rq->rt_time > ratio) {
62 rt_rq->rt_throttled = rq->clock + period - rt_rq->rt_time;
63 return 1;
64 }
65
66 return 0;
67}
68
69static void update_sched_rt_period(struct rq *rq)
70{
71 while (rq->clock > rq->rt_period_expire) {
72 u64 period, ratio;
73
74 period = (u64)sysctl_sched_rt_period * NSEC_PER_MSEC;
75 ratio = (period * sysctl_sched_rt_ratio) >> SCHED_RT_FRAC_SHIFT;
76
77 rq->rt.rt_time -= min(rq->rt.rt_time, ratio);
78 rq->rt_period_expire += period;
79 }
80
81 /*
82 * When the rt throttle is expired, let them rip.
83 * (XXX: use hrtick when available)
84 */
85 if (rq->rt.rt_throttled && rq->clock > rq->rt.rt_throttled) {
86 rq->rt.rt_throttled = 0;
87 if (!sched_rt_ratio_exceeded(rq, &rq->rt))
88 resched_task(rq->curr);
89 }
90}
91
48/* 92/*
49 * Update the current task's runtime statistics. Skip current tasks that 93 * Update the current task's runtime statistics. Skip current tasks that
50 * are not in our scheduling class. 94 * are not in our scheduling class.
@@ -66,6 +110,11 @@ static void update_curr_rt(struct rq *rq)
66 curr->se.sum_exec_runtime += delta_exec; 110 curr->se.sum_exec_runtime += delta_exec;
67 curr->se.exec_start = rq->clock; 111 curr->se.exec_start = rq->clock;
68 cpuacct_charge(curr, delta_exec); 112 cpuacct_charge(curr, delta_exec);
113
114 rq->rt.rt_time += delta_exec;
115 update_sched_rt_period(rq);
116 if (sched_rt_ratio_exceeded(rq, &rq->rt))
117 resched_task(curr);
69} 118}
70 119
71static inline void inc_rt_tasks(struct task_struct *p, struct rq *rq) 120static inline void inc_rt_tasks(struct task_struct *p, struct rq *rq)
@@ -208,8 +257,12 @@ static struct task_struct *pick_next_task_rt(struct rq *rq)
208 struct rt_prio_array *array = &rq->rt.active; 257 struct rt_prio_array *array = &rq->rt.active;
209 struct task_struct *next; 258 struct task_struct *next;
210 struct list_head *queue; 259 struct list_head *queue;
260 struct rt_rq *rt_rq = &rq->rt;
211 int idx; 261 int idx;
212 262
263 if (sched_rt_ratio_exceeded(rq, rt_rq))
264 return NULL;
265
213 idx = sched_find_first_bit(array->bitmap); 266 idx = sched_find_first_bit(array->bitmap);
214 if (idx >= MAX_RT_PRIO) 267 if (idx >= MAX_RT_PRIO)
215 return NULL; 268 return NULL;