mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-25 21:35:39 +07:00
9aaf516546
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>
115 lines
2.9 KiB
C
115 lines
2.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _BCACHE_WRITEBACK_H
|
|
#define _BCACHE_WRITEBACK_H
|
|
|
|
#define CUTOFF_WRITEBACK 40
|
|
#define CUTOFF_WRITEBACK_SYNC 70
|
|
|
|
#define CUTOFF_WRITEBACK_MAX 70
|
|
#define CUTOFF_WRITEBACK_SYNC_MAX 90
|
|
|
|
#define MAX_WRITEBACKS_IN_PASS 5
|
|
#define MAX_WRITESIZE_IN_PASS 5000 /* *512b */
|
|
|
|
#define WRITEBACK_RATE_UPDATE_SECS_MAX 60
|
|
#define WRITEBACK_RATE_UPDATE_SECS_DEFAULT 5
|
|
|
|
#define BCH_AUTO_GC_DIRTY_THRESHOLD 50
|
|
|
|
/*
|
|
* 14 (16384ths) is chosen here as something that each backing device
|
|
* should be a reasonable fraction of the share, and not to blow up
|
|
* until individual backing devices are a petabyte.
|
|
*/
|
|
#define WRITEBACK_SHARE_SHIFT 14
|
|
|
|
static inline uint64_t bcache_dev_sectors_dirty(struct bcache_device *d)
|
|
{
|
|
uint64_t i, ret = 0;
|
|
|
|
for (i = 0; i < d->nr_stripes; i++)
|
|
ret += atomic_read(d->stripe_sectors_dirty + i);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static inline unsigned int offset_to_stripe(struct bcache_device *d,
|
|
uint64_t offset)
|
|
{
|
|
do_div(offset, d->stripe_size);
|
|
return offset;
|
|
}
|
|
|
|
static inline bool bcache_dev_stripe_dirty(struct cached_dev *dc,
|
|
uint64_t offset,
|
|
unsigned int nr_sectors)
|
|
{
|
|
unsigned int stripe = offset_to_stripe(&dc->disk, offset);
|
|
|
|
while (1) {
|
|
if (atomic_read(dc->disk.stripe_sectors_dirty + stripe))
|
|
return true;
|
|
|
|
if (nr_sectors <= dc->disk.stripe_size)
|
|
return false;
|
|
|
|
nr_sectors -= dc->disk.stripe_size;
|
|
stripe++;
|
|
}
|
|
}
|
|
|
|
extern unsigned int bch_cutoff_writeback;
|
|
extern unsigned int bch_cutoff_writeback_sync;
|
|
|
|
static inline bool should_writeback(struct cached_dev *dc, struct bio *bio,
|
|
unsigned int cache_mode, bool would_skip)
|
|
{
|
|
unsigned int in_use = dc->disk.c->gc_stats.in_use;
|
|
|
|
if (cache_mode != CACHE_MODE_WRITEBACK ||
|
|
test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) ||
|
|
in_use > bch_cutoff_writeback_sync)
|
|
return false;
|
|
|
|
if (dc->partial_stripes_expensive &&
|
|
bcache_dev_stripe_dirty(dc, bio->bi_iter.bi_sector,
|
|
bio_sectors(bio)))
|
|
return true;
|
|
|
|
if (would_skip)
|
|
return false;
|
|
|
|
return (op_is_sync(bio->bi_opf) ||
|
|
bio->bi_opf & (REQ_META|REQ_PRIO) ||
|
|
in_use <= bch_cutoff_writeback);
|
|
}
|
|
|
|
static inline void bch_writeback_queue(struct cached_dev *dc)
|
|
{
|
|
if (!IS_ERR_OR_NULL(dc->writeback_thread))
|
|
wake_up_process(dc->writeback_thread);
|
|
}
|
|
|
|
static inline void bch_writeback_add(struct cached_dev *dc)
|
|
{
|
|
if (!atomic_read(&dc->has_dirty) &&
|
|
!atomic_xchg(&dc->has_dirty, 1)) {
|
|
if (BDEV_STATE(&dc->sb) != BDEV_STATE_DIRTY) {
|
|
SET_BDEV_STATE(&dc->sb, BDEV_STATE_DIRTY);
|
|
/* XXX: should do this synchronously */
|
|
bch_write_bdev_super(dc, NULL);
|
|
}
|
|
|
|
bch_writeback_queue(dc);
|
|
}
|
|
}
|
|
|
|
void bcache_dev_sectors_dirty_add(struct cache_set *c, unsigned int inode,
|
|
uint64_t offset, int nr_sectors);
|
|
|
|
void bch_sectors_dirty_init(struct bcache_device *d);
|
|
void bch_cached_dev_writeback_init(struct cached_dev *dc);
|
|
int bch_cached_dev_writeback_start(struct cached_dev *dc);
|
|
|
|
#endif
|