Linux Device Mapper development
 help / color / mirror / Atom feed
* Re: dm-crypt: never use write same (was Re: [v3.7 Regression] [SCSI] sd: Implement support for WRITE SAME)
       [not found]             ` <yq1mwx960ri.fsf@sermon.lab.mkp.net>
@ 2012-12-20  5:47               ` Mike Snitzer
  2012-12-20  5:57                 ` [PATCH 1/4] dm: default to disabling WRITE SAME support for all targets Mike Snitzer
  0 siblings, 1 reply; 5+ messages in thread
From: Mike Snitzer @ 2012-12-20  5:47 UTC (permalink / raw)
  To: Martin K. Petersen
  Cc: Milan Broz, Joseph Salisbury, Kernel Team, linux-kernel, jgarzik,
	JBottomley, dm-devel

On Wed, Dec 19 2012 at  7:11pm -0500,
Martin K. Petersen <martin.petersen@oracle.com> wrote:

> >>>>> "Milan" == Milan Broz <mbroz@redhat.com> writes:
> 
> Milan> dm-crypt: never use write same
> 
> Milan> Ciphertext device is not compatible with WRITE SAME, disable it
> Milan> for all dmcrypt devices.
> 
> Milan> Signed-off-by: Milan Broz <mbroz@redhat.com>
> 
> Acked-by: Martin K. Petersen <martin.petersen@oracle.com>

I've developed more comprehensive WRITE SAME support for DM.  It can be
used in conjunction with Milan's patch (which enables Milan's patch to
go in too and be more easily tagged for v3.7 stable).

Anyway, my changes are available in the 'dm-write-same' branch of my
github tree: git://github.com/snitm/linux.git

See the top 5 commits: https://github.com/snitm/linux/commits/dm-write-same
(topmost needs to be folded, I'll do that when posting to dm-devel in
reply to this mail)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] dm: default to disabling WRITE SAME support for all targets
  2012-12-20  5:47               ` dm-crypt: never use write same (was Re: [v3.7 Regression] [SCSI] sd: Implement support for WRITE SAME) Mike Snitzer
@ 2012-12-20  5:57                 ` Mike Snitzer
  2012-12-20  5:57                   ` [PATCH 2/4] dm: add WRITE SAME support Mike Snitzer
                                     ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Mike Snitzer @ 2012-12-20  5:57 UTC (permalink / raw)
  To: dm-devel; +Cc: martin.petersen

Best to disable WRITE SAME support for all targets and then require each
target to opt-in by setting 'num_write_same_requests' in the dm_target
structure.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
---
 drivers/md/dm-table.c         |   30 ++++++++++++++++++++++++++++++
 include/linux/device-mapper.h |    6 ++++++
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 4c145fa..1ae337b 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -1423,6 +1423,33 @@ static bool dm_table_all_devices_attribute(struct dm_table *t,
 	return 1;
 }
 
+static int device_write_same_capable(struct dm_target *ti, struct dm_dev *dev,
+				     sector_t start, sector_t len, void *data)
+{
+	struct request_queue *q = bdev_get_queue(dev->bdev);
+
+	return q && q->limits.max_write_same_sectors;
+}
+
+static bool dm_table_supports_write_same(struct dm_table *t)
+{
+	struct dm_target *ti;
+	unsigned i = 0;
+
+	while (i < dm_table_get_num_targets(t)) {
+		ti = dm_table_get_target(t, i++);
+
+		if (!ti->num_write_same_requests)
+			continue;
+
+		if (!ti->type->iterate_devices ||
+		    !ti->type->iterate_devices(ti, device_write_same_capable, NULL))
+			return 1;
+	}
+
+	return 0;
+}
+
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
 			       struct queue_limits *limits)
 {
@@ -1454,6 +1481,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
 	else
 		queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q);
 
+	if (!dm_table_supports_write_same(t))
+		q->limits.max_write_same_sectors = 0;
+
 	dm_table_set_integrity(t);
 
 	/*
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 2d65c70..072b72f 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -211,6 +211,12 @@ struct dm_target {
 	unsigned num_discard_requests;
 
 	/*
+	 * The number of WRITE SAME requests that will be submitted to the target.
+	 * The request number can be accessed with dm_bio_get_target_request_nr.
+	 */
+	unsigned num_write_same_requests;
+
+	/*
 	 * The minimum number of extra bytes allocated in each bio for the
 	 * target to use.  dm_per_bio_data returns the data location.
 	 */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] dm: add WRITE SAME support
  2012-12-20  5:57                 ` [PATCH 1/4] dm: default to disabling WRITE SAME support for all targets Mike Snitzer
@ 2012-12-20  5:57                   ` Mike Snitzer
  2012-12-20  5:57                   ` [PATCH 3/4] dm linear: " Mike Snitzer
  2012-12-20  5:57                   ` [PATCH 4/4] dm stripe: " Mike Snitzer
  2 siblings, 0 replies; 5+ messages in thread
From: Mike Snitzer @ 2012-12-20  5:57 UTC (permalink / raw)
  To: dm-devel; +Cc: martin.petersen

WRITE SAME bios have a payload that contain a single page.  When
cloning WRITE SAME bios DM has no need to modify the bi_io_vec
attributes (doing so would be detrimental).  DM need only alter the
start and end of the WRITE SAME bio accordingly.

Rather than duplicate __clone_and_map_discard, factor out a common
function that is also used by __clone_and_map_write_same.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
---
 drivers/md/dm.c |   44 +++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 739fd2b..cee9926 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1218,7 +1218,28 @@ static void __clone_and_map_simple(struct clone_info *ci, struct dm_target *ti)
 	ci->sector_count = 0;
 }
 
-static int __clone_and_map_discard(struct clone_info *ci)
+typedef unsigned (*get_num_requests_fn)(struct dm_target *ti);
+
+static unsigned get_num_discard_requests(struct dm_target *ti)
+{
+	return ti->num_discard_requests;
+}
+
+static unsigned get_num_write_same_requests(struct dm_target *ti)
+{
+	return ti->num_write_same_requests;
+}
+
+typedef bool (*is_split_required_fn)(struct dm_target *ti);
+
+static bool is_split_required_for_discard(struct dm_target *ti)
+{
+	return ti->split_discard_requests;
+}
+
+static int __clone_and_map_changing_extent_only(struct clone_info *ci,
+						get_num_requests_fn get_num_requests,
+						is_split_required_fn is_split_required)
 {
 	struct dm_target *ti;
 	sector_t len;
@@ -1229,15 +1250,15 @@ static int __clone_and_map_discard(struct clone_info *ci)
 			return -EIO;
 
 		/*
-		 * Even though the device advertised discard support,
-		 * that does not mean every target supports it, and
+		 * Even though the device advertised support for this type of
+		 * request, that does not mean every target supports it, and
 		 * reconfiguration might also have changed that since the
 		 * check was performed.
 		 */
-		if (!ti->num_discard_requests)
+		if (!get_num_requests || !get_num_requests(ti))
 			return -EOPNOTSUPP;
 
-		if (!ti->split_discard_requests)
+		if (is_split_required && !is_split_required(ti))
 			len = min(ci->sector_count, max_io_len_target_boundary(ci->sector, ti));
 		else
 			len = min(ci->sector_count, max_io_len(ci->sector, ti));
@@ -1250,6 +1271,17 @@ static int __clone_and_map_discard(struct clone_info *ci)
 	return 0;
 }
 
+static int __clone_and_map_discard(struct clone_info *ci)
+{
+	return __clone_and_map_changing_extent_only(ci, get_num_discard_requests,
+						    is_split_required_for_discard);
+}
+
+static int __clone_and_map_write_same(struct clone_info *ci)
+{
+	return __clone_and_map_changing_extent_only(ci, get_num_write_same_requests, NULL);
+}
+
 static int __clone_and_map(struct clone_info *ci)
 {
 	struct bio *bio = ci->bio;
@@ -1258,6 +1290,8 @@ static int __clone_and_map(struct clone_info *ci)
 
 	if (unlikely(bio->bi_rw & REQ_DISCARD))
 		return __clone_and_map_discard(ci);
+	else if (unlikely(bio->bi_rw & REQ_WRITE_SAME))
+		return __clone_and_map_write_same(ci);
 
 	ti = dm_table_find_target(ci->map, ci->sector);
 	if (!dm_target_is_valid(ti))
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] dm linear: add WRITE SAME support
  2012-12-20  5:57                 ` [PATCH 1/4] dm: default to disabling WRITE SAME support for all targets Mike Snitzer
  2012-12-20  5:57                   ` [PATCH 2/4] dm: add WRITE SAME support Mike Snitzer
@ 2012-12-20  5:57                   ` Mike Snitzer
  2012-12-20  5:57                   ` [PATCH 4/4] dm stripe: " Mike Snitzer
  2 siblings, 0 replies; 5+ messages in thread
From: Mike Snitzer @ 2012-12-20  5:57 UTC (permalink / raw)
  To: dm-devel; +Cc: martin.petersen

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
---
 drivers/md/dm-linear.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 2f57bd8..f982e9c 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -55,6 +55,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
 	ti->num_flush_requests = 1;
 	ti->num_discard_requests = 1;
+	ti->num_write_same_requests = 1;
 	ti->private = lc;
 	return 0;
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] dm stripe: add WRITE SAME support
  2012-12-20  5:57                 ` [PATCH 1/4] dm: default to disabling WRITE SAME support for all targets Mike Snitzer
  2012-12-20  5:57                   ` [PATCH 2/4] dm: add WRITE SAME support Mike Snitzer
  2012-12-20  5:57                   ` [PATCH 3/4] dm linear: " Mike Snitzer
@ 2012-12-20  5:57                   ` Mike Snitzer
  2 siblings, 0 replies; 5+ messages in thread
From: Mike Snitzer @ 2012-12-20  5:57 UTC (permalink / raw)
  To: dm-devel; +Cc: martin.petersen

Rename stripe_map_discard to stripe_map_range and reuse it for WRITE
SAME bio processing.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
---
 drivers/md/dm-stripe.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 6b0e5ea..c89cde8 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -162,6 +162,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
 	ti->num_flush_requests = stripes;
 	ti->num_discard_requests = stripes;
+	ti->num_write_same_requests = stripes;
 
 	sc->chunk_size = chunk_size;
 	if (chunk_size & (chunk_size - 1))
@@ -251,8 +252,8 @@ static void stripe_map_range_sector(struct stripe_c *sc, sector_t sector,
 		*result += sc->chunk_size;		/* next chunk */
 }
 
-static int stripe_map_discard(struct stripe_c *sc, struct bio *bio,
-			      uint32_t target_stripe)
+static int stripe_map_range(struct stripe_c *sc, struct bio *bio,
+			    uint32_t target_stripe)
 {
 	sector_t begin, end;
 
@@ -283,10 +284,11 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
 		bio->bi_bdev = sc->stripe[target_request_nr].dev->bdev;
 		return DM_MAPIO_REMAPPED;
 	}
-	if (unlikely(bio->bi_rw & REQ_DISCARD)) {
+	if (unlikely(bio->bi_rw & REQ_DISCARD) ||
+	    unlikely(bio->bi_rw & REQ_WRITE_SAME)) {
 		target_request_nr = dm_bio_get_target_request_nr(bio);
 		BUG_ON(target_request_nr >= sc->stripes);
-		return stripe_map_discard(sc, bio, target_request_nr);
+		return stripe_map_range(sc, bio, target_request_nr);
 	}
 
 	stripe_map_sector(sc, bio->bi_sector, &stripe, &bio->bi_sector);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-12-20  5:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <50CB8C74.3090102@canonical.com>
     [not found] ` <yq11uesdzya.fsf@sermon.lab.mkp.net>
     [not found]   ` <50D0C971.1000907@canonical.com>
     [not found]     ` <yq1bodq7zdv.fsf@sermon.lab.mkp.net>
     [not found]       ` <20121219195801.GA14456@redhat.com>
     [not found]         ` <50D22766.9090107@redhat.com>
     [not found]           ` <50D22C7F.2020201@redhat.com>
     [not found]             ` <yq1mwx960ri.fsf@sermon.lab.mkp.net>
2012-12-20  5:47               ` dm-crypt: never use write same (was Re: [v3.7 Regression] [SCSI] sd: Implement support for WRITE SAME) Mike Snitzer
2012-12-20  5:57                 ` [PATCH 1/4] dm: default to disabling WRITE SAME support for all targets Mike Snitzer
2012-12-20  5:57                   ` [PATCH 2/4] dm: add WRITE SAME support Mike Snitzer
2012-12-20  5:57                   ` [PATCH 3/4] dm linear: " Mike Snitzer
2012-12-20  5:57                   ` [PATCH 4/4] dm stripe: " Mike Snitzer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox