aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2016-02-14 09:12:22 -0500
committerBjoern Brandenburg <bbb@mpi-sws.org>2016-03-08 10:12:50 -0500
commitff0e731b2a9789c78349659602b485d38de78bde (patch)
treedf47f0cb37e90705f498e53e9ec890cfce4d0381
parenta83a958e62cb903e14bc458a5ace4b9f380fc802 (diff)
LITMUS^RT core: add next_became_invalid() callback
-rw-r--r--include/litmus/sched_plugin.h8
-rw-r--r--kernel/sched/litmus.c42
-rw-r--r--litmus/sched_plugin.c5
3 files changed, 22 insertions, 33 deletions
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h
index 1906a139e6e9..2021e817b243 100644
--- a/include/litmus/sched_plugin.h
+++ b/include/litmus/sched_plugin.h
@@ -35,6 +35,11 @@ typedef void (*finish_switch_t)(struct task_struct *prev);
35 * the scheduler is invoked again. */ 35 * the scheduler is invoked again. */
36typedef bool (*should_wait_for_stack_t)(struct task_struct *next); 36typedef bool (*should_wait_for_stack_t)(struct task_struct *next);
37 37
38/* After dropping the lock to facilitate a pull migration, the task
39 * state may have changed. In this case, the core notifies the plugin
40 * with this callback and then invokes the scheduler again. */
41typedef void (*next_became_invalid_t)(struct task_struct *next);
42
38/********************* task state changes ********************/ 43/********************* task state changes ********************/
39 44
40/* Called to setup a new real-time task. 45/* Called to setup a new real-time task.
@@ -109,7 +114,10 @@ struct sched_plugin {
109 /* scheduler invocation */ 114 /* scheduler invocation */
110 schedule_t schedule; 115 schedule_t schedule;
111 finish_switch_t finish_switch; 116 finish_switch_t finish_switch;
117
118 /* control over pull migrations */
112 should_wait_for_stack_t should_wait_for_stack; 119 should_wait_for_stack_t should_wait_for_stack;
120 next_became_invalid_t next_became_invalid;
113 121
114 /* syscall backend */ 122 /* syscall backend */
115 complete_job_t complete_job; 123 complete_job_t complete_job;
diff --git a/kernel/sched/litmus.c b/kernel/sched/litmus.c
index 4fa5a941a284..8eb9df31ea01 100644
--- a/kernel/sched/litmus.c
+++ b/kernel/sched/litmus.c
@@ -121,45 +121,21 @@ litmus_schedule(struct rq *rq, struct task_struct *prev)
121 } 121 }
122#endif 122#endif
123 double_rq_lock(rq, other_rq); 123 double_rq_lock(rq, other_rq);
124 mb();
125 if (is_realtime(current) && is_current_running() != was_running) {
126 TRACE_TASK(prev,
127 "state changed while we dropped"
128 " the lock: is_running=%d, was_running=%d\n",
129 is_current_running(), was_running);
130 if (is_current_running() && !was_running) {
131 /* prev task became unblocked
132 * we need to simulate normal sequence of events
133 * to scheduler plugins.
134 */
135 litmus->task_block(prev);
136 litmus->task_wake_up(prev);
137 }
138 }
139
140 set_task_cpu(next, smp_processor_id()); 124 set_task_cpu(next, smp_processor_id());
141
142 /* DEBUG: now that we have the lock we need to make sure a
143 * couple of things still hold:
144 * - it is still a real-time task
145 * - it is still runnable (could have been stopped)
146 * If either is violated, then the active plugin is
147 * doing something wrong.
148 */
149 if (!is_realtime(next) || !tsk_rt(next)->present) {
150 /* BAD BAD BAD */
151 TRACE_TASK(next,"BAD: migration invariant FAILED: "
152 "rt=%d present=%d\n",
153 is_realtime(next),
154 tsk_rt(next)->present);
155 /* drop the task */
156 next = NULL;
157 }
158 /* release the other CPU's runqueue, but keep ours */ 125 /* release the other CPU's runqueue, but keep ours */
159 raw_spin_unlock(&other_rq->lock); 126 raw_spin_unlock(&other_rq->lock);
160 } 127 }
161#endif 128#endif
162 129
130 /* check if the task became invalid while we dropped the lock */
131 if (next && (!is_realtime(next) || !tsk_rt(next)->present)) {
132 TRACE_TASK(next,
133 "BAD: next (no longer?) valid\n");
134 litmus->next_became_invalid(next);
135 litmus_reschedule_local();
136 next = NULL;
137 }
138
163 if (next) { 139 if (next) {
164#ifdef CONFIG_SMP 140#ifdef CONFIG_SMP
165 next->rt_param.stack_in_use = rq->cpu; 141 next->rt_param.stack_in_use = rq->cpu;
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c
index 4007e5129e80..1ff9516cbbfc 100644
--- a/litmus/sched_plugin.c
+++ b/litmus/sched_plugin.c
@@ -75,6 +75,10 @@ static bool litmus_dummy_should_wait_for_stack(struct task_struct *next)
75 return true; /* by default, wait indefinitely */ 75 return true; /* by default, wait indefinitely */
76} 76}
77 77
78static void litmus_dummy_next_became_invalid(struct task_struct *next)
79{
80}
81
78static long litmus_dummy_admit_task(struct task_struct* tsk) 82static long litmus_dummy_admit_task(struct task_struct* tsk)
79{ 83{
80 printk(KERN_CRIT "LITMUS^RT: Linux plugin rejects %s/%d.\n", 84 printk(KERN_CRIT "LITMUS^RT: Linux plugin rejects %s/%d.\n",
@@ -192,6 +196,7 @@ int register_sched_plugin(struct sched_plugin* plugin)
192 CHECK(finish_switch); 196 CHECK(finish_switch);
193 CHECK(schedule); 197 CHECK(schedule);
194 CHECK(should_wait_for_stack); 198 CHECK(should_wait_for_stack);
199 CHECK(next_became_invalid);
195 CHECK(task_wake_up); 200 CHECK(task_wake_up);
196 CHECK(task_exit); 201 CHECK(task_exit);
197 CHECK(task_cleanup); 202 CHECK(task_cleanup);