Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcache: make cutoff_writeback and cutoff_writeback_sync tunable

Currently the cutoff writeback and cutoff writeback sync thresholds are
defined by CUTOFF_WRITEBACK (40) and CUTOFF_WRITEBACK_SYNC (70) as
static values. Most of time these they work fine, but when people want
to do research on bcache writeback mode performance tuning, there is no
chance to modify the soft and hard cutoff writeback values.

This patch introduces two module parameters bch_cutoff_writeback_sync
and bch_cutoff_writeback which permit people to tune the values when
loading bcache.ko. If they are not specified by module loading, current
values CUTOFF_WRITEBACK_SYNC and CUTOFF_WRITEBACK will be used as
default and nothing changes.

When people want to tune this two values,
- cutoff_writeback can be set in range [1, 70]
- cutoff_writeback_sync can be set in range [1, 90]
- cutoff_writeback always <= cutoff_writeback_sync

The default values are strongly recommended to most of users for most of
workloads. Anyway, if people wants to take their own risk to do research
on new writeback cutoff tuning for their own workload, now they can make
it.

Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Coly Li and committed by
Jens Axboe
9aaf5165 009673d0

+55 -2
+40
drivers/md/bcache/super.c
··· 25 25 #include <linux/reboot.h> 26 26 #include <linux/sysfs.h> 27 27 28 + unsigned int bch_cutoff_writeback; 29 + unsigned int bch_cutoff_writeback_sync; 30 + 28 31 static const char bcache_magic[] = { 29 32 0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca, 30 33 0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 ··· 2423 2420 mutex_destroy(&bch_register_lock); 2424 2421 } 2425 2422 2423 + /* Check and fixup module parameters */ 2424 + static void check_module_parameters(void) 2425 + { 2426 + if (bch_cutoff_writeback_sync == 0) 2427 + bch_cutoff_writeback_sync = CUTOFF_WRITEBACK_SYNC; 2428 + else if (bch_cutoff_writeback_sync > CUTOFF_WRITEBACK_SYNC_MAX) { 2429 + pr_warn("set bch_cutoff_writeback_sync (%u) to max value %u", 2430 + bch_cutoff_writeback_sync, CUTOFF_WRITEBACK_SYNC_MAX); 2431 + bch_cutoff_writeback_sync = CUTOFF_WRITEBACK_SYNC_MAX; 2432 + } 2433 + 2434 + if (bch_cutoff_writeback == 0) 2435 + bch_cutoff_writeback = CUTOFF_WRITEBACK; 2436 + else if (bch_cutoff_writeback > CUTOFF_WRITEBACK_MAX) { 2437 + pr_warn("set bch_cutoff_writeback (%u) to max value %u", 2438 + bch_cutoff_writeback, CUTOFF_WRITEBACK_MAX); 2439 + bch_cutoff_writeback = CUTOFF_WRITEBACK_MAX; 2440 + } 2441 + 2442 + if (bch_cutoff_writeback > bch_cutoff_writeback_sync) { 2443 + pr_warn("set bch_cutoff_writeback (%u) to %u", 2444 + bch_cutoff_writeback, bch_cutoff_writeback_sync); 2445 + bch_cutoff_writeback = bch_cutoff_writeback_sync; 2446 + } 2447 + } 2448 + 2426 2449 static int __init bcache_init(void) 2427 2450 { 2428 2451 static const struct attribute *files[] = { ··· 2456 2427 &ksysfs_register_quiet.attr, 2457 2428 NULL 2458 2429 }; 2430 + 2431 + check_module_parameters(); 2459 2432 2460 2433 mutex_init(&bch_register_lock); 2461 2434 init_waitqueue_head(&unregister_wait); ··· 2495 2464 return -ENOMEM; 2496 2465 } 2497 2466 2467 + /* 2468 + * Module hooks 2469 + */ 2498 2470 module_exit(bcache_exit); 2499 2471 module_init(bcache_init); 2472 + 2473 + module_param(bch_cutoff_writeback, uint, 0); 2474 + MODULE_PARM_DESC(bch_cutoff_writeback, "threshold to cutoff writeback"); 2475 + 2476 + module_param(bch_cutoff_writeback_sync, uint, 0); 2477 + MODULE_PARM_DESC(bch_cutoff_writeback_sync, "hard threshold to cutoff writeback"); 2500 2478 2501 2479 MODULE_DESCRIPTION("Bcache: a Linux block layer cache"); 2502 2480 MODULE_AUTHOR("Kent Overstreet <kent.overstreet@gmail.com>");
+7
drivers/md/bcache/sysfs.c
··· 88 88 read_attribute(writeback_keys_failed); 89 89 read_attribute(io_errors); 90 90 read_attribute(congested); 91 + read_attribute(cutoff_writeback); 92 + read_attribute(cutoff_writeback_sync); 91 93 rw_attribute(congested_read_threshold_us); 92 94 rw_attribute(congested_write_threshold_us); 93 95 ··· 688 686 sysfs_print(congested_write_threshold_us, 689 687 c->congested_write_threshold_us); 690 688 689 + sysfs_print(cutoff_writeback, bch_cutoff_writeback); 690 + sysfs_print(cutoff_writeback_sync, bch_cutoff_writeback_sync); 691 + 691 692 sysfs_print(active_journal_entries, fifo_used(&c->journal.pin)); 692 693 sysfs_printf(verify, "%i", c->verify); 693 694 sysfs_printf(key_merging_disabled, "%i", c->key_merging_disabled); ··· 888 883 &sysfs_copy_gc_enabled, 889 884 &sysfs_gc_after_writeback, 890 885 &sysfs_io_disable, 886 + &sysfs_cutoff_writeback, 887 + &sysfs_cutoff_writeback_sync, 891 888 NULL 892 889 }; 893 890 KTYPE(bch_cache_set_internal);
+8 -2
drivers/md/bcache/writeback.h
··· 5 5 #define CUTOFF_WRITEBACK 40 6 6 #define CUTOFF_WRITEBACK_SYNC 70 7 7 8 + #define CUTOFF_WRITEBACK_MAX 70 9 + #define CUTOFF_WRITEBACK_SYNC_MAX 90 10 + 8 11 #define MAX_WRITEBACKS_IN_PASS 5 9 12 #define MAX_WRITESIZE_IN_PASS 5000 /* *512b */ 10 13 ··· 58 55 } 59 56 } 60 57 58 + extern unsigned int bch_cutoff_writeback; 59 + extern unsigned int bch_cutoff_writeback_sync; 60 + 61 61 static inline bool should_writeback(struct cached_dev *dc, struct bio *bio, 62 62 unsigned int cache_mode, bool would_skip) 63 63 { ··· 68 62 69 63 if (cache_mode != CACHE_MODE_WRITEBACK || 70 64 test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) || 71 - in_use > CUTOFF_WRITEBACK_SYNC) 65 + in_use > bch_cutoff_writeback_sync) 72 66 return false; 73 67 74 68 if (dc->partial_stripes_expensive && ··· 81 75 82 76 return (op_is_sync(bio->bi_opf) || 83 77 bio->bi_opf & (REQ_META|REQ_PRIO) || 84 - in_use <= CUTOFF_WRITEBACK); 78 + in_use <= bch_cutoff_writeback); 85 79 } 86 80 87 81 static inline void bch_writeback_queue(struct cached_dev *dc)