diff options
-rw-r--r-- | drivers/md/md.c | 48 |
1 files changed, 10 insertions, 38 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 008149e2bc4a..30e3624f3d90 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 | ||
3138 | void md_unregister_thread(mdk_thread_t *thread) | 3122 | void 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 | ||