Merge tag 'for-6.0/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper updates from Mike Snitzer: - Refactor DM core's mempool allocation so that it clearer by not being split acorss files. - Improve DM core's BLK_STS_DM_REQUEUE and BLK_STS_AGAIN handling. - Optimize DM core's more common bio splitting by eliminating the use of bio cloning with bio_split+bio_chain. Shift that cloning cost to the relatively unlikely dm_io requeue case that only occurs during error handling. Introduces dm_io_rewind() that will clone a bio that reflects the subset of the original bio that must be requeued. - Remove DM core's dm_table_get_num_targets() wrapper and audit all dm_table_get_target() callers. - Fix potential for OOM with DM writecache target by setting a default MAX_WRITEBACK_JOBS (set to 256MiB or 1/16 of total system memory, whichever is smaller). - Fix DM writecache target's stats that are reported through DM-specific table info. - Fix use-after-free crash in dm_sm_register_threshold_callback(). - Refine DM core's Persistent Reservation handling in preparation for broader work Mike Christie is doing to add compatibility with Microsoft Windows Failover Cluster. - Fix various KASAN reported bugs in the DM raid target. - Fix DM raid target crash due to md_handle_request() bio splitting that recurses to block core without properly initializing the bio's bi_dev. - Fix some code comment typos and fix some Documentation formatting. * tag 'for-6.0/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: (29 commits) dm: fix dm-raid crash if md_handle_request() splits bio dm raid: fix address sanitizer warning in raid_resume dm raid: fix address sanitizer warning in raid_status dm: Start pr_preempt from the same starting path dm: Fix PR release handling for non All Registrants dm: Start pr_reserve from the same starting path dm: Allow dm_call_pr to be used for path searches dm: return early from dm_pr_call() if DM device is suspended dm thin: fix use-after-free crash in dm_sm_register_threshold_callback dm writecache: count number of blocks discarded, not number of discard bios dm writecache: count number of blocks written, not number of write bios dm writecache: count number of blocks read, not number of read bios dm writecache: return void from functions dm kcopyd: use __GFP_HIGHMEM when allocating pages dm writecache: set a default MAX_WRITEBACK_JOBS Documentation: dm writecache: Render status list as list Documentation: dm writecache: add blank line before optional parameters dm snapshot: fix typo in snapshot_map() comment dm raid: remove redundant "the" in parse_raid_params() comment dm cache: fix typo in 2 comment blocks ...
This commit is contained in:
+25
-18
@@ -22,7 +22,7 @@
|
||||
|
||||
#define HIGH_WATERMARK 50
|
||||
#define LOW_WATERMARK 45
|
||||
#define MAX_WRITEBACK_JOBS 0
|
||||
#define MAX_WRITEBACK_JOBS min(0x10000000 / PAGE_SIZE, totalram_pages() / 16)
|
||||
#define ENDIO_LATENCY 16
|
||||
#define WRITEBACK_LATENCY 64
|
||||
#define AUTOCOMMIT_BLOCKS_SSD 65536
|
||||
@@ -1325,8 +1325,8 @@ enum wc_map_op {
|
||||
WC_MAP_ERROR,
|
||||
};
|
||||
|
||||
static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
|
||||
struct wc_entry *e)
|
||||
static void writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
|
||||
struct wc_entry *e)
|
||||
{
|
||||
if (e) {
|
||||
sector_t next_boundary =
|
||||
@@ -1334,8 +1334,6 @@ static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, stru
|
||||
if (next_boundary < bio->bi_iter.bi_size >> SECTOR_SHIFT)
|
||||
dm_accept_partial_bio(bio, next_boundary);
|
||||
}
|
||||
|
||||
return WC_MAP_REMAP_ORIGIN;
|
||||
}
|
||||
|
||||
static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *bio)
|
||||
@@ -1362,14 +1360,16 @@ read_next_block:
|
||||
map_op = WC_MAP_REMAP;
|
||||
}
|
||||
} else {
|
||||
map_op = writecache_map_remap_origin(wc, bio, e);
|
||||
writecache_map_remap_origin(wc, bio, e);
|
||||
wc->stats.reads += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits;
|
||||
map_op = WC_MAP_REMAP_ORIGIN;
|
||||
}
|
||||
|
||||
return map_op;
|
||||
}
|
||||
|
||||
static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
|
||||
struct wc_entry *e, bool search_used)
|
||||
static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
|
||||
struct wc_entry *e, bool search_used)
|
||||
{
|
||||
unsigned bio_size = wc->block_size;
|
||||
sector_t start_cache_sec = cache_sector(wc, e);
|
||||
@@ -1409,14 +1409,15 @@ static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct b
|
||||
bio->bi_iter.bi_sector = start_cache_sec;
|
||||
dm_accept_partial_bio(bio, bio_size >> SECTOR_SHIFT);
|
||||
|
||||
wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
|
||||
wc->stats.writes_allocate += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits;
|
||||
|
||||
if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) {
|
||||
wc->uncommitted_blocks = 0;
|
||||
queue_work(wc->writeback_wq, &wc->flush_work);
|
||||
} else {
|
||||
writecache_schedule_autocommit(wc);
|
||||
}
|
||||
|
||||
return WC_MAP_REMAP;
|
||||
}
|
||||
|
||||
static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio *bio)
|
||||
@@ -1426,9 +1427,10 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
|
||||
do {
|
||||
bool found_entry = false;
|
||||
bool search_used = false;
|
||||
wc->stats.writes++;
|
||||
if (writecache_has_error(wc))
|
||||
if (writecache_has_error(wc)) {
|
||||
wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
|
||||
return WC_MAP_ERROR;
|
||||
}
|
||||
e = writecache_find_entry(wc, bio->bi_iter.bi_sector, 0);
|
||||
if (e) {
|
||||
if (!writecache_entry_is_committed(wc, e)) {
|
||||
@@ -1452,9 +1454,11 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
|
||||
if (unlikely(!e)) {
|
||||
if (!WC_MODE_PMEM(wc) && !found_entry) {
|
||||
direct_write:
|
||||
wc->stats.writes_around++;
|
||||
e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
|
||||
return writecache_map_remap_origin(wc, bio, e);
|
||||
writecache_map_remap_origin(wc, bio, e);
|
||||
wc->stats.writes_around += bio->bi_iter.bi_size >> wc->block_size_bits;
|
||||
wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
|
||||
return WC_MAP_REMAP_ORIGIN;
|
||||
}
|
||||
wc->stats.writes_blocked_on_freelist++;
|
||||
writecache_wait_on_freelist(wc);
|
||||
@@ -1465,10 +1469,13 @@ direct_write:
|
||||
wc->uncommitted_blocks++;
|
||||
wc->stats.writes_allocate++;
|
||||
bio_copy:
|
||||
if (WC_MODE_PMEM(wc))
|
||||
if (WC_MODE_PMEM(wc)) {
|
||||
bio_copy_block(wc, bio, memory_data(wc, e));
|
||||
else
|
||||
return writecache_bio_copy_ssd(wc, bio, e, search_used);
|
||||
wc->stats.writes++;
|
||||
} else {
|
||||
writecache_bio_copy_ssd(wc, bio, e, search_used);
|
||||
return WC_MAP_REMAP;
|
||||
}
|
||||
} while (bio->bi_iter.bi_size);
|
||||
|
||||
if (unlikely(bio->bi_opf & REQ_FUA || wc->uncommitted_blocks >= wc->autocommit_blocks))
|
||||
@@ -1503,7 +1510,7 @@ static enum wc_map_op writecache_map_flush(struct dm_writecache *wc, struct bio
|
||||
|
||||
static enum wc_map_op writecache_map_discard(struct dm_writecache *wc, struct bio *bio)
|
||||
{
|
||||
wc->stats.discards++;
|
||||
wc->stats.discards += bio->bi_iter.bi_size >> wc->block_size_bits;
|
||||
|
||||
if (writecache_has_error(wc))
|
||||
return WC_MAP_ERROR;
|
||||
|
||||
Reference in New Issue
Block a user