]> Pileus Git - ~andy/linux/commitdiff
bcache: Allocation kthread fixes
authorKent Overstreet <kmo@daterainc.com>
Thu, 11 Jul 2013 01:31:58 +0000 (18:31 -0700)
committerKent Overstreet <kmo@daterainc.com>
Fri, 12 Jul 2013 07:22:49 +0000 (00:22 -0700)
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>
drivers/md/bcache/alloc.c
drivers/md/bcache/bcache.h
drivers/md/bcache/super.c

index b54b73b9b2b7bc230536c60e1bc19c35cbeb891b..e45f5575fd4dde8d2768daaa553ab57b9d0023b1 100644 (file)
@@ -63,6 +63,7 @@
 #include "bcache.h"
 #include "btree.h"
 
+#include <linux/freezer.h>
 #include <linux/kthread.h>
 #include <linux/random.h>
 #include <trace/events/bcache.h>
@@ -363,11 +364,10 @@ do {                                                                      \
                        break;                                          \
                                                                        \
                mutex_unlock(&(ca)->set->bucket_lock);                  \
-               if (test_bit(CACHE_SET_STOPPING_2, &ca->set->flags)) {  \
-                       closure_put(&ca->set->cl);                      \
+               if (kthread_should_stop())                              \
                        return 0;                                       \
-               }                                                       \
                                                                        \
+               try_to_freeze();                                        \
                schedule();                                             \
                mutex_lock(&(ca)->set->bucket_lock);                    \
        }                                                               \
@@ -547,14 +547,12 @@ int bch_bucket_alloc_set(struct cache_set *c, unsigned watermark,
 
 int bch_cache_allocator_start(struct cache *ca)
 {
-       ca->alloc_thread = kthread_create(bch_allocator_thread,
-                                         ca, "bcache_allocator");
-       if (IS_ERR(ca->alloc_thread))
-               return PTR_ERR(ca->alloc_thread);
-
-       closure_get(&ca->set->cl);
-       wake_up_process(ca->alloc_thread);
+       struct task_struct *k = kthread_run(bch_allocator_thread,
+                                           ca, "bcache_allocator");
+       if (IS_ERR(k))
+               return PTR_ERR(k);
 
+       ca->alloc_thread = k;
        return 0;
 }
 
index 68f1ded81ae0b98ec3cf2c604aac50a66ced3171..b39f6f0b45f27b89f29e580844e41d8d315d9c18 100644 (file)
@@ -664,13 +664,9 @@ struct gc_stat {
  * CACHE_SET_STOPPING always gets set first when we're closing down a cache set;
  * we'll continue to run normally for awhile with CACHE_SET_STOPPING set (i.e.
  * flushing dirty data).
- *
- * CACHE_SET_STOPPING_2 gets set at the last phase, when it's time to shut down
- * the allocation thread.
  */
 #define CACHE_SET_UNREGISTERING                0
 #define        CACHE_SET_STOPPING              1
-#define        CACHE_SET_STOPPING_2            2
 
 struct cache_set {
        struct closure          cl;
index f6a62174e8f6ac6e448e7f259a3bf74fe0392291..547c4c57b052efbb6fcd3df67c4b52c505023606 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/buffer_head.h>
 #include <linux/debugfs.h>
 #include <linux/genhd.h>
+#include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/random.h>
 #include <linux/reboot.h>
@@ -1329,11 +1330,9 @@ static void cache_set_free(struct closure *cl)
 static void cache_set_flush(struct closure *cl)
 {
        struct cache_set *c = container_of(cl, struct cache_set, caching);
+       struct cache *ca;
        struct btree *b;
-
-       /* Shut down allocator threads */
-       set_bit(CACHE_SET_STOPPING_2, &c->flags);
-       wake_up_allocators(c);
+       unsigned i;
 
        bch_cache_accounting_destroy(&c->accounting);
 
@@ -1348,6 +1347,10 @@ static void cache_set_flush(struct closure *cl)
                if (btree_node_dirty(b))
                        bch_btree_node_write(b, NULL);
 
+       for_each_cache(ca, c, i)
+               if (ca->alloc_thread)
+                       kthread_stop(ca->alloc_thread);
+
        closure_return(cl);
 }