diff --git a/Documentation/admin-guide/bcache.rst b/Documentation/admin-guide/bcache.rst index c0ce64d75bbf7cfe02fa0a99af136f3ae02ba60c..44ae47ea5f43a5c2cefc6bd11dbe087528896636 100644 --- a/Documentation/admin-guide/bcache.rst +++ b/Documentation/admin-guide/bcache.rst @@ -434,6 +434,10 @@ sequential_cutoff most recent 128 IOs are tracked so sequential IO can be detected even when it isn't all done at once. +read_bypass + If enbale, all IO will bypass the cache. This option could be useful when we + enable userspace prefetch and the cache device is low capacity. + sequential_merge If non zero, bcache keeps a list of the last 128 requests submitted to compare against all new requests to determine which new requests are sequential diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index 8a65a859bc488eae2a13e539ded91bed4c66ab31..f2bb640b740f07a2b8a91a068011e30893cb75c7 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -379,6 +379,8 @@ struct cached_dev { unsigned char writeback_percent; unsigned int writeback_delay; + unsigned int read_bypass; + uint64_t writeback_rate_target; int64_t writeback_rate_proportional; int64_t writeback_rate_integral; diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 55588d13255d3ef189af6eff779b92927792f512..800a7ba00fbecefab51d0ce47ee32e50fe7de0a9 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -852,7 +852,7 @@ static void cached_dev_read_done(struct closure *cl) if (!s->prefetch) bio_complete(s); - if (s->iop.bio && + if (s->iop.bio && (!dc->read_bypass || s->prefetch) && !test_bit(CACHE_SET_STOPPING, &s->iop.c->flags)) { BUG_ON(!s->iop.replace); closure_call(&s->iop.cl, bch_data_insert, NULL, cl); @@ -897,12 +897,14 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s, s->cache_missed = 1; - if (s->cache_miss || s->iop.bypass) { + if (s->cache_miss || s->iop.bypass || + (dc->read_bypass && !s->prefetch)) { miss = bio_next_split(bio, sectors, GFP_NOIO, &s->d->bio_split); ret = miss == bio ? MAP_DONE : MAP_CONTINUE; goto out_submit; } + /* if called form do_readahead, no need to do this */ if (!(bio->bi_opf & REQ_RAHEAD) && !(bio->bi_opf & REQ_META) && s->iop.c->gc_stats.in_use < CUTOFF_CACHE_READA && diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index b272f0c1ff3b82c3209821dbfc4a7b55a29abf1f..169e6ad4f16a0e3b1111127a504985f5d27cdd16 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1321,6 +1321,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size) bch_cache_accounting_init(&dc->accounting, &dc->disk.cl); dc->sequential_cutoff = 4 << 20; + dc->read_bypass = 0; for (io = dc->io; io < dc->io + RECENT_IO; io++) { list_add(&io->lru, &dc->io_lru); diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 3470fae4eabc1bfd268064d4902ac5e4ee4f13ed..4adc22b112872dd1c6e227ac2a21a3807d30bb12 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -104,6 +104,7 @@ rw_attribute(congested_read_threshold_us); rw_attribute(congested_write_threshold_us); rw_attribute(sequential_cutoff); +rw_attribute(read_bypass); rw_attribute(data_csum); rw_attribute(cache_mode); rw_attribute(readahead_cache_policy); @@ -248,6 +249,7 @@ SHOW(__bch_cached_dev) var_printf(partial_stripes_expensive, "%u"); var_hprint(sequential_cutoff); + var_print(read_bypass); var_hprint(readahead); sysfs_print(running, atomic_read(&dc->running)); @@ -342,6 +344,9 @@ STORE(__cached_dev) sysfs_strtoul_clamp(sequential_cutoff, dc->sequential_cutoff, 0, UINT_MAX); + sysfs_strtoul_clamp(read_bypass, + dc->read_bypass, + 0, 1); d_strtoi_h(readahead); if (attr == &sysfs_clear_stats) @@ -507,6 +512,7 @@ static struct attribute *bch_cached_dev_files[] = { &sysfs_stripe_size, &sysfs_partial_stripes_expensive, &sysfs_sequential_cutoff, + &sysfs_read_bypass, &sysfs_clear_stats, &sysfs_running, &sysfs_state,