aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_rt.c
diff options
context:
space:
mode:
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;