Re: [PATCH] kernel_thread race

Andrea Arcangeli (andrea@suse.de)
Fri, 27 Aug 1999 02:49:03 +0200 (CEST)


On Thu, 26 Aug 1999, Jeff Dike wrote:

>kswapd_init does this:
> kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
>
>kswapd does this:
> struct task_struct *tsk = current;
> kswapd_process = tsk;
>
>However, if try_to_free_pages runs before kswapd, then it will do this:
> wake_up_process(kswapd_process)
>with kswapd_process == NULL which causes NULL dereferences in wake_up_process.

With your patch you must be careful because the child may always be
rescheduled before the parent after a kernel_thread call, so if you
convert a piece of code this way:

struct task_struct child_tsk = NULL;

parent()
{
child_tsk = kernel_thread(child);
}

child()
{
child_tsk->something = pippo;
}

then you may really get an Oops. With the old logic you was forced to do:

struct task_struct child_tsk = NULL;

parent()
{
kernel_thread(child);
}

child()
{
child_tsk = current;
child_tsk->something = pippo;
}

and the above can't fail.

Anyway both bdflush and kflushd doesn't use the global task-struct pointer
inside themself so they seems safe w.r.t. the above scenario.

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/