diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2010-08-11 23:14:02 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2010-08-11 23:14:02 -0400 |
commit | b1d5552838334c600b068c9c8cc18638e5a8cb47 (patch) | |
tree | 789e435ab60e6956abffc15b4da85fe1e5b1714c /drivers | |
parent | 4a0b4ddf261fc89c050fe0a10ec57a61251d7ac0 (diff) |
dm snapshot: implement merge
Implement merge method for the snapshot origin to improve read
performance.
Without merge method, dm asks the upper layers to submit smallest possible
bios --- one page. Submitting such small bios impacts performance negatively
when reading or writing the origin device.
Without this patch, CPU consumption when reading the origin on lvm on md-raid0
was 6 to 12%, with this patch, it drops to 1 to 4%.
Note: in my testing, it actually degraded performance in some settings, I
traced it to Maxtor disks having problems with > 512-sector requests.
Reducing the number of sectors to /sys/block/sd*/queue/max_sectors_kb to
256 fixed the read performance. I think we don't have to care about weird
disks that actually degrade performance because of large requests being
sent to them.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/dm-snap.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index a1f2ab553b92..96feada5e761 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -2171,6 +2171,21 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result, | |||
2171 | return 0; | 2171 | return 0; |
2172 | } | 2172 | } |
2173 | 2173 | ||
2174 | static int origin_merge(struct dm_target *ti, struct bvec_merge_data *bvm, | ||
2175 | struct bio_vec *biovec, int max_size) | ||
2176 | { | ||
2177 | struct dm_dev *dev = ti->private; | ||
2178 | struct request_queue *q = bdev_get_queue(dev->bdev); | ||
2179 | |||
2180 | if (!q->merge_bvec_fn) | ||
2181 | return max_size; | ||
2182 | |||
2183 | bvm->bi_bdev = dev->bdev; | ||
2184 | bvm->bi_sector = bvm->bi_sector; | ||
2185 | |||
2186 | return min(max_size, q->merge_bvec_fn(q, bvm, biovec)); | ||
2187 | } | ||
2188 | |||
2174 | static int origin_iterate_devices(struct dm_target *ti, | 2189 | static int origin_iterate_devices(struct dm_target *ti, |
2175 | iterate_devices_callout_fn fn, void *data) | 2190 | iterate_devices_callout_fn fn, void *data) |
2176 | { | 2191 | { |
@@ -2188,6 +2203,7 @@ static struct target_type origin_target = { | |||
2188 | .map = origin_map, | 2203 | .map = origin_map, |
2189 | .resume = origin_resume, | 2204 | .resume = origin_resume, |
2190 | .status = origin_status, | 2205 | .status = origin_status, |
2206 | .merge = origin_merge, | ||
2191 | .iterate_devices = origin_iterate_devices, | 2207 | .iterate_devices = origin_iterate_devices, |
2192 | }; | 2208 | }; |
2193 | 2209 | ||