Messages in this thread Patch in this message | | | Subject | [PATCH] kernel_thread race | Date | Thu, 26 Aug 1999 14:30:19 -0400 | From | Jeff Dike <> |
| |
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.
The fix implemented in the patch below changes kernel_thread to return a task_struct instead of a pid. kswapd_process and bdflush_tsk get initialized in kswapd_init and bdflush_init, respectively, rather than in the new thread.
The two kernel_thread calls which look at the pid change from pid = kernel_thread(...); to pid = kernel_thread(...)->pid;
Jeff diff -Naur -X ../exclude-files orig/fs/buffer.c um/fs/buffer.c --- orig/fs/buffer.c Thu Aug 26 01:32:33 1999 +++ um/fs/buffer.c Thu Aug 26 13:16:27 1999 @@ -2392,7 +2392,6 @@ current->session = 1; current->pgrp = 1; sprintf(current->comm, "kflushd"); - bdflush_tsk = current; for (;;) { int nlist; @@ -2472,7 +2471,8 @@ static int __init bdflush_init(void) { - kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + bdflush_tsk = kernel_thread(bdflush, NULL, + CLONE_FS | CLONE_FILES | CLONE_SIGHAND); return 0; } diff -Naur -X ../exclude-files orig/init/main.c um/init/main.c --- orig/init/main.c Thu Aug 26 00:30:18 1999 +++ um/init/main.c Thu Aug 26 13:17:16 1999 @@ -666,7 +667,7 @@ int error; int i, pid; - pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); + pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD)->pid; if (pid>0) while (pid != wait(&i)); if (MAJOR(real_root_dev) != RAMDISK_MAJOR diff -Naur -X ../exclude-files orig/kernel/kmod.c um/kernel/kmod.c --- orig/kernel/kmod.c Thu Nov 12 12:58:32 1998 +++ um/kernel/kmod.c Thu Aug 26 13:17:33 1999 @@ -104,7 +104,7 @@ return -EPERM; } - pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS); + pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS)->pid; if (pid < 0) { printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid); return pid; diff -Naur -X ../exclude-files orig/mm/vmscan.c um/mm/vmscan.c --- orig/mm/vmscan.c Thu Aug 26 00:30:19 1999 +++ um/mm/vmscan.c Thu Aug 26 13:16:55 1999 @@ -454,7 +454,6 @@ { struct task_struct *tsk = current; - kswapd_process = tsk; tsk->session = 1; tsk->pgrp = 1; strcpy(tsk->comm, "kswapd"); @@ -525,7 +524,8 @@ { printk("Starting kswapd v1.6\n"); swap_setup(); - kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + kswapd_process = kernel_thread(kswapd, NULL, + CLONE_FS | CLONE_FILES | CLONE_SIGHAND); return 0; }
- 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/
| |