aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-09-09 19:23:56 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 19:39:13 -0400
commita6fb0934f923f889055152cb0b033674f627460b (patch)
tree4f33272ba325ed31dbd7c1fa76cfe4ac12939c44 /drivers/md/md.c
parent934ce7c840992a771ffc478b132092db9c935c42 (diff)
[PATCH] md: use kthread infrastructure in md
Switch MD to use the kthread infrastructure, to simplify the code and get rid of tasklist_lock abuse in md_unregister_thread. Also don't flush signals in md_thread, as the called thread will always do that. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c48
1 files changed, 10 insertions, 38 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 008149e2bc4..30e3624f3d9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -34,6 +34,7 @@
34 34
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/config.h> 36#include <linux/config.h>
37#include <linux/kthread.h>
37#include <linux/linkage.h> 38#include <linux/linkage.h>
38#include <linux/raid/md.h> 39#include <linux/raid/md.h>
39#include <linux/raid/bitmap.h> 40#include <linux/raid/bitmap.h>
@@ -3049,18 +3050,6 @@ static int md_thread(void * arg)
3049{ 3050{
3050 mdk_thread_t *thread = arg; 3051 mdk_thread_t *thread = arg;
3051 3052
3052 lock_kernel();
3053
3054 /*
3055 * Detach thread
3056 */
3057
3058 daemonize(thread->name, mdname(thread->mddev));
3059
3060 current->exit_signal = SIGCHLD;
3061 allow_signal(SIGKILL);
3062 thread->tsk = current;
3063
3064 /* 3053 /*
3065 * md_thread is a 'system-thread', it's priority should be very 3054 * md_thread is a 'system-thread', it's priority should be very
3066 * high. We avoid resource deadlocks individually in each 3055 * high. We avoid resource deadlocks individually in each
@@ -3072,14 +3061,14 @@ static int md_thread(void * arg)
3072 * bdflush, otherwise bdflush will deadlock if there are too 3061 * bdflush, otherwise bdflush will deadlock if there are too
3073 * many dirty RAID5 blocks. 3062 * many dirty RAID5 blocks.
3074 */ 3063 */
3075 unlock_kernel();
3076 3064
3077 complete(thread->event); 3065 complete(thread->event);
3078 while (thread->run) { 3066 while (!kthread_should_stop()) {
3079 void (*run)(mddev_t *); 3067 void (*run)(mddev_t *);
3080 3068
3081 wait_event_interruptible_timeout(thread->wqueue, 3069 wait_event_interruptible_timeout(thread->wqueue,
3082 test_bit(THREAD_WAKEUP, &thread->flags), 3070 test_bit(THREAD_WAKEUP, &thread->flags)
3071 || kthread_should_stop(),
3083 thread->timeout); 3072 thread->timeout);
3084 try_to_freeze(); 3073 try_to_freeze();
3085 3074
@@ -3088,11 +3077,8 @@ static int md_thread(void * arg)
3088 run = thread->run; 3077 run = thread->run;
3089 if (run) 3078 if (run)
3090 run(thread->mddev); 3079 run(thread->mddev);
3091
3092 if (signal_pending(current))
3093 flush_signals(current);
3094 } 3080 }
3095 complete(thread->event); 3081
3096 return 0; 3082 return 0;
3097} 3083}
3098 3084
@@ -3109,11 +3095,9 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3109 const char *name) 3095 const char *name)
3110{ 3096{
3111 mdk_thread_t *thread; 3097 mdk_thread_t *thread;
3112 int ret;
3113 struct completion event; 3098 struct completion event;
3114 3099
3115 thread = (mdk_thread_t *) kmalloc 3100 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
3116 (sizeof(mdk_thread_t), GFP_KERNEL);
3117 if (!thread) 3101 if (!thread)
3118 return NULL; 3102 return NULL;
3119 3103
@@ -3126,8 +3110,8 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3126 thread->mddev = mddev; 3110 thread->mddev = mddev;
3127 thread->name = name; 3111 thread->name = name;
3128 thread->timeout = MAX_SCHEDULE_TIMEOUT; 3112 thread->timeout = MAX_SCHEDULE_TIMEOUT;
3129 ret = kernel_thread(md_thread, thread, 0); 3113 thread->tsk = kthread_run(md_thread, thread, mdname(thread->mddev));
3130 if (ret < 0) { 3114 if (IS_ERR(thread->tsk)) {
3131 kfree(thread); 3115 kfree(thread);
3132 return NULL; 3116 return NULL;
3133 } 3117 }
@@ -3137,21 +3121,9 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3137 3121
3138void md_unregister_thread(mdk_thread_t *thread) 3122void md_unregister_thread(mdk_thread_t *thread)
3139{ 3123{
3140 struct completion event;
3141
3142 init_completion(&event);
3143
3144 thread->event = &event;
3145
3146 /* As soon as ->run is set to NULL, the task could disappear,
3147 * so we need to hold tasklist_lock until we have sent the signal
3148 */
3149 dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid); 3124 dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
3150 read_lock(&tasklist_lock); 3125
3151 thread->run = NULL; 3126 kthread_stop(thread->tsk);
3152 send_sig(SIGKILL, thread->tsk, 1);
3153 read_unlock(&tasklist_lock);
3154 wait_for_completion(&event);
3155 kfree(thread); 3127 kfree(thread);
3156} 3128}
3157 3129