Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcache: Allocation kthread fixes

The alloc kthread should've been using try_to_freeze() - and also there
was the potential for the alloc kthread to get woken up after it had
shut down, which would have been bad.

Signed-off-by: Kent Overstreet <kmo@daterainc.com>

+15 -18
+8 -10
drivers/md/bcache/alloc.c
··· 63 63 #include "bcache.h" 64 64 #include "btree.h" 65 65 66 + #include <linux/freezer.h> 66 67 #include <linux/kthread.h> 67 68 #include <linux/random.h> 68 69 #include <trace/events/bcache.h> ··· 364 363 break; \ 365 364 \ 366 365 mutex_unlock(&(ca)->set->bucket_lock); \ 367 - if (test_bit(CACHE_SET_STOPPING_2, &ca->set->flags)) { \ 368 - closure_put(&ca->set->cl); \ 366 + if (kthread_should_stop()) \ 369 367 return 0; \ 370 - } \ 371 368 \ 369 + try_to_freeze(); \ 372 370 schedule(); \ 373 371 mutex_lock(&(ca)->set->bucket_lock); \ 374 372 } \ ··· 547 547 548 548 int bch_cache_allocator_start(struct cache *ca) 549 549 { 550 - ca->alloc_thread = kthread_create(bch_allocator_thread, 551 - ca, "bcache_allocator"); 552 - if (IS_ERR(ca->alloc_thread)) 553 - return PTR_ERR(ca->alloc_thread); 550 + struct task_struct *k = kthread_run(bch_allocator_thread, 551 + ca, "bcache_allocator"); 552 + if (IS_ERR(k)) 553 + return PTR_ERR(k); 554 554 555 - closure_get(&ca->set->cl); 556 - wake_up_process(ca->alloc_thread); 557 - 555 + ca->alloc_thread = k; 558 556 return 0; 559 557 } 560 558
-4
drivers/md/bcache/bcache.h
··· 664 664 * CACHE_SET_STOPPING always gets set first when we're closing down a cache set; 665 665 * we'll continue to run normally for awhile with CACHE_SET_STOPPING set (i.e. 666 666 * flushing dirty data). 667 - * 668 - * CACHE_SET_STOPPING_2 gets set at the last phase, when it's time to shut down 669 - * the allocation thread. 670 667 */ 671 668 #define CACHE_SET_UNREGISTERING 0 672 669 #define CACHE_SET_STOPPING 1 673 - #define CACHE_SET_STOPPING_2 2 674 670 675 671 struct cache_set { 676 672 struct closure cl;
+7 -4
drivers/md/bcache/super.c
··· 16 16 #include <linux/buffer_head.h> 17 17 #include <linux/debugfs.h> 18 18 #include <linux/genhd.h> 19 + #include <linux/kthread.h> 19 20 #include <linux/module.h> 20 21 #include <linux/random.h> 21 22 #include <linux/reboot.h> ··· 1330 1329 static void cache_set_flush(struct closure *cl) 1331 1330 { 1332 1331 struct cache_set *c = container_of(cl, struct cache_set, caching); 1332 + struct cache *ca; 1333 1333 struct btree *b; 1334 - 1335 - /* Shut down allocator threads */ 1336 - set_bit(CACHE_SET_STOPPING_2, &c->flags); 1337 - wake_up_allocators(c); 1334 + unsigned i; 1338 1335 1339 1336 bch_cache_accounting_destroy(&c->accounting); 1340 1337 ··· 1346 1347 list_for_each_entry(b, &c->btree_cache, list) 1347 1348 if (btree_node_dirty(b)) 1348 1349 bch_btree_node_write(b, NULL); 1350 + 1351 + for_each_cache(ca, c, i) 1352 + if (ca->alloc_thread) 1353 + kthread_stop(ca->alloc_thread); 1349 1354 1350 1355 closure_return(cl); 1351 1356 }