aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2015-08-09 07:18:49 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2015-08-09 06:21:19 -0400
commit0db6e11e49f7bc4893ffff4d8a7af1235894d986 (patch)
tree062186c38cf5752b550d116d4ad7ece3472e3c34
parent4d6bd5eaa2e1e06d0957376d6e49e6b76ca88db5 (diff)
Integrate preemption state machine with Linux scheduler
Track when a processor is going to schedule "soon".
-rw-r--r--arch/arm/kernel/smp.c4
-rw-r--r--arch/x86/kernel/smp.c6
-rw-r--r--arch/x86/xen/smp.c2
-rw-r--r--include/linux/sched.h2
-rw-r--r--kernel/sched/core.c8
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
280static inline void smp_entering_irq(void) 286static 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
130struct futex_pi_state; 131struct futex_pi_state;
131struct robust_list_head; 132struct robust_list_head;
@@ -2784,6 +2785,7 @@ static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag)
2784static inline void set_tsk_need_resched(struct task_struct *tsk) 2785static 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
2789static inline void clear_tsk_need_resched(struct task_struct *tsk) 2791static 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);