diff mbox

mmc: card: Add Sanitize unit test

Message ID 1343198350-5307-1-git-send-email-merez@codeaurora.org (mailing list archive)
State New, archived
Headers show

Commit Message

Maya Erez July 25, 2012, 6:37 a.m. UTC
This test write data to the card, then send DISCARD on random
addresses on the card, send SANITIZE to the card to erase all
the unmapped areas.

Signed-off-by: Maya Erez <merez@codeaurora.org>
---
This patch depends of the following patches:
  [PATCH RESEND v7 1/2] block: ioctl support for sanitize in eMMC 4.5
  [PATCH RESEND v7 2/2] mmc: card: Adding support for sanitize in eMMC 4.5
  [PATCH v4 2/3] block: Add test-iosched scheduler
  [PATCH v4 3/3] mmc: card: Add eMMC4.5 write packed commands unit-tests

---
 block/test-iosched.c              |    3 +
 drivers/mmc/card/mmc_block_test.c |  120 +++++++++++++++++++++++++++++++++++++
 include/linux/test-iosched.h      |    1 +
 3 files changed, 124 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/block/test-iosched.c b/block/test-iosched.c
index 6f0b0b3..e04befd 100644
--- a/block/test-iosched.c
+++ b/block/test-iosched.c
@@ -173,6 +173,9 @@  int test_iosched_add_unique_test_req(int is_err_expcted,
 		bio->bi_size = nr_sects << 9;
 		bio->bi_sector = start_sec;
 		break;
+	case REQ_UNIQUE_SANITIZE:
+		bio->bi_rw = REQ_WRITE | REQ_SANITIZE;
+		break;
 	default:
 		test_pr_err("%s: Invalid request type %d", __func__,
 			    req_unique);
diff --git a/drivers/mmc/card/mmc_block_test.c b/drivers/mmc/card/mmc_block_test.c
index f2a0ac7..25af8cc 100644
--- a/drivers/mmc/card/mmc_block_test.c
+++ b/drivers/mmc/card/mmc_block_test.c
@@ -33,11 +33,16 @@ 
 #define PACKED_HDR_RW_MASK 0x0000FF00
 #define PACKED_HDR_NUM_REQS_MASK 0x00FF0000
 #define PACKED_HDR_BITS_16_TO_29_SET 0x3FFF0000
+#define SECTOR_SIZE 512
+#define NUM_OF_SECTORS_PER_BIO		((BIO_U32_SIZE * 4) / SECTOR_SIZE)
+#define BIO_TO_SECTOR(x)		(x * NUM_OF_SECTORS_PER_BIO)
 
 #define test_pr_debug(fmt, args...) pr_debug("%s: "fmt"\n", MODULE_NAME, args)
 #define test_pr_info(fmt, args...) pr_info("%s: "fmt"\n", MODULE_NAME, args)
 #define test_pr_err(fmt, args...) pr_err("%s: "fmt"\n", MODULE_NAME, args)
 
+#define SANITIZE_TEST_TIMEOUT 240000
+
 enum is_random {
 	NON_RANDOM_TEST,
 	RANDOM_TEST,
@@ -83,6 +88,8 @@  enum mmc_block_test_testcases {
 	TEST_CMD23_BITS_16TO29_SET,
 	TEST_CMD23_HDR_BLK_NOT_IN_COUNT,
 	INVALID_CMD_MAX_TESTCASE = TEST_CMD23_HDR_BLK_NOT_IN_COUNT,
+
+	TEST_WRITE_DISCARD_SANITIZE_READ,
 };
 
 enum mmc_block_test_group {
@@ -98,6 +105,7 @@  struct mmc_block_test_debug {
 	struct dentry *err_check_test;
 	struct dentry *send_invalid_packed_test;
 	struct dentry *random_test_seed;
+	struct dentry *discard_sanitize_test;
 };
 
 struct mmc_block_test_data {
@@ -454,6 +462,8 @@  static char *get_test_case_str(struct test_data *td)
 		return "Test invalid - cmd23 bits [16-29] set";
 	case TEST_CMD23_HDR_BLK_NOT_IN_COUNT:
 		return "Test invalid - cmd23 header block not in count";
+	case TEST_WRITE_DISCARD_SANITIZE_READ:
+		return "\nTest write, discard, sanitize";
 	default:
 		 return "Unknown testcase";
 	}
@@ -1080,6 +1090,63 @@  static int validate_packed_commands_settings(void)
 	return 0;
 }
 
+static void pseudo_rnd_sector_and_size(unsigned int *seed,
+				       unsigned int min_start_sector,
+				       unsigned int *start_sector,
+				       unsigned int *num_of_bios)
+{
+	unsigned int max_sec = min_start_sector + TEST_MAX_SECTOR_RANGE;
+	do {
+		*start_sector = pseudo_random_seed(seed,
+						   1, max_sec);
+		*num_of_bios = pseudo_random_seed(seed,
+						  1, TEST_MAX_BIOS_PER_REQ);
+		if (!(*num_of_bios))
+			*num_of_bios = 1;
+	} while ((*start_sector < min_start_sector) ||
+		 (*start_sector + (*num_of_bios * BIO_U32_SIZE * 4)) > max_sec);
+}
+
+/* sanitize test functions */
+static int prepare_write_discard_sanitize_read(struct test_data *td)
+{
+	unsigned int start_sector;
+	unsigned int num_of_bios = 0;
+	static unsigned int total_bios;
+	unsigned int *num_bios_seed;
+	int i = 0;
+
+	if (mbtd->random_test_seed == 0) {
+		mbtd->random_test_seed =
+			(unsigned int)(get_jiffies_64() & 0xFFFF);
+		test_pr_info("%s: got seed from jiffies %d",
+			     __func__, mbtd->random_test_seed);
+	}
+	num_bios_seed = &mbtd->random_test_seed;
+
+	do {
+		pseudo_rnd_sector_and_size(num_bios_seed, td->start_sector,
+					   &start_sector, &num_of_bios);
+
+		/* DISCARD */
+		total_bios += num_of_bios;
+		test_pr_info("%s: discard req: id=%d, startSec=%d, NumBios=%d",
+		       __func__, td->unique_next_req_id, start_sector,
+			     num_of_bios);
+		test_iosched_add_unique_test_req(0, REQ_UNIQUE_DISCARD,
+				    start_sector, BIO_TO_SECTOR(num_of_bios),
+						 NULL);
+
+	} while (++i < (BLKDEV_MAX_RQ-10));
+
+	test_pr_info("%s: total discard bios = %d", __func__, total_bios);
+
+	test_pr_info("%s: add sanitize req", __func__);
+	test_iosched_add_unique_test_req(0, REQ_UNIQUE_SANITIZE, 0, 0, NULL);
+
+	return 0;
+}
+
 static bool message_repeat;
 static int test_open(struct inode *inode, struct file *file)
 {
@@ -1397,12 +1464,56 @@  const struct file_operations send_invalid_packed_test_ops = {
 	.read = send_invalid_packed_test_read,
 };
 
+static ssize_t write_discard_sanitize_test_write(struct file *file,
+				const char __user *buf,
+				size_t count,
+				loff_t *ppos)
+{
+	int ret = 0;
+	int i = 0;
+	int number = -1;
+
+	sscanf(buf, "%d", &number);
+	if (number <= 0)
+		number = 1;
+
+	test_pr_info("%s: -- write_discard_sanitize TEST --\n", __func__);
+
+	memset(&mbtd->test_info, 0, sizeof(struct test_info));
+
+	mbtd->test_group = TEST_GENERAL_GROUP;
+
+	mbtd->test_info.data = mbtd;
+	mbtd->test_info.prepare_test_fn = prepare_write_discard_sanitize_read;
+	mbtd->test_info.get_test_case_str_fn = get_test_case_str;
+	mbtd->test_info.timeout_msec = SANITIZE_TEST_TIMEOUT;
+
+	for (i = 0 ; i < number ; ++i) {
+		test_pr_info("%s: Cycle # %d / %d\n", __func__, i+1, number);
+		test_pr_info("%s: ===================", __func__);
+
+		mbtd->test_info.testcase = TEST_WRITE_DISCARD_SANITIZE_READ;
+		ret = test_iosched_start_test(&mbtd->test_info);
+
+		if (ret)
+			break;
+	}
+
+	return count;
+}
+
+const struct file_operations write_discard_sanitize_test_ops = {
+	.open = test_open,
+	.write = write_discard_sanitize_test_write,
+};
+
 static void mmc_block_test_debugfs_cleanup(void)
 {
 	debugfs_remove(mbtd->debug.random_test_seed);
 	debugfs_remove(mbtd->debug.send_write_packing_test);
 	debugfs_remove(mbtd->debug.err_check_test);
 	debugfs_remove(mbtd->debug.send_invalid_packed_test);
+	debugfs_remove(mbtd->debug.discard_sanitize_test);
 }
 
 static int mmc_block_test_debugfs_init(void)
@@ -1454,6 +1565,15 @@  static int mmc_block_test_debugfs_init(void)
 	if (!mbtd->debug.send_invalid_packed_test)
 		goto err_nomem;
 
+	mbtd->debug.discard_sanitize_test =
+		debugfs_create_file("write_discard_sanitize_test",
+				    S_IRUGO | S_IWUGO,
+				    tests_root,
+				    NULL,
+				    &write_discard_sanitize_test_ops);
+	if (!mbtd->debug.discard_sanitize_test)
+		goto err_nomem;
+
 	return 0;
 
 err_nomem:
diff --git a/include/linux/test-iosched.h b/include/linux/test-iosched.h
index 8054409..1e428c5 100644
--- a/include/linux/test-iosched.h
+++ b/include/linux/test-iosched.h
@@ -65,6 +65,7 @@  enum req_unique_type {
 	REQ_UNIQUE_NONE,
 	REQ_UNIQUE_DISCARD,
 	REQ_UNIQUE_FLUSH,
+	REQ_UNIQUE_SANITIZE,
 };
 
 /**