[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