@@ -107,7 +107,8 @@ static void check_idle_worker(struct btrfs_worker_thread *worker)
107107 worker -> idle = 1 ;
108108
109109 /* the list may be empty if the worker is just starting */
110- if (!list_empty (& worker -> worker_list )) {
110+ if (!list_empty (& worker -> worker_list ) &&
111+ !worker -> workers -> stopping ) {
111112 list_move (& worker -> worker_list ,
112113 & worker -> workers -> idle_list );
113114 }
@@ -127,7 +128,8 @@ static void check_busy_worker(struct btrfs_worker_thread *worker)
127128 spin_lock_irqsave (& worker -> workers -> lock , flags );
128129 worker -> idle = 0 ;
129130
130- if (!list_empty (& worker -> worker_list )) {
131+ if (!list_empty (& worker -> worker_list ) &&
132+ !worker -> workers -> stopping ) {
131133 list_move_tail (& worker -> worker_list ,
132134 & worker -> workers -> worker_list );
133135 }
@@ -412,6 +414,7 @@ void btrfs_stop_workers(struct btrfs_workers *workers)
412414 int can_stop ;
413415
414416 spin_lock_irq (& workers -> lock );
417+ workers -> stopping = 1 ;
415418 list_splice_init (& workers -> idle_list , & workers -> worker_list );
416419 while (!list_empty (& workers -> worker_list )) {
417420 cur = workers -> worker_list .next ;
@@ -455,6 +458,7 @@ void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
455458 workers -> ordered = 0 ;
456459 workers -> atomic_start_pending = 0 ;
457460 workers -> atomic_worker_start = async_helper ;
461+ workers -> stopping = 0 ;
458462}
459463
460464/*
@@ -480,24 +484,33 @@ static int __btrfs_start_workers(struct btrfs_workers *workers)
480484 atomic_set (& worker -> num_pending , 0 );
481485 atomic_set (& worker -> refs , 1 );
482486 worker -> workers = workers ;
483- worker -> task = kthread_run (worker_loop , worker ,
484- "btrfs-%s-%d" , workers -> name ,
485- workers -> num_workers + 1 );
487+ worker -> task = kthread_create (worker_loop , worker ,
488+ "btrfs-%s-%d" , workers -> name ,
489+ workers -> num_workers + 1 );
486490 if (IS_ERR (worker -> task )) {
487491 ret = PTR_ERR (worker -> task );
488- kfree (worker );
489492 goto fail ;
490493 }
494+
491495 spin_lock_irq (& workers -> lock );
496+ if (workers -> stopping ) {
497+ spin_unlock_irq (& workers -> lock );
498+ goto fail_kthread ;
499+ }
492500 list_add_tail (& worker -> worker_list , & workers -> idle_list );
493501 worker -> idle = 1 ;
494502 workers -> num_workers ++ ;
495503 workers -> num_workers_starting -- ;
496504 WARN_ON (workers -> num_workers_starting < 0 );
497505 spin_unlock_irq (& workers -> lock );
498506
507+ wake_up_process (worker -> task );
499508 return 0 ;
509+
510+ fail_kthread :
511+ kthread_stop (worker -> task );
500512fail :
513+ kfree (worker );
501514 spin_lock_irq (& workers -> lock );
502515 workers -> num_workers_starting -- ;
503516 spin_unlock_irq (& workers -> lock );
0 commit comments