aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2012-09-29 16:50:30 -0400
committerChristopher Kenna <cjk@cs.unc.edu>2012-09-29 16:50:30 -0400
commitfe23bc6b4d29552409354ed74a0b066a6fc647cb (patch)
tree36aa9a5e676196da3fa4bfbfb68489a84f9b3dbe /kernel/sched.c
parent611926edc62a15f77b891658ac70cb66e7a638f2 (diff)
parente6f51fb826ce98d436f445aae4eb9e9dba1f30e8 (diff)
Merge LITMUS^RT staging (as of time of this commit).
Conflicts: Makefile include/linux/sched.h
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c151
1 files changed, 138 insertions, 13 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 71c64ba10af..6d400c11b6f 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -84,6 +84,11 @@
84#define CREATE_TRACE_POINTS 84#define CREATE_TRACE_POINTS
85#include <trace/events/sched.h> 85#include <trace/events/sched.h>
86 86
87#include <litmus/sched_trace.h>
88#include <litmus/trace.h>
89
90static void litmus_tick(struct rq*, struct task_struct*);
91
87/* 92/*
88 * Convert user-nice values [ -20 ... 0 ... 19 ] 93 * Convert user-nice values [ -20 ... 0 ... 19 ]
89 * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], 94 * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
@@ -411,6 +416,12 @@ struct rt_rq {
411#endif 416#endif
412}; 417};
413 418
419/* Litmus related fields in a runqueue */
420struct litmus_rq {
421 unsigned long nr_running;
422 struct task_struct *prev;
423};
424
414#ifdef CONFIG_SMP 425#ifdef CONFIG_SMP
415 426
416/* 427/*
@@ -476,6 +487,7 @@ struct rq {
476 487
477 struct cfs_rq cfs; 488 struct cfs_rq cfs;
478 struct rt_rq rt; 489 struct rt_rq rt;
490 struct litmus_rq litmus;
479 491
480#ifdef CONFIG_FAIR_GROUP_SCHED 492#ifdef CONFIG_FAIR_GROUP_SCHED
481 /* list of leaf cfs_rq on this cpu: */ 493 /* list of leaf cfs_rq on this cpu: */
@@ -1050,6 +1062,7 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer)
1050 raw_spin_lock(&rq->lock); 1062 raw_spin_lock(&rq->lock);
1051 update_rq_clock(rq); 1063 update_rq_clock(rq);
1052 rq->curr->sched_class->task_tick(rq, rq->curr, 1); 1064 rq->curr->sched_class->task_tick(rq, rq->curr, 1);
1065 litmus_tick(rq, rq->curr);
1053 raw_spin_unlock(&rq->lock); 1066 raw_spin_unlock(&rq->lock);
1054 1067
1055 return HRTIMER_NORESTART; 1068 return HRTIMER_NORESTART;
@@ -1793,7 +1806,7 @@ static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
1793 1806
1794static const struct sched_class rt_sched_class; 1807static const struct sched_class rt_sched_class;
1795 1808
1796#define sched_class_highest (&stop_sched_class) 1809#define sched_class_highest (&litmus_sched_class)
1797#define for_each_class(class) \ 1810#define for_each_class(class) \
1798 for (class = sched_class_highest; class; class = class->next) 1811 for (class = sched_class_highest; class; class = class->next)
1799 1812
@@ -2051,6 +2064,7 @@ static void update_rq_clock_task(struct rq *rq, s64 delta)
2051#include "sched_rt.c" 2064#include "sched_rt.c"
2052#include "sched_autogroup.c" 2065#include "sched_autogroup.c"
2053#include "sched_stoptask.c" 2066#include "sched_stoptask.c"
2067#include "../litmus/sched_litmus.c"
2054#ifdef CONFIG_SCHED_DEBUG 2068#ifdef CONFIG_SCHED_DEBUG
2055# include "sched_debug.c" 2069# include "sched_debug.c"
2056#endif 2070#endif
@@ -2173,6 +2187,10 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
2173 * A queue event has occurred, and we're going to schedule. In 2187 * A queue event has occurred, and we're going to schedule. In
2174 * this case, we can save a useless back to back clock update. 2188 * this case, we can save a useless back to back clock update.
2175 */ 2189 */
2190 /* LITMUS^RT:
2191 * The "disable-clock-update" approach was buggy in Linux 2.6.36.
2192 * The issue has been solved in 2.6.37.
2193 */
2176 if (rq->curr->on_rq && test_tsk_need_resched(rq->curr)) 2194 if (rq->curr->on_rq && test_tsk_need_resched(rq->curr))
2177 rq->skip_clock_update = 1; 2195 rq->skip_clock_update = 1;
2178} 2196}
@@ -2663,7 +2681,12 @@ static void ttwu_queue(struct task_struct *p, int cpu)
2663 struct rq *rq = cpu_rq(cpu); 2681 struct rq *rq = cpu_rq(cpu);
2664 2682
2665#if defined(CONFIG_SMP) 2683#if defined(CONFIG_SMP)
2666 if (sched_feat(TTWU_QUEUE) && cpu != smp_processor_id()) { 2684 /*
2685 * LITMUS^RT: whether to send an IPI to the remote CPU
2686 * is plugin specific.
2687 */
2688 if (!is_realtime(p) &&
2689 sched_feat(TTWU_QUEUE) && cpu != smp_processor_id()) {
2667 sched_clock_cpu(cpu); /* sync clocks x-cpu */ 2690 sched_clock_cpu(cpu); /* sync clocks x-cpu */
2668 ttwu_queue_remote(p, cpu); 2691 ttwu_queue_remote(p, cpu);
2669 return; 2692 return;
@@ -2696,6 +2719,9 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
2696 unsigned long flags; 2719 unsigned long flags;
2697 int cpu, success = 0; 2720 int cpu, success = 0;
2698 2721
2722 if (is_realtime(p))
2723 TRACE_TASK(p, "try_to_wake_up() state:%d\n", p->state);
2724
2699 smp_wmb(); 2725 smp_wmb();
2700 raw_spin_lock_irqsave(&p->pi_lock, flags); 2726 raw_spin_lock_irqsave(&p->pi_lock, flags);
2701 if (!(p->state & state)) 2727 if (!(p->state & state))
@@ -2732,6 +2758,12 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
2732 */ 2758 */
2733 smp_rmb(); 2759 smp_rmb();
2734 2760
2761 /* LITMUS^RT: once the task can be safely referenced by this
2762 * CPU, don't mess up with Linux load balancing stuff.
2763 */
2764 if (is_realtime(p))
2765 goto litmus_out_activate;
2766
2735 p->sched_contributes_to_load = !!task_contributes_to_load(p); 2767 p->sched_contributes_to_load = !!task_contributes_to_load(p);
2736 p->state = TASK_WAKING; 2768 p->state = TASK_WAKING;
2737 2769
@@ -2743,12 +2775,16 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
2743 wake_flags |= WF_MIGRATED; 2775 wake_flags |= WF_MIGRATED;
2744 set_task_cpu(p, cpu); 2776 set_task_cpu(p, cpu);
2745 } 2777 }
2778
2779litmus_out_activate:
2746#endif /* CONFIG_SMP */ 2780#endif /* CONFIG_SMP */
2747 2781
2748 ttwu_queue(p, cpu); 2782 ttwu_queue(p, cpu);
2749stat: 2783stat:
2750 ttwu_stat(p, cpu, wake_flags); 2784 ttwu_stat(p, cpu, wake_flags);
2751out: 2785out:
2786 if (is_realtime(p))
2787 TRACE_TASK(p, "try_to_wake_up() done state:%d\n", p->state);
2752 raw_spin_unlock_irqrestore(&p->pi_lock, flags); 2788 raw_spin_unlock_irqrestore(&p->pi_lock, flags);
2753 2789
2754 return success; 2790 return success;
@@ -2859,7 +2895,8 @@ void sched_fork(struct task_struct *p)
2859 * Revert to default priority/policy on fork if requested. 2895 * Revert to default priority/policy on fork if requested.
2860 */ 2896 */
2861 if (unlikely(p->sched_reset_on_fork)) { 2897 if (unlikely(p->sched_reset_on_fork)) {
2862 if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) { 2898 if (p->policy == SCHED_FIFO || p->policy == SCHED_RR ||
2899 p->policy == SCHED_LITMUS) {
2863 p->policy = SCHED_NORMAL; 2900 p->policy = SCHED_NORMAL;
2864 p->normal_prio = p->static_prio; 2901 p->normal_prio = p->static_prio;
2865 } 2902 }
@@ -3088,6 +3125,8 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
3088 */ 3125 */
3089 prev_state = prev->state; 3126 prev_state = prev->state;
3090 finish_arch_switch(prev); 3127 finish_arch_switch(prev);
3128 litmus->finish_switch(prev);
3129 prev->rt_param.stack_in_use = NO_CPU;
3091#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW 3130#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
3092 local_irq_disable(); 3131 local_irq_disable();
3093#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */ 3132#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
@@ -3117,6 +3156,15 @@ static inline void pre_schedule(struct rq *rq, struct task_struct *prev)
3117{ 3156{
3118 if (prev->sched_class->pre_schedule) 3157 if (prev->sched_class->pre_schedule)
3119 prev->sched_class->pre_schedule(rq, prev); 3158 prev->sched_class->pre_schedule(rq, prev);
3159
3160 /* LITMUS^RT not very clean hack: we need to save the prev task
3161 * as our scheduling decision rely on it (as we drop the rq lock
3162 * something in prev can change...); there is no way to escape
3163 * this ack apart from modifying pick_nex_task(rq, _prev_) or
3164 * falling back on the previous solution of decoupling
3165 * scheduling decisions
3166 */
3167 rq->litmus.prev = prev;
3120} 3168}
3121 3169
3122/* rq->lock is NOT held, but preemption is disabled */ 3170/* rq->lock is NOT held, but preemption is disabled */
@@ -3153,16 +3201,26 @@ static inline void post_schedule(struct rq *rq)
3153asmlinkage void schedule_tail(struct task_struct *prev) 3201asmlinkage void schedule_tail(struct task_struct *prev)
3154 __releases(rq->lock) 3202 __releases(rq->lock)
3155{ 3203{
3156 struct rq *rq = this_rq(); 3204 struct rq *rq;
3157 3205
3206 preempt_disable();
3207
3208 rq = this_rq();
3158 finish_task_switch(rq, prev); 3209 finish_task_switch(rq, prev);
3159 3210
3211 sched_trace_task_switch_to(current);
3212
3160 /* 3213 /*
3161 * FIXME: do we need to worry about rq being invalidated by the 3214 * FIXME: do we need to worry about rq being invalidated by the
3162 * task_switch? 3215 * task_switch?
3163 */ 3216 */
3164 post_schedule(rq); 3217 post_schedule(rq);
3165 3218
3219 if (sched_state_validate_switch())
3220 litmus_reschedule_local();
3221
3222 preempt_enable();
3223
3166#ifdef __ARCH_WANT_UNLOCKED_CTXSW 3224#ifdef __ARCH_WANT_UNLOCKED_CTXSW
3167 /* In this case, finish_task_switch does not reenable preemption */ 3225 /* In this case, finish_task_switch does not reenable preemption */
3168 preempt_enable(); 3226 preempt_enable();
@@ -4107,18 +4165,26 @@ void scheduler_tick(void)
4107 4165
4108 sched_clock_tick(); 4166 sched_clock_tick();
4109 4167
4168 TS_TICK_START(current);
4169
4110 raw_spin_lock(&rq->lock); 4170 raw_spin_lock(&rq->lock);
4111 update_rq_clock(rq); 4171 update_rq_clock(rq);
4112 update_cpu_load_active(rq); 4172 update_cpu_load_active(rq);
4113 curr->sched_class->task_tick(rq, curr, 0); 4173 curr->sched_class->task_tick(rq, curr, 0);
4174
4175 /* litmus_tick may force current to resched */
4176 litmus_tick(rq, curr);
4177
4114 raw_spin_unlock(&rq->lock); 4178 raw_spin_unlock(&rq->lock);
4115 4179
4116 perf_event_task_tick(); 4180 perf_event_task_tick();
4117 4181
4118#ifdef CONFIG_SMP 4182#ifdef CONFIG_SMP
4119 rq->idle_at_tick = idle_cpu(cpu); 4183 rq->idle_at_tick = idle_cpu(cpu);
4120 trigger_load_balance(rq, cpu); 4184 if (!is_realtime(current))
4185 trigger_load_balance(rq, cpu);
4121#endif 4186#endif
4187 TS_TICK_END(current);
4122} 4188}
4123 4189
4124notrace unsigned long get_parent_ip(unsigned long addr) 4190notrace unsigned long get_parent_ip(unsigned long addr)
@@ -4238,12 +4304,20 @@ pick_next_task(struct rq *rq)
4238 /* 4304 /*
4239 * Optimization: we know that if all tasks are in 4305 * Optimization: we know that if all tasks are in
4240 * the fair class we can call that function directly: 4306 * the fair class we can call that function directly:
4241 */ 4307
4242 if (likely(rq->nr_running == rq->cfs.nr_running)) { 4308 * NOT IN LITMUS^RT!
4309
4310 * This breaks many assumptions in the plugins.
4311 * Do not uncomment without thinking long and hard
4312 * about how this affects global plugins such as GSN-EDF.
4313
4314 if (rq->nr_running == rq->cfs.nr_running) {
4315 TRACE("taking shortcut in pick_next_task()\n");
4243 p = fair_sched_class.pick_next_task(rq); 4316 p = fair_sched_class.pick_next_task(rq);
4244 if (likely(p)) 4317 if (likely(p))
4245 return p; 4318 return p;
4246 } 4319 }
4320 */
4247 4321
4248 for_each_class(class) { 4322 for_each_class(class) {
4249 p = class->pick_next_task(rq); 4323 p = class->pick_next_task(rq);
@@ -4266,11 +4340,19 @@ static void __sched __schedule(void)
4266 4340
4267need_resched: 4341need_resched:
4268 preempt_disable(); 4342 preempt_disable();
4343 sched_state_entered_schedule();
4269 cpu = smp_processor_id(); 4344 cpu = smp_processor_id();
4270 rq = cpu_rq(cpu); 4345 rq = cpu_rq(cpu);
4271 rcu_note_context_switch(cpu); 4346 rcu_note_context_switch(cpu);
4272 prev = rq->curr; 4347 prev = rq->curr;
4273 4348
4349 /* LITMUS^RT: quickly re-evaluate the scheduling decision
4350 * if the previous one is no longer valid after CTX.
4351 */
4352litmus_need_resched_nonpreemptible:
4353 TS_SCHED_START;
4354 sched_trace_task_switch_away(prev);
4355
4274 schedule_debug(prev); 4356 schedule_debug(prev);
4275 4357
4276 if (sched_feat(HRTICK)) 4358 if (sched_feat(HRTICK))
@@ -4320,7 +4402,10 @@ need_resched:
4320#endif 4402#endif
4321 ++*switch_count; 4403 ++*switch_count;
4322 4404
4405 TS_SCHED_END(next);
4406 TS_CXS_START(next);
4323 context_switch(rq, prev, next); /* unlocks the rq */ 4407 context_switch(rq, prev, next); /* unlocks the rq */
4408 TS_CXS_END(current);
4324 /* 4409 /*
4325 * The context switch have flipped the stack from under us 4410 * The context switch have flipped the stack from under us
4326 * and restored the local variables which were saved when 4411 * and restored the local variables which were saved when
@@ -4329,14 +4414,23 @@ need_resched:
4329 */ 4414 */
4330 cpu = smp_processor_id(); 4415 cpu = smp_processor_id();
4331 rq = cpu_rq(cpu); 4416 rq = cpu_rq(cpu);
4332 } else 4417 } else {
4418 TS_SCHED_END(prev);
4333 raw_spin_unlock_irq(&rq->lock); 4419 raw_spin_unlock_irq(&rq->lock);
4420 }
4421
4422 sched_trace_task_switch_to(current);
4334 4423
4335 post_schedule(rq); 4424 post_schedule(rq);
4336 4425
4426 if (sched_state_validate_switch())
4427 goto litmus_need_resched_nonpreemptible;
4428
4337 preempt_enable_no_resched(); 4429 preempt_enable_no_resched();
4338 if (need_resched()) 4430 if (need_resched())
4339 goto need_resched; 4431 goto need_resched;
4432
4433 srp_ceiling_block();
4340} 4434}
4341 4435
4342static inline void sched_submit_work(struct task_struct *tsk) 4436static inline void sched_submit_work(struct task_struct *tsk)
@@ -4626,6 +4720,17 @@ void complete_all(struct completion *x)
4626} 4720}
4627EXPORT_SYMBOL(complete_all); 4721EXPORT_SYMBOL(complete_all);
4628 4722
4723void complete_n(struct completion *x, int n)
4724{
4725 unsigned long flags;
4726
4727 spin_lock_irqsave(&x->wait.lock, flags);
4728 x->done += n;
4729 __wake_up_common(&x->wait, TASK_NORMAL, n, 0, NULL);
4730 spin_unlock_irqrestore(&x->wait.lock, flags);
4731}
4732EXPORT_SYMBOL(complete_n);
4733
4629static inline long __sched 4734static inline long __sched
4630do_wait_for_common(struct completion *x, long timeout, int state) 4735do_wait_for_common(struct completion *x, long timeout, int state)
4631{ 4736{
@@ -5065,7 +5170,9 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
5065 p->normal_prio = normal_prio(p); 5170 p->normal_prio = normal_prio(p);
5066 /* we are holding p->pi_lock already */ 5171 /* we are holding p->pi_lock already */
5067 p->prio = rt_mutex_getprio(p); 5172 p->prio = rt_mutex_getprio(p);
5068 if (rt_prio(p->prio)) 5173 if (p->policy == SCHED_LITMUS)
5174 p->sched_class = &litmus_sched_class;
5175 else if (rt_prio(p->prio))
5069 p->sched_class = &rt_sched_class; 5176 p->sched_class = &rt_sched_class;
5070 else 5177 else
5071 p->sched_class = &fair_sched_class; 5178 p->sched_class = &fair_sched_class;
@@ -5113,7 +5220,7 @@ recheck:
5113 5220
5114 if (policy != SCHED_FIFO && policy != SCHED_RR && 5221 if (policy != SCHED_FIFO && policy != SCHED_RR &&
5115 policy != SCHED_NORMAL && policy != SCHED_BATCH && 5222 policy != SCHED_NORMAL && policy != SCHED_BATCH &&
5116 policy != SCHED_IDLE) 5223 policy != SCHED_IDLE && policy != SCHED_LITMUS)
5117 return -EINVAL; 5224 return -EINVAL;
5118 } 5225 }
5119 5226
@@ -5128,6 +5235,8 @@ recheck:
5128 return -EINVAL; 5235 return -EINVAL;
5129 if (rt_policy(policy) != (param->sched_priority != 0)) 5236 if (rt_policy(policy) != (param->sched_priority != 0))
5130 return -EINVAL; 5237 return -EINVAL;
5238 if (policy == SCHED_LITMUS && policy == p->policy)
5239 return -EINVAL;
5131 5240
5132 /* 5241 /*
5133 * Allow unprivileged RT tasks to decrease priority: 5242 * Allow unprivileged RT tasks to decrease priority:
@@ -5171,6 +5280,12 @@ recheck:
5171 return retval; 5280 return retval;
5172 } 5281 }
5173 5282
5283 if (policy == SCHED_LITMUS) {
5284 retval = litmus_admit_task(p);
5285 if (retval)
5286 return retval;
5287 }
5288
5174 /* 5289 /*
5175 * make sure no PI-waiters arrive (or leave) while we are 5290 * make sure no PI-waiters arrive (or leave) while we are
5176 * changing the priority of the task: 5291 * changing the priority of the task:
@@ -5229,10 +5344,19 @@ recheck:
5229 5344
5230 p->sched_reset_on_fork = reset_on_fork; 5345 p->sched_reset_on_fork = reset_on_fork;
5231 5346
5347 if (p->policy == SCHED_LITMUS)
5348 litmus_exit_task(p);
5349
5232 oldprio = p->prio; 5350 oldprio = p->prio;
5233 prev_class = p->sched_class; 5351 prev_class = p->sched_class;
5234 __setscheduler(rq, p, policy, param->sched_priority); 5352 __setscheduler(rq, p, policy, param->sched_priority);
5235 5353
5354 if (policy == SCHED_LITMUS) {
5355 p->rt_param.stack_in_use = running ? rq->cpu : NO_CPU;
5356 p->rt_param.present = running;
5357 litmus->task_new(p, on_rq, running);
5358 }
5359
5236 if (running) 5360 if (running)
5237 p->sched_class->set_curr_task(rq); 5361 p->sched_class->set_curr_task(rq);
5238 if (on_rq) 5362 if (on_rq)
@@ -5400,10 +5524,11 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
5400 rcu_read_lock(); 5524 rcu_read_lock();
5401 5525
5402 p = find_process_by_pid(pid); 5526 p = find_process_by_pid(pid);
5403 if (!p) { 5527 /* Don't set affinity if task not found and for LITMUS tasks */
5528 if (!p || is_realtime(p)) {
5404 rcu_read_unlock(); 5529 rcu_read_unlock();
5405 put_online_cpus(); 5530 put_online_cpus();
5406 return -ESRCH; 5531 return p ? -EPERM : -ESRCH;
5407 } 5532 }
5408 5533
5409 /* Prevent p going away */ 5534 /* Prevent p going away */