Skip to content

Commit 7e28407

Browse files
committed
Merge tag 'for-5.19/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper updates from Mike Snitzer: - Enable DM core bioset's per-cpu bio cache if QUEUE_FLAG_POLL set. This change improves DM's hipri bio polling (REQ_POLLED) performance by 7 - 20% depending on the system. - Update DM core to use jump_labels to further reduce cost of unlikely branches for zoned block devices, dm-stats and swap_bios throttling. - Various DM core changes to reduce bio-based DM overhead and simplify IO accounting. - Fundamental DM core improvements to dm_io reference counting and the elimination of using bio_split()+bio_chain() -- instead DM's bio-based IO accounting is updated to account that a split occurred. - Improve DM core's abnormal bio processing to do less work. - Improve DM core's hipri polling support to use a single list rather than an hlist. - Update DM core to pass NULL bdev to bio_alloc_clone() so that initialization that isn't useful for DM can be elided. - Add cond_resched to DM stats' various loops that loop over all entries. - Fix incorrect error code return from DM integrity's constructor. - Make DM crypt's printing of the key constant-time. - Update bio-based DM multipath to provide high-resolution timer to the Historical Service Time (HST) path selector. * tag 'for-5.19/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: (26 commits) dm: pass NULL bdev to bio_alloc_clone dm cache metadata: remove unnecessary variable in __dump_mapping dm mpath: provide high-resolution timer to HST for bio-based dm crypt: make printing of the key constant-time dm integrity: fix error code in dm_integrity_ctr() dm stats: add cond_resched when looping over entries dm: improve abnormal bio processing dm: simplify bio-based IO accounting further dm: put all polled dm_io instances into a single list dm: improve dm_io reference counting dm: don't grab target io reference in dm_zone_map_bio dm: improve bio splitting and associated IO accounting dm: switch to bdev based IO accounting interfaces dm: pass dm_io instance to dm_io_acct directly dm: don't pass bio to __dm_start_io_acct and dm_end_io_acct dm: use bio_sectors in dm_aceept_partial_bio dm: simplify basic targets dm: conditionally enable branching for less used features dm: introduce dm_{get,put}_live_table_bio called from dm_submit_bio dm: move hot dm_io members to same cacheline as dm_target_io ...
2 parents 780d8ce + ca52248 commit 7e28407

15 files changed

+409
-287
lines changed

drivers/md/dm-cache-metadata.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,15 +1509,14 @@ int dm_cache_load_mappings(struct dm_cache_metadata *cmd,
15091509

15101510
static int __dump_mapping(void *context, uint64_t cblock, void *leaf)
15111511
{
1512-
int r = 0;
15131512
__le64 value;
15141513
dm_oblock_t oblock;
15151514
unsigned flags;
15161515

15171516
memcpy(&value, leaf, sizeof(value));
15181517
unpack_value(value, &oblock, &flags);
15191518

1520-
return r;
1519+
return 0;
15211520
}
15221521

15231522
static int __dump_mappings(struct dm_cache_metadata *cmd)

drivers/md/dm-core.h

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/ktime.h>
1414
#include <linux/blk-mq.h>
1515
#include <linux/blk-crypto-profile.h>
16+
#include <linux/jump_label.h>
1617

1718
#include <trace/events/block.h>
1819

@@ -154,6 +155,10 @@ static inline struct dm_stats *dm_get_stats(struct mapped_device *md)
154155
return &md->stats;
155156
}
156157

158+
DECLARE_STATIC_KEY_FALSE(stats_enabled);
159+
DECLARE_STATIC_KEY_FALSE(swap_bios_enabled);
160+
DECLARE_STATIC_KEY_FALSE(zoned_enabled);
161+
157162
static inline bool dm_emulate_zone_append(struct mapped_device *md)
158163
{
159164
if (blk_queue_is_zoned(md->queue))
@@ -237,6 +242,12 @@ static inline void dm_tio_set_flag(struct dm_target_io *tio, unsigned int bit)
237242
tio->flags |= (1U << bit);
238243
}
239244

245+
static inline bool dm_tio_is_normal(struct dm_target_io *tio)
246+
{
247+
return (dm_tio_flagged(tio, DM_TIO_INSIDE_DM_IO) &&
248+
!dm_tio_flagged(tio, DM_TIO_IS_DUPLICATE_BIO));
249+
}
250+
240251
/*
241252
* One of these is allocated per original bio.
242253
* It contains the first clone used for that original.
@@ -245,16 +256,20 @@ static inline void dm_tio_set_flag(struct dm_target_io *tio, unsigned int bit)
245256
struct dm_io {
246257
unsigned short magic;
247258
blk_short_t flags;
248-
atomic_t io_count;
249-
struct mapped_device *md;
250-
struct bio *orig_bio;
251-
blk_status_t status;
252259
spinlock_t lock;
253260
unsigned long start_time;
254261
void *data;
255-
struct hlist_node node;
256-
struct task_struct *map_task;
262+
struct dm_io *next;
257263
struct dm_stats_aux stats_aux;
264+
blk_status_t status;
265+
atomic_t io_count;
266+
struct mapped_device *md;
267+
268+
/* The three fields represent mapped part of original bio */
269+
struct bio *orig_bio;
270+
unsigned int sector_offset; /* offset to end of orig_bio */
271+
unsigned int sectors;
272+
258273
/* last member of dm_target_io is 'struct bio' */
259274
struct dm_target_io tio;
260275
};
@@ -263,8 +278,8 @@ struct dm_io {
263278
* dm_io flags
264279
*/
265280
enum {
266-
DM_IO_START_ACCT,
267-
DM_IO_ACCOUNTED
281+
DM_IO_ACCOUNTED,
282+
DM_IO_WAS_SPLIT
268283
};
269284

270285
static inline bool dm_io_flagged(struct dm_io *io, unsigned int bit)
@@ -277,13 +292,6 @@ static inline void dm_io_set_flag(struct dm_io *io, unsigned int bit)
277292
io->flags |= (1U << bit);
278293
}
279294

280-
static inline void dm_io_inc_pending(struct dm_io *io)
281-
{
282-
atomic_inc(&io->io_count);
283-
}
284-
285-
void dm_io_dec_pending(struct dm_io *io, blk_status_t error);
286-
287295
static inline struct completion *dm_get_completion_from_kobject(struct kobject *kobj)
288296
{
289297
return &container_of(kobj, struct dm_kobject_holder, kobj)->completion;

drivers/md/dm-crypt.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3439,6 +3439,11 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
34393439
return DM_MAPIO_SUBMITTED;
34403440
}
34413441

3442+
static char hex2asc(unsigned char c)
3443+
{
3444+
return c + '0' + ((unsigned)(9 - c) >> 4 & 0x27);
3445+
}
3446+
34423447
static void crypt_status(struct dm_target *ti, status_type_t type,
34433448
unsigned status_flags, char *result, unsigned maxlen)
34443449
{
@@ -3457,9 +3462,12 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
34573462
if (cc->key_size > 0) {
34583463
if (cc->key_string)
34593464
DMEMIT(":%u:%s", cc->key_size, cc->key_string);
3460-
else
3461-
for (i = 0; i < cc->key_size; i++)
3462-
DMEMIT("%02x", cc->key[i]);
3465+
else {
3466+
for (i = 0; i < cc->key_size; i++) {
3467+
DMEMIT("%c%c", hex2asc(cc->key[i] >> 4),
3468+
hex2asc(cc->key[i] & 0xf));
3469+
}
3470+
}
34633471
} else
34643472
DMEMIT("-");
34653473

drivers/md/dm-delay.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,7 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
296296
}
297297
delayed->class = c;
298298
bio_set_dev(bio, c->dev->bdev);
299-
if (bio_sectors(bio))
300-
bio->bi_iter.bi_sector = c->start + dm_target_offset(ti, bio->bi_iter.bi_sector);
299+
bio->bi_iter.bi_sector = c->start + dm_target_offset(ti, bio->bi_iter.bi_sector);
301300

302301
return delay_bio(dc, c, bio);
303302
}

drivers/md/dm-flakey.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,7 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
280280
struct flakey_c *fc = ti->private;
281281

282282
bio_set_dev(bio, fc->dev->bdev);
283-
if (bio_sectors(bio) || op_is_zone_mgmt(bio_op(bio)))
284-
bio->bi_iter.bi_sector =
285-
flakey_map_sector(ti, bio->bi_iter.bi_sector);
283+
bio->bi_iter.bi_sector = flakey_map_sector(ti, bio->bi_iter.bi_sector);
286284
}
287285

288286
static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)

drivers/md/dm-integrity.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4494,8 +4494,6 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
44944494
}
44954495

44964496
if (should_write_sb) {
4497-
int r;
4498-
44994497
init_journal(ic, 0, ic->journal_sections, 0);
45004498
r = dm_integrity_failed(ic);
45014499
if (unlikely(r)) {

drivers/md/dm-linear.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,12 @@ static sector_t linear_map_sector(struct dm_target *ti, sector_t bi_sector)
8484
return lc->start + dm_target_offset(ti, bi_sector);
8585
}
8686

87-
static void linear_map_bio(struct dm_target *ti, struct bio *bio)
87+
static int linear_map(struct dm_target *ti, struct bio *bio)
8888
{
8989
struct linear_c *lc = ti->private;
9090

9191
bio_set_dev(bio, lc->dev->bdev);
92-
if (bio_sectors(bio) || op_is_zone_mgmt(bio_op(bio)))
93-
bio->bi_iter.bi_sector =
94-
linear_map_sector(ti, bio->bi_iter.bi_sector);
95-
}
96-
97-
static int linear_map(struct dm_target *ti, struct bio *bio)
98-
{
99-
linear_map_bio(ti, bio);
92+
bio->bi_iter.bi_sector = linear_map_sector(ti, bio->bi_iter.bi_sector);
10093

10194
return DM_MAPIO_REMAPPED;
10295
}

drivers/md/dm-mpath.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ struct multipath {
105105
struct dm_mpath_io {
106106
struct pgpath *pgpath;
107107
size_t nr_bytes;
108+
u64 start_time_ns;
108109
};
109110

110111
typedef int (*action_fn) (struct pgpath *pgpath);
@@ -295,6 +296,7 @@ static void multipath_init_per_bio_data(struct bio *bio, struct dm_mpath_io **mp
295296

296297
mpio->nr_bytes = bio->bi_iter.bi_size;
297298
mpio->pgpath = NULL;
299+
mpio->start_time_ns = 0;
298300
*mpio_p = mpio;
299301

300302
dm_bio_record(bio_details, bio);
@@ -647,6 +649,9 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio,
647649

648650
mpio->pgpath = pgpath;
649651

652+
if (dm_ps_use_hr_timer(pgpath->pg->ps.type))
653+
mpio->start_time_ns = ktime_get_ns();
654+
650655
bio->bi_status = 0;
651656
bio_set_dev(bio, pgpath->path.dev->bdev);
652657
bio->bi_opf |= REQ_FAILFAST_TRANSPORT;
@@ -1713,7 +1718,8 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone,
17131718

17141719
if (ps->type->end_io)
17151720
ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes,
1716-
dm_start_time_ns_from_clone(clone));
1721+
(mpio->start_time_ns ?:
1722+
dm_start_time_ns_from_clone(clone)));
17171723
}
17181724

17191725
return r;

drivers/md/dm-path-selector.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,26 @@ struct path_selector {
2626
void *context;
2727
};
2828

29+
/*
30+
* If a path selector uses this flag, a high resolution timer is used
31+
* (via ktime_get_ns) to account for IO start time in BIO-based mpath.
32+
* This improves performance of some path selectors (i.e. HST), in
33+
* exchange for slightly higher overhead when submitting the BIO.
34+
* The extra cost is usually offset by improved path selection for
35+
* some benchmarks.
36+
*
37+
* This has no effect for request-based mpath, since it already uses a
38+
* higher precision timer by default.
39+
*/
40+
#define DM_PS_USE_HR_TIMER 0x00000001
41+
#define dm_ps_use_hr_timer(type) ((type)->features & DM_PS_USE_HR_TIMER)
42+
2943
/* Information about a path selector type */
3044
struct path_selector_type {
3145
char *name;
3246
struct module *module;
3347

48+
unsigned int features;
3449
unsigned int table_args;
3550
unsigned int info_args;
3651

drivers/md/dm-ps-historical-service-time.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ static int hst_end_io(struct path_selector *ps, struct dm_path *path,
523523
static struct path_selector_type hst_ps = {
524524
.name = "historical-service-time",
525525
.module = THIS_MODULE,
526+
.features = DM_PS_USE_HR_TIMER,
526527
.table_args = 1,
527528
.info_args = 3,
528529
.create = hst_create,

0 commit comments

Comments
 (0)