* [PATCH V2] UBI: power cut emulation for testing
@ 2015-03-26 22:59 david.oberhollenzer
2015-04-05 19:31 ` Pavel Machek
2015-04-09 8:34 ` Richard Weinberger
0 siblings, 2 replies; 8+ messages in thread
From: david.oberhollenzer @ 2015-03-26 22:59 UTC (permalink / raw)
To: linux-mtd, linux-kernel; +Cc: David Oberhollenzer
Emulate random power cuts by switching device to ro after a number of
writes to allow simple power cut testing with nand-sim.
Maximum and minimum number of successful writes before power cut and
what kind of writes (EC header, VID header or none) to interrupt
configurable via debugfs.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
---
V2: Remove broken check to prevent multiple triggering
---
drivers/mtd/ubi/debug.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++--
drivers/mtd/ubi/debug.h | 2 ++
drivers/mtd/ubi/io.c | 6 ++++
drivers/mtd/ubi/ubi.h | 25 ++++++++++++++
4 files changed, 120 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 7335c9f..aa9deca 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -263,7 +263,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
struct dentry *dent = file->f_path.dentry;
struct ubi_device *ubi;
struct ubi_debug_info *d;
- char buf[3];
+ char buf[8];
int val;
ubi = ubi_get_device(ubi_num);
@@ -281,6 +281,22 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
val = d->emulate_bitflips;
else if (dent == d->dfs_emulate_io_failures)
val = d->emulate_io_failures;
+ else if (dent == d->dfs_emulate_power_cut) {
+ snprintf(buf, sizeof(buf), "%u\n", d->emulate_power_cut);
+ count = simple_read_from_buffer(user_buf, count, ppos,
+ buf, strlen(buf));
+ goto out;
+ } else if (dent == d->dfs_power_cut_min) {
+ snprintf(buf, sizeof(buf), "%u\n", d->power_cut_min);
+ count = simple_read_from_buffer(user_buf, count, ppos,
+ buf, strlen(buf));
+ goto out;
+ } else if (dent == d->dfs_power_cut_max) {
+ snprintf(buf, sizeof(buf), "%u\n", d->power_cut_max);
+ count = simple_read_from_buffer(user_buf, count, ppos,
+ buf, strlen(buf));
+ goto out;
+ }
else {
count = -EINVAL;
goto out;
@@ -309,7 +325,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
struct ubi_device *ubi;
struct ubi_debug_info *d;
size_t buf_size;
- char buf[8];
+ char buf[8] = {0};
int val;
ubi = ubi_get_device(ubi_num);
@@ -323,6 +339,21 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
goto out;
}
+ if (dent == d->dfs_power_cut_min) {
+ if (kstrtouint(buf, 0, &d->power_cut_min) != 0)
+ count = -EINVAL;
+ goto out;
+ } else if (dent == d->dfs_power_cut_max) {
+ if (kstrtouint(buf, 0, &d->power_cut_max) != 0)
+ count = -EINVAL;
+ goto out;
+ } else if (dent == d->dfs_emulate_power_cut) {
+ if (kstrtoint(buf, 0, &val) != 0)
+ count = -EINVAL;
+ d->emulate_power_cut = val;
+ goto out;
+ }
+
if (buf[0] == '1')
val = 1;
else if (buf[0] == '0')
@@ -427,6 +458,27 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
goto out_remove;
d->dfs_emulate_io_failures = dent;
+ fname = "tst_emulate_power_cut";
+ dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_emulate_power_cut = dent;
+
+ fname = "tst_emulate_power_cut_min";
+ dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_power_cut_min = dent;
+
+ fname = "tst_emulate_power_cut_max";
+ dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num,
+ &dfs_fops);
+ if (IS_ERR_OR_NULL(dent))
+ goto out_remove;
+ d->dfs_power_cut_max = dent;
+
return 0;
out_remove:
@@ -447,3 +499,36 @@ void ubi_debugfs_exit_dev(struct ubi_device *ubi)
if (IS_ENABLED(CONFIG_DEBUG_FS))
debugfs_remove_recursive(ubi->dbg.dfs_dir);
}
+
+/**
+ * ubi_dbg_power_cut - emulate a power cut if it is time to do so
+ * @ubi: UBI device description object
+ * @caller: Flags set to indicate from where the function is being called
+ *
+ * Returns non-zero if a power cut was emulated, zero if not.
+ */
+int ubi_dbg_power_cut(struct ubi_device *ubi, int caller)
+{
+ unsigned int range;
+
+ if ((ubi->dbg.emulate_power_cut & caller) == 0)
+ return 0;
+
+ if (ubi->dbg.power_cut_counter == 0) {
+ ubi->dbg.power_cut_counter = ubi->dbg.power_cut_min;
+
+ if (ubi->dbg.power_cut_max > ubi->dbg.power_cut_min) {
+ range = ubi->dbg.power_cut_max - ubi->dbg.power_cut_min;
+ ubi->dbg.power_cut_counter += prandom_u32() % range;
+ }
+ return 0;
+ }
+
+ ubi->dbg.power_cut_counter--;
+ if (ubi->dbg.power_cut_counter)
+ return 0;
+
+ ubi_msg(ubi, "XXXXXXXXXXXXXXX emulating a power cut XXXXXXXXXXXXXXXX");
+ ubi_ro_mode(ubi);
+ return 1;
+}
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index cba89fc..d74b339 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -127,4 +127,6 @@ static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi)
{
return ubi->dbg.chk_gen;
}
+
+int ubi_dbg_power_cut(struct ubi_device *ubi, int caller);
#endif /* !__UBI_DEBUG_H__ */
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index ed0bcb3..5bbd1f0 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -859,6 +859,9 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum,
if (err)
return err;
+ if (ubi_dbg_power_cut(ubi, POWER_CUT_EC_WRITE))
+ return -EROFS;
+
err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize);
return err;
}
@@ -1106,6 +1109,9 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
if (err)
return err;
+ if (ubi_dbg_power_cut(ubi, POWER_CUT_VID_WRITE))
+ return -EROFS;
+
p = (char *)vid_hdr - ubi->vid_hdr_shift;
err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset,
ubi->vid_hdr_alsize);
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index c5be82d..4e0981a 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -151,6 +151,17 @@ enum {
UBI_BAD_FASTMAP,
};
+/*
+ * Flags for emulate_power_cut in ubi_debug_info
+ *
+ * POWER_CUT_EC_WRITE: Emulate a power cut when writing an EC header
+ * POWER_CUT_VID_WRITE: Emulate a power cut when writing a VID header
+ */
+enum {
+ POWER_CUT_EC_WRITE = 0x01,
+ POWER_CUT_VID_WRITE = 0x02,
+};
+
/**
* struct ubi_wl_entry - wear-leveling entry.
* @u.rb: link in the corresponding (free/used) RB-tree
@@ -359,6 +370,10 @@ struct ubi_wl_entry;
* @disable_bgt: disable the background task for testing purposes
* @emulate_bitflips: emulate bit-flips for testing purposes
* @emulate_io_failures: emulate write/erase failures for testing purposes
+ * @emulate_power_cut: emulate power cut for testing purposes
+ * @power_cut_counter: count down for writes left until emulated power cut
+ * @power_cut_min: minimum number of writes before emulating a power cut
+ * @power_cut_max: maximum number of writes until emulating a power cut
* @dfs_dir_name: name of debugfs directory containing files of this UBI device
* @dfs_dir: direntry object of the UBI device debugfs directory
* @dfs_chk_gen: debugfs knob to enable UBI general extra checks
@@ -366,6 +381,9 @@ struct ubi_wl_entry;
* @dfs_disable_bgt: debugfs knob to disable the background task
* @dfs_emulate_bitflips: debugfs knob to emulate bit-flips
* @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures
+ * @dfs_emulate_power_cut: debugfs knob to emulate power cuts
+ * @dfs_power_cut_min: debugfs knob for minimum writes before power cut
+ * @dfs_power_cut_max: debugfs knob for maximum writes until power cut
*/
struct ubi_debug_info {
unsigned int chk_gen:1;
@@ -373,6 +391,10 @@ struct ubi_debug_info {
unsigned int disable_bgt:1;
unsigned int emulate_bitflips:1;
unsigned int emulate_io_failures:1;
+ unsigned int emulate_power_cut:2;
+ unsigned int power_cut_counter;
+ unsigned int power_cut_min;
+ unsigned int power_cut_max;
char dfs_dir_name[UBI_DFS_DIR_LEN + 1];
struct dentry *dfs_dir;
struct dentry *dfs_chk_gen;
@@ -380,6 +402,9 @@ struct ubi_debug_info {
struct dentry *dfs_disable_bgt;
struct dentry *dfs_emulate_bitflips;
struct dentry *dfs_emulate_io_failures;
+ struct dentry *dfs_emulate_power_cut;
+ struct dentry *dfs_power_cut_min;
+ struct dentry *dfs_power_cut_max;
};
/**
--
2.3.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH V2] UBI: power cut emulation for testing
2015-03-26 22:59 [PATCH V2] UBI: power cut emulation for testing david.oberhollenzer
@ 2015-04-05 19:31 ` Pavel Machek
2015-04-05 19:49 ` Richard Weinberger
2015-04-09 8:34 ` Richard Weinberger
1 sibling, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2015-04-05 19:31 UTC (permalink / raw)
To: david.oberhollenzer; +Cc: linux-mtd, linux-kernel
On Thu 2015-03-26 23:59:50, david.oberhollenzer@sigma-star.at wrote:
> Emulate random power cuts by switching device to ro after a number of
> writes to allow simple power cut testing with nand-sim.
>
> Maximum and minimum number of successful writes before power cut and
> what kind of writes (EC header, VID header or none) to interrupt
> configurable via debugfs.
>
> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
> ---
> V2: Remove broken check to prevent multiple triggering
Does NAND always finish write of full block during powerfail?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2] UBI: power cut emulation for testing
2015-04-05 19:31 ` Pavel Machek
@ 2015-04-05 19:49 ` Richard Weinberger
2015-04-05 20:04 ` Pavel Machek
0 siblings, 1 reply; 8+ messages in thread
From: Richard Weinberger @ 2015-04-05 19:49 UTC (permalink / raw)
To: Pavel Machek; +Cc: linux-mtd@lists.infradead.org, david.oberhollenzer, LKML
On Sun, Apr 5, 2015 at 9:31 PM, Pavel Machek <pavel@ucw.cz> wrote:
> On Thu 2015-03-26 23:59:50, david.oberhollenzer@sigma-star.at wrote:
>> Emulate random power cuts by switching device to ro after a number of
>> writes to allow simple power cut testing with nand-sim.
>>
>> Maximum and minimum number of successful writes before power cut and
>> what kind of writes (EC header, VID header or none) to interrupt
>> configurable via debugfs.
>>
>> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
>> ---
>> V2: Remove broken check to prevent multiple triggering
>
> Does NAND always finish write of full block during powerfail?
Not sure if I correctly understand your question.
Unless you don't have special hardware a write can be interrupted and
can cause problems.
--
Thanks,
//richard
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2] UBI: power cut emulation for testing
2015-04-05 19:49 ` Richard Weinberger
@ 2015-04-05 20:04 ` Pavel Machek
2015-04-05 20:09 ` Richard Weinberger
0 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2015-04-05 20:04 UTC (permalink / raw)
To: Richard Weinberger
Cc: linux-mtd@lists.infradead.org, david.oberhollenzer, LKML
On Sun 2015-04-05 21:49:27, Richard Weinberger wrote:
> On Sun, Apr 5, 2015 at 9:31 PM, Pavel Machek <pavel@ucw.cz> wrote:
> > On Thu 2015-03-26 23:59:50, david.oberhollenzer@sigma-star.at wrote:
> >> Emulate random power cuts by switching device to ro after a number of
> >> writes to allow simple power cut testing with nand-sim.
> >>
> >> Maximum and minimum number of successful writes before power cut and
> >> what kind of writes (EC header, VID header or none) to interrupt
> >> configurable via debugfs.
> >>
> >> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
> >> ---
> >> V2: Remove broken check to prevent multiple triggering
> >
> > Does NAND always finish write of full block during powerfail?
>
> Not sure if I correctly understand your question.
> Unless you don't have special hardware a write can be interrupted and
> can cause problems.
But this only emulates fail after a full block written, no?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2] UBI: power cut emulation for testing
2015-04-05 20:04 ` Pavel Machek
@ 2015-04-05 20:09 ` Richard Weinberger
2015-04-05 20:25 ` Pavel Machek
0 siblings, 1 reply; 8+ messages in thread
From: Richard Weinberger @ 2015-04-05 20:09 UTC (permalink / raw)
To: Pavel Machek; +Cc: linux-mtd@lists.infradead.org, david.oberhollenzer, LKML
Am 05.04.2015 um 22:04 schrieb Pavel Machek:
> On Sun 2015-04-05 21:49:27, Richard Weinberger wrote:
>> On Sun, Apr 5, 2015 at 9:31 PM, Pavel Machek <pavel@ucw.cz> wrote:
>>> On Thu 2015-03-26 23:59:50, david.oberhollenzer@sigma-star.at wrote:
>>>> Emulate random power cuts by switching device to ro after a number of
>>>> writes to allow simple power cut testing with nand-sim.
>>>>
>>>> Maximum and minimum number of successful writes before power cut and
>>>> what kind of writes (EC header, VID header or none) to interrupt
>>>> configurable via debugfs.
>>>>
>>>> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
>>>> ---
>>>> V2: Remove broken check to prevent multiple triggering
>>>
>>> Does NAND always finish write of full block during powerfail?
>>
>> Not sure if I correctly understand your question.
>> Unless you don't have special hardware a write can be interrupted and
>> can cause problems.
>
> But this only emulates fail after a full block written, no?
Emulating all aspects of real hardware is almost impossible.
Thanks,
//richard
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2] UBI: power cut emulation for testing
2015-04-05 20:09 ` Richard Weinberger
@ 2015-04-05 20:25 ` Pavel Machek
2015-04-05 20:34 ` Richard Weinberger
0 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2015-04-05 20:25 UTC (permalink / raw)
To: Richard Weinberger
Cc: linux-mtd@lists.infradead.org, david.oberhollenzer, LKML
On Sun 2015-04-05 22:09:27, Richard Weinberger wrote:
> Am 05.04.2015 um 22:04 schrieb Pavel Machek:
> > On Sun 2015-04-05 21:49:27, Richard Weinberger wrote:
> >> On Sun, Apr 5, 2015 at 9:31 PM, Pavel Machek <pavel@ucw.cz> wrote:
> >>> On Thu 2015-03-26 23:59:50, david.oberhollenzer@sigma-star.at wrote:
> >>>> Emulate random power cuts by switching device to ro after a number of
> >>>> writes to allow simple power cut testing with nand-sim.
> >>>>
> >>>> Maximum and minimum number of successful writes before power cut and
> >>>> what kind of writes (EC header, VID header or none) to interrupt
> >>>> configurable via debugfs.
> >>>>
> >>>> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
> >>>> ---
> >>>> V2: Remove broken check to prevent multiple triggering
> >>>
> >>> Does NAND always finish write of full block during powerfail?
> >>
> >> Not sure if I correctly understand your question.
> >> Unless you don't have special hardware a write can be interrupted and
> >> can cause problems.
> >
> > But this only emulates fail after a full block written, no?
>
> Emulating all aspects of real hardware is almost impossible.
I guess so. So maybe warning in the documentation somewhere that real
hardware is nastier than designed-to-be-nasty emulation would be
nice..?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2] UBI: power cut emulation for testing
2015-04-05 20:25 ` Pavel Machek
@ 2015-04-05 20:34 ` Richard Weinberger
0 siblings, 0 replies; 8+ messages in thread
From: Richard Weinberger @ 2015-04-05 20:34 UTC (permalink / raw)
To: Pavel Machek; +Cc: linux-mtd@lists.infradead.org, david.oberhollenzer, LKML
Am 05.04.2015 um 22:25 schrieb Pavel Machek:
> I guess so. So maybe warning in the documentation somewhere that real
> hardware is nastier than designed-to-be-nasty emulation would be
> nice..?
Yeah, that's a good idea. David, can you please create a patch
against mtd-www.git?
Please also cover the existing powercut emulation of UBIFS.
The reason why David added emulation for UBI was to stress-test
UBI fastmap. The crucial operation of UBI changing the mapping between
LEB and PEBs. This is why this emulation intercepts writes to the UBI
VID header. For the sake of completeness interception of EC writes
is also possible.
Thanks,
//richard
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH V2] UBI: power cut emulation for testing
2015-03-26 22:59 [PATCH V2] UBI: power cut emulation for testing david.oberhollenzer
2015-04-05 19:31 ` Pavel Machek
@ 2015-04-09 8:34 ` Richard Weinberger
1 sibling, 0 replies; 8+ messages in thread
From: Richard Weinberger @ 2015-04-09 8:34 UTC (permalink / raw)
To: david.oberhollenzer; +Cc: linux-mtd@lists.infradead.org, LKML
On Thu, Mar 26, 2015 at 11:59 PM, <david.oberhollenzer@sigma-star.at> wrote:
> Emulate random power cuts by switching device to ro after a number of
> writes to allow simple power cut testing with nand-sim.
>
> Maximum and minimum number of successful writes before power cut and
> what kind of writes (EC header, VID header or none) to interrupt
> configurable via debugfs.
>
> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
> ---
> V2: Remove broken check to prevent multiple triggering
Applied and pushed to linux-ubifs.git/master!
--
Thanks,
//richard
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-04-09 8:34 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-26 22:59 [PATCH V2] UBI: power cut emulation for testing david.oberhollenzer
2015-04-05 19:31 ` Pavel Machek
2015-04-05 19:49 ` Richard Weinberger
2015-04-05 20:04 ` Pavel Machek
2015-04-05 20:09 ` Richard Weinberger
2015-04-05 20:25 ` Pavel Machek
2015-04-05 20:34 ` Richard Weinberger
2015-04-09 8:34 ` Richard Weinberger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox