diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-19 17:31:52 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-19 17:31:52 -0400 |
commit | f70a290e8a889caa905ab7650c696f2bb299be1a (patch) | |
tree | 56f0886d839499e9f522f189999024b3e86f9be2 /kernel/sched.c | |
parent | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (diff) | |
parent | 7ef4a793a624c6e66c16ca1051847f75161f5bec (diff) |
Merge branch 'wip-nested-locking' into tegra-nested-lockingwip-nested-locking
Conflicts:
Makefile
include/linux/fs.h
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 152 |
1 files changed, 138 insertions, 14 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index f6cf5cbc64b..a1bf2646d12 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -87,6 +87,11 @@ | |||
87 | #define CREATE_TRACE_POINTS | 87 | #define CREATE_TRACE_POINTS |
88 | #include <trace/events/sched.h> | 88 | #include <trace/events/sched.h> |
89 | 89 | ||
90 | #include <litmus/sched_trace.h> | ||
91 | #include <litmus/trace.h> | ||
92 | |||
93 | static void litmus_tick(struct rq*, struct task_struct*); | ||
94 | |||
90 | /* | 95 | /* |
91 | * Convert user-nice values [ -20 ... 0 ... 19 ] | 96 | * Convert user-nice values [ -20 ... 0 ... 19 ] |
92 | * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], | 97 | * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], |
@@ -414,6 +419,12 @@ struct rt_rq { | |||
414 | #endif | 419 | #endif |
415 | }; | 420 | }; |
416 | 421 | ||
422 | /* Litmus related fields in a runqueue */ | ||
423 | struct litmus_rq { | ||
424 | unsigned long nr_running; | ||
425 | struct task_struct *prev; | ||
426 | }; | ||
427 | |||
417 | #ifdef CONFIG_SMP | 428 | #ifdef CONFIG_SMP |
418 | 429 | ||
419 | /* | 430 | /* |
@@ -479,6 +490,7 @@ struct rq { | |||
479 | 490 | ||
480 | struct cfs_rq cfs; | 491 | struct cfs_rq cfs; |
481 | struct rt_rq rt; | 492 | struct rt_rq rt; |
493 | struct litmus_rq litmus; | ||
482 | 494 | ||
483 | #ifdef CONFIG_FAIR_GROUP_SCHED | 495 | #ifdef CONFIG_FAIR_GROUP_SCHED |
484 | /* list of leaf cfs_rq on this cpu: */ | 496 | /* list of leaf cfs_rq on this cpu: */ |
@@ -1054,6 +1066,7 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer) | |||
1054 | raw_spin_lock(&rq->lock); | 1066 | raw_spin_lock(&rq->lock); |
1055 | update_rq_clock(rq); | 1067 | update_rq_clock(rq); |
1056 | rq->curr->sched_class->task_tick(rq, rq->curr, 1); | 1068 | rq->curr->sched_class->task_tick(rq, rq->curr, 1); |
1069 | litmus_tick(rq, rq->curr); | ||
1057 | raw_spin_unlock(&rq->lock); | 1070 | raw_spin_unlock(&rq->lock); |
1058 | 1071 | ||
1059 | return HRTIMER_NORESTART; | 1072 | return HRTIMER_NORESTART; |
@@ -1750,7 +1763,7 @@ static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu) | |||
1750 | 1763 | ||
1751 | static const struct sched_class rt_sched_class; | 1764 | static const struct sched_class rt_sched_class; |
1752 | 1765 | ||
1753 | #define sched_class_highest (&stop_sched_class) | 1766 | #define sched_class_highest (&litmus_sched_class) |
1754 | #define for_each_class(class) \ | 1767 | #define for_each_class(class) \ |
1755 | for (class = sched_class_highest; class; class = class->next) | 1768 | for (class = sched_class_highest; class; class = class->next) |
1756 | 1769 | ||
@@ -2044,6 +2057,7 @@ static int irqtime_account_si_update(void) | |||
2044 | #include "sched_rt.c" | 2057 | #include "sched_rt.c" |
2045 | #include "sched_autogroup.c" | 2058 | #include "sched_autogroup.c" |
2046 | #include "sched_stoptask.c" | 2059 | #include "sched_stoptask.c" |
2060 | #include "../litmus/sched_litmus.c" | ||
2047 | #ifdef CONFIG_SCHED_DEBUG | 2061 | #ifdef CONFIG_SCHED_DEBUG |
2048 | # include "sched_debug.c" | 2062 | # include "sched_debug.c" |
2049 | #endif | 2063 | #endif |
@@ -2166,6 +2180,10 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags) | |||
2166 | * A queue event has occurred, and we're going to schedule. In | 2180 | * A queue event has occurred, and we're going to schedule. In |
2167 | * this case, we can save a useless back to back clock update. | 2181 | * this case, we can save a useless back to back clock update. |
2168 | */ | 2182 | */ |
2183 | /* LITMUS^RT: | ||
2184 | * The "disable-clock-update" approach was buggy in Linux 2.6.36. | ||
2185 | * The issue has been solved in 2.6.37. | ||
2186 | */ | ||
2169 | if (rq->curr->on_rq && test_tsk_need_resched(rq->curr)) | 2187 | if (rq->curr->on_rq && test_tsk_need_resched(rq->curr)) |
2170 | rq->skip_clock_update = 1; | 2188 | rq->skip_clock_update = 1; |
2171 | } | 2189 | } |
@@ -2592,8 +2610,12 @@ void scheduler_ipi(void) | |||
2592 | struct rq *rq = this_rq(); | 2610 | struct rq *rq = this_rq(); |
2593 | struct task_struct *list = xchg(&rq->wake_list, NULL); | 2611 | struct task_struct *list = xchg(&rq->wake_list, NULL); |
2594 | 2612 | ||
2595 | if (!list) | 2613 | if (!list) { |
2614 | /* If we don't call irq_enter(), we need to trigger the IRQ | ||
2615 | * tracing manually. */ | ||
2616 | ft_irq_fired(); | ||
2596 | return; | 2617 | return; |
2618 | } | ||
2597 | 2619 | ||
2598 | /* | 2620 | /* |
2599 | * Not all reschedule IPI handlers call irq_enter/irq_exit, since | 2621 | * Not all reschedule IPI handlers call irq_enter/irq_exit, since |
@@ -2656,7 +2678,12 @@ static void ttwu_queue(struct task_struct *p, int cpu) | |||
2656 | struct rq *rq = cpu_rq(cpu); | 2678 | struct rq *rq = cpu_rq(cpu); |
2657 | 2679 | ||
2658 | #if defined(CONFIG_SMP) | 2680 | #if defined(CONFIG_SMP) |
2659 | if (sched_feat(TTWU_QUEUE) && cpu != smp_processor_id()) { | 2681 | /* |
2682 | * LITMUS^RT: whether to send an IPI to the remote CPU | ||
2683 | * is plugin specific. | ||
2684 | */ | ||
2685 | if (!is_realtime(p) && | ||
2686 | sched_feat(TTWU_QUEUE) && cpu != smp_processor_id()) { | ||
2660 | sched_clock_cpu(cpu); /* sync clocks x-cpu */ | 2687 | sched_clock_cpu(cpu); /* sync clocks x-cpu */ |
2661 | ttwu_queue_remote(p, cpu); | 2688 | ttwu_queue_remote(p, cpu); |
2662 | return; | 2689 | return; |
@@ -2689,6 +2716,9 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) | |||
2689 | unsigned long flags; | 2716 | unsigned long flags; |
2690 | int cpu, success = 0; | 2717 | int cpu, success = 0; |
2691 | 2718 | ||
2719 | if (is_realtime(p)) | ||
2720 | TRACE_TASK(p, "try_to_wake_up() state:%d\n", p->state); | ||
2721 | |||
2692 | smp_wmb(); | 2722 | smp_wmb(); |
2693 | raw_spin_lock_irqsave(&p->pi_lock, flags); | 2723 | raw_spin_lock_irqsave(&p->pi_lock, flags); |
2694 | if (!(p->state & state)) | 2724 | if (!(p->state & state)) |
@@ -2725,6 +2755,12 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) | |||
2725 | */ | 2755 | */ |
2726 | smp_rmb(); | 2756 | smp_rmb(); |
2727 | 2757 | ||
2758 | /* LITMUS^RT: once the task can be safely referenced by this | ||
2759 | * CPU, don't mess up with Linux load balancing stuff. | ||
2760 | */ | ||
2761 | if (is_realtime(p)) | ||
2762 | goto litmus_out_activate; | ||
2763 | |||
2728 | p->sched_contributes_to_load = !!task_contributes_to_load(p); | 2764 | p->sched_contributes_to_load = !!task_contributes_to_load(p); |
2729 | p->state = TASK_WAKING; | 2765 | p->state = TASK_WAKING; |
2730 | 2766 | ||
@@ -2736,12 +2772,16 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) | |||
2736 | wake_flags |= WF_MIGRATED; | 2772 | wake_flags |= WF_MIGRATED; |
2737 | set_task_cpu(p, cpu); | 2773 | set_task_cpu(p, cpu); |
2738 | } | 2774 | } |
2775 | |||
2776 | litmus_out_activate: | ||
2739 | #endif /* CONFIG_SMP */ | 2777 | #endif /* CONFIG_SMP */ |
2740 | 2778 | ||
2741 | ttwu_queue(p, cpu); | 2779 | ttwu_queue(p, cpu); |
2742 | stat: | 2780 | stat: |
2743 | ttwu_stat(p, cpu, wake_flags); | 2781 | ttwu_stat(p, cpu, wake_flags); |
2744 | out: | 2782 | out: |
2783 | if (is_realtime(p)) | ||
2784 | TRACE_TASK(p, "try_to_wake_up() done state:%d\n", p->state); | ||
2745 | raw_spin_unlock_irqrestore(&p->pi_lock, flags); | 2785 | raw_spin_unlock_irqrestore(&p->pi_lock, flags); |
2746 | 2786 | ||
2747 | return success; | 2787 | return success; |
@@ -2852,7 +2892,8 @@ void sched_fork(struct task_struct *p) | |||
2852 | * Revert to default priority/policy on fork if requested. | 2892 | * Revert to default priority/policy on fork if requested. |
2853 | */ | 2893 | */ |
2854 | if (unlikely(p->sched_reset_on_fork)) { | 2894 | if (unlikely(p->sched_reset_on_fork)) { |
2855 | if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) { | 2895 | if (p->policy == SCHED_FIFO || p->policy == SCHED_RR || |
2896 | p->policy == SCHED_LITMUS) { | ||
2856 | p->policy = SCHED_NORMAL; | 2897 | p->policy = SCHED_NORMAL; |
2857 | p->normal_prio = p->static_prio; | 2898 | p->normal_prio = p->static_prio; |
2858 | } | 2899 | } |
@@ -3063,6 +3104,8 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev) | |||
3063 | */ | 3104 | */ |
3064 | prev_state = prev->state; | 3105 | prev_state = prev->state; |
3065 | finish_arch_switch(prev); | 3106 | finish_arch_switch(prev); |
3107 | litmus->finish_switch(prev); | ||
3108 | prev->rt_param.stack_in_use = NO_CPU; | ||
3066 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | 3109 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW |
3067 | local_irq_disable(); | 3110 | local_irq_disable(); |
3068 | #endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */ | 3111 | #endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */ |
@@ -3092,6 +3135,15 @@ static inline void pre_schedule(struct rq *rq, struct task_struct *prev) | |||
3092 | { | 3135 | { |
3093 | if (prev->sched_class->pre_schedule) | 3136 | if (prev->sched_class->pre_schedule) |
3094 | prev->sched_class->pre_schedule(rq, prev); | 3137 | prev->sched_class->pre_schedule(rq, prev); |
3138 | |||
3139 | /* LITMUS^RT not very clean hack: we need to save the prev task | ||
3140 | * as our scheduling decision rely on it (as we drop the rq lock | ||
3141 | * something in prev can change...); there is no way to escape | ||
3142 | * this ack apart from modifying pick_nex_task(rq, _prev_) or | ||
3143 | * falling back on the previous solution of decoupling | ||
3144 | * scheduling decisions | ||
3145 | */ | ||
3146 | rq->litmus.prev = prev; | ||
3095 | } | 3147 | } |
3096 | 3148 | ||
3097 | /* rq->lock is NOT held, but preemption is disabled */ | 3149 | /* rq->lock is NOT held, but preemption is disabled */ |
@@ -3128,16 +3180,26 @@ static inline void post_schedule(struct rq *rq) | |||
3128 | asmlinkage void schedule_tail(struct task_struct *prev) | 3180 | asmlinkage void schedule_tail(struct task_struct *prev) |
3129 | __releases(rq->lock) | 3181 | __releases(rq->lock) |
3130 | { | 3182 | { |
3131 | struct rq *rq = this_rq(); | 3183 | struct rq *rq; |
3132 | 3184 | ||
3185 | preempt_disable(); | ||
3186 | |||
3187 | rq = this_rq(); | ||
3133 | finish_task_switch(rq, prev); | 3188 | finish_task_switch(rq, prev); |
3134 | 3189 | ||
3190 | sched_trace_task_switch_to(current); | ||
3191 | |||
3135 | /* | 3192 | /* |
3136 | * FIXME: do we need to worry about rq being invalidated by the | 3193 | * FIXME: do we need to worry about rq being invalidated by the |
3137 | * task_switch? | 3194 | * task_switch? |
3138 | */ | 3195 | */ |
3139 | post_schedule(rq); | 3196 | post_schedule(rq); |
3140 | 3197 | ||
3198 | if (sched_state_validate_switch()) | ||
3199 | litmus_reschedule_local(); | ||
3200 | |||
3201 | preempt_enable(); | ||
3202 | |||
3141 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW | 3203 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW |
3142 | /* In this case, finish_task_switch does not reenable preemption */ | 3204 | /* In this case, finish_task_switch does not reenable preemption */ |
3143 | preempt_enable(); | 3205 | preempt_enable(); |
@@ -4108,18 +4170,26 @@ void scheduler_tick(void) | |||
4108 | 4170 | ||
4109 | sched_clock_tick(); | 4171 | sched_clock_tick(); |
4110 | 4172 | ||
4173 | TS_TICK_START(current); | ||
4174 | |||
4111 | raw_spin_lock(&rq->lock); | 4175 | raw_spin_lock(&rq->lock); |
4112 | update_rq_clock(rq); | 4176 | update_rq_clock(rq); |
4113 | update_cpu_load_active(rq); | 4177 | update_cpu_load_active(rq); |
4114 | curr->sched_class->task_tick(rq, curr, 0); | 4178 | curr->sched_class->task_tick(rq, curr, 0); |
4179 | |||
4180 | /* litmus_tick may force current to resched */ | ||
4181 | litmus_tick(rq, curr); | ||
4182 | |||
4115 | raw_spin_unlock(&rq->lock); | 4183 | raw_spin_unlock(&rq->lock); |
4116 | 4184 | ||
4117 | perf_event_task_tick(); | 4185 | perf_event_task_tick(); |
4118 | 4186 | ||
4119 | #ifdef CONFIG_SMP | 4187 | #ifdef CONFIG_SMP |
4120 | rq->idle_at_tick = idle_cpu(cpu); | 4188 | rq->idle_at_tick = idle_cpu(cpu); |
4121 | trigger_load_balance(rq, cpu); | 4189 | if (!is_realtime(current)) |
4190 | trigger_load_balance(rq, cpu); | ||
4122 | #endif | 4191 | #endif |
4192 | TS_TICK_END(current); | ||
4123 | } | 4193 | } |
4124 | 4194 | ||
4125 | notrace unsigned long get_parent_ip(unsigned long addr) | 4195 | notrace unsigned long get_parent_ip(unsigned long addr) |
@@ -4239,12 +4309,20 @@ pick_next_task(struct rq *rq) | |||
4239 | /* | 4309 | /* |
4240 | * Optimization: we know that if all tasks are in | 4310 | * Optimization: we know that if all tasks are in |
4241 | * the fair class we can call that function directly: | 4311 | * the fair class we can call that function directly: |
4242 | */ | 4312 | |
4243 | if (likely(rq->nr_running == rq->cfs.nr_running)) { | 4313 | * NOT IN LITMUS^RT! |
4314 | |||
4315 | * This breaks many assumptions in the plugins. | ||
4316 | * Do not uncomment without thinking long and hard | ||
4317 | * about how this affects global plugins such as GSN-EDF. | ||
4318 | |||
4319 | if (rq->nr_running == rq->cfs.nr_running) { | ||
4320 | TRACE("taking shortcut in pick_next_task()\n"); | ||
4244 | p = fair_sched_class.pick_next_task(rq); | 4321 | p = fair_sched_class.pick_next_task(rq); |
4245 | if (likely(p)) | 4322 | if (likely(p)) |
4246 | return p; | 4323 | return p; |
4247 | } | 4324 | } |
4325 | */ | ||
4248 | 4326 | ||
4249 | for_each_class(class) { | 4327 | for_each_class(class) { |
4250 | p = class->pick_next_task(rq); | 4328 | p = class->pick_next_task(rq); |
@@ -4267,11 +4345,19 @@ static void __sched __schedule(void) | |||
4267 | 4345 | ||
4268 | need_resched: | 4346 | need_resched: |
4269 | preempt_disable(); | 4347 | preempt_disable(); |
4348 | sched_state_entered_schedule(); | ||
4270 | cpu = smp_processor_id(); | 4349 | cpu = smp_processor_id(); |
4271 | rq = cpu_rq(cpu); | 4350 | rq = cpu_rq(cpu); |
4272 | rcu_note_context_switch(cpu); | 4351 | rcu_note_context_switch(cpu); |
4273 | prev = rq->curr; | 4352 | prev = rq->curr; |
4274 | 4353 | ||
4354 | /* LITMUS^RT: quickly re-evaluate the scheduling decision | ||
4355 | * if the previous one is no longer valid after CTX. | ||
4356 | */ | ||
4357 | litmus_need_resched_nonpreemptible: | ||
4358 | TS_SCHED_START; | ||
4359 | sched_trace_task_switch_away(prev); | ||
4360 | |||
4275 | schedule_debug(prev); | 4361 | schedule_debug(prev); |
4276 | 4362 | ||
4277 | if (sched_feat(HRTICK)) | 4363 | if (sched_feat(HRTICK)) |
@@ -4318,7 +4404,10 @@ need_resched: | |||
4318 | rq->curr = next; | 4404 | rq->curr = next; |
4319 | ++*switch_count; | 4405 | ++*switch_count; |
4320 | 4406 | ||
4407 | TS_SCHED_END(next); | ||
4408 | TS_CXS_START(next); | ||
4321 | context_switch(rq, prev, next); /* unlocks the rq */ | 4409 | context_switch(rq, prev, next); /* unlocks the rq */ |
4410 | TS_CXS_END(current); | ||
4322 | /* | 4411 | /* |
4323 | * The context switch have flipped the stack from under us | 4412 | * The context switch have flipped the stack from under us |
4324 | * and restored the local variables which were saved when | 4413 | * and restored the local variables which were saved when |
@@ -4327,14 +4416,29 @@ need_resched: | |||
4327 | */ | 4416 | */ |
4328 | cpu = smp_processor_id(); | 4417 | cpu = smp_processor_id(); |
4329 | rq = cpu_rq(cpu); | 4418 | rq = cpu_rq(cpu); |
4330 | } else | 4419 | } else { |
4420 | TS_SCHED_END(prev); | ||
4331 | raw_spin_unlock_irq(&rq->lock); | 4421 | raw_spin_unlock_irq(&rq->lock); |
4422 | } | ||
4423 | |||
4424 | TS_SCHED2_START(prev); | ||
4425 | sched_trace_task_switch_to(current); | ||
4332 | 4426 | ||
4333 | post_schedule(rq); | 4427 | post_schedule(rq); |
4334 | 4428 | ||
4429 | if (sched_state_validate_switch()) { | ||
4430 | TS_SCHED2_END(prev); | ||
4431 | goto litmus_need_resched_nonpreemptible; | ||
4432 | } | ||
4433 | |||
4335 | preempt_enable_no_resched(); | 4434 | preempt_enable_no_resched(); |
4435 | |||
4436 | TS_SCHED2_END(prev); | ||
4437 | |||
4336 | if (need_resched()) | 4438 | if (need_resched()) |
4337 | goto need_resched; | 4439 | goto need_resched; |
4440 | |||
4441 | srp_ceiling_block(); | ||
4338 | } | 4442 | } |
4339 | 4443 | ||
4340 | static inline void sched_submit_work(struct task_struct *tsk) | 4444 | static inline void sched_submit_work(struct task_struct *tsk) |
@@ -5056,7 +5160,9 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) | |||
5056 | p->normal_prio = normal_prio(p); | 5160 | p->normal_prio = normal_prio(p); |
5057 | /* we are holding p->pi_lock already */ | 5161 | /* we are holding p->pi_lock already */ |
5058 | p->prio = rt_mutex_getprio(p); | 5162 | p->prio = rt_mutex_getprio(p); |
5059 | if (rt_prio(p->prio)) | 5163 | if (p->policy == SCHED_LITMUS) |
5164 | p->sched_class = &litmus_sched_class; | ||
5165 | else if (rt_prio(p->prio)) | ||
5060 | p->sched_class = &rt_sched_class; | 5166 | p->sched_class = &rt_sched_class; |
5061 | else | 5167 | else |
5062 | p->sched_class = &fair_sched_class; | 5168 | p->sched_class = &fair_sched_class; |
@@ -5104,7 +5210,7 @@ recheck: | |||
5104 | 5210 | ||
5105 | if (policy != SCHED_FIFO && policy != SCHED_RR && | 5211 | if (policy != SCHED_FIFO && policy != SCHED_RR && |
5106 | policy != SCHED_NORMAL && policy != SCHED_BATCH && | 5212 | policy != SCHED_NORMAL && policy != SCHED_BATCH && |
5107 | policy != SCHED_IDLE) | 5213 | policy != SCHED_IDLE && policy != SCHED_LITMUS) |
5108 | return -EINVAL; | 5214 | return -EINVAL; |
5109 | } | 5215 | } |
5110 | 5216 | ||
@@ -5119,6 +5225,8 @@ recheck: | |||
5119 | return -EINVAL; | 5225 | return -EINVAL; |
5120 | if (rt_policy(policy) != (param->sched_priority != 0)) | 5226 | if (rt_policy(policy) != (param->sched_priority != 0)) |
5121 | return -EINVAL; | 5227 | return -EINVAL; |
5228 | if (policy == SCHED_LITMUS && policy == p->policy) | ||
5229 | return -EINVAL; | ||
5122 | 5230 | ||
5123 | /* | 5231 | /* |
5124 | * Allow unprivileged RT tasks to decrease priority: | 5232 | * Allow unprivileged RT tasks to decrease priority: |
@@ -5162,6 +5270,12 @@ recheck: | |||
5162 | return retval; | 5270 | return retval; |
5163 | } | 5271 | } |
5164 | 5272 | ||
5273 | if (policy == SCHED_LITMUS) { | ||
5274 | retval = litmus_admit_task(p); | ||
5275 | if (retval) | ||
5276 | return retval; | ||
5277 | } | ||
5278 | |||
5165 | /* | 5279 | /* |
5166 | * make sure no PI-waiters arrive (or leave) while we are | 5280 | * make sure no PI-waiters arrive (or leave) while we are |
5167 | * changing the priority of the task: | 5281 | * changing the priority of the task: |
@@ -5220,10 +5334,19 @@ recheck: | |||
5220 | 5334 | ||
5221 | p->sched_reset_on_fork = reset_on_fork; | 5335 | p->sched_reset_on_fork = reset_on_fork; |
5222 | 5336 | ||
5337 | if (p->policy == SCHED_LITMUS) | ||
5338 | litmus_exit_task(p); | ||
5339 | |||
5223 | oldprio = p->prio; | 5340 | oldprio = p->prio; |
5224 | prev_class = p->sched_class; | 5341 | prev_class = p->sched_class; |
5225 | __setscheduler(rq, p, policy, param->sched_priority); | 5342 | __setscheduler(rq, p, policy, param->sched_priority); |
5226 | 5343 | ||
5344 | if (policy == SCHED_LITMUS) { | ||
5345 | p->rt_param.stack_in_use = running ? rq->cpu : NO_CPU; | ||
5346 | p->rt_param.present = running; | ||
5347 | litmus->task_new(p, on_rq, running); | ||
5348 | } | ||
5349 | |||
5227 | if (running) | 5350 | if (running) |
5228 | p->sched_class->set_curr_task(rq); | 5351 | p->sched_class->set_curr_task(rq); |
5229 | if (on_rq) | 5352 | if (on_rq) |
@@ -5391,10 +5514,11 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) | |||
5391 | rcu_read_lock(); | 5514 | rcu_read_lock(); |
5392 | 5515 | ||
5393 | p = find_process_by_pid(pid); | 5516 | p = find_process_by_pid(pid); |
5394 | if (!p) { | 5517 | /* Don't set affinity if task not found and for LITMUS tasks */ |
5518 | if (!p || is_realtime(p)) { | ||
5395 | rcu_read_unlock(); | 5519 | rcu_read_unlock(); |
5396 | put_online_cpus(); | 5520 | put_online_cpus(); |
5397 | return -ESRCH; | 5521 | return p ? -EPERM : -ESRCH; |
5398 | } | 5522 | } |
5399 | 5523 | ||
5400 | /* Prevent p going away */ | 5524 | /* Prevent p going away */ |