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 | ||
