All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 0/2] *** adding and exposing SANITIZE capability to the user space via a unique IOCTL ***
@ 2012-07-25  9:32 Yaniv Gardi
  2012-07-25  9:32   ` Yaniv Gardi
  2012-07-25  9:32   ` Yaniv Gardi
  0 siblings, 2 replies; 13+ messages in thread
From: Yaniv Gardi @ 2012-07-25  9:32 UTC (permalink / raw)
  To: linux-mmc; +Cc: linux-arm-msm, Yaniv Gardi

*** adding and exposing SANITIZE capability to the user space via a unique IOCTL ***

Yaniv Gardi (2):
  block: ioctl support for sanitize in eMMC 4.5
  mmc: card: Adding support for sanitize in eMMC 4.5

 block/blk-core.c          |   15 +++++++--
 block/blk-lib.c           |   51 +++++++++++++++++++++++++++++++
 block/blk-merge.c         |    4 ++
 block/elevator.c          |    2 +-
 block/ioctl.c             |    9 +++++
 drivers/mmc/card/block.c  |   72 ++++++++++++++++++++++++++++++++------------
 drivers/mmc/card/queue.c  |   10 +++++-
 include/linux/blk_types.h |    5 ++-
 include/linux/blkdev.h    |    3 ++
 include/linux/fs.h        |    1 +
 include/linux/mmc/host.h  |    1 +
 kernel/trace/blktrace.c   |    2 +
 12 files changed, 149 insertions(+), 26 deletions(-)

-- 
1.7.6
-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum

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

* [PATCH v8 1/2] block: ioctl support for sanitize in eMMC 4.5
  2012-07-25  9:32 [PATCH v8 0/2] *** adding and exposing SANITIZE capability to the user space via a unique IOCTL *** Yaniv Gardi
@ 2012-07-25  9:32   ` Yaniv Gardi
  2012-07-25  9:32   ` Yaniv Gardi
  1 sibling, 0 replies; 13+ messages in thread
From: Yaniv Gardi @ 2012-07-25  9:32 UTC (permalink / raw)
  To: linux-mmc; +Cc: linux-arm-msm, Yaniv Gardi, open list

Adding a new ioctl to support sanitize operation in eMMC
cards version 4.5.
The sanitize ioctl support helps performing this operation
via user application.

Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>

---
 block/blk-core.c          |   15 ++++++++++--
 block/blk-lib.c           |   51 +++++++++++++++++++++++++++++++++++++++++++++
 block/blk-merge.c         |    4 +++
 block/elevator.c          |    2 +-
 block/ioctl.c             |    9 ++++++++
 include/linux/blk_types.h |    5 +++-
 include/linux/blkdev.h    |    3 ++
 include/linux/fs.h        |    1 +
 kernel/trace/blktrace.c   |    2 +
 9 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 3c923a7..4a56102b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1641,7 +1641,7 @@ generic_make_request_checks(struct bio *bio)
 		goto end_io;
 	}
 
-	if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
+	if (unlikely(!(bio->bi_rw & (REQ_DISCARD | REQ_SANITIZE)) &&
 		     nr_sectors > queue_max_hw_sectors(q))) {
 		printk(KERN_ERR "bio too big device %s (%u > %u)\n",
 		       bdevname(bio->bi_bdev, b),
@@ -1689,6 +1689,14 @@ generic_make_request_checks(struct bio *bio)
 		goto end_io;
 	}
 
+	if ((bio->bi_rw & REQ_SANITIZE) &&
+	    (!blk_queue_sanitize(q))) {
+		pr_info("%s - got a SANITIZE request but the queue "
+		       "doesn't support sanitize requests", __func__);
+		err = -EOPNOTSUPP;
+		goto end_io;
+	}
+
 	if (blk_throtl_bio(q, bio))
 		return false;	/* throttled, will be resubmitted later */
 
@@ -1794,7 +1802,8 @@ void submit_bio(int rw, struct bio *bio)
 	 * If it's a regular read/write or a barrier with data attached,
 	 * go through the normal accounting stuff before submission.
 	 */
-	if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {
+	if (bio_has_data(bio) &&
+	    (!(rw & (REQ_DISCARD | REQ_SANITIZE)))) {
 		if (rw & WRITE) {
 			count_vm_events(PGPGOUT, count);
 		} else {
@@ -1840,7 +1849,7 @@ EXPORT_SYMBOL(submit_bio);
  */
 int blk_rq_check_limits(struct request_queue *q, struct request *rq)
 {
-	if (rq->cmd_flags & REQ_DISCARD)
+	if (rq->cmd_flags & (REQ_DISCARD | REQ_SANITIZE))
 		return 0;
 
 	if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 2b461b4..280d63e 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -115,6 +115,57 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 EXPORT_SYMBOL(blkdev_issue_discard);
 
 /**
+ * blkdev_issue_sanitize - queue a sanitize request
+ * @bdev:	blockdev to issue sanitize for
+ * @gfp_mask:	memory allocation flags (for bio_alloc)
+ *
+ * Description:
+ *    Issue a sanitize request for the specified block device
+ */
+int blkdev_issue_sanitize(struct block_device *bdev, gfp_t gfp_mask)
+{
+	DECLARE_COMPLETION_ONSTACK(wait);
+	struct request_queue *q = bdev_get_queue(bdev);
+	int type = REQ_WRITE | REQ_SANITIZE;
+	struct bio_batch bb;
+	struct bio *bio;
+	int ret = 0;
+
+	if (!q)
+		return -ENXIO;
+
+	if (!blk_queue_sanitize(q)) {
+		pr_err("%s - card doesn't support sanitize", __func__);
+		return -EOPNOTSUPP;
+	}
+
+	bio = bio_alloc(gfp_mask, 1);
+	if (!bio)
+		return -ENOMEM;
+
+	atomic_set(&bb.done, 1);
+	bb.flags = 1 << BIO_UPTODATE;
+	bb.wait = &wait;
+
+	bio->bi_end_io = bio_batch_end_io;
+	bio->bi_bdev = bdev;
+	bio->bi_private = &bb;
+
+	atomic_inc(&bb.done);
+	submit_bio(type, bio);
+
+	/* Wait for bios in-flight */
+	if (!atomic_dec_and_test(&bb.done))
+		wait_for_completion(&wait);
+
+	if (!test_bit(BIO_UPTODATE, &bb.flags))
+		ret = -EIO;
+
+	return ret;
+}
+EXPORT_SYMBOL(blkdev_issue_sanitize);
+
+/**
  * blkdev_issue_zeroout - generate number of zero filed write bios
  * @bdev:	blockdev to issue
  * @sector:	start sector
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 160035f..ef93b23 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -477,6 +477,10 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 	if (!rq_mergeable(rq))
 		return false;
 
+	/* don't merge file system requests and sanitize requests */
+	if ((bio->bi_rw & REQ_SANITIZE) != (rq->bio->bi_rw & REQ_SANITIZE))
+		return false;
+
 	/* don't merge file system requests and discard requests */
 	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
 		return false;
diff --git a/block/elevator.c b/block/elevator.c
index 6a55d41..91f1de1 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -563,7 +563,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where)
 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
 		/* barriers are scheduling boundary, update end_sector */
 		if (rq->cmd_type == REQ_TYPE_FS ||
-		    (rq->cmd_flags & REQ_DISCARD)) {
+		    (rq->cmd_flags & (REQ_DISCARD | REQ_SANITIZE))) {
 			q->end_sector = rq_end_sector(rq);
 			q->boundary_rq = rq;
 		}
diff --git a/block/ioctl.c b/block/ioctl.c
index ba15b2d..dd76ba0 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -132,6 +132,11 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
 	return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
 }
 
+static int blk_ioctl_sanitize(struct block_device *bdev)
+{
+	return blkdev_issue_sanitize(bdev, GFP_KERNEL);
+}
+
 static int put_ushort(unsigned long arg, unsigned short val)
 {
 	return put_user(val, (unsigned short __user *)arg);
@@ -234,6 +239,10 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 		set_device_ro(bdev, n);
 		return 0;
 
+	case BLKSANITIZE:
+		ret = blk_ioctl_sanitize(bdev);
+		break;
+
 	case BLKDISCARD:
 	case BLKSECDISCARD: {
 		uint64_t range[2];
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 0edb65d..e58e0db 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -160,6 +160,7 @@ enum rq_flag_bits {
 	__REQ_FLUSH_SEQ,	/* request for flush sequence */
 	__REQ_IO_STAT,		/* account I/O stat */
 	__REQ_MIXED_MERGE,	/* merge of different types, fail separately */
+	__REQ_SANITIZE,		/* sanitize */
 	__REQ_NR_BITS,		/* stops here */
 };
 
@@ -171,13 +172,15 @@ enum rq_flag_bits {
 #define REQ_META		(1 << __REQ_META)
 #define REQ_PRIO		(1 << __REQ_PRIO)
 #define REQ_DISCARD		(1 << __REQ_DISCARD)
+#define REQ_SANITIZE		(1 << __REQ_SANITIZE)
 #define REQ_NOIDLE		(1 << __REQ_NOIDLE)
 
 #define REQ_FAILFAST_MASK \
 	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
 #define REQ_COMMON_MASK \
 	(REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
-	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE)
+	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE | \
+	 REQ_SANITIZE)
 #define REQ_CLONE_MASK		REQ_COMMON_MASK
 
 #define REQ_RAHEAD		(1 << __REQ_RAHEAD)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ba43f40..1db6c91 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -438,6 +438,7 @@ struct request_queue {
 #define QUEUE_FLAG_ADD_RANDOM  16	/* Contributes to random pool */
 #define QUEUE_FLAG_SECDISCARD  17	/* supports SECDISCARD */
 #define QUEUE_FLAG_SAME_FORCE  18	/* force complete on same CPU */
+#define QUEUE_FLAG_SANITIZE    19	/* supports SANITIZE */
 
 #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
 				 (1 << QUEUE_FLAG_STACKABLE)	|	\
@@ -518,6 +519,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
 #define blk_queue_stackable(q)	\
 	test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
 #define blk_queue_discard(q)	test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
+#define blk_queue_sanitize(q)	test_bit(QUEUE_FLAG_SANITIZE, &(q)->queue_flags)
 #define blk_queue_secdiscard(q)	(blk_queue_discard(q) && \
 	test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags))
 
@@ -971,6 +973,7 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
 extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
 extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 		sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
+extern int blkdev_issue_sanitize(struct block_device *bdev, gfp_t gfp_mask);
 extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
 			sector_t nr_sects, gfp_t gfp_mask);
 static inline int sb_issue_discard(struct super_block *sb, sector_t block,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b0a6d44..167c450 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -333,6 +333,7 @@ struct inodes_stat_t {
 #define BLKDISCARDZEROES _IO(0x12,124)
 #define BLKSECDISCARD _IO(0x12,125)
 #define BLKROTATIONAL _IO(0x12,126)
+#define BLKSANITIZE _IO(0x12, 127)
 
 #define BMAP_IOCTL 1		/* obsolete - kept for compatibility */
 #define FIBMAP	   _IO(0x00,1)	/* bmap access */
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index c0bd030..06f7940 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1788,6 +1788,8 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes)
 		rwbs[i++] = 'W';
 	else if (rw & REQ_DISCARD)
 		rwbs[i++] = 'D';
+	else if (rw & REQ_SANITIZE)
+		rwbs[i++] = 'Z';
 	else if (bytes)
 		rwbs[i++] = 'R';
 	else
-- 
1.7.6
-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum

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

* [PATCH v8 1/2] block: ioctl support for sanitize in eMMC 4.5
@ 2012-07-25  9:32   ` Yaniv Gardi
  0 siblings, 0 replies; 13+ messages in thread
From: Yaniv Gardi @ 2012-07-25  9:32 UTC (permalink / raw)
  To: linux-mmc; +Cc: linux-arm-msm, Yaniv Gardi, open list

Adding a new ioctl to support sanitize operation in eMMC
cards version 4.5.
The sanitize ioctl support helps performing this operation
via user application.

Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>

---
 block/blk-core.c          |   15 ++++++++++--
 block/blk-lib.c           |   51 +++++++++++++++++++++++++++++++++++++++++++++
 block/blk-merge.c         |    4 +++
 block/elevator.c          |    2 +-
 block/ioctl.c             |    9 ++++++++
 include/linux/blk_types.h |    5 +++-
 include/linux/blkdev.h    |    3 ++
 include/linux/fs.h        |    1 +
 kernel/trace/blktrace.c   |    2 +
 9 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 3c923a7..4a56102b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1641,7 +1641,7 @@ generic_make_request_checks(struct bio *bio)
 		goto end_io;
 	}
 
-	if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
+	if (unlikely(!(bio->bi_rw & (REQ_DISCARD | REQ_SANITIZE)) &&
 		     nr_sectors > queue_max_hw_sectors(q))) {
 		printk(KERN_ERR "bio too big device %s (%u > %u)\n",
 		       bdevname(bio->bi_bdev, b),
@@ -1689,6 +1689,14 @@ generic_make_request_checks(struct bio *bio)
 		goto end_io;
 	}
 
+	if ((bio->bi_rw & REQ_SANITIZE) &&
+	    (!blk_queue_sanitize(q))) {
+		pr_info("%s - got a SANITIZE request but the queue "
+		       "doesn't support sanitize requests", __func__);
+		err = -EOPNOTSUPP;
+		goto end_io;
+	}
+
 	if (blk_throtl_bio(q, bio))
 		return false;	/* throttled, will be resubmitted later */
 
@@ -1794,7 +1802,8 @@ void submit_bio(int rw, struct bio *bio)
 	 * If it's a regular read/write or a barrier with data attached,
 	 * go through the normal accounting stuff before submission.
 	 */
-	if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {
+	if (bio_has_data(bio) &&
+	    (!(rw & (REQ_DISCARD | REQ_SANITIZE)))) {
 		if (rw & WRITE) {
 			count_vm_events(PGPGOUT, count);
 		} else {
@@ -1840,7 +1849,7 @@ EXPORT_SYMBOL(submit_bio);
  */
 int blk_rq_check_limits(struct request_queue *q, struct request *rq)
 {
-	if (rq->cmd_flags & REQ_DISCARD)
+	if (rq->cmd_flags & (REQ_DISCARD | REQ_SANITIZE))
 		return 0;
 
 	if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 2b461b4..280d63e 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -115,6 +115,57 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 EXPORT_SYMBOL(blkdev_issue_discard);
 
 /**
+ * blkdev_issue_sanitize - queue a sanitize request
+ * @bdev:	blockdev to issue sanitize for
+ * @gfp_mask:	memory allocation flags (for bio_alloc)
+ *
+ * Description:
+ *    Issue a sanitize request for the specified block device
+ */
+int blkdev_issue_sanitize(struct block_device *bdev, gfp_t gfp_mask)
+{
+	DECLARE_COMPLETION_ONSTACK(wait);
+	struct request_queue *q = bdev_get_queue(bdev);
+	int type = REQ_WRITE | REQ_SANITIZE;
+	struct bio_batch bb;
+	struct bio *bio;
+	int ret = 0;
+
+	if (!q)
+		return -ENXIO;
+
+	if (!blk_queue_sanitize(q)) {
+		pr_err("%s - card doesn't support sanitize", __func__);
+		return -EOPNOTSUPP;
+	}
+
+	bio = bio_alloc(gfp_mask, 1);
+	if (!bio)
+		return -ENOMEM;
+
+	atomic_set(&bb.done, 1);
+	bb.flags = 1 << BIO_UPTODATE;
+	bb.wait = &wait;
+
+	bio->bi_end_io = bio_batch_end_io;
+	bio->bi_bdev = bdev;
+	bio->bi_private = &bb;
+
+	atomic_inc(&bb.done);
+	submit_bio(type, bio);
+
+	/* Wait for bios in-flight */
+	if (!atomic_dec_and_test(&bb.done))
+		wait_for_completion(&wait);
+
+	if (!test_bit(BIO_UPTODATE, &bb.flags))
+		ret = -EIO;
+
+	return ret;
+}
+EXPORT_SYMBOL(blkdev_issue_sanitize);
+
+/**
  * blkdev_issue_zeroout - generate number of zero filed write bios
  * @bdev:	blockdev to issue
  * @sector:	start sector
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 160035f..ef93b23 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -477,6 +477,10 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 	if (!rq_mergeable(rq))
 		return false;
 
+	/* don't merge file system requests and sanitize requests */
+	if ((bio->bi_rw & REQ_SANITIZE) != (rq->bio->bi_rw & REQ_SANITIZE))
+		return false;
+
 	/* don't merge file system requests and discard requests */
 	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
 		return false;
diff --git a/block/elevator.c b/block/elevator.c
index 6a55d41..91f1de1 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -563,7 +563,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where)
 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
 		/* barriers are scheduling boundary, update end_sector */
 		if (rq->cmd_type == REQ_TYPE_FS ||
-		    (rq->cmd_flags & REQ_DISCARD)) {
+		    (rq->cmd_flags & (REQ_DISCARD | REQ_SANITIZE))) {
 			q->end_sector = rq_end_sector(rq);
 			q->boundary_rq = rq;
 		}
diff --git a/block/ioctl.c b/block/ioctl.c
index ba15b2d..dd76ba0 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -132,6 +132,11 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
 	return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
 }
 
+static int blk_ioctl_sanitize(struct block_device *bdev)
+{
+	return blkdev_issue_sanitize(bdev, GFP_KERNEL);
+}
+
 static int put_ushort(unsigned long arg, unsigned short val)
 {
 	return put_user(val, (unsigned short __user *)arg);
@@ -234,6 +239,10 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 		set_device_ro(bdev, n);
 		return 0;
 
+	case BLKSANITIZE:
+		ret = blk_ioctl_sanitize(bdev);
+		break;
+
 	case BLKDISCARD:
 	case BLKSECDISCARD: {
 		uint64_t range[2];
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 0edb65d..e58e0db 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -160,6 +160,7 @@ enum rq_flag_bits {
 	__REQ_FLUSH_SEQ,	/* request for flush sequence */
 	__REQ_IO_STAT,		/* account I/O stat */
 	__REQ_MIXED_MERGE,	/* merge of different types, fail separately */
+	__REQ_SANITIZE,		/* sanitize */
 	__REQ_NR_BITS,		/* stops here */
 };
 
@@ -171,13 +172,15 @@ enum rq_flag_bits {
 #define REQ_META		(1 << __REQ_META)
 #define REQ_PRIO		(1 << __REQ_PRIO)
 #define REQ_DISCARD		(1 << __REQ_DISCARD)
+#define REQ_SANITIZE		(1 << __REQ_SANITIZE)
 #define REQ_NOIDLE		(1 << __REQ_NOIDLE)
 
 #define REQ_FAILFAST_MASK \
 	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
 #define REQ_COMMON_MASK \
 	(REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
-	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE)
+	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE | \
+	 REQ_SANITIZE)
 #define REQ_CLONE_MASK		REQ_COMMON_MASK
 
 #define REQ_RAHEAD		(1 << __REQ_RAHEAD)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ba43f40..1db6c91 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -438,6 +438,7 @@ struct request_queue {
 #define QUEUE_FLAG_ADD_RANDOM  16	/* Contributes to random pool */
 #define QUEUE_FLAG_SECDISCARD  17	/* supports SECDISCARD */
 #define QUEUE_FLAG_SAME_FORCE  18	/* force complete on same CPU */
+#define QUEUE_FLAG_SANITIZE    19	/* supports SANITIZE */
 
 #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
 				 (1 << QUEUE_FLAG_STACKABLE)	|	\
@@ -518,6 +519,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
 #define blk_queue_stackable(q)	\
 	test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
 #define blk_queue_discard(q)	test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
+#define blk_queue_sanitize(q)	test_bit(QUEUE_FLAG_SANITIZE, &(q)->queue_flags)
 #define blk_queue_secdiscard(q)	(blk_queue_discard(q) && \
 	test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags))
 
@@ -971,6 +973,7 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
 extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
 extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 		sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
+extern int blkdev_issue_sanitize(struct block_device *bdev, gfp_t gfp_mask);
 extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
 			sector_t nr_sects, gfp_t gfp_mask);
 static inline int sb_issue_discard(struct super_block *sb, sector_t block,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b0a6d44..167c450 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -333,6 +333,7 @@ struct inodes_stat_t {
 #define BLKDISCARDZEROES _IO(0x12,124)
 #define BLKSECDISCARD _IO(0x12,125)
 #define BLKROTATIONAL _IO(0x12,126)
+#define BLKSANITIZE _IO(0x12, 127)
 
 #define BMAP_IOCTL 1		/* obsolete - kept for compatibility */
 #define FIBMAP	   _IO(0x00,1)	/* bmap access */
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index c0bd030..06f7940 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1788,6 +1788,8 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes)
 		rwbs[i++] = 'W';
 	else if (rw & REQ_DISCARD)
 		rwbs[i++] = 'D';
+	else if (rw & REQ_SANITIZE)
+		rwbs[i++] = 'Z';
 	else if (bytes)
 		rwbs[i++] = 'R';
 	else
-- 
1.7.6
-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum

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

* [PATCH v8 2/2] mmc: card: Adding support for sanitize in eMMC 4.5
  2012-07-25  9:32 [PATCH v8 0/2] *** adding and exposing SANITIZE capability to the user space via a unique IOCTL *** Yaniv Gardi
@ 2012-07-25  9:32   ` Yaniv Gardi
  2012-07-25  9:32   ` Yaniv Gardi
  1 sibling, 0 replies; 13+ messages in thread
From: Yaniv Gardi @ 2012-07-25  9:32 UTC (permalink / raw)
  To: linux-mmc; +Cc: linux-arm-msm, Yaniv Gardi, open list

This feature delete the unmap memory region of the eMMC card,
by writing to a specific register in the EXT_CSD
unmap region is the memory region that were previously deleted
(by erase, trim or discard operation)

Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>

---
 drivers/mmc/card/block.c |   72 +++++++++++++++++++++++++++++++++-------------
 drivers/mmc/card/queue.c |   10 ++++++-
 include/linux/mmc/host.h |    1 +
 3 files changed, 62 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index dd2d374..139971e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -874,10 +874,10 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
 {
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
-	unsigned int from, nr, arg, trim_arg, erase_arg;
+	unsigned int from, nr, arg;
 	int err = 0, type = MMC_BLK_SECDISCARD;
 
-	if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
+	if (!(mmc_can_secure_erase_trim(card))) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -885,23 +885,10 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
 	from = blk_rq_pos(req);
 	nr = blk_rq_sectors(req);
 
-	/* The sanitize operation is supported at v4.5 only */
-	if (mmc_can_sanitize(card)) {
-		erase_arg = MMC_ERASE_ARG;
-		trim_arg = MMC_TRIM_ARG;
-	} else {
-		erase_arg = MMC_SECURE_ERASE_ARG;
-		trim_arg = MMC_SECURE_TRIM1_ARG;
-	}
-
-	if (mmc_erase_group_aligned(card, from, nr))
-		arg = erase_arg;
-	else if (mmc_can_trim(card))
-		arg = trim_arg;
-	else {
-		err = -EINVAL;
-		goto out;
-	}
+	if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
+		arg = MMC_SECURE_TRIM1_ARG;
+	else
+		arg = MMC_SECURE_ERASE_ARG;
 retry:
 	if (card->quirks & MMC_QUIRK_INAND_CMD38) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -953,6 +940,46 @@ out:
 	return err ? 0 : 1;
 }
 
+static int mmc_blk_issue_sanitize_rq(struct mmc_queue *mq,
+				      struct request *req)
+{
+	struct mmc_blk_data *md = mq->data;
+	struct mmc_card *card = md->queue.card;
+	int err = 0;
+
+	BUG_ON(!card);
+	BUG_ON(!card->host);
+
+	if (!(mmc_can_sanitize(card) &&
+	     (card->host->caps2 & MMC_CAP2_SANITIZE))) {
+			pr_warning("%s: %s - SANITIZE is not supported\n",
+				   mmc_hostname(card->host), __func__);
+			err = -EOPNOTSUPP;
+			goto out;
+	}
+
+	pr_debug("%s: %s - SANITIZE IN PROGRESS...\n",
+		mmc_hostname(card->host), __func__);
+
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+					 EXT_CSD_SANITIZE_START, 1, 0);
+
+	if (err)
+		pr_err("%s: %s - mmc_switch() with "
+		       "EXT_CSD_SANITIZE_START failed. err=%d\n",
+		       mmc_hostname(card->host), __func__, err);
+
+	pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host),
+					     __func__);
+
+out:
+	spin_lock_irq(&md->lock);
+	__blk_end_request(req, err, blk_rq_bytes(req));
+	spin_unlock_irq(&md->lock);
+
+	return err ? 0 : 1;
+}
+
 static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
 {
 	struct mmc_blk_data *md = mq->data;
@@ -1437,7 +1464,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 		goto out;
 	}
 
-	if (req && req->cmd_flags & REQ_DISCARD) {
+	if (req && req->cmd_flags & REQ_SANITIZE) {
+		/* complete ongoing async transfer before issuing sanitize */
+		if (card->host && card->host->areq)
+			mmc_blk_issue_rw_rq(mq, NULL);
+		ret = mmc_blk_issue_sanitize_rq(mq, req);
+	} else if (req && req->cmd_flags & REQ_DISCARD) {
 		/* complete ongoing async transfer before issuing discard */
 		if (card->host->areq)
 			mmc_blk_issue_rw_rq(mq, NULL);
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index e360a97..4f3250e 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -145,10 +145,15 @@ static void mmc_queue_setup_discard(struct request_queue *q,
 	/* granularity must not be greater than max. discard */
 	if (card->pref_erase > max_discard)
 		q->limits.discard_granularity = 0;
-	if (mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))
+	if (mmc_can_secure_erase_trim(card))
 		queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
 }
 
+static void mmc_queue_setup_sanitize(struct request_queue *q)
+{
+	queue_flag_set_unlocked(QUEUE_FLAG_SANITIZE, q);
+}
+
 /**
  * mmc_init_queue - initialise a queue structure.
  * @mq: mmc queue
@@ -184,6 +189,9 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
 	if (mmc_can_erase(card))
 		mmc_queue_setup_discard(mq->queue, card);
 
+	if ((mmc_can_sanitize(card) && (host->caps2 & MMC_CAP2_SANITIZE)))
+		mmc_queue_setup_sanitize(mq->queue);
+
 #ifdef CONFIG_MMC_BLOCK_BOUNCE
 	if (host->max_segs == 1) {
 		unsigned int bouncesz;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 0707d22..be2b89f 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -238,6 +238,7 @@ struct mmc_host {
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_SANITIZE	(1 << 10)		/* Support Sanitize */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
-- 
1.7.6
-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum

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

* [PATCH v8 2/2] mmc: card: Adding support for sanitize in eMMC 4.5
@ 2012-07-25  9:32   ` Yaniv Gardi
  0 siblings, 0 replies; 13+ messages in thread
From: Yaniv Gardi @ 2012-07-25  9:32 UTC (permalink / raw)
  To: linux-mmc; +Cc: linux-arm-msm, Yaniv Gardi, open list

This feature delete the unmap memory region of the eMMC card,
by writing to a specific register in the EXT_CSD
unmap region is the memory region that were previously deleted
(by erase, trim or discard operation)

Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>

---
 drivers/mmc/card/block.c |   72 +++++++++++++++++++++++++++++++++-------------
 drivers/mmc/card/queue.c |   10 ++++++-
 include/linux/mmc/host.h |    1 +
 3 files changed, 62 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index dd2d374..139971e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -874,10 +874,10 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
 {
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
-	unsigned int from, nr, arg, trim_arg, erase_arg;
+	unsigned int from, nr, arg;
 	int err = 0, type = MMC_BLK_SECDISCARD;
 
-	if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
+	if (!(mmc_can_secure_erase_trim(card))) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -885,23 +885,10 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
 	from = blk_rq_pos(req);
 	nr = blk_rq_sectors(req);
 
-	/* The sanitize operation is supported at v4.5 only */
-	if (mmc_can_sanitize(card)) {
-		erase_arg = MMC_ERASE_ARG;
-		trim_arg = MMC_TRIM_ARG;
-	} else {
-		erase_arg = MMC_SECURE_ERASE_ARG;
-		trim_arg = MMC_SECURE_TRIM1_ARG;
-	}
-
-	if (mmc_erase_group_aligned(card, from, nr))
-		arg = erase_arg;
-	else if (mmc_can_trim(card))
-		arg = trim_arg;
-	else {
-		err = -EINVAL;
-		goto out;
-	}
+	if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
+		arg = MMC_SECURE_TRIM1_ARG;
+	else
+		arg = MMC_SECURE_ERASE_ARG;
 retry:
 	if (card->quirks & MMC_QUIRK_INAND_CMD38) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -953,6 +940,46 @@ out:
 	return err ? 0 : 1;
 }
 
+static int mmc_blk_issue_sanitize_rq(struct mmc_queue *mq,
+				      struct request *req)
+{
+	struct mmc_blk_data *md = mq->data;
+	struct mmc_card *card = md->queue.card;
+	int err = 0;
+
+	BUG_ON(!card);
+	BUG_ON(!card->host);
+
+	if (!(mmc_can_sanitize(card) &&
+	     (card->host->caps2 & MMC_CAP2_SANITIZE))) {
+			pr_warning("%s: %s - SANITIZE is not supported\n",
+				   mmc_hostname(card->host), __func__);
+			err = -EOPNOTSUPP;
+			goto out;
+	}
+
+	pr_debug("%s: %s - SANITIZE IN PROGRESS...\n",
+		mmc_hostname(card->host), __func__);
+
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+					 EXT_CSD_SANITIZE_START, 1, 0);
+
+	if (err)
+		pr_err("%s: %s - mmc_switch() with "
+		       "EXT_CSD_SANITIZE_START failed. err=%d\n",
+		       mmc_hostname(card->host), __func__, err);
+
+	pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host),
+					     __func__);
+
+out:
+	spin_lock_irq(&md->lock);
+	__blk_end_request(req, err, blk_rq_bytes(req));
+	spin_unlock_irq(&md->lock);
+
+	return err ? 0 : 1;
+}
+
 static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
 {
 	struct mmc_blk_data *md = mq->data;
@@ -1437,7 +1464,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 		goto out;
 	}
 
-	if (req && req->cmd_flags & REQ_DISCARD) {
+	if (req && req->cmd_flags & REQ_SANITIZE) {
+		/* complete ongoing async transfer before issuing sanitize */
+		if (card->host && card->host->areq)
+			mmc_blk_issue_rw_rq(mq, NULL);
+		ret = mmc_blk_issue_sanitize_rq(mq, req);
+	} else if (req && req->cmd_flags & REQ_DISCARD) {
 		/* complete ongoing async transfer before issuing discard */
 		if (card->host->areq)
 			mmc_blk_issue_rw_rq(mq, NULL);
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index e360a97..4f3250e 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -145,10 +145,15 @@ static void mmc_queue_setup_discard(struct request_queue *q,
 	/* granularity must not be greater than max. discard */
 	if (card->pref_erase > max_discard)
 		q->limits.discard_granularity = 0;
-	if (mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))
+	if (mmc_can_secure_erase_trim(card))
 		queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
 }
 
+static void mmc_queue_setup_sanitize(struct request_queue *q)
+{
+	queue_flag_set_unlocked(QUEUE_FLAG_SANITIZE, q);
+}
+
 /**
  * mmc_init_queue - initialise a queue structure.
  * @mq: mmc queue
@@ -184,6 +189,9 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
 	if (mmc_can_erase(card))
 		mmc_queue_setup_discard(mq->queue, card);
 
+	if ((mmc_can_sanitize(card) && (host->caps2 & MMC_CAP2_SANITIZE)))
+		mmc_queue_setup_sanitize(mq->queue);
+
 #ifdef CONFIG_MMC_BLOCK_BOUNCE
 	if (host->max_segs == 1) {
 		unsigned int bouncesz;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 0707d22..be2b89f 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -238,6 +238,7 @@ struct mmc_host {
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_SANITIZE	(1 << 10)		/* Support Sanitize */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
-- 
1.7.6
-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum

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

* Re: [PATCH v8 1/2] block: ioctl support for sanitize in eMMC 4.5
  2012-07-25  9:32   ` Yaniv Gardi
@ 2012-07-25 10:41     ` merez
  -1 siblings, 0 replies; 13+ messages in thread
From: merez @ 2012-07-25 10:41 UTC (permalink / raw)
  Cc: linux-mmc, linux-arm-msm, Yaniv Gardi, open list

Looks good to me.
Reviewed-by: Maya Erez <merez@codeaurora.org>

On Wed, July 25, 2012 2:32 am, Yaniv Gardi wrote:
> Adding a new ioctl to support sanitize operation in eMMC
> cards version 4.5.
> The sanitize ioctl support helps performing this operation
> via user application.
>
> Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>
>
> ---
>  block/blk-core.c          |   15 ++++++++++--
>  block/blk-lib.c           |   51
> +++++++++++++++++++++++++++++++++++++++++++++
>  block/blk-merge.c         |    4 +++
>  block/elevator.c          |    2 +-
>  block/ioctl.c             |    9 ++++++++
>  include/linux/blk_types.h |    5 +++-
>  include/linux/blkdev.h    |    3 ++
>  include/linux/fs.h        |    1 +
>  kernel/trace/blktrace.c   |    2 +
>  9 files changed, 87 insertions(+), 5 deletions(-)
>
> diff --git a/block/blk-core.c b/block/blk-core.c
> index 3c923a7..4a56102b 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -1641,7 +1641,7 @@ generic_make_request_checks(struct bio *bio)
>  		goto end_io;
>  	}
>
> -	if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
> +	if (unlikely(!(bio->bi_rw & (REQ_DISCARD | REQ_SANITIZE)) &&
>  		     nr_sectors > queue_max_hw_sectors(q))) {
>  		printk(KERN_ERR "bio too big device %s (%u > %u)\n",
>  		       bdevname(bio->bi_bdev, b),
> @@ -1689,6 +1689,14 @@ generic_make_request_checks(struct bio *bio)
>  		goto end_io;
>  	}
>
> +	if ((bio->bi_rw & REQ_SANITIZE) &&
> +	    (!blk_queue_sanitize(q))) {
> +		pr_info("%s - got a SANITIZE request but the queue "
> +		       "doesn't support sanitize requests", __func__);
> +		err = -EOPNOTSUPP;
> +		goto end_io;
> +	}
> +
>  	if (blk_throtl_bio(q, bio))
>  		return false;	/* throttled, will be resubmitted later */
>
> @@ -1794,7 +1802,8 @@ void submit_bio(int rw, struct bio *bio)
>  	 * If it's a regular read/write or a barrier with data attached,
>  	 * go through the normal accounting stuff before submission.
>  	 */
> -	if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {
> +	if (bio_has_data(bio) &&
> +	    (!(rw & (REQ_DISCARD | REQ_SANITIZE)))) {
>  		if (rw & WRITE) {
>  			count_vm_events(PGPGOUT, count);
>  		} else {
> @@ -1840,7 +1849,7 @@ EXPORT_SYMBOL(submit_bio);
>   */
>  int blk_rq_check_limits(struct request_queue *q, struct request *rq)
>  {
> -	if (rq->cmd_flags & REQ_DISCARD)
> +	if (rq->cmd_flags & (REQ_DISCARD | REQ_SANITIZE))
>  		return 0;
>
>  	if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
> diff --git a/block/blk-lib.c b/block/blk-lib.c
> index 2b461b4..280d63e 100644
> --- a/block/blk-lib.c
> +++ b/block/blk-lib.c
> @@ -115,6 +115,57 @@ int blkdev_issue_discard(struct block_device *bdev,
> sector_t sector,
>  EXPORT_SYMBOL(blkdev_issue_discard);
>
>  /**
> + * blkdev_issue_sanitize - queue a sanitize request
> + * @bdev:	blockdev to issue sanitize for
> + * @gfp_mask:	memory allocation flags (for bio_alloc)
> + *
> + * Description:
> + *    Issue a sanitize request for the specified block device
> + */
> +int blkdev_issue_sanitize(struct block_device *bdev, gfp_t gfp_mask)
> +{
> +	DECLARE_COMPLETION_ONSTACK(wait);
> +	struct request_queue *q = bdev_get_queue(bdev);
> +	int type = REQ_WRITE | REQ_SANITIZE;
> +	struct bio_batch bb;
> +	struct bio *bio;
> +	int ret = 0;
> +
> +	if (!q)
> +		return -ENXIO;
> +
> +	if (!blk_queue_sanitize(q)) {
> +		pr_err("%s - card doesn't support sanitize", __func__);
> +		return -EOPNOTSUPP;
> +	}
> +
> +	bio = bio_alloc(gfp_mask, 1);
> +	if (!bio)
> +		return -ENOMEM;
> +
> +	atomic_set(&bb.done, 1);
> +	bb.flags = 1 << BIO_UPTODATE;
> +	bb.wait = &wait;
> +
> +	bio->bi_end_io = bio_batch_end_io;
> +	bio->bi_bdev = bdev;
> +	bio->bi_private = &bb;
> +
> +	atomic_inc(&bb.done);
> +	submit_bio(type, bio);
> +
> +	/* Wait for bios in-flight */
> +	if (!atomic_dec_and_test(&bb.done))
> +		wait_for_completion(&wait);
> +
> +	if (!test_bit(BIO_UPTODATE, &bb.flags))
> +		ret = -EIO;
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(blkdev_issue_sanitize);
> +
> +/**
>   * blkdev_issue_zeroout - generate number of zero filed write bios
>   * @bdev:	blockdev to issue
>   * @sector:	start sector
> diff --git a/block/blk-merge.c b/block/blk-merge.c
> index 160035f..ef93b23 100644
> --- a/block/blk-merge.c
> +++ b/block/blk-merge.c
> @@ -477,6 +477,10 @@ bool blk_rq_merge_ok(struct request *rq, struct bio
> *bio)
>  	if (!rq_mergeable(rq))
>  		return false;
>
> +	/* don't merge file system requests and sanitize requests */
> +	if ((bio->bi_rw & REQ_SANITIZE) != (rq->bio->bi_rw & REQ_SANITIZE))
> +		return false;
> +
>  	/* don't merge file system requests and discard requests */
>  	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
>  		return false;
> diff --git a/block/elevator.c b/block/elevator.c
> index 6a55d41..91f1de1 100644
> --- a/block/elevator.c
> +++ b/block/elevator.c
> @@ -563,7 +563,7 @@ void __elv_add_request(struct request_queue *q, struct
> request *rq, int where)
>  	if (rq->cmd_flags & REQ_SOFTBARRIER) {
>  		/* barriers are scheduling boundary, update end_sector */
>  		if (rq->cmd_type == REQ_TYPE_FS ||
> -		    (rq->cmd_flags & REQ_DISCARD)) {
> +		    (rq->cmd_flags & (REQ_DISCARD | REQ_SANITIZE))) {
>  			q->end_sector = rq_end_sector(rq);
>  			q->boundary_rq = rq;
>  		}
> diff --git a/block/ioctl.c b/block/ioctl.c
> index ba15b2d..dd76ba0 100644
> --- a/block/ioctl.c
> +++ b/block/ioctl.c
> @@ -132,6 +132,11 @@ static int blk_ioctl_discard(struct block_device
> *bdev, uint64_t start,
>  	return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
>  }
>
> +static int blk_ioctl_sanitize(struct block_device *bdev)
> +{
> +	return blkdev_issue_sanitize(bdev, GFP_KERNEL);
> +}
> +
>  static int put_ushort(unsigned long arg, unsigned short val)
>  {
>  	return put_user(val, (unsigned short __user *)arg);
> @@ -234,6 +239,10 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t
> mode, unsigned cmd,
>  		set_device_ro(bdev, n);
>  		return 0;
>
> +	case BLKSANITIZE:
> +		ret = blk_ioctl_sanitize(bdev);
> +		break;
> +
>  	case BLKDISCARD:
>  	case BLKSECDISCARD: {
>  		uint64_t range[2];
> diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
> index 0edb65d..e58e0db 100644
> --- a/include/linux/blk_types.h
> +++ b/include/linux/blk_types.h
> @@ -160,6 +160,7 @@ enum rq_flag_bits {
>  	__REQ_FLUSH_SEQ,	/* request for flush sequence */
>  	__REQ_IO_STAT,		/* account I/O stat */
>  	__REQ_MIXED_MERGE,	/* merge of different types, fail separately */
> +	__REQ_SANITIZE,		/* sanitize */
>  	__REQ_NR_BITS,		/* stops here */
>  };
>
> @@ -171,13 +172,15 @@ enum rq_flag_bits {
>  #define REQ_META		(1 << __REQ_META)
>  #define REQ_PRIO		(1 << __REQ_PRIO)
>  #define REQ_DISCARD		(1 << __REQ_DISCARD)
> +#define REQ_SANITIZE		(1 << __REQ_SANITIZE)
>  #define REQ_NOIDLE		(1 << __REQ_NOIDLE)
>
>  #define REQ_FAILFAST_MASK \
>  	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
>  #define REQ_COMMON_MASK \
>  	(REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
> -	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE)
> +	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE | \
> +	 REQ_SANITIZE)
>  #define REQ_CLONE_MASK		REQ_COMMON_MASK
>
>  #define REQ_RAHEAD		(1 << __REQ_RAHEAD)
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index ba43f40..1db6c91 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -438,6 +438,7 @@ struct request_queue {
>  #define QUEUE_FLAG_ADD_RANDOM  16	/* Contributes to random pool */
>  #define QUEUE_FLAG_SECDISCARD  17	/* supports SECDISCARD */
>  #define QUEUE_FLAG_SAME_FORCE  18	/* force complete on same CPU */
> +#define QUEUE_FLAG_SANITIZE    19	/* supports SANITIZE */
>
>  #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
>  				 (1 << QUEUE_FLAG_STACKABLE)	|	\
> @@ -518,6 +519,7 @@ static inline void queue_flag_clear(unsigned int flag,
> struct request_queue *q)
>  #define blk_queue_stackable(q)	\
>  	test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
>  #define blk_queue_discard(q)	test_bit(QUEUE_FLAG_DISCARD,
> &(q)->queue_flags)
> +#define blk_queue_sanitize(q)	test_bit(QUEUE_FLAG_SANITIZE,
> &(q)->queue_flags)
>  #define blk_queue_secdiscard(q)	(blk_queue_discard(q) && \
>  	test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags))
>
> @@ -971,6 +973,7 @@ static inline struct request
> *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
>  extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
>  extern int blkdev_issue_discard(struct block_device *bdev, sector_t
> sector,
>  		sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
> +extern int blkdev_issue_sanitize(struct block_device *bdev, gfp_t
> gfp_mask);
>  extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t
> sector,
>  			sector_t nr_sects, gfp_t gfp_mask);
>  static inline int sb_issue_discard(struct super_block *sb, sector_t
> block,
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index b0a6d44..167c450 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -333,6 +333,7 @@ struct inodes_stat_t {
>  #define BLKDISCARDZEROES _IO(0x12,124)
>  #define BLKSECDISCARD _IO(0x12,125)
>  #define BLKROTATIONAL _IO(0x12,126)
> +#define BLKSANITIZE _IO(0x12, 127)
>
>  #define BMAP_IOCTL 1		/* obsolete - kept for compatibility */
>  #define FIBMAP	   _IO(0x00,1)	/* bmap access */
> diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
> index c0bd030..06f7940 100644
> --- a/kernel/trace/blktrace.c
> +++ b/kernel/trace/blktrace.c
> @@ -1788,6 +1788,8 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes)
>  		rwbs[i++] = 'W';
>  	else if (rw & REQ_DISCARD)
>  		rwbs[i++] = 'D';
> +	else if (rw & REQ_SANITIZE)
> +		rwbs[i++] = 'Z';
>  	else if (bytes)
>  		rwbs[i++] = 'R';
>  	else
> --
> 1.7.6
> --
> Sent by a consultant of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Sent by consultant of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

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

* Re: [PATCH v8 1/2] block: ioctl support for sanitize in eMMC 4.5
@ 2012-07-25 10:41     ` merez
  0 siblings, 0 replies; 13+ messages in thread
From: merez @ 2012-07-25 10:41 UTC (permalink / raw)
  To: Yaniv Gardi; +Cc: linux-mmc, linux-arm-msm, Yaniv Gardi, open list

Looks good to me.
Reviewed-by: Maya Erez <merez@codeaurora.org>

On Wed, July 25, 2012 2:32 am, Yaniv Gardi wrote:
> Adding a new ioctl to support sanitize operation in eMMC
> cards version 4.5.
> The sanitize ioctl support helps performing this operation
> via user application.
>
> Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>
>
> ---
>  block/blk-core.c          |   15 ++++++++++--
>  block/blk-lib.c           |   51
> +++++++++++++++++++++++++++++++++++++++++++++
>  block/blk-merge.c         |    4 +++
>  block/elevator.c          |    2 +-
>  block/ioctl.c             |    9 ++++++++
>  include/linux/blk_types.h |    5 +++-
>  include/linux/blkdev.h    |    3 ++
>  include/linux/fs.h        |    1 +
>  kernel/trace/blktrace.c   |    2 +
>  9 files changed, 87 insertions(+), 5 deletions(-)
>
> diff --git a/block/blk-core.c b/block/blk-core.c
> index 3c923a7..4a56102b 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -1641,7 +1641,7 @@ generic_make_request_checks(struct bio *bio)
>  		goto end_io;
>  	}
>
> -	if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
> +	if (unlikely(!(bio->bi_rw & (REQ_DISCARD | REQ_SANITIZE)) &&
>  		     nr_sectors > queue_max_hw_sectors(q))) {
>  		printk(KERN_ERR "bio too big device %s (%u > %u)\n",
>  		       bdevname(bio->bi_bdev, b),
> @@ -1689,6 +1689,14 @@ generic_make_request_checks(struct bio *bio)
>  		goto end_io;
>  	}
>
> +	if ((bio->bi_rw & REQ_SANITIZE) &&
> +	    (!blk_queue_sanitize(q))) {
> +		pr_info("%s - got a SANITIZE request but the queue "
> +		       "doesn't support sanitize requests", __func__);
> +		err = -EOPNOTSUPP;
> +		goto end_io;
> +	}
> +
>  	if (blk_throtl_bio(q, bio))
>  		return false;	/* throttled, will be resubmitted later */
>
> @@ -1794,7 +1802,8 @@ void submit_bio(int rw, struct bio *bio)
>  	 * If it's a regular read/write or a barrier with data attached,
>  	 * go through the normal accounting stuff before submission.
>  	 */
> -	if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {
> +	if (bio_has_data(bio) &&
> +	    (!(rw & (REQ_DISCARD | REQ_SANITIZE)))) {
>  		if (rw & WRITE) {
>  			count_vm_events(PGPGOUT, count);
>  		} else {
> @@ -1840,7 +1849,7 @@ EXPORT_SYMBOL(submit_bio);
>   */
>  int blk_rq_check_limits(struct request_queue *q, struct request *rq)
>  {
> -	if (rq->cmd_flags & REQ_DISCARD)
> +	if (rq->cmd_flags & (REQ_DISCARD | REQ_SANITIZE))
>  		return 0;
>
>  	if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
> diff --git a/block/blk-lib.c b/block/blk-lib.c
> index 2b461b4..280d63e 100644
> --- a/block/blk-lib.c
> +++ b/block/blk-lib.c
> @@ -115,6 +115,57 @@ int blkdev_issue_discard(struct block_device *bdev,
> sector_t sector,
>  EXPORT_SYMBOL(blkdev_issue_discard);
>
>  /**
> + * blkdev_issue_sanitize - queue a sanitize request
> + * @bdev:	blockdev to issue sanitize for
> + * @gfp_mask:	memory allocation flags (for bio_alloc)
> + *
> + * Description:
> + *    Issue a sanitize request for the specified block device
> + */
> +int blkdev_issue_sanitize(struct block_device *bdev, gfp_t gfp_mask)
> +{
> +	DECLARE_COMPLETION_ONSTACK(wait);
> +	struct request_queue *q = bdev_get_queue(bdev);
> +	int type = REQ_WRITE | REQ_SANITIZE;
> +	struct bio_batch bb;
> +	struct bio *bio;
> +	int ret = 0;
> +
> +	if (!q)
> +		return -ENXIO;
> +
> +	if (!blk_queue_sanitize(q)) {
> +		pr_err("%s - card doesn't support sanitize", __func__);
> +		return -EOPNOTSUPP;
> +	}
> +
> +	bio = bio_alloc(gfp_mask, 1);
> +	if (!bio)
> +		return -ENOMEM;
> +
> +	atomic_set(&bb.done, 1);
> +	bb.flags = 1 << BIO_UPTODATE;
> +	bb.wait = &wait;
> +
> +	bio->bi_end_io = bio_batch_end_io;
> +	bio->bi_bdev = bdev;
> +	bio->bi_private = &bb;
> +
> +	atomic_inc(&bb.done);
> +	submit_bio(type, bio);
> +
> +	/* Wait for bios in-flight */
> +	if (!atomic_dec_and_test(&bb.done))
> +		wait_for_completion(&wait);
> +
> +	if (!test_bit(BIO_UPTODATE, &bb.flags))
> +		ret = -EIO;
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(blkdev_issue_sanitize);
> +
> +/**
>   * blkdev_issue_zeroout - generate number of zero filed write bios
>   * @bdev:	blockdev to issue
>   * @sector:	start sector
> diff --git a/block/blk-merge.c b/block/blk-merge.c
> index 160035f..ef93b23 100644
> --- a/block/blk-merge.c
> +++ b/block/blk-merge.c
> @@ -477,6 +477,10 @@ bool blk_rq_merge_ok(struct request *rq, struct bio
> *bio)
>  	if (!rq_mergeable(rq))
>  		return false;
>
> +	/* don't merge file system requests and sanitize requests */
> +	if ((bio->bi_rw & REQ_SANITIZE) != (rq->bio->bi_rw & REQ_SANITIZE))
> +		return false;
> +
>  	/* don't merge file system requests and discard requests */
>  	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
>  		return false;
> diff --git a/block/elevator.c b/block/elevator.c
> index 6a55d41..91f1de1 100644
> --- a/block/elevator.c
> +++ b/block/elevator.c
> @@ -563,7 +563,7 @@ void __elv_add_request(struct request_queue *q, struct
> request *rq, int where)
>  	if (rq->cmd_flags & REQ_SOFTBARRIER) {
>  		/* barriers are scheduling boundary, update end_sector */
>  		if (rq->cmd_type == REQ_TYPE_FS ||
> -		    (rq->cmd_flags & REQ_DISCARD)) {
> +		    (rq->cmd_flags & (REQ_DISCARD | REQ_SANITIZE))) {
>  			q->end_sector = rq_end_sector(rq);
>  			q->boundary_rq = rq;
>  		}
> diff --git a/block/ioctl.c b/block/ioctl.c
> index ba15b2d..dd76ba0 100644
> --- a/block/ioctl.c
> +++ b/block/ioctl.c
> @@ -132,6 +132,11 @@ static int blk_ioctl_discard(struct block_device
> *bdev, uint64_t start,
>  	return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
>  }
>
> +static int blk_ioctl_sanitize(struct block_device *bdev)
> +{
> +	return blkdev_issue_sanitize(bdev, GFP_KERNEL);
> +}
> +
>  static int put_ushort(unsigned long arg, unsigned short val)
>  {
>  	return put_user(val, (unsigned short __user *)arg);
> @@ -234,6 +239,10 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t
> mode, unsigned cmd,
>  		set_device_ro(bdev, n);
>  		return 0;
>
> +	case BLKSANITIZE:
> +		ret = blk_ioctl_sanitize(bdev);
> +		break;
> +
>  	case BLKDISCARD:
>  	case BLKSECDISCARD: {
>  		uint64_t range[2];
> diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
> index 0edb65d..e58e0db 100644
> --- a/include/linux/blk_types.h
> +++ b/include/linux/blk_types.h
> @@ -160,6 +160,7 @@ enum rq_flag_bits {
>  	__REQ_FLUSH_SEQ,	/* request for flush sequence */
>  	__REQ_IO_STAT,		/* account I/O stat */
>  	__REQ_MIXED_MERGE,	/* merge of different types, fail separately */
> +	__REQ_SANITIZE,		/* sanitize */
>  	__REQ_NR_BITS,		/* stops here */
>  };
>
> @@ -171,13 +172,15 @@ enum rq_flag_bits {
>  #define REQ_META		(1 << __REQ_META)
>  #define REQ_PRIO		(1 << __REQ_PRIO)
>  #define REQ_DISCARD		(1 << __REQ_DISCARD)
> +#define REQ_SANITIZE		(1 << __REQ_SANITIZE)
>  #define REQ_NOIDLE		(1 << __REQ_NOIDLE)
>
>  #define REQ_FAILFAST_MASK \
>  	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
>  #define REQ_COMMON_MASK \
>  	(REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
> -	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE)
> +	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE | \
> +	 REQ_SANITIZE)
>  #define REQ_CLONE_MASK		REQ_COMMON_MASK
>
>  #define REQ_RAHEAD		(1 << __REQ_RAHEAD)
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index ba43f40..1db6c91 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -438,6 +438,7 @@ struct request_queue {
>  #define QUEUE_FLAG_ADD_RANDOM  16	/* Contributes to random pool */
>  #define QUEUE_FLAG_SECDISCARD  17	/* supports SECDISCARD */
>  #define QUEUE_FLAG_SAME_FORCE  18	/* force complete on same CPU */
> +#define QUEUE_FLAG_SANITIZE    19	/* supports SANITIZE */
>
>  #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
>  				 (1 << QUEUE_FLAG_STACKABLE)	|	\
> @@ -518,6 +519,7 @@ static inline void queue_flag_clear(unsigned int flag,
> struct request_queue *q)
>  #define blk_queue_stackable(q)	\
>  	test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
>  #define blk_queue_discard(q)	test_bit(QUEUE_FLAG_DISCARD,
> &(q)->queue_flags)
> +#define blk_queue_sanitize(q)	test_bit(QUEUE_FLAG_SANITIZE,
> &(q)->queue_flags)
>  #define blk_queue_secdiscard(q)	(blk_queue_discard(q) && \
>  	test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags))
>
> @@ -971,6 +973,7 @@ static inline struct request
> *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
>  extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
>  extern int blkdev_issue_discard(struct block_device *bdev, sector_t
> sector,
>  		sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
> +extern int blkdev_issue_sanitize(struct block_device *bdev, gfp_t
> gfp_mask);
>  extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t
> sector,
>  			sector_t nr_sects, gfp_t gfp_mask);
>  static inline int sb_issue_discard(struct super_block *sb, sector_t
> block,
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index b0a6d44..167c450 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -333,6 +333,7 @@ struct inodes_stat_t {
>  #define BLKDISCARDZEROES _IO(0x12,124)
>  #define BLKSECDISCARD _IO(0x12,125)
>  #define BLKROTATIONAL _IO(0x12,126)
> +#define BLKSANITIZE _IO(0x12, 127)
>
>  #define BMAP_IOCTL 1		/* obsolete - kept for compatibility */
>  #define FIBMAP	   _IO(0x00,1)	/* bmap access */
> diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
> index c0bd030..06f7940 100644
> --- a/kernel/trace/blktrace.c
> +++ b/kernel/trace/blktrace.c
> @@ -1788,6 +1788,8 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes)
>  		rwbs[i++] = 'W';
>  	else if (rw & REQ_DISCARD)
>  		rwbs[i++] = 'D';
> +	else if (rw & REQ_SANITIZE)
> +		rwbs[i++] = 'Z';
>  	else if (bytes)
>  		rwbs[i++] = 'R';
>  	else
> --
> 1.7.6
> --
> Sent by a consultant of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Sent by consultant of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum


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

* Re: [PATCH v8 2/2] mmc: card: Adding support for sanitize in eMMC 4.5
  2012-07-25  9:32   ` Yaniv Gardi
@ 2012-07-25 11:06     ` merez
  -1 siblings, 0 replies; 13+ messages in thread
From: merez @ 2012-07-25 11:06 UTC (permalink / raw)
  Cc: linux-mmc, linux-arm-msm, Yaniv Gardi, open list


On Wed, July 25, 2012 2:32 am, Yaniv Gardi wrote:
> @@ -238,6 +238,7 @@ struct mmc_host {
>  #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
>  #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal
> */
>  #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
> +#define MMC_CAP2_SANITIZE	(1 << 10)		/* Support Sanitize */
Need to rebase and change CAP2 according to the latest number.
>
>  	mmc_pm_flag_t		pm_caps;	/* supported pm features */
>  	unsigned int        power_notify_type;
> --
> 1.7.6
> --
> Sent by a consultant of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Thanks,
Maya

-- 
Sent by consultant of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

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

* Re: [PATCH v8 2/2] mmc: card: Adding support for sanitize in eMMC  4.5
@ 2012-07-25 11:06     ` merez
  0 siblings, 0 replies; 13+ messages in thread
From: merez @ 2012-07-25 11:06 UTC (permalink / raw)
  To: Yaniv Gardi; +Cc: linux-mmc, linux-arm-msm, Yaniv Gardi, open list


On Wed, July 25, 2012 2:32 am, Yaniv Gardi wrote:
> @@ -238,6 +238,7 @@ struct mmc_host {
>  #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
>  #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal
> */
>  #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
> +#define MMC_CAP2_SANITIZE	(1 << 10)		/* Support Sanitize */
Need to rebase and change CAP2 according to the latest number.
>
>  	mmc_pm_flag_t		pm_caps;	/* supported pm features */
>  	unsigned int        power_notify_type;
> --
> 1.7.6
> --
> Sent by a consultant of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Thanks,
Maya

-- 
Sent by consultant of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum


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

* Re: [PATCH v8 2/2] mmc: card: Adding support for sanitize in eMMC 4.5
  2012-07-25  9:32   ` Yaniv Gardi
  (?)
  (?)
@ 2012-07-26 13:27   ` Arnd Bergmann
  -1 siblings, 0 replies; 13+ messages in thread
From: Arnd Bergmann @ 2012-07-26 13:27 UTC (permalink / raw)
  To: Yaniv Gardi; +Cc: linux-mmc, linux-arm-msm, open list

On Wednesday 25 July 2012, Yaniv Gardi wrote:
> This feature delete the unmap memory region of the eMMC card,
> by writing to a specific register in the EXT_CSD
> unmap region is the memory region that were previously deleted
> (by erase, trim or discard operation)
> 
> Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>

This looks like it will only work for eMMC-4.5 but not for SD-3.01, which
offers the same funcitonality in the form of the "start recording" option
to CMD20. Is there any reason why you would want to implement one but
not the other?

	Arnd


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

* Re: [PATCH v8 1/2] block: ioctl support for sanitize in eMMC 4.5
  2012-07-25  9:32   ` Yaniv Gardi
  (?)
  (?)
@ 2012-07-26 13:36   ` Arnd Bergmann
  2012-09-09 12:12       ` Yaniv Gardi
  -1 siblings, 1 reply; 13+ messages in thread
From: Arnd Bergmann @ 2012-07-26 13:36 UTC (permalink / raw)
  To: Yaniv Gardi; +Cc: linux-mmc, linux-arm-msm, open list

On Wednesday 25 July 2012, Yaniv Gardi wrote:
> 
> Adding a new ioctl to support sanitize operation in eMMC
> cards version 4.5.
> The sanitize ioctl support helps performing this operation
> via user application.
> 
> Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>
> 

Can you explain how you expect this to be called by a file system?
We've debated this in the past and concluded that we probably
want to do it at the same time as batched discard, but I don't
see if the sanitize request should be sent for each FITRIM
or whether we should better have a separate file system level
ioctl. My feeling is that it would be more useful to call this
feature through a file system level ioctl than through a block
level ioctl, but I guess it makes sense to support both.

	Arnd

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

* RE: [PATCH v8 1/2] block: ioctl support for sanitize in eMMC 4.5
  2012-07-26 13:36   ` Arnd Bergmann
@ 2012-09-09 12:12       ` Yaniv Gardi
  0 siblings, 0 replies; 13+ messages in thread
From: Yaniv Gardi @ 2012-09-09 12:12 UTC (permalink / raw)
  To: 'Arnd Bergmann'; +Cc: linux-mmc, linux-arm-msm, 'open list'

I didn't quite understand everything that you meant in your mail, however I
will try to explain briefly:

SANITIZE replaces the need to issue REQ_SECURE as part of the REQ_DISCARD
request. In this way DISCARD request finishes much faster (order of
magnitude) and thus improves system performance. When the NVM content must
be erased, the user may use SANITIZE to erase all unmapped sectors. 

An example of usage is refurbished devices in which the carrier wants to
erase NVM content (since the user used only DISCARDs), in this case the a
SANITIZE operation will be triggered in the carrier labs from a dedicated
application through IOCTL that goes directly to the device. Note that no
change to the FS is required for such operation.

Hope that answers your comments.

Thanks,
Yaniv

QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


= > -----Original Message-----
= > From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
= > owner@vger.kernel.org] On Behalf Of Arnd Bergmann
= > Sent: Thursday, July 26, 2012 4:37 PM
= > To: Yaniv Gardi
= > Cc: linux-mmc@vger.kernel.org; linux-arm-msm@vger.kernel.org; open
= > list
= > Subject: Re: [PATCH v8 1/2] block: ioctl support for sanitize in eMMC
4.5
= > 
= > On Wednesday 25 July 2012, Yaniv Gardi wrote:
= > >
= > > Adding a new ioctl to support sanitize operation in eMMC cards version
= > > 4.5.
= > > The sanitize ioctl support helps performing this operation via user
= > > application.
= > >
= > > Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>
= > >
= > 
= > Can you explain how you expect this to be called by a file system?
= > We've debated this in the past and concluded that we probably want to do
= > it at the same time as batched discard, but I don't see if the sanitize
= > request should be sent for each FITRIM or whether we should better have
= > a separate file system level ioctl. My feeling is that it would be more
useful
= > to call this feature through a file system level ioctl than through a
block
= > level ioctl, but I guess it makes sense to support both.
= > 
= > 	Arnd
= > 
= > --
= > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the
= > body of a message to majordomo@vger.kernel.org More majordomo info
= > at  http://vger.kernel.org/majordomo-info.html


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

* RE: [PATCH v8 1/2] block: ioctl support for sanitize in eMMC 4.5
@ 2012-09-09 12:12       ` Yaniv Gardi
  0 siblings, 0 replies; 13+ messages in thread
From: Yaniv Gardi @ 2012-09-09 12:12 UTC (permalink / raw)
  To: 'Arnd Bergmann'; +Cc: linux-mmc, linux-arm-msm, 'open list'

I didn't quite understand everything that you meant in your mail, however I
will try to explain briefly:

SANITIZE replaces the need to issue REQ_SECURE as part of the REQ_DISCARD
request. In this way DISCARD request finishes much faster (order of
magnitude) and thus improves system performance. When the NVM content must
be erased, the user may use SANITIZE to erase all unmapped sectors. 

An example of usage is refurbished devices in which the carrier wants to
erase NVM content (since the user used only DISCARDs), in this case the a
SANITIZE operation will be triggered in the carrier labs from a dedicated
application through IOCTL that goes directly to the device. Note that no
change to the FS is required for such operation.

Hope that answers your comments.

Thanks,
Yaniv

QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


= > -----Original Message-----
= > From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
= > owner@vger.kernel.org] On Behalf Of Arnd Bergmann
= > Sent: Thursday, July 26, 2012 4:37 PM
= > To: Yaniv Gardi
= > Cc: linux-mmc@vger.kernel.org; linux-arm-msm@vger.kernel.org; open
= > list
= > Subject: Re: [PATCH v8 1/2] block: ioctl support for sanitize in eMMC
4.5
= > 
= > On Wednesday 25 July 2012, Yaniv Gardi wrote:
= > >
= > > Adding a new ioctl to support sanitize operation in eMMC cards version
= > > 4.5.
= > > The sanitize ioctl support helps performing this operation via user
= > > application.
= > >
= > > Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>
= > >
= > 
= > Can you explain how you expect this to be called by a file system?
= > We've debated this in the past and concluded that we probably want to do
= > it at the same time as batched discard, but I don't see if the sanitize
= > request should be sent for each FITRIM or whether we should better have
= > a separate file system level ioctl. My feeling is that it would be more
useful
= > to call this feature through a file system level ioctl than through a
block
= > level ioctl, but I guess it makes sense to support both.
= > 
= > 	Arnd
= > 
= > --
= > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the
= > body of a message to majordomo@vger.kernel.org More majordomo info
= > at  http://vger.kernel.org/majordomo-info.html


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

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

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-25  9:32 [PATCH v8 0/2] *** adding and exposing SANITIZE capability to the user space via a unique IOCTL *** Yaniv Gardi
2012-07-25  9:32 ` [PATCH v8 1/2] block: ioctl support for sanitize in eMMC 4.5 Yaniv Gardi
2012-07-25  9:32   ` Yaniv Gardi
2012-07-25 10:41   ` merez
2012-07-25 10:41     ` merez
2012-07-26 13:36   ` Arnd Bergmann
2012-09-09 12:12     ` Yaniv Gardi
2012-09-09 12:12       ` Yaniv Gardi
2012-07-25  9:32 ` [PATCH v8 2/2] mmc: card: Adding " Yaniv Gardi
2012-07-25  9:32   ` Yaniv Gardi
2012-07-25 11:06   ` merez
2012-07-25 11:06     ` merez
2012-07-26 13:27   ` Arnd Bergmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.