diff options
author | Christopher Kenna <cjk@cs.unc.edu> | 2012-09-29 16:50:30 -0400 |
---|---|---|
committer | Christopher Kenna <cjk@cs.unc.edu> | 2012-09-29 16:50:30 -0400 |
commit | fe23bc6b4d29552409354ed74a0b066a6fc647cb (patch) | |
tree | 36aa9a5e676196da3fa4bfbfb68489a84f9b3dbe /kernel/sched.c | |
parent | 611926edc62a15f77b891658ac70cb66e7a638f2 (diff) | |
parent | e6f51fb826ce98d436f445aae4eb9e9dba1f30e8 (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.c | 151 |
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 | |||
90 | static 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 */ | ||
420 | struct 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 | ||
1794 | static const struct sched_class rt_sched_class; | 1807 | static 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 | |||
2779 | litmus_out_activate: | ||
2746 | #endif /* CONFIG_SMP */ | 2780 | #endif /* CONFIG_SMP */ |
2747 | 2781 | ||
2748 | ttwu_queue(p, cpu); | 2782 | ttwu_queue(p, cpu); |
2749 | stat: | 2783 | stat: |
2750 | ttwu_stat(p, cpu, wake_flags); | 2784 | ttwu_stat(p, cpu, wake_flags); |
2751 | out: | 2785 | out: |
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) | |||
3153 | asmlinkage void schedule_tail(struct task_struct *prev) | 3201 | asmlinkage 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 | ||
4124 | notrace unsigned long get_parent_ip(unsigned long addr) | 4190 | notrace 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 | ||
4267 | need_resched: | 4341 | need_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 | */ | ||
4352 | litmus_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 | ||
4342 | static inline void sched_submit_work(struct task_struct *tsk) | 4436 | static inline void sched_submit_work(struct task_struct *tsk) |
@@ -4626,6 +4720,17 @@ void complete_all(struct completion *x) | |||
4626 | } | 4720 | } |
4627 | EXPORT_SYMBOL(complete_all); | 4721 | EXPORT_SYMBOL(complete_all); |
4628 | 4722 | ||
4723 | void 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 | } | ||
4732 | EXPORT_SYMBOL(complete_n); | ||
4733 | |||
4629 | static inline long __sched | 4734 | static inline long __sched |
4630 | do_wait_for_common(struct completion *x, long timeout, int state) | 4735 | do_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 */ |