Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 0535693

Browse files
Coly Liaxboe
authored andcommitted
bcache: call force_wake_up_gc() if necessary in check_should_bypass()
If there are extreme heavy write I/O continuously hit on relative small cache device (512GB in my testing), it is possible to make counter c->gc_stats.in_use continue to increase and exceed CUTOFF_CACHE_ADD. If 'c->gc_stats.in_use > CUTOFF_CACHE_ADD' happens, all following write requests will bypass the cache device because check_should_bypass() returns 'true'. Because all writes bypass the cache device, counter c->sectors_to_gc has no chance to be negative value, and garbage collection thread won't be waken up even the whole cache becomes clean after writeback accomplished. The aftermath is that all write I/Os go directly into backing device even the cache device is clean. To avoid the above situation, this patch uses a quite conservative way to fix: if 'c->gc_stats.in_use > CUTOFF_CACHE_ADD' happens, only wakes up garbage collection thread when the whole cache device is clean. Before the fix, the writes-always-bypass situation happens after 10+ hours write I/O pressure on 512GB Intel optane memory which acts as cache device. After this fix, such situation doesn't happen after 36+ hours testing. Signed-off-by: Coly Li <colyli@suse.de> Link: https://lore.kernel.org/r/20240528120914.28705-3-colyli@suse.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent a14a68b commit 0535693

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

drivers/md/bcache/request.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,24 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
369369
struct io *i;
370370

371371
if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) ||
372-
c->gc_stats.in_use > CUTOFF_CACHE_ADD ||
373372
(bio_op(bio) == REQ_OP_DISCARD))
374373
goto skip;
375374

375+
if (c->gc_stats.in_use > CUTOFF_CACHE_ADD) {
376+
/*
377+
* If cached buckets are all clean now, 'true' will be
378+
* returned and all requests will bypass the cache device.
379+
* Then c->sectors_to_gc has no chance to be negative, and
380+
* gc thread won't wake up and caching won't work forever.
381+
* Here call force_wake_up_gc() to avoid such aftermath.
382+
*/
383+
if (BDEV_STATE(&dc->sb) == BDEV_STATE_CLEAN &&
384+
c->gc_mark_valid)
385+
force_wake_up_gc(c);
386+
387+
goto skip;
388+
}
389+
376390
if (mode == CACHE_MODE_NONE ||
377391
(mode == CACHE_MODE_WRITEAROUND &&
378392
op_is_write(bio_op(bio))))

0 commit comments

Comments
 (0)