diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2015-08-09 07:18:49 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2015-08-09 06:21:19 -0400 |
commit | 0db6e11e49f7bc4893ffff4d8a7af1235894d986 (patch) | |
tree | 062186c38cf5752b550d116d4ad7ece3472e3c34 | |
parent | 4d6bd5eaa2e1e06d0957376d6e49e6b76ca88db5 (diff) |
Integrate preemption state machine with Linux scheduler
Track when a processor is going to schedule "soon".
-rw-r--r-- | arch/arm/kernel/smp.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/smp.c | 6 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 2 | ||||
-rw-r--r-- | include/linux/sched.h | 2 | ||||
-rw-r--r-- | kernel/sched/core.c | 8 |
5 files changed, 22 insertions, 0 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index cca5b8758185..29a742bbf3ab 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -50,6 +50,8 @@ | |||
50 | #define CREATE_TRACE_POINTS | 50 | #define CREATE_TRACE_POINTS |
51 | #include <trace/events/ipi.h> | 51 | #include <trace/events/ipi.h> |
52 | 52 | ||
53 | #include <litmus/preempt.h> | ||
54 | |||
53 | /* | 55 | /* |
54 | * as from 2.5, kernels no longer have an init_tasks structure | 56 | * as from 2.5, kernels no longer have an init_tasks structure |
55 | * so we need some other way of telling a new secondary core | 57 | * so we need some other way of telling a new secondary core |
@@ -593,6 +595,8 @@ void handle_IPI(int ipinr, struct pt_regs *regs) | |||
593 | #endif | 595 | #endif |
594 | 596 | ||
595 | case IPI_RESCHEDULE: | 597 | case IPI_RESCHEDULE: |
598 | /* LITMUS^RT: take action based on scheduler state */ | ||
599 | sched_state_ipi(); | ||
596 | scheduler_ipi(); | 600 | scheduler_ipi(); |
597 | break; | 601 | break; |
598 | 602 | ||
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 7ce9fb210d55..431c3d29a667 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cpu.h> | 24 | #include <linux/cpu.h> |
25 | #include <linux/gfp.h> | 25 | #include <linux/gfp.h> |
26 | 26 | ||
27 | #include <litmus/preempt.h> | ||
27 | #include <litmus/debug_trace.h> | 28 | #include <litmus/debug_trace.h> |
28 | 29 | ||
29 | #include <asm/mtrr.h> | 30 | #include <asm/mtrr.h> |
@@ -275,6 +276,11 @@ __visible void smp_reschedule_interrupt(struct pt_regs *regs) | |||
275 | /* | 276 | /* |
276 | * KVM uses this interrupt to force a cpu out of guest mode | 277 | * KVM uses this interrupt to force a cpu out of guest mode |
277 | */ | 278 | */ |
279 | |||
280 | /* LITMUS^RT: this IPI might need to trigger the sched state machine. | ||
281 | * Starting from 3.0 schedule_ipi() actually does something. This may | ||
282 | * increase IPI latencies compared with previous versions. */ | ||
283 | sched_state_ipi(); | ||
278 | } | 284 | } |
279 | 285 | ||
280 | static inline void smp_entering_irq(void) | 286 | static inline void smp_entering_irq(void) |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 86484384492e..517295f6b034 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -63,6 +63,8 @@ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) | |||
63 | inc_irq_stat(irq_resched_count); | 63 | inc_irq_stat(irq_resched_count); |
64 | scheduler_ipi(); | 64 | scheduler_ipi(); |
65 | 65 | ||
66 | sched_state_ipi(); | ||
67 | |||
66 | return IRQ_HANDLED; | 68 | return IRQ_HANDLED; |
67 | } | 69 | } |
68 | 70 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index 3e6e669db92b..ade13badfacc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -126,6 +126,7 @@ struct sched_attr { | |||
126 | }; | 126 | }; |
127 | 127 | ||
128 | #include <litmus/rt_param.h> | 128 | #include <litmus/rt_param.h> |
129 | #include <litmus/preempt.h> | ||
129 | 130 | ||
130 | struct futex_pi_state; | 131 | struct futex_pi_state; |
131 | struct robust_list_head; | 132 | struct robust_list_head; |
@@ -2784,6 +2785,7 @@ static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag) | |||
2784 | static inline void set_tsk_need_resched(struct task_struct *tsk) | 2785 | static inline void set_tsk_need_resched(struct task_struct *tsk) |
2785 | { | 2786 | { |
2786 | set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); | 2787 | set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); |
2788 | sched_state_will_schedule(tsk); | ||
2787 | } | 2789 | } |
2788 | 2790 | ||
2789 | static inline void clear_tsk_need_resched(struct task_struct *tsk) | 2791 | static inline void clear_tsk_need_resched(struct task_struct *tsk) |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 50f9f4c45ce9..377273d6cecc 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -2294,6 +2294,10 @@ asmlinkage __visible void schedule_tail(struct task_struct *prev) | |||
2294 | preempt_disable(); | 2294 | preempt_disable(); |
2295 | rq = finish_task_switch(prev); | 2295 | rq = finish_task_switch(prev); |
2296 | post_schedule(rq); | 2296 | post_schedule(rq); |
2297 | |||
2298 | if (sched_state_validate_switch()) | ||
2299 | litmus_reschedule_local(); | ||
2300 | |||
2297 | preempt_enable(); | 2301 | preempt_enable(); |
2298 | 2302 | ||
2299 | if (current->set_child_tid) | 2303 | if (current->set_child_tid) |
@@ -2745,6 +2749,7 @@ static void __sched __schedule(void) | |||
2745 | int cpu; | 2749 | int cpu; |
2746 | 2750 | ||
2747 | preempt_disable(); | 2751 | preempt_disable(); |
2752 | sched_state_entered_schedule(); | ||
2748 | cpu = smp_processor_id(); | 2753 | cpu = smp_processor_id(); |
2749 | rq = cpu_rq(cpu); | 2754 | rq = cpu_rq(cpu); |
2750 | rcu_note_context_switch(); | 2755 | rcu_note_context_switch(); |
@@ -2819,6 +2824,9 @@ static void __sched __schedule(void) | |||
2819 | 2824 | ||
2820 | post_schedule(rq); | 2825 | post_schedule(rq); |
2821 | 2826 | ||
2827 | if (unlikely(sched_state_validate_switch())) | ||
2828 | litmus_reschedule_local(); | ||
2829 | |||
2822 | sched_preempt_enable_no_resched(); | 2830 | sched_preempt_enable_no_resched(); |
2823 | 2831 | ||
2824 | TS_SCHED2_END(prev); | 2832 | TS_SCHED2_END(prev); |