Commit b6dc61e0 authored by Coly Li's avatar Coly Li Committed by Greg Kroah-Hartman

bcache: Revert "bcache: fix high CPU occupancy during journal"

commit 249a5f6d upstream.

This reverts commit c4dc2497.

This patch enlarges a race between normal btree flush code path and
flush_btree_write(), which causes deadlock when journal space is
exhausted. Reverts this patch makes the race window from 128 btree
nodes to only 1 btree nodes.

Fixes: c4dc2497 ("bcache: fix high CPU occupancy during journal")
Signed-off-by: default avatarColy Li <colyli@suse.de>
Cc: stable@vger.kernel.org
Cc: Tang Junhui <tang.junhui.linux@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f1f65afd
...@@ -726,8 +726,6 @@ struct cache_set { ...@@ -726,8 +726,6 @@ struct cache_set {
#define BUCKET_HASH_BITS 12 #define BUCKET_HASH_BITS 12
struct hlist_head bucket_hash[1 << BUCKET_HASH_BITS]; struct hlist_head bucket_hash[1 << BUCKET_HASH_BITS];
DECLARE_HEAP(struct btree *, flush_btree);
}; };
struct bbio { struct bbio {
......
...@@ -390,12 +390,6 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list) ...@@ -390,12 +390,6 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list)
} }
/* Journalling */ /* Journalling */
#define journal_max_cmp(l, r) \
(fifo_idx(&c->journal.pin, btree_current_write(l)->journal) < \
fifo_idx(&(c)->journal.pin, btree_current_write(r)->journal))
#define journal_min_cmp(l, r) \
(fifo_idx(&c->journal.pin, btree_current_write(l)->journal) > \
fifo_idx(&(c)->journal.pin, btree_current_write(r)->journal))
static void btree_flush_write(struct cache_set *c) static void btree_flush_write(struct cache_set *c)
{ {
...@@ -403,35 +397,25 @@ static void btree_flush_write(struct cache_set *c) ...@@ -403,35 +397,25 @@ static void btree_flush_write(struct cache_set *c)
* Try to find the btree node with that references the oldest journal * Try to find the btree node with that references the oldest journal
* entry, best is our current candidate and is locked if non NULL: * entry, best is our current candidate and is locked if non NULL:
*/ */
struct btree *b; struct btree *b, *best;
int i; unsigned int i;
atomic_long_inc(&c->flush_write); atomic_long_inc(&c->flush_write);
retry: retry:
spin_lock(&c->journal.lock); best = NULL;
if (heap_empty(&c->flush_btree)) {
for_each_cached_btree(b, c, i) for_each_cached_btree(b, c, i)
if (btree_current_write(b)->journal) { if (btree_current_write(b)->journal) {
if (!heap_full(&c->flush_btree)) if (!best)
heap_add(&c->flush_btree, b, best = b;
journal_max_cmp); else if (journal_pin_cmp(c,
else if (journal_max_cmp(b, btree_current_write(best)->journal,
heap_peek(&c->flush_btree))) { btree_current_write(b)->journal)) {
c->flush_btree.data[0] = b; best = b;
heap_sift(&c->flush_btree, 0,
journal_max_cmp);
}
} }
}
for (i = c->flush_btree.used / 2 - 1; i >= 0; --i) b = best;
heap_sift(&c->flush_btree, i, journal_min_cmp);
}
b = NULL;
heap_pop(&c->flush_btree, b, journal_min_cmp);
spin_unlock(&c->journal.lock);
if (b) { if (b) {
mutex_lock(&b->write_lock); mutex_lock(&b->write_lock);
if (!btree_current_write(b)->journal) { if (!btree_current_write(b)->journal) {
...@@ -873,8 +857,7 @@ int bch_journal_alloc(struct cache_set *c) ...@@ -873,8 +857,7 @@ int bch_journal_alloc(struct cache_set *c)
j->w[0].c = c; j->w[0].c = c;
j->w[1].c = c; j->w[1].c = c;
if (!(init_heap(&c->flush_btree, 128, GFP_KERNEL)) || if (!(init_fifo(&j->pin, JOURNAL_PIN, GFP_KERNEL)) ||
!(init_fifo(&j->pin, JOURNAL_PIN, GFP_KERNEL)) ||
!(j->w[0].data = (void *) __get_free_pages(GFP_KERNEL, JSET_BITS)) || !(j->w[0].data = (void *) __get_free_pages(GFP_KERNEL, JSET_BITS)) ||
!(j->w[1].data = (void *) __get_free_pages(GFP_KERNEL, JSET_BITS))) !(j->w[1].data = (void *) __get_free_pages(GFP_KERNEL, JSET_BITS)))
return -ENOMEM; return -ENOMEM;
......
...@@ -113,8 +113,6 @@ do { \ ...@@ -113,8 +113,6 @@ do { \
#define heap_full(h) ((h)->used == (h)->size) #define heap_full(h) ((h)->used == (h)->size)
#define heap_empty(h) ((h)->used == 0)
#define DECLARE_FIFO(type, name) \ #define DECLARE_FIFO(type, name) \
struct { \ struct { \
size_t front, back, size, mask; \ size_t front, back, size, mask; \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment