diff --git a/Documentation/admin-guide/bcache.rst b/Documentation/admin-guide/bcache.rst index 8d3a2d045c0ae7c2fa541588435630399c99d904..c75aebf5821afbaa80bb9b5ab0940131a26fa53c 100644 --- a/Documentation/admin-guide/bcache.rst +++ b/Documentation/admin-guide/bcache.rst @@ -441,6 +441,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 e8bf4f752e8beebcad27756fb533b7550ba53686..8b10bd5df364a88c00e8b13210a068db5139ad36 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -376,6 +376,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 5a64afd56b971a8fc210122d74c29416391207b4..2e9ff76b877b0416779344f7cbfbbdfab024d560 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|REQ_PRIO) ) && 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 a849fc51cd8843e02d78d4a54e75a292ee3d72f7..e96174ca10d1e13e978934a9d33f1e0403089a78 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1439,6 +1439,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 554e3afc9b688be1b3415d7fb1fdf407f5c192b0..39c1e7a544e54c0d37b8fb32ae50062c35a7cb9a 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -108,6 +108,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); @@ -252,6 +253,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)); @@ -346,6 +348,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) @@ -511,6 +516,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,