Skip to content

Commit

Permalink
bcache: Revert "bcache: fix high CPU occupancy during journal"
Browse files Browse the repository at this point in the history
This reverts commit c4dc249.

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: c4dc249 ("bcache: fix high CPU occupancy during journal")
Signed-off-by: Coly Li <[email protected]>
Cc: [email protected]
Cc: Tang Junhui <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Coly Li authored and axboe committed Jun 28, 2019
1 parent ba82c1a commit 249a5f6
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 36 deletions.
2 changes: 0 additions & 2 deletions drivers/md/bcache/bcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,6 @@ struct cache_set {

#define BUCKET_HASH_BITS 12
struct hlist_head bucket_hash[1 << BUCKET_HASH_BITS];

DECLARE_HEAP(struct btree *, flush_btree);
};

struct bbio {
Expand Down
47 changes: 15 additions & 32 deletions drivers/md/bcache/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,48 +416,32 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list)
}

/* 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)
{
/*
* Try to find the btree node with that references the oldest journal
* entry, best is our current candidate and is locked if non NULL:
*/
struct btree *b;
int i;
struct btree *b, *best;
unsigned int i;

atomic_long_inc(&c->flush_write);

retry:
spin_lock(&c->journal.lock);
if (heap_empty(&c->flush_btree)) {
for_each_cached_btree(b, c, i)
if (btree_current_write(b)->journal) {
if (!heap_full(&c->flush_btree))
heap_add(&c->flush_btree, b,
journal_max_cmp);
else if (journal_max_cmp(b,
heap_peek(&c->flush_btree))) {
c->flush_btree.data[0] = b;
heap_sift(&c->flush_btree, 0,
journal_max_cmp);
}
best = NULL;

for_each_cached_btree(b, c, i)
if (btree_current_write(b)->journal) {
if (!best)
best = b;
else if (journal_pin_cmp(c,
btree_current_write(best)->journal,
btree_current_write(b)->journal)) {
best = b;
}
}

for (i = c->flush_btree.used / 2 - 1; i >= 0; --i)
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);

b = best;
if (b) {
mutex_lock(&b->write_lock);
if (!btree_current_write(b)->journal) {
Expand Down Expand Up @@ -898,8 +882,7 @@ int bch_journal_alloc(struct cache_set *c)
j->w[0].c = c;
j->w[1].c = c;

if (!(init_heap(&c->flush_btree, 128, GFP_KERNEL)) ||
!(init_fifo(&j->pin, JOURNAL_PIN, GFP_KERNEL)) ||
if (!(init_fifo(&j->pin, JOURNAL_PIN, GFP_KERNEL)) ||
!(j->w[0].data = (void *) __get_free_pages(GFP_KERNEL, JSET_BITS)) ||
!(j->w[1].data = (void *) __get_free_pages(GFP_KERNEL, JSET_BITS)))
return -ENOMEM;
Expand Down
2 changes: 0 additions & 2 deletions drivers/md/bcache/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ do { \

#define heap_full(h) ((h)->used == (h)->size)

#define heap_empty(h) ((h)->used == 0)

#define DECLARE_FIFO(type, name) \
struct { \
size_t front, back, size, mask; \
Expand Down

0 comments on commit 249a5f6

Please sign in to comment.