diff options
| author | Mike Snitzer <snitzer@redhat.com> | 2017-12-11 23:17:47 -0500 |
|---|---|---|
| committer | Mike Snitzer <snitzer@redhat.com> | 2017-12-16 20:43:13 -0500 |
| commit | 64f52b0e31489b46465cff2e61ab2e1f60a3b4eb (patch) | |
| tree | df8fa456e546efbff6aa8bf39157a18caf32047e /include/linux/device-mapper.h | |
| parent | 745dc570b2c379730d2a78acdeb65b5239e833c6 (diff) | |
dm: improve performance by moving dm_io structure to per-bio-data
Eliminates need for a separate mempool to allocate 'struct dm_io'
objects from. As such, it saves an extra mempool allocation for each
original bio that DM core is issued.
This complicates the per-bio-data accessor functions by needing to
conditonally add extra padding to get to a target's per-bio-data. But
in the end this provides a decent performance improvement for all
bio-based DM devices.
On an NVMe-loop based testbed to a ramdisk (~3100 MB/s): bio-based
DM linear performance improved by 2% (went from 2665 to 2777 MB/s).
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'include/linux/device-mapper.h')
| -rw-r--r-- | include/linux/device-mapper.h | 32 |
1 files changed, 3 insertions, 29 deletions
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 5a68b366e664..0e518d2ee280 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
| @@ -314,35 +314,9 @@ struct dm_target_callbacks { | |||
| 314 | int (*congested_fn) (struct dm_target_callbacks *, int); | 314 | int (*congested_fn) (struct dm_target_callbacks *, int); |
| 315 | }; | 315 | }; |
| 316 | 316 | ||
| 317 | /* | 317 | void *dm_per_bio_data(struct bio *bio, size_t data_size); |
| 318 | * For bio-based dm. | 318 | struct bio *dm_bio_from_per_bio_data(void *data, size_t data_size); |
| 319 | * One of these is allocated for each bio. | 319 | unsigned dm_bio_get_target_bio_nr(const struct bio *bio); |
| 320 | * This structure shouldn't be touched directly by target drivers. | ||
| 321 | * It is here so that we can inline dm_per_bio_data and | ||
| 322 | * dm_bio_from_per_bio_data | ||
| 323 | */ | ||
| 324 | struct dm_target_io { | ||
| 325 | struct dm_io *io; | ||
| 326 | struct dm_target *ti; | ||
| 327 | unsigned target_bio_nr; | ||
| 328 | unsigned *len_ptr; | ||
| 329 | struct bio clone; | ||
| 330 | }; | ||
| 331 | |||
| 332 | static inline void *dm_per_bio_data(struct bio *bio, size_t data_size) | ||
| 333 | { | ||
| 334 | return (char *)bio - offsetof(struct dm_target_io, clone) - data_size; | ||
| 335 | } | ||
| 336 | |||
| 337 | static inline struct bio *dm_bio_from_per_bio_data(void *data, size_t data_size) | ||
| 338 | { | ||
| 339 | return (struct bio *)((char *)data + data_size + offsetof(struct dm_target_io, clone)); | ||
| 340 | } | ||
| 341 | |||
| 342 | static inline unsigned dm_bio_get_target_bio_nr(const struct bio *bio) | ||
| 343 | { | ||
| 344 | return container_of(bio, struct dm_target_io, clone)->target_bio_nr; | ||
| 345 | } | ||
| 346 | 320 | ||
| 347 | int dm_register_target(struct target_type *t); | 321 | int dm_register_target(struct target_type *t); |
| 348 | void dm_unregister_target(struct target_type *t); | 322 | void dm_unregister_target(struct target_type *t); |
