bcache: Revert "bcache: fix high CPU occupancy during journal"
This reverts commitalistair/sunxi64-5.4-dsic4dc2497d5
. 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:c4dc2497d5
("bcache: fix high CPU occupancy during journal") Signed-off-by: Coly Li <colyli@suse.de> Cc: stable@vger.kernel.org Cc: Tang Junhui <tang.junhui.linux@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
parent
ba82c1ac16
commit
249a5f6da5
|
@ -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 {
|
||||||
|
|
|
@ -416,12 +416,6 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
{
|
{
|
||||||
|
@ -429,35 +423,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) {
|
||||||
|
@ -898,8 +882,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 { \
|
||||||
|
|
||||||
#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; \
|
||||||
|
|
Loading…
Reference in New Issue