[kernel] r16611 - in dists/lenny/linux-2.6/debian: . patches/bugfix/all patches/series
Ben Hutchings
benh at alioth.debian.org
Mon Nov 29 02:03:58 UTC 2010
Author: benh
Date: Mon Nov 29 02:03:51 2010
New Revision: 16611
Log:
dm,md: Deal with merge_bvec_fn in component devices better (Closes: #604457)
Added:
dists/lenny/linux-2.6/debian/patches/bugfix/all/dm-Deal-with-merge_bvec_fn-in-component-devices-bett.patch
dists/lenny/linux-2.6/debian/patches/bugfix/all/md-deal-with-merge_bvec_fn-in-component-devices-bett.patch
dists/lenny/linux-2.6/debian/patches/series/27
Modified:
dists/lenny/linux-2.6/debian/changelog
Modified: dists/lenny/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny/linux-2.6/debian/changelog Mon Nov 29 01:39:38 2010 (r16610)
+++ dists/lenny/linux-2.6/debian/changelog Mon Nov 29 02:03:51 2010 (r16611)
@@ -1,3 +1,11 @@
+linux-2.6 (2.6.26-27) UNRELEASED; urgency=low
+
+ [ Ben Hutchings ]
+ * dm,md: Deal with merge_bvec_fn in component devices better
+ (Closes: #604457)
+
+ -- Ben Hutchings <ben at decadent.org.uk> Mon, 29 Nov 2010 02:01:24 +0000
+
linux-2.6 (2.6.26-26) stable; urgency=high
[ Ben Hutchings ]
Added: dists/lenny/linux-2.6/debian/patches/bugfix/all/dm-Deal-with-merge_bvec_fn-in-component-devices-bett.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny/linux-2.6/debian/patches/bugfix/all/dm-Deal-with-merge_bvec_fn-in-component-devices-bett.patch Mon Nov 29 02:03:51 2010 (r16611)
@@ -0,0 +1,59 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sun, 28 Nov 2010 23:46:46 +0000
+Subject: [PATCH 2/2] dm: Deal with merge_bvec_fn in component devices better
+
+This is analogous to commit 627a2d3c29427637f4c5d31ccc7fcbd8d312cd71,
+which does the same for md-devices at the top of the stack. The
+following explanation is taken from that commit. Thanks to Neil Brown
+<neilb at suse.de> for the advice.
+
+If a component device has a merge_bvec_fn then as we never call it
+we must ensure we never need to. Currently this is done by setting
+max_sector to 1 PAGE, however this does not stop a bio being created
+with several sub-page iovecs that would violate the merge_bvec_fn.
+
+So instead set max_segments to 1 and set the segment boundary to the
+same as a page boundary to ensure there is only ever one single-page
+segment of IO requested at a time.
+
+This can particularly be an issue when 'xen' is used as it is
+known to submit multiple small buffers in a single bio.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ drivers/md/dm-table.c | 18 ++++++++----------
+ 1 files changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 94116ea..186445d0 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -506,17 +506,15 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
+ rs->max_sectors =
+ min_not_zero(rs->max_sectors, q->max_sectors);
+
+- /* FIXME: Device-Mapper on top of RAID-0 breaks because DM
+- * currently doesn't honor MD's merge_bvec_fn routine.
+- * In this case, we'll force DM to use PAGE_SIZE or
+- * smaller I/O, just to be safe. A better fix is in the
+- * works, but add this for the time being so it will at
+- * least operate correctly.
++ /*
++ * Since we don't call merge_bvec_fn, we must never risk
++ * violating it, so limit max_phys_segments to 1 lying within
++ * a single page.
+ */
+- if (q->merge_bvec_fn)
+- rs->max_sectors =
+- min_not_zero(rs->max_sectors,
+- (unsigned int) (PAGE_SIZE >> 9));
++ if (q->merge_bvec_fn) {
++ rs->max_phys_segments = 1;
++ rs->seg_boundary_mask = PAGE_CACHE_SIZE - 1;
++ }
+
+ rs->max_phys_segments =
+ min_not_zero(rs->max_phys_segments,
+--
+1.7.2.3
+
Added: dists/lenny/linux-2.6/debian/patches/bugfix/all/md-deal-with-merge_bvec_fn-in-component-devices-bett.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny/linux-2.6/debian/patches/bugfix/all/md-deal-with-merge_bvec_fn-in-component-devices-bett.patch Mon Nov 29 02:03:51 2010 (r16611)
@@ -0,0 +1,219 @@
+From: NeilBrown <neilb at suse.de>
+Date: Mon, 8 Mar 2010 16:44:38 +1100
+Subject: [PATCH 1/2] md: deal with merge_bvec_fn in component devices better.
+
+commit 627a2d3c29427637f4c5d31ccc7fcbd8d312cd71 upstream.
+
+If a component device has a merge_bvec_fn then as we never call it
+we must ensure we never need to. Currently this is done by setting
+max_sector to 1 PAGE, however this does not stop a bio being created
+with several sub-page iovecs that would violate the merge_bvec_fn.
+
+So instead set max_segments to 1 and set the segment boundary to the
+same as a page boundary to ensure there is only ever one single-page
+segment of IO requested at a time.
+
+This can particularly be an issue when 'xen' is used as it is
+known to submit multiple small buffers in a single bio.
+
+Signed-off-by: NeilBrown <neilb at suse.de>
+Cc: stable at kernel.org
+[bwh: Backport to Linux 2.6.26]
+---
+ drivers/md/linear.c | 12 +++++++-----
+ drivers/md/multipath.c | 20 ++++++++++++--------
+ drivers/md/raid0.c | 13 +++++++------
+ drivers/md/raid1.c | 28 +++++++++++++++++-----------
+ drivers/md/raid10.c | 28 +++++++++++++++++-----------
+ 5 files changed, 60 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/md/linear.c b/drivers/md/linear.c
+index ec921f5..fe8508a 100644
+--- a/drivers/md/linear.c
++++ b/drivers/md/linear.c
+@@ -136,12 +136,14 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
+ blk_queue_stack_limits(mddev->queue,
+ rdev->bdev->bd_disk->queue);
+ /* as we don't honour merge_bvec_fn, we must never risk
+- * violating it, so limit ->max_sector to one PAGE, as
+- * a one page request is never in violation.
++ * violating it, so limit max_segments to 1 lying within
++ * a single page.
+ */
+- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
+- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+- blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
++ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
++ blk_queue_max_phys_segments(mddev->queue, 1);
++ blk_queue_segment_boundary(mddev->queue,
++ PAGE_CACHE_SIZE - 1);
++ }
+
+ disk->size = rdev->size;
+ conf->array_size += rdev->size;
+diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
+index e968116..67dd8a3 100644
+--- a/drivers/md/multipath.c
++++ b/drivers/md/multipath.c
+@@ -293,14 +293,16 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
+ blk_queue_stack_limits(mddev->queue, q);
+
+ /* as we don't honour merge_bvec_fn, we must never risk
+- * violating it, so limit ->max_sector to one PAGE, as
+- * a one page request is never in violation.
++ * violating it, so limit ->max_segments to one, lying
++ * within a single page.
+ * (Note: it is very unlikely that a device with
+ * merge_bvec_fn will be involved in multipath.)
+ */
+- if (q->merge_bvec_fn &&
+- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+- blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
++ if (q->merge_bvec_fn) {
++ blk_queue_max_phys_segments(mddev->queue, 1);
++ blk_queue_segment_boundary(mddev->queue,
++ PAGE_CACHE_SIZE - 1);
++ }
+
+ conf->working_disks++;
+ mddev->degraded--;
+@@ -453,9 +455,11 @@ static int multipath_run (mddev_t *mddev)
+ /* as we don't honour merge_bvec_fn, we must never risk
+ * violating it, not that we ever expect a device with
+ * a merge_bvec_fn to be involved in multipath */
+- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
+- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+- blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
++ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
++ blk_queue_max_phys_segments(mddev->queue, 1);
++ blk_queue_segment_boundary(mddev->queue,
++ PAGE_CACHE_SIZE - 1);
++ }
+
+ if (!test_bit(Faulty, &rdev->flags))
+ conf->working_disks++;
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 914c04d..b344e0e 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -141,14 +141,15 @@ static int create_strip_zones (mddev_t *mddev)
+ blk_queue_stack_limits(mddev->queue,
+ rdev1->bdev->bd_disk->queue);
+ /* as we don't honour merge_bvec_fn, we must never risk
+- * violating it, so limit ->max_sector to one PAGE, as
+- * a one page request is never in violation.
++ * violating it, so limit ->max_segments to 1, lying within
++ * a single page.
+ */
+
+- if (rdev1->bdev->bd_disk->queue->merge_bvec_fn &&
+- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+- blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
+-
++ if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) {
++ blk_queue_max_phys_segments(mddev->queue, 1);
++ blk_queue_segment_boundary(mddev->queue,
++ PAGE_CACHE_SIZE - 1);
++ }
+ if (!smallest || (rdev1->size <smallest->size))
+ smallest = rdev1;
+ cnt++;
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index c610b94..360c079 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1109,13 +1109,17 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
+
+ blk_queue_stack_limits(mddev->queue,
+ rdev->bdev->bd_disk->queue);
+- /* as we don't honour merge_bvec_fn, we must never risk
+- * violating it, so limit ->max_sector to one PAGE, as
+- * a one page request is never in violation.
++ /* as we don't honour merge_bvec_fn, we must
++ * never risk violating it, so limit
++ * ->max_segments to one lying with a single
++ * page, as a one page request is never in
++ * violation.
+ */
+- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
+- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+- blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
++ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
++ blk_queue_max_phys_segments(mddev->queue, 1);
++ blk_queue_segment_boundary(mddev->queue,
++ PAGE_CACHE_SIZE - 1);
++ }
+
+ p->head_position = 0;
+ rdev->raid_disk = mirror;
+@@ -1971,12 +1975,14 @@ static int run(mddev_t *mddev)
+ blk_queue_stack_limits(mddev->queue,
+ rdev->bdev->bd_disk->queue);
+ /* as we don't honour merge_bvec_fn, we must never risk
+- * violating it, so limit ->max_sector to one PAGE, as
+- * a one page request is never in violation.
++ * violating it, so limit ->max_segments to 1 lying within
++ * a single page, as a one page request is never in violation.
+ */
+- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
+- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+- blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
++ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
++ blk_queue_max_phys_segments(mddev->queue, 1);
++ blk_queue_segment_boundary(mddev->queue,
++ PAGE_CACHE_SIZE - 1);
++ }
+
+ disk->head_position = 0;
+ }
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index a71277b..bf7654d 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1135,13 +1135,17 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
+
+ blk_queue_stack_limits(mddev->queue,
+ rdev->bdev->bd_disk->queue);
+- /* as we don't honour merge_bvec_fn, we must never risk
+- * violating it, so limit ->max_sector to one PAGE, as
+- * a one page request is never in violation.
++ /* as we don't honour merge_bvec_fn, we must
++ * never risk violating it, so limit
++ * ->max_segments to one lying with a single
++ * page, as a one page request is never in
++ * violation.
+ */
+- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
+- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+- mddev->queue->max_sectors = (PAGE_SIZE>>9);
++ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
++ blk_queue_max_phys_segments(mddev->queue, 1);
++ blk_queue_segment_boundary(mddev->queue,
++ PAGE_CACHE_SIZE - 1);
++ }
+
+ p->head_position = 0;
+ rdev->raid_disk = mirror;
+@@ -2107,12 +2111,14 @@ static int run(mddev_t *mddev)
+ blk_queue_stack_limits(mddev->queue,
+ rdev->bdev->bd_disk->queue);
+ /* as we don't honour merge_bvec_fn, we must never risk
+- * violating it, so limit ->max_sector to one PAGE, as
+- * a one page request is never in violation.
++ * violating it, so limit max_segments to 1 lying
++ * within a single page.
+ */
+- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
+- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+- mddev->queue->max_sectors = (PAGE_SIZE>>9);
++ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
++ blk_queue_max_phys_segments(mddev->queue, 1);
++ blk_queue_segment_boundary(mddev->queue,
++ PAGE_CACHE_SIZE - 1);
++ }
+
+ disk->head_position = 0;
+ }
+--
+1.7.2.3
+
Added: dists/lenny/linux-2.6/debian/patches/series/27
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny/linux-2.6/debian/patches/series/27 Mon Nov 29 02:03:51 2010 (r16611)
@@ -0,0 +1,2 @@
++ bugfix/all/md-deal-with-merge_bvec_fn-in-component-devices-bett.patch
++ bugfix/all/dm-Deal-with-merge_bvec_fn-in-component-devices-bett.patch
More information about the Kernel-svn-changes
mailing list