Messages in this thread Patch in this message |  | | Date | Tue, 19 Feb 2008 23:52:11 +0100 | | From | "Dmitry Adamushko" <> | | Subject | Re: [PATCH, RFC] kthread: (possibly) a missing memory barrier in kthread_stop() |
| |
humm... following the same logic, there is also a problem in kthread.c.
(1) the main loop of kthreadd() :
set_current_state(TASK_INTERRUPTIBLE); if (list_empty(&kthread_create_list)) schedule();
and
(2) kthread_create() does:
spin_lock(&kthread_create_lock); list_add_tail(&create.list, &kthread_create_list); wake_up_process(kthreadd_task); spin_unlock(&kthread_create_lock);
provided,
- (1) doesn't want to take the 'kthread_create_lock' in order to do a check for list_empty(&kthread_create_list) [ which can be possible if list_empty() results in a single word-size aligned read op. -- which is guaranteed to be atomic on any arch, iirc ]
and
- (1) and (2) can run in parallel.
then it's crucial that a modification of the list (i.e. list_add_tail()) is completed by the moment a state of the task (kthreadd_task->state) is checked in try_to_wake_up(). i.e. they must not be re-ordered.
which makes me think that try_to_wake_up() could be better off just acting as a full mb.
otherwise, a possible fix would be:
this way we get a pair of UNLOCK/LOCK which is guaranteed to be a full mb (the LOCK is in try_to_wake_up())
[ moreover, there seems to be no need to call wake_up_process() with 'kthread_create_lock' being held ]
--- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -145,8 +145,8 @@ struct task_struct *kthread_create(int (*threadfn)(void *data),
spin_lock(&kthread_create_lock); list_add_tail(&create.list, &kthread_create_list); - wake_up_process(kthreadd_task); spin_unlock(&kthread_create_lock); + wake_up_process(kthreadd_task);
wait_for_completion(&create.done);
-- Best regards, Dmitry Adamushko
|  |