diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-01-29 19:25:26 -0500 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-29 17:25:50 -0400 |
commit | 5e987d486c0f89d615d134512938fc1198b3ca67 (patch) | |
tree | b781dfcce3dcfe37e8c0a18e694bc58165165ac2 | |
parent | 37b840336a1663a5ce62d663a702d9afefd56d23 (diff) |
Bugfix: clear LITMUS^RT state on fork completely
When a real-time task forks, then its LITMUS^RT-specific fields should be cleared,
because we don't want real-time tasks to spawn new real-time tasks that bypass
the plugin's admission control (if any).
This was broken in three ways:
1) kernel/fork.c did not erase all of tsk->rt_param, only the first few bytes due to
a wrong size argument to memset().
2) It should have been calling litmus_fork() instead anyway.
3) litmus_fork() was _also_ not clearing all of tsk->rt_param, due to another size
argument bug.
Interestingly, 1) and 2) can be traced back to the 2007->2008 port,
whereas 3) was added by Mitchell much later on (to dead code, no less).
I'm really surprised that this never blew up before.
-rw-r--r-- | kernel/fork.c | 2 | ||||
-rw-r--r-- | litmus/litmus.c | 2 |
2 files changed, 2 insertions, 2 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 889730cce3ad..9fad346d7029 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -249,7 +249,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
249 | tsk->stack = ti; | 249 | tsk->stack = ti; |
250 | 250 | ||
251 | /* Don't let the new task be a real-time task. */ | 251 | /* Don't let the new task be a real-time task. */ |
252 | memset(&tsk->rt_param, 0, sizeof(struct rt_task)); | 252 | litmus_fork(tsk); |
253 | 253 | ||
254 | err = prop_local_init_single(&tsk->dirties); | 254 | err = prop_local_init_single(&tsk->dirties); |
255 | if (err) | 255 | if (err) |
diff --git a/litmus/litmus.c b/litmus/litmus.c index 2dea340aea1d..d31a2ba030e4 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -285,7 +285,7 @@ static void reinit_litmus_state(struct task_struct* p, int restore) | |||
285 | // __setscheduler(p, p->rt_param.old_policy, p->rt_param.old_prio); | 285 | // __setscheduler(p, p->rt_param.old_policy, p->rt_param.old_prio); |
286 | 286 | ||
287 | /* Cleanup everything else. */ | 287 | /* Cleanup everything else. */ |
288 | memset(&p->rt_param, 0, sizeof(user_config)); | 288 | memset(&p->rt_param, 0, sizeof(p->rt_param)); |
289 | 289 | ||
290 | /* Restore preserved fields. */ | 290 | /* Restore preserved fields. */ |
291 | if (restore) { | 291 | if (restore) { |