aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/litmus.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/litmus.c')
-rw-r--r--litmus/litmus.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/litmus/litmus.c b/litmus/litmus.c
index 11ccaafd50de..16b3aeda5615 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -17,6 +17,12 @@
17#include <litmus/litmus_proc.h> 17#include <litmus/litmus_proc.h>
18#include <litmus/sched_trace.h> 18#include <litmus/sched_trace.h>
19 19
20#ifdef CONFIG_PLUGIN_MC
21#include <litmus/sched_mc.h>
22#else
23struct mc_task;
24#endif
25
20/* Number of RT tasks that exist in the system */ 26/* Number of RT tasks that exist in the system */
21atomic_t rt_task_count = ATOMIC_INIT(0); 27atomic_t rt_task_count = ATOMIC_INIT(0);
22static DEFINE_RAW_SPINLOCK(task_transition_lock); 28static DEFINE_RAW_SPINLOCK(task_transition_lock);
@@ -274,6 +280,74 @@ asmlinkage long sys_null_call(cycles_t __user *ts)
274 return ret; 280 return ret;
275} 281}
276 282
283#ifdef CONFIG_PLUGIN_MC
284asmlinkage long sys_set_rt_task_mc_param(pid_t pid, struct mc_task __user *param)
285{
286 struct mc_task mc;
287 struct mc_data *mc_data;
288 struct task_struct *target;
289 int retval = -EINVAL;
290
291 printk("Setting up mixed-criicality task parameters for process %d.\n",
292 pid);
293
294 if (pid < 0 || param == 0) {
295 goto out;
296 }
297 if (copy_from_user(&mc, param, sizeof(mc))) {
298 retval = -EFAULT;
299 goto out;
300 }
301
302 /* Task search and manipulation must be protected */
303 read_lock_irq(&tasklist_lock);
304 if (!(target = find_task_by_vpid(pid))) {
305 retval = -ESRCH;
306 goto out_unlock;
307 }
308
309 if (is_realtime(target)) {
310 /* The task is already a real-time task.
311 * We cannot not allow parameter changes at this point.
312 */
313 retval = -EBUSY;
314 goto out_unlock;
315 }
316
317 if (mc.crit < CRIT_LEVEL_A || mc.crit > CRIT_LEVEL_D)
318 {
319 printk(KERN_WARNING "litmus: real-time task %d rejected because "
320 "of invalid criticality level\n", pid);
321 goto out_unlock;
322 }
323
324 mc_data = tsk_rt(target)->mc_data;
325 if (!mc_data)
326 {
327 mc_data = kmalloc(sizeof(*mc_data), GFP_ATOMIC);
328 if (!mc_data)
329 {
330 retval = -ENOMEM;
331 goto out_unlock;
332 }
333 tsk_rt(target)->mc_data = mc_data;
334 }
335 mc_data->mc_task.crit = mc.crit;
336
337 retval = 0;
338out_unlock:
339 read_unlock_irq(&tasklist_lock);
340out:
341 return retval;
342}
343#else
344asmlinkage long sys_set_rt_task_mc_param(pid_t pid, struct mc_task __user *param)
345{
346 /* don't allow this syscall if the plugin is not enabled */
347 return -EINVAL;
348}
349#endif
350
277/* p is a real-time task. Re-init its state as a best-effort task. */ 351/* p is a real-time task. Re-init its state as a best-effort task. */
278static void reinit_litmus_state(struct task_struct* p, int restore) 352static void reinit_litmus_state(struct task_struct* p, int restore)
279{ 353{
@@ -479,6 +553,15 @@ void exit_litmus(struct task_struct *dead_tsk)
479 free_page((unsigned long) tsk_rt(dead_tsk)->ctrl_page); 553 free_page((unsigned long) tsk_rt(dead_tsk)->ctrl_page);
480 } 554 }
481 555
556#ifdef CONFIG_PLUGIN_MC
557 /* The MC-setup syscall might succeed and allocate mc_data, but the
558 task may not exit in real-time mode, and that memory will leak.
559 Check and free it here.
560 */
561 if (tsk_rt(dead_tsk)->mc_data)
562 kfree(tsk_rt(dead_tsk)->mc_data);
563#endif
564
482 /* main cleanup only for RT tasks */ 565 /* main cleanup only for RT tasks */
483 if (is_realtime(dead_tsk)) 566 if (is_realtime(dead_tsk))
484 litmus_exit_task(dead_tsk); 567 litmus_exit_task(dead_tsk);