diff options
-rw-r--r-- | include/litmus/litmus.h | 1 | ||||
-rw-r--r-- | litmus/sched_plugin.c | 60 |
2 files changed, 60 insertions, 1 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index faaf83961dfa..62107e659c12 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h | |||
@@ -124,6 +124,7 @@ static inline lt_t litmus_clock(void) | |||
124 | (a)->rt_param.job_params.release,\ | 124 | (a)->rt_param.job_params.release,\ |
125 | (b)->rt_param.job_params.release)) | 125 | (b)->rt_param.job_params.release)) |
126 | 126 | ||
127 | void preempt_if_preemptable(struct task_struct* t, int on_cpu); | ||
127 | 128 | ||
128 | #ifdef CONFIG_SRP | 129 | #ifdef CONFIG_SRP |
129 | void srp_ceiling_block(void); | 130 | void srp_ceiling_block(void); |
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c index 0be091ece569..bc7c0e93fb18 100644 --- a/litmus/sched_plugin.c +++ b/litmus/sched_plugin.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* sched_plugin.c -- core infrastructure for the scheduler plugin system | 1 | /* sched_plugin.c -- core infrastructure for the scheduler plugin system |
2 | * | 2 | * |
3 | * This file includes the initialization of the plugin system, the no-op Linux | 3 | * This file includes the initialization of the plugin system, the no-op Linux |
4 | * scheduler plugin and some dummy functions. | 4 | * scheduler plugin, some dummy functions, and some helper functions. |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/list.h> | 7 | #include <linux/list.h> |
@@ -12,6 +12,64 @@ | |||
12 | 12 | ||
13 | #include <litmus/jobs.h> | 13 | #include <litmus/jobs.h> |
14 | 14 | ||
15 | /* | ||
16 | * Generic function to trigger preemption on either local or remote cpu | ||
17 | * from scheduler plugins. The key feature is that this function is | ||
18 | * non-preemptive section aware and does not invoke the scheduler / send | ||
19 | * IPIs if the to-be-preempted task is actually non-preemptive. | ||
20 | */ | ||
21 | void preempt_if_preemptable(struct task_struct* t, int on_cpu) | ||
22 | { | ||
23 | /* t is the real-time task executing on CPU on_cpu If t is NULL, then | ||
24 | * on_cpu is currently scheduling background work. | ||
25 | */ | ||
26 | |||
27 | int send_ipi; | ||
28 | |||
29 | if (smp_processor_id() == on_cpu) { | ||
30 | /* local CPU case */ | ||
31 | if (t) { | ||
32 | /* check if we need to poke userspace */ | ||
33 | if (is_user_np(t)) | ||
34 | /* yes, poke it */ | ||
35 | request_exit_np(t); | ||
36 | else | ||
37 | /* no, see if we are allowed to preempt the | ||
38 | * currently-executing task */ | ||
39 | if (!is_kernel_np(t)) | ||
40 | set_tsk_need_resched(t); | ||
41 | } else | ||
42 | /* move non-real-time task out of the way */ | ||
43 | set_tsk_need_resched(current); | ||
44 | } else { | ||
45 | /* remote CPU case */ | ||
46 | if (!t) | ||
47 | /* currently schedules non-real-time work */ | ||
48 | send_ipi = 1; | ||
49 | else { | ||
50 | /* currently schedules real-time work */ | ||
51 | if (is_user_np(t)) { | ||
52 | /* need to notify user space of delayed | ||
53 | * preemption */ | ||
54 | |||
55 | /* to avoid a race, set the flag, then test | ||
56 | * again */ | ||
57 | request_exit_np(t); | ||
58 | /* make sure it got written */ | ||
59 | mb(); | ||
60 | } | ||
61 | /* Only send an ipi if remote task might have raced our | ||
62 | * request, i.e., send an IPI to make sure if it exited | ||
63 | * its critical section. | ||
64 | */ | ||
65 | send_ipi = !is_np(t) && !is_kernel_np(t); | ||
66 | } | ||
67 | if (likely(send_ipi)) | ||
68 | smp_send_reschedule(on_cpu); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | |||
15 | /************************************************************* | 73 | /************************************************************* |
16 | * Dummy plugin functions * | 74 | * Dummy plugin functions * |
17 | *************************************************************/ | 75 | *************************************************************/ |