diff options
Diffstat (limited to 'litmus/litmus.c')
-rw-r--r-- | litmus/litmus.c | 83 |
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 | ||
23 | struct 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 */ |
21 | atomic_t rt_task_count = ATOMIC_INIT(0); | 27 | atomic_t rt_task_count = ATOMIC_INIT(0); |
22 | static DEFINE_RAW_SPINLOCK(task_transition_lock); | 28 | static 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 | ||
284 | asmlinkage 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; | ||
338 | out_unlock: | ||
339 | read_unlock_irq(&tasklist_lock); | ||
340 | out: | ||
341 | return retval; | ||
342 | } | ||
343 | #else | ||
344 | asmlinkage 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. */ |
278 | static void reinit_litmus_state(struct task_struct* p, int restore) | 352 | static 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); |