Merge branch 'for-linus' of git://neil.brown.name/md

* 'for-linus' of git://neil.brown.name/md:
md: Avoid waking up a thread after it has been freed.

+26 -15
+19 -3
drivers/md/md.c
··· 61 61 static void autostart_arrays(int part); 62 62 #endif 63 63 64 + /* pers_list is a list of registered personalities protected 65 + * by pers_lock. 66 + * pers_lock does extra service to protect accesses to 67 + * mddev->thread when the mutex cannot be held. 68 + */ 64 69 static LIST_HEAD(pers_list); 65 70 static DEFINE_SPINLOCK(pers_lock); 66 71 ··· 744 739 } else 745 740 mutex_unlock(&mddev->reconfig_mutex); 746 741 742 + /* was we've dropped the mutex we need a spinlock to 743 + * make sur the thread doesn't disappear 744 + */ 745 + spin_lock(&pers_lock); 747 746 md_wakeup_thread(mddev->thread); 747 + spin_unlock(&pers_lock); 748 748 } 749 749 750 750 static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) ··· 6439 6429 return thread; 6440 6430 } 6441 6431 6442 - void md_unregister_thread(mdk_thread_t *thread) 6432 + void md_unregister_thread(mdk_thread_t **threadp) 6443 6433 { 6434 + mdk_thread_t *thread = *threadp; 6444 6435 if (!thread) 6445 6436 return; 6446 6437 dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); 6438 + /* Locking ensures that mddev_unlock does not wake_up a 6439 + * non-existent thread 6440 + */ 6441 + spin_lock(&pers_lock); 6442 + *threadp = NULL; 6443 + spin_unlock(&pers_lock); 6447 6444 6448 6445 kthread_stop(thread->tsk); 6449 6446 kfree(thread); ··· 7357 7340 mdk_rdev_t *rdev; 7358 7341 7359 7342 /* resync has finished, collect result */ 7360 - md_unregister_thread(mddev->sync_thread); 7361 - mddev->sync_thread = NULL; 7343 + md_unregister_thread(&mddev->sync_thread); 7362 7344 if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && 7363 7345 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { 7364 7346 /* success...*/
+1 -1
drivers/md/md.h
··· 560 560 extern int unregister_md_personality(struct mdk_personality *p); 561 561 extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), 562 562 mddev_t *mddev, const char *name); 563 - extern void md_unregister_thread(mdk_thread_t *thread); 563 + extern void md_unregister_thread(mdk_thread_t **threadp); 564 564 extern void md_wakeup_thread(mdk_thread_t *thread); 565 565 extern void md_check_recovery(mddev_t *mddev); 566 566 extern void md_write_start(mddev_t *mddev, struct bio *bi);
+1 -2
drivers/md/multipath.c
··· 514 514 { 515 515 multipath_conf_t *conf = mddev->private; 516 516 517 - md_unregister_thread(mddev->thread); 518 - mddev->thread = NULL; 517 + md_unregister_thread(&mddev->thread); 519 518 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 520 519 mempool_destroy(conf->pool); 521 520 kfree(conf->multipaths);
+1 -2
drivers/md/raid1.c
··· 2562 2562 raise_barrier(conf); 2563 2563 lower_barrier(conf); 2564 2564 2565 - md_unregister_thread(mddev->thread); 2566 - mddev->thread = NULL; 2565 + md_unregister_thread(&mddev->thread); 2567 2566 if (conf->r1bio_pool) 2568 2567 mempool_destroy(conf->r1bio_pool); 2569 2568 kfree(conf->mirrors);
+2 -3
drivers/md/raid10.c
··· 2955 2955 return 0; 2956 2956 2957 2957 out_free_conf: 2958 - md_unregister_thread(mddev->thread); 2958 + md_unregister_thread(&mddev->thread); 2959 2959 if (conf->r10bio_pool) 2960 2960 mempool_destroy(conf->r10bio_pool); 2961 2961 safe_put_page(conf->tmppage); ··· 2973 2973 raise_barrier(conf, 0); 2974 2974 lower_barrier(conf); 2975 2975 2976 - md_unregister_thread(mddev->thread); 2977 - mddev->thread = NULL; 2976 + md_unregister_thread(&mddev->thread); 2978 2977 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 2979 2978 if (conf->r10bio_pool) 2980 2979 mempool_destroy(conf->r10bio_pool);
+2 -4
drivers/md/raid5.c
··· 4941 4941 4942 4942 return 0; 4943 4943 abort: 4944 - md_unregister_thread(mddev->thread); 4945 - mddev->thread = NULL; 4944 + md_unregister_thread(&mddev->thread); 4946 4945 if (conf) { 4947 4946 print_raid5_conf(conf); 4948 4947 free_conf(conf); ··· 4955 4956 { 4956 4957 raid5_conf_t *conf = mddev->private; 4957 4958 4958 - md_unregister_thread(mddev->thread); 4959 - mddev->thread = NULL; 4959 + md_unregister_thread(&mddev->thread); 4960 4960 if (mddev->queue) 4961 4961 mddev->queue->backing_dev_info.congested_fn = NULL; 4962 4962 free_conf(conf);