diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-02-03 19:35:20 -0500 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-29 17:25:59 -0400 |
commit | b973c95c86e6710c913c01a67013605f68a3c2c3 (patch) | |
tree | 73786af2a164c8cb89009cc4069e60b7de04bc4b /litmus/litmus.c | |
parent | 5e987d486c0f89d615d134512938fc1198b3ca67 (diff) |
Add virtual LITMUS^RT control device.
This device only supports mmap()'ing a single page.
This page is shared RW between the kernel and userspace.
It is inteded to allow near-zero-overhead communication
between the kernel and userspace. It's first use will be a
proper implementation of user-signaled
non-preemptable section support.
Diffstat (limited to 'litmus/litmus.c')
-rw-r--r-- | litmus/litmus.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/litmus/litmus.c b/litmus/litmus.c index d31a2ba030e4..589062f8ab87 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -268,12 +268,13 @@ asmlinkage long sys_null_call(cycles_t __user *ts) | |||
268 | static void reinit_litmus_state(struct task_struct* p, int restore) | 268 | static void reinit_litmus_state(struct task_struct* p, int restore) |
269 | { | 269 | { |
270 | struct rt_task user_config = {}; | 270 | struct rt_task user_config = {}; |
271 | __user short *np_flag = NULL; | 271 | void* ctrl_page = NULL; |
272 | 272 | ||
273 | if (restore) { | 273 | if (restore) { |
274 | /* Safe user-space provided configuration data. */ | 274 | /* Safe user-space provided configuration data. |
275 | * and allocated page. */ | ||
275 | user_config = p->rt_param.task_params; | 276 | user_config = p->rt_param.task_params; |
276 | np_flag = p->rt_param.np_flag; | 277 | ctrl_page = p->rt_param.ctrl_page; |
277 | } | 278 | } |
278 | 279 | ||
279 | /* We probably should not be inheriting any task's priority | 280 | /* We probably should not be inheriting any task's priority |
@@ -282,7 +283,7 @@ static void reinit_litmus_state(struct task_struct* p, int restore) | |||
282 | WARN_ON(p->rt_param.inh_task); | 283 | WARN_ON(p->rt_param.inh_task); |
283 | 284 | ||
284 | /* We need to restore the priority of the task. */ | 285 | /* We need to restore the priority of the task. */ |
285 | // __setscheduler(p, p->rt_param.old_policy, p->rt_param.old_prio); | 286 | // __setscheduler(p, p->rt_param.old_policy, p->rt_param.old_prio); XXX why is this commented? |
286 | 287 | ||
287 | /* Cleanup everything else. */ | 288 | /* Cleanup everything else. */ |
288 | memset(&p->rt_param, 0, sizeof(p->rt_param)); | 289 | memset(&p->rt_param, 0, sizeof(p->rt_param)); |
@@ -290,7 +291,7 @@ static void reinit_litmus_state(struct task_struct* p, int restore) | |||
290 | /* Restore preserved fields. */ | 291 | /* Restore preserved fields. */ |
291 | if (restore) { | 292 | if (restore) { |
292 | p->rt_param.task_params = user_config; | 293 | p->rt_param.task_params = user_config; |
293 | p->rt_param.np_flag = np_flag; | 294 | p->rt_param.ctrl_page = ctrl_page; |
294 | } | 295 | } |
295 | } | 296 | } |
296 | 297 | ||
@@ -412,8 +413,11 @@ out: | |||
412 | void litmus_fork(struct task_struct* p) | 413 | void litmus_fork(struct task_struct* p) |
413 | { | 414 | { |
414 | if (is_realtime(p)) | 415 | if (is_realtime(p)) |
415 | /* clean out any litmus related state, don't preserve anything*/ | 416 | /* clean out any litmus related state, don't preserve anything */ |
416 | reinit_litmus_state(p, 0); | 417 | reinit_litmus_state(p, 0); |
418 | else | ||
419 | /* non-rt tasks might have ctrl_page set */ | ||
420 | tsk_rt(p)->ctrl_page = NULL; | ||
417 | } | 421 | } |
418 | 422 | ||
419 | /* Called upon execve(). | 423 | /* Called upon execve(). |
@@ -426,12 +430,29 @@ void litmus_exec(void) | |||
426 | 430 | ||
427 | if (is_realtime(p)) { | 431 | if (is_realtime(p)) { |
428 | WARN_ON(p->rt_param.inh_task); | 432 | WARN_ON(p->rt_param.inh_task); |
429 | p->rt_param.np_flag = NULL; | 433 | if (tsk_rt(p)->ctrl_page) { |
434 | free_page((unsigned long) tsk_rt(p)->ctrl_page); | ||
435 | tsk_rt(p)->ctrl_page = NULL; | ||
436 | } | ||
430 | } | 437 | } |
431 | } | 438 | } |
432 | 439 | ||
433 | void exit_litmus(struct task_struct *dead_tsk) | 440 | void exit_litmus(struct task_struct *dead_tsk) |
434 | { | 441 | { |
442 | /* We also allow non-RT tasks to | ||
443 | * allocate control pages to allow | ||
444 | * measurements with non-RT tasks. | ||
445 | * So check if we need to free the page | ||
446 | * in any case. | ||
447 | */ | ||
448 | if (tsk_rt(dead_tsk)->ctrl_page) { | ||
449 | TRACE_TASK(dead_tsk, | ||
450 | "freeing ctrl_page %p\n", | ||
451 | tsk_rt(dead_tsk)->ctrl_page); | ||
452 | free_page((unsigned long) tsk_rt(dead_tsk)->ctrl_page); | ||
453 | } | ||
454 | |||
455 | /* main cleanup only for RT tasks */ | ||
435 | if (is_realtime(dead_tsk)) | 456 | if (is_realtime(dead_tsk)) |
436 | litmus_exit_task(dead_tsk); | 457 | litmus_exit_task(dead_tsk); |
437 | } | 458 | } |