Skip to content

Commit

Permalink
bcache: allow allocator to invalidate bucket in gc
Browse files Browse the repository at this point in the history
Currently, if the gc is running, when the allocator found free_inc
is empty, allocator has to wait the gc finish. Before that, the
IO is blocked.

But actually, there would be some buckets is reclaimable before gc,
and gc will never mark this kind of bucket to be unreclaimable.

So we can put these buckets into free_inc in gc running to avoid
IO being blocked.

Signed-off-by: Dongsheng Yang <[email protected]>
Signed-off-by: Mingzhe Zou <[email protected]>
Signed-off-by: Coly Li <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
yangdongsheng authored and axboe committed May 28, 2024
1 parent e993db2 commit a14a68b
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 9 deletions.
13 changes: 5 additions & 8 deletions drivers/md/bcache/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,9 @@ static inline bool can_inc_bucket_gen(struct bucket *b)

bool bch_can_invalidate_bucket(struct cache *ca, struct bucket *b)
{
BUG_ON(!ca->set->gc_mark_valid);

return (!GC_MARK(b) ||
GC_MARK(b) == GC_MARK_RECLAIMABLE) &&
!atomic_read(&b->pin) &&
can_inc_bucket_gen(b);
return (ca->set->gc_mark_valid || b->reclaimable_in_gc) &&
((!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE) &&
!atomic_read(&b->pin) && can_inc_bucket_gen(b));
}

void __bch_invalidate_one_bucket(struct cache *ca, struct bucket *b)
Expand All @@ -148,6 +145,7 @@ void __bch_invalidate_one_bucket(struct cache *ca, struct bucket *b)
bch_inc_gen(ca, b);
b->prio = INITIAL_PRIO;
atomic_inc(&b->pin);
b->reclaimable_in_gc = 0;
}

static void bch_invalidate_one_bucket(struct cache *ca, struct bucket *b)
Expand Down Expand Up @@ -352,8 +350,7 @@ static int bch_allocator_thread(void *arg)
*/

retry_invalidate:
allocator_wait(ca, ca->set->gc_mark_valid &&
!ca->invalidate_needs_gc);
allocator_wait(ca, !ca->invalidate_needs_gc);
invalidate_buckets(ca);

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/md/bcache/bcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ struct bucket {
uint8_t gen;
uint8_t last_gc; /* Most out of date gen in the btree */
uint16_t gc_mark; /* Bitfield used by GC. See below for field */
uint16_t reclaimable_in_gc:1;
};

/*
Expand Down
7 changes: 6 additions & 1 deletion drivers/md/bcache/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1741,18 +1741,20 @@ static void btree_gc_start(struct cache_set *c)

mutex_lock(&c->bucket_lock);

c->gc_mark_valid = 0;
c->gc_done = ZERO_KEY;

ca = c->cache;
for_each_bucket(b, ca) {
b->last_gc = b->gen;
if (bch_can_invalidate_bucket(ca, b))
b->reclaimable_in_gc = 1;
if (!atomic_read(&b->pin)) {
SET_GC_MARK(b, 0);
SET_GC_SECTORS_USED(b, 0);
}
}

c->gc_mark_valid = 0;
mutex_unlock(&c->bucket_lock);
}

Expand Down Expand Up @@ -1809,6 +1811,9 @@ static void bch_btree_gc_finish(struct cache_set *c)
for_each_bucket(b, ca) {
c->need_gc = max(c->need_gc, bucket_gc_gen(b));

if (b->reclaimable_in_gc)
b->reclaimable_in_gc = 0;

if (atomic_read(&b->pin))
continue;

Expand Down

0 comments on commit a14a68b

Please sign in to comment.