public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] NAND: nandsim bad block injection
@ 2006-12-24 13:08 Vijay Kumar
  2006-12-27 11:26 ` Artem Bityutskiy
  0 siblings, 1 reply; 4+ messages in thread
From: Vijay Kumar @ 2006-12-24 13:08 UTC (permalink / raw)
  To: dedekind; +Cc: linux-mtd

Adds support for bad block creation on block erase and page program,
by returning erase/program failed in the status byte. The probability
of fault occurrence can be specified through module parameters.

Signed-off-by: Vijay Kumar <vijaykumar@bravegnu.org>

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index c3bca95..ee71357 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -37,6 +37,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
+#include <linux/random.h>
 
 /* Default simulator parameters values */
 #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE)  || \
@@ -70,6 +71,12 @@
 #ifndef CONFIG_NANDSIM_DO_DELAYS
 #define CONFIG_NANDSIM_DO_DELAYS  0
 #endif
+#ifndef CONFIG_NANDSIM_ERASE_FAIL_PROB
+#define CONFIG_NANDSIM_ERASE_FAIL_PROB 0
+#endif
+#ifndef CONFIG_NANDSIM_PROG_FAIL_PROB
+#define CONFIG_NANDSIM_PROG_FAIL_PROB 0
+#endif
 #ifndef CONFIG_NANDSIM_LOG
 #define CONFIG_NANDSIM_LOG        0
 #endif
@@ -77,6 +84,9 @@
 #define CONFIG_NANDSIM_DBG        0
 #endif
 
+#define PROB_SCALE_FACTOR         1000
+#define PROB_SCALE_FACTOR_STR     "1000"
+
 static uint first_id_byte  = CONFIG_NANDSIM_FIRST_ID_BYTE;
 static uint second_id_byte = CONFIG_NANDSIM_SECOND_ID_BYTE;
 static uint third_id_byte  = CONFIG_NANDSIM_THIRD_ID_BYTE;
@@ -88,6 +98,8 @@ static uint output_cycle   = CONFIG_NAND
 static uint input_cycle    = CONFIG_NANDSIM_INPUT_CYCLE;
 static uint bus_width      = CONFIG_NANDSIM_BUS_WIDTH;
 static uint do_delays      = CONFIG_NANDSIM_DO_DELAYS;
+static uint erase_fail_prob = CONFIG_NANDSIM_ERASE_FAIL_PROB;
+static uint prog_fail_prob = CONFIG_NANDSIM_PROG_FAIL_PROB;
 static uint log            = CONFIG_NANDSIM_LOG;
 static uint dbg            = CONFIG_NANDSIM_DBG;
 
@@ -102,6 +114,8 @@ module_param(output_cycle,   uint, 0400)
 module_param(input_cycle,    uint, 0400);
 module_param(bus_width,      uint, 0400);
 module_param(do_delays,      uint, 0400);
+module_param(erase_fail_prob, uint, 0400);
+module_param(prog_fail_prob, uint, 0400);
 module_param(log,            uint, 0400);
 module_param(dbg,            uint, 0400);
 
@@ -116,6 +130,8 @@ MODULE_PARM_DESC(output_cycle,   "Word o
 MODULE_PARM_DESC(input_cycle,    "Word input (to flash) time (nanodeconds)");
 MODULE_PARM_DESC(bus_width,      "Chip's bus width (8- or 16-bit)");
 MODULE_PARM_DESC(do_delays,      "Simulate NAND delays using busy-waits if not zero");
+MODULE_PARM_DESC(erase_fail_prob, "Probability (scaled by " PROB_SCALE_FACTOR_STR ") of erase failing, default 0");
+MODULE_PARM_DESC(prog_fail_prob, "Probability (scaled by " PROB_SCALE_FACTOR_STR ") of program failing, default 0");
 MODULE_PARM_DESC(log,            "Perform logging if not zero");
 MODULE_PARM_DESC(dbg,            "Output debug information if not zero");
 
@@ -875,6 +891,37 @@ static int prog_page(struct nandsim *ns,
 }
 
 /*
+ * Given the probability (scaled by PROB_SCALE_FACTOR) 'prob', the
+ * function determines whether fault has to be injected. 'prob' is
+ * specified in the range 0 - PROB_SCALE_FACTOR. Probability is
+ * calculated as 'prob'/PROB_SCALE_FACTOR.
+ *
+ * RETURNS: 1 if fault should be injected, 0 if fault should not be
+ * injected.
+ */
+static int inject_fault_with_prob(int prob)
+{
+	int rnd;
+
+	rnd = random32() % PROB_SCALE_FACTOR;
+
+	if (rnd < prob)
+		return 1;
+	else
+		return 0;
+}
+
+static inline int inject_erase_fault(void)
+{
+	return inject_fault_with_prob(erase_fail_prob);
+}
+
+static inline int inject_prog_fault(void)
+{
+	return inject_fault_with_prob(prog_fail_prob);
+}
+
+/*
  * If state has any action bit, perform this action.
  *
  * RETURNS: 0 if success, -1 if error.
@@ -948,6 +995,16 @@ static int do_state_action(struct nandsi
 
 		erase_sector(ns);
 
+		/* 
+		 * Injecting fault after erasing the sector, saves
+		 * memory since the memory used by the bad block is
+		 * freed.
+		 */
+		if (inject_erase_fault()) {
+			NS_DBG("do_state_action: injecting erase fault\n");
+			return -1;
+		}
+
 		NS_MDELAY(erase_delay);
 
 		break;
@@ -969,6 +1026,15 @@ static int do_state_action(struct nandsi
 			return -1;
 		}
 
+		/* 
+		 * Injecting fault before programming the sector,
+		 * helps to save memory.
+		 */
+		if (inject_prog_fault()) {
+			NS_DBG("do_state_action: injecting page prog fault\n");
+			return -1;
+		}
+
 		if (prog_page(ns, num) == -1)
 			return -1;
 

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

* Re: [PATCH] NAND: nandsim bad block injection
  2006-12-24 13:08 [PATCH] NAND: nandsim bad block injection Vijay Kumar
@ 2006-12-27 11:26 ` Artem Bityutskiy
  0 siblings, 0 replies; 4+ messages in thread
From: Artem Bityutskiy @ 2006-12-27 11:26 UTC (permalink / raw)
  To: Vijay Kumar; +Cc: linux-mtd

Hello Vijay,

On Sun, 2006-12-24 at 18:38 +0530, Vijay Kumar wrote:
> Adds support for bad block creation on block erase and page program,
> by returning erase/program failed in the status byte. The probability
> of fault occurrence can be specified through module parameters.
> 
> Signed-off-by: Vijay Kumar <vijaykumar@bravegnu.org>

Looks useful.
 
> +#define PROB_SCALE_FACTOR         1000
> +#define PROB_SCALE_FACTOR_STR     "1000"
Use __stringify(PROB_SCALE_FACTOR) instead.

> +static int inject_fault_with_prob(int prob)
> +{
> +	int rnd;
> +
> +	rnd = random32() % PROB_SCALE_FACTOR;
> +
> +	if (rnd < prob)
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +static inline int inject_erase_fault(void)
> +{
> +	return inject_fault_with_prob(erase_fail_prob);
> +}
I think there is no need in having 'inject_fault_with_prob()' function
at all. Just use

int rnd = random32() % PROB_SCALE_FACTOR;
return rnd < prob;

> +
> +static inline int inject_prog_fault(void)
> +{
> +	return inject_fault_with_prob(prog_fail_prob);
> +}
Ditto.

-- 
Best regards,
Artem Bityutskiy (Битюцкий Артём)

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

* [PATCH] NAND: nandsim bad block injection
@ 2006-12-27 15:24 Vijay Kumar
  2006-12-28 10:22 ` Artem Bityutskiy
  0 siblings, 1 reply; 4+ messages in thread
From: Vijay Kumar @ 2006-12-27 15:24 UTC (permalink / raw)
  To: dedekind; +Cc: linux-mtd

Artem, here's the update patch.

Adds support for bad block creation on block erase and page program,
by returning erase/program failed in the status byte. The probability
of fault occurrence can be specified through module parameters.

Signed-off-by: Vijay Kumar <vijaykumar@bravegnu.org>

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index c3bca95..00b60dc 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -37,6 +37,8 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/stringify.h>
 
 /* Default simulator parameters values */
 #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE)  || \
@@ -70,6 +72,12 @@
 #ifndef CONFIG_NANDSIM_DO_DELAYS
 #define CONFIG_NANDSIM_DO_DELAYS  0
 #endif
+#ifndef CONFIG_NANDSIM_ERASE_FAIL_PROB
+#define CONFIG_NANDSIM_ERASE_FAIL_PROB 0
+#endif
+#ifndef CONFIG_NANDSIM_PROG_FAIL_PROB
+#define CONFIG_NANDSIM_PROG_FAIL_PROB 0
+#endif
 #ifndef CONFIG_NANDSIM_LOG
 #define CONFIG_NANDSIM_LOG        0
 #endif
@@ -77,6 +85,9 @@
 #define CONFIG_NANDSIM_DBG        0
 #endif
 
+#define PROB_SCALE_FACTOR         1000
+#define PROB_SCALE_FACTOR_STR     __stringify(PROB_SCALE_FACTOR)
+
 static uint first_id_byte  = CONFIG_NANDSIM_FIRST_ID_BYTE;
 static uint second_id_byte = CONFIG_NANDSIM_SECOND_ID_BYTE;
 static uint third_id_byte  = CONFIG_NANDSIM_THIRD_ID_BYTE;
@@ -88,6 +99,8 @@ static uint output_cycle   = CONFIG_NAND
 static uint input_cycle    = CONFIG_NANDSIM_INPUT_CYCLE;
 static uint bus_width      = CONFIG_NANDSIM_BUS_WIDTH;
 static uint do_delays      = CONFIG_NANDSIM_DO_DELAYS;
+static uint erase_fail_prob = CONFIG_NANDSIM_ERASE_FAIL_PROB;
+static uint prog_fail_prob = CONFIG_NANDSIM_PROG_FAIL_PROB;
 static uint log            = CONFIG_NANDSIM_LOG;
 static uint dbg            = CONFIG_NANDSIM_DBG;
 
@@ -102,6 +115,8 @@ module_param(output_cycle,   uint, 0400)
 module_param(input_cycle,    uint, 0400);
 module_param(bus_width,      uint, 0400);
 module_param(do_delays,      uint, 0400);
+module_param(erase_fail_prob, uint, 0400);
+module_param(prog_fail_prob, uint, 0400);
 module_param(log,            uint, 0400);
 module_param(dbg,            uint, 0400);
 
@@ -116,6 +131,8 @@ MODULE_PARM_DESC(output_cycle,   "Word o
 MODULE_PARM_DESC(input_cycle,    "Word input (to flash) time (nanodeconds)");
 MODULE_PARM_DESC(bus_width,      "Chip's bus width (8- or 16-bit)");
 MODULE_PARM_DESC(do_delays,      "Simulate NAND delays using busy-waits if not zero");
+MODULE_PARM_DESC(erase_fail_prob, "Probability (scaled by " PROB_SCALE_FACTOR_STR ") of erase failing, default 0");
+MODULE_PARM_DESC(prog_fail_prob, "Probability (scaled by " PROB_SCALE_FACTOR_STR ") of program failing, default 0");
 MODULE_PARM_DESC(log,            "Perform logging if not zero");
 MODULE_PARM_DESC(dbg,            "Output debug information if not zero");
 
@@ -875,6 +892,32 @@ static int prog_page(struct nandsim *ns,
 }
 
 /*
+ * The function determines whether erase failure has to be
+ * injected. 
+ *
+ * RETURNS: 1 if fault should be injected, 0 if fault should not be
+ * injected.
+ */
+static inline int inject_erase_fault(void)
+{
+	int rnd = random32() % PROB_SCALE_FACTOR;
+	return rnd < erase_fail_prob;
+}
+
+/*
+ * The function determines whether prog failure has to be
+ * injected. 
+ *
+ * RETURNS: 1 if fault should be injected, 0 if fault should not be
+ * injected.
+ */
+static inline int inject_prog_fault(void)
+{
+	int rnd = random32() % PROB_SCALE_FACTOR;
+	return rnd < prog_fail_prob;
+}
+
+/*
  * If state has any action bit, perform this action.
  *
  * RETURNS: 0 if success, -1 if error.
@@ -948,6 +991,16 @@ static int do_state_action(struct nandsi
 
 		erase_sector(ns);
 
+		/* 
+		 * Injecting fault after erasing the sector, saves
+		 * memory since the memory used by the bad block is
+		 * freed.
+		 */
+		if (inject_erase_fault()) {
+			NS_DBG("do_state_action: injecting erase fault\n");
+			return -1;
+		}
+
 		NS_MDELAY(erase_delay);
 
 		break;
@@ -969,6 +1022,15 @@ static int do_state_action(struct nandsi
 			return -1;
 		}
 
+		/* 
+		 * Injecting fault before programming the sector,
+		 * helps to save memory.
+		 */
+		if (inject_prog_fault()) {
+			NS_DBG("do_state_action: injecting page prog fault\n");
+			return -1;
+		}
+
 		if (prog_page(ns, num) == -1)
 			return -1;
 

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

* Re: [PATCH] NAND: nandsim bad block injection
  2006-12-27 15:24 Vijay Kumar
@ 2006-12-28 10:22 ` Artem Bityutskiy
  0 siblings, 0 replies; 4+ messages in thread
From: Artem Bityutskiy @ 2006-12-28 10:22 UTC (permalink / raw)
  To: Vijay Kumar; +Cc: linux-mtd

Vijay,

On Wed, 2006-12-27 at 20:54 +0530, Vijay Kumar wrote:
> Adds support for bad block creation on block erase and page program,
> by returning erase/program failed in the status byte. The probability
> of fault occurrence can be specified through module parameters.

the patch looks fine, and it is useful for debugging. But I have few
concerns.

1. Suppose we decided to emulate an erase failure for a certain
eraseblock. Then the MTD user re-tries the operation and succeeds.
Shouldn't we start always returning erase errors for this eraseblock
instead?

2. In case of I/O errors, the correct MTD user should mark the bogus
eraseblock bad. So, after some time we end up with most of our
eraseblocks marked bad which is not very nice.

How would you comment this?

-- 
Best regards,
Artem Bityutskiy (Битюцкий Артём)

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

end of thread, other threads:[~2006-12-28 10:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-24 13:08 [PATCH] NAND: nandsim bad block injection Vijay Kumar
2006-12-27 11:26 ` Artem Bityutskiy
  -- strict thread matches above, loose matches on Subject: below --
2006-12-27 15:24 Vijay Kumar
2006-12-28 10:22 ` Artem Bityutskiy

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