* [PATCH V2 0/5] ubi: Enhanced fault injection capability for the UBI driver
@ 2023-07-18 8:51 ZhaoLong Wang
2023-07-18 8:51 ` [PATCH V2 1/5] ubi: Use the fault injection framework to enhance the fault injection capability ZhaoLong Wang
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: ZhaoLong Wang @ 2023-07-18 8:51 UTC (permalink / raw)
To: richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, chengzhihao1, wangzhaolong1, yi.zhang
The existing fault injection capability of UBI is too simple.
It uses hard-coded fault probability values and lacks other
configurable options. As a result, these interfaces are difficult
to use when digging defects in the abnormal path of code and
reproducing some problems.
The kernel provides a powerful fault injection framework, which
provides rich configurable fault injection attributes during runtime.
So it can be used to improve the fault injection capability of the
UBI driver.
This series of patches refactor the existing fault injection interface
and add some fault injection types to help testers and developers
find potential problems in the code.
This series of patches enhance the existing fault injection interface
and retain the old debugfs interface, and add some fault injection types
to help testers and developers Look for potential problems in the code.
ZhaoLong Wang (5):
ubi: Use the fault injection framework to enhance the fault injection
capability
ubi: Split io_failures into write_failure and erase_failure
ubi: Add six fault injection type for testing
ubi: Reserve sufficient buffer length for the input mask
mtd: Add several functions to the fail_function list
drivers/mtd/mtdcore.c | 6 +-
drivers/mtd/ubi/Kconfig | 9 ++
drivers/mtd/ubi/debug.c | 107 ++++++++++++++--
drivers/mtd/ubi/debug.h | 264 ++++++++++++++++++++++++++++++++++++----
drivers/mtd/ubi/io.c | 85 ++++++++++++-
drivers/mtd/ubi/ubi.h | 46 +++----
6 files changed, 458 insertions(+), 59 deletions(-)
--
2.31.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V2 1/5] ubi: Use the fault injection framework to enhance the fault injection capability
2023-07-18 8:51 [PATCH V2 0/5] ubi: Enhanced fault injection capability for the UBI driver ZhaoLong Wang
@ 2023-07-18 8:51 ` ZhaoLong Wang
2023-07-31 11:15 ` Zhihao Cheng
2023-07-18 8:51 ` [PATCH V2 2/5] ubi: Split io_failures into write_failure and erase_failure ZhaoLong Wang
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: ZhaoLong Wang @ 2023-07-18 8:51 UTC (permalink / raw)
To: richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, chengzhihao1, wangzhaolong1, yi.zhang
To make debug parameters configurable at run time, use the
fault injection framework to reconstruct the debugfs interface,
and retain the legacy fault injection interface.
Now, the file emulate_failures and fault_attr files control whether
to enable fault emmulation.
The file emulate_failures receives a mask that controls type and
process of fault injection. Generally, for ease of use, you can
directly enter a mask with all 1s.
echo 0xffff > /sys/kernel/debug/ubi/ubi0/emulate_failures
And you need to configure other fault-injection capabilities for
testing purpose:
echo 100 > /sys/kernel/debug/ubi/fault_inject/emulate_power_cut/probability
echo 15 > /sys/kernel/debug/ubi/fault_inject/emulate_power_cut/space
echo 2 > /sys/kernel/debug/ubi/fault_inject/emulate_power_cut/verbose
echo -1 > /sys/kernel/debug/ubi/fault_inject/emulate_power_cut/times
The CONFIG_MTD_UBI_FAULT_INJECTION to enable the Fault Injection is
added to kconfig.
Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
---
V2:
- Retain the original interface.
- When both the new and original interfaces are enabled, the original
interface takes precedence over the new interface.
- Adjusted the order of masks to be compatible with original interfaces.
drivers/mtd/ubi/Kconfig | 9 +++
drivers/mtd/ubi/debug.c | 68 +++++++++++++++++--
drivers/mtd/ubi/debug.h | 142 +++++++++++++++++++++++++++++++++-------
drivers/mtd/ubi/io.c | 10 ++-
drivers/mtd/ubi/ubi.h | 15 ++---
5 files changed, 202 insertions(+), 42 deletions(-)
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index 2ed77b7b3fcb..138fae7e8f96 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -104,4 +104,13 @@ config MTD_UBI_BLOCK
If in doubt, say "N".
+config MTD_UBI_FAULT_INJECTION
+ bool "Fault injection capability of UBI device"
+ default n
+ depends on FAULT_INJECTION_DEBUG_FS
+ help
+ this option enable fault-injection support for UBI devices for
+ testing purposes.
+
+ If in doubt, say "N".
endif # MTD_UBI
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 27168f511d6d..9ca584da32c6 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -10,7 +10,23 @@
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/seq_file.h>
+#include <linux/fault-inject.h>
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+static DECLARE_FAULT_ATTR(fault_bitflips_attr);
+static DECLARE_FAULT_ATTR(fault_io_failures_attr);
+static DECLARE_FAULT_ATTR(fault_power_cut_attr);
+
+#define FAIL_ACTION(name, fault_attr) \
+bool should_fail_##name(void) \
+{ \
+ return should_fail(&fault_attr, 1); \
+}
+
+FAIL_ACTION(bitflips, fault_bitflips_attr)
+FAIL_ACTION(io_failures, fault_io_failures_attr)
+FAIL_ACTION(power_cut, fault_power_cut_attr)
+#endif
/**
* ubi_dump_flash - dump a region of flash.
@@ -212,6 +228,31 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req)
*/
static struct dentry *dfs_rootdir;
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+static void dfs_create_fault_entry(struct dentry *parent)
+{
+ struct dentry *dir;
+
+ dir = debugfs_create_dir("fault_inject", parent);
+ if (IS_ERR_OR_NULL(dir)) {
+ int err = dir ? PTR_ERR(dir) : -ENODEV;
+
+ pr_warn("UBI error: cannot create \"fault_inject\" debugfs directory, error %d\n",
+ err);
+ return;
+ }
+
+ fault_create_debugfs_attr("emulate_bitflips", dir,
+ &fault_bitflips_attr);
+
+ fault_create_debugfs_attr("emulate_io_failures", dir,
+ &fault_io_failures_attr);
+
+ fault_create_debugfs_attr("emulate_power_cut", dir,
+ &fault_power_cut_attr);
+}
+#endif
+
/**
* ubi_debugfs_init - create UBI debugfs directory.
*
@@ -232,6 +273,10 @@ int ubi_debugfs_init(void)
return err;
}
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+ dfs_create_fault_entry(dfs_rootdir);
+#endif
+
return 0;
}
@@ -272,7 +317,12 @@ 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) {
+ else if (dent == d->dfs_emulate_failures) {
+ snprintf(buf, sizeof(buf), "%u\n", d->emulate_failures);
+ count = simple_read_from_buffer(user_buf, count, ppos,
+ buf, strlen(buf));
+ goto out;
+ } 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));
@@ -287,8 +337,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
count = simple_read_from_buffer(user_buf, count, ppos,
buf, strlen(buf));
goto out;
- }
- else {
+ } else {
count = -EINVAL;
goto out;
}
@@ -330,7 +379,11 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
goto out;
}
- if (dent == d->dfs_power_cut_min) {
+ if (dent == d->dfs_emulate_failures) {
+ if (kstrtouint(buf, 0, &d->emulate_failures) != 0)
+ count = -EINVAL;
+ goto out;
+ } else if (dent == d->dfs_power_cut_min) {
if (kstrtouint(buf, 0, &d->power_cut_min) != 0)
count = -EINVAL;
goto out;
@@ -559,6 +612,11 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
debugfs_create_file("detailed_erase_block_info", S_IRUSR, d->dfs_dir,
(void *)ubi_num, &eraseblk_count_fops);
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+ d->dfs_emulate_failures = debugfs_create_file("emulate_failures", mode,
+ d->dfs_dir, (void *)ubi_num,
+ &dfs_fops);
+#endif
return 0;
}
@@ -600,7 +658,5 @@ int ubi_dbg_power_cut(struct ubi_device *ubi, int caller)
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 23676f32b681..fc4234c9a90a 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -53,56 +53,153 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi);
void ubi_debugfs_exit_dev(struct ubi_device *ubi);
/**
- * ubi_dbg_is_bgt_disabled - if the background thread is disabled.
+ * The following function is a legacy implementation of UBI fault-injection
+ * hook. When using more powerful fault injection capabilities, the legacy
+ * fault injection interface should be retained.
+ */
+int ubi_dbg_power_cut(struct ubi_device *ubi, int caller);
+
+static inline int ubi_dbg_bitflip(const struct ubi_device *ubi)
+{
+ if (ubi->dbg.emulate_bitflips)
+ return !get_random_u32_below(200);
+ return 0;
+}
+
+static inline int ubi_dbg_write_failure(const struct ubi_device *ubi)
+{
+ if (ubi->dbg.emulate_io_failures)
+ return !get_random_u32_below(500);
+ return 0;
+}
+
+static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
+{
+ if (ubi->dbg.emulate_io_failures)
+ return !get_random_u32_below(400);
+ return 0;
+}
+
+/**
+ * MASK_XXX: Mask for emulate_failures in ubi_debug_info.The mask is used to
+ * precisely control the type and process of fault injection.
+ */
+/* Emulate a power cut when writing EC/VID header */
+#define MASK_POWER_CUT_EC (1 << 1)
+#define MASK_POWER_CUT_VID (1 << 2)
+
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+/* Emulate bit-flips */
+#define MASK_BITFLIPS (1 << 3)
+/* Emulates -EIO during write/erase */
+#define MASK_IO_FAILURE (1 << 4)
+
+extern bool should_fail_bitflips(void);
+extern bool should_fail_io_failures(void);
+extern bool should_fail_power_cut(void);
+
+static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
+{
+ if (ubi->dbg.emulate_failures & MASK_BITFLIPS)
+ return should_fail_bitflips();
+ return false;
+}
+
+static inline bool ubi_dbg_fail_write(const struct ubi_device *ubi)
+{
+ if (ubi->dbg.emulate_failures & MASK_IO_FAILURE)
+ return should_fail_io_failures();
+ return false;
+}
+
+static inline bool ubi_dbg_fail_erase(const struct ubi_device *ubi)
+{
+ if (ubi->dbg.emulate_failures & MASK_IO_FAILURE)
+ return should_fail_io_failures();
+ return false;
+}
+
+static inline bool ubi_dbg_fail_power_cut(const struct ubi_device *ubi,
+ unsigned int caller)
+{
+ if (ubi->dbg.emulate_failures & caller)
+ return should_fail_power_cut();
+ return false;
+}
+
+#else /* CONFIG_MTD_UBI_FAULT_INJECTION */
+
+#define ubi_dbg_fail_bitflip(u) false
+#define ubi_dbg_fail_write(u) false
+#define ubi_dbg_fail_erase(u) false
+#define ubi_dbg_fail_power_cut(u,c) false
+#endif
+
+/**
+ * ubi_dbg_is_power_cut - if it is time to emulate power cut.
* @ubi: UBI device description object
*
- * Returns non-zero if the UBI background thread is disabled for testing
- * purposes.
+ * Returns true if power cut should be emulated, otherwise returns false.
*/
-static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
+static inline bool ubi_dbg_is_power_cut(struct ubi_device *ubi,
+ unsigned int caller)
{
- return ubi->dbg.disable_bgt;
+ if (ubi_dbg_power_cut(ubi, caller))
+ return true;
+ return ubi_dbg_fail_power_cut(ubi, caller);
}
/**
* ubi_dbg_is_bitflip - if it is time to emulate a bit-flip.
* @ubi: UBI device description object
*
- * Returns non-zero if a bit-flip should be emulated, otherwise returns zero.
+ * Returns true if a bit-flip should be emulated, otherwise returns false.
*/
-static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi)
+static inline bool ubi_dbg_is_bitflip(const struct ubi_device *ubi)
{
- if (ubi->dbg.emulate_bitflips)
- return !get_random_u32_below(200);
- return 0;
+ if (ubi_dbg_bitflip(ubi))
+ return true;
+ return ubi_dbg_fail_bitflip(ubi);
}
/**
* ubi_dbg_is_write_failure - if it is time to emulate a write failure.
* @ubi: UBI device description object
*
- * Returns non-zero if a write failure should be emulated, otherwise returns
- * zero.
+ * Returns true if a write failure should be emulated, otherwise returns
+ * false.
*/
-static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi)
+static inline bool ubi_dbg_is_write_failure(const struct ubi_device *ubi)
{
- if (ubi->dbg.emulate_io_failures)
- return !get_random_u32_below(500);
- return 0;
+ if (ubi_dbg_write_failure(ubi))
+ return true;;
+ return ubi_dbg_fail_write(ubi);
}
/**
* ubi_dbg_is_erase_failure - if its time to emulate an erase failure.
* @ubi: UBI device description object
*
- * Returns non-zero if an erase failure should be emulated, otherwise returns
- * zero.
+ * Returns true if an erase failure should be emulated, otherwise returns
+ * false.
*/
-static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
+static inline bool ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
{
- if (ubi->dbg.emulate_io_failures)
- return !get_random_u32_below(400);
- return 0;
+ if (ubi_dbg_erase_failure(ubi))
+ return true;
+ return ubi_dbg_fail_erase(ubi);
+}
+
+/**
+ * ubi_dbg_is_bgt_disabled - if the background thread is disabled.
+ * @ubi: UBI device description object
+ *
+ * Returns non-zero if the UBI background thread is disabled for testing
+ * purposes.
+ */
+static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
+{
+ return ubi->dbg.disable_bgt;
}
static inline int ubi_dbg_chk_io(const struct ubi_device *ubi)
@@ -125,5 +222,4 @@ static inline void ubi_enable_dbg_chk_fastmap(struct ubi_device *ubi)
ubi->dbg.chk_fastmap = 1;
}
-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 01b644861253..ffa7bbf27bc2 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -821,8 +821,11 @@ 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))
+ if (ubi_dbg_is_power_cut(ubi, MASK_POWER_CUT_EC)) {
+ ubi_warn(ubi, "XXXXX emulating a power cut when writing EC header XXXXX");
+ ubi_ro_mode(ubi);
return -EROFS;
+ }
err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize);
return err;
@@ -1071,8 +1074,11 @@ 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))
+ if (ubi_dbg_is_power_cut(ubi, MASK_POWER_CUT_VID)) {
+ ubi_warn(ubi, "XXXXX emulating a power cut when writing VID header XXXXX");
+ ubi_ro_mode(ubi);
return -EROFS;
+ }
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 c8f1bd4fa100..41f57d5717b2 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -142,17 +142,6 @@ 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_vid_io_buf - VID buffer used to read/write VID info to/from the
* flash.
@@ -401,6 +390,7 @@ struct ubi_volume_desc {
* @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
+ * @emulate_failures: emulate failures for testing purposes
* @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
@@ -412,6 +402,7 @@ struct ubi_volume_desc {
* @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
+ * @dfs_emulate_failures: debugfs entry to control the fault injection type
*/
struct ubi_debug_info {
unsigned int chk_gen:1;
@@ -424,6 +415,7 @@ struct ubi_debug_info {
unsigned int power_cut_counter;
unsigned int power_cut_min;
unsigned int power_cut_max;
+ unsigned int emulate_failures;
char dfs_dir_name[UBI_DFS_DIR_LEN + 1];
struct dentry *dfs_dir;
struct dentry *dfs_chk_gen;
@@ -435,6 +427,7 @@ struct ubi_debug_info {
struct dentry *dfs_emulate_power_cut;
struct dentry *dfs_power_cut_min;
struct dentry *dfs_power_cut_max;
+ struct dentry *dfs_emulate_failures;
};
/**
--
2.31.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V2 2/5] ubi: Split io_failures into write_failure and erase_failure
2023-07-18 8:51 [PATCH V2 0/5] ubi: Enhanced fault injection capability for the UBI driver ZhaoLong Wang
2023-07-18 8:51 ` [PATCH V2 1/5] ubi: Use the fault injection framework to enhance the fault injection capability ZhaoLong Wang
@ 2023-07-18 8:51 ` ZhaoLong Wang
2023-07-31 11:24 ` Zhihao Cheng
2023-07-18 8:51 ` [PATCH V2 3/5] ubi: Add six fault injection type for testing ZhaoLong Wang
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: ZhaoLong Wang @ 2023-07-18 8:51 UTC (permalink / raw)
To: richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, chengzhihao1, wangzhaolong1, yi.zhang
The emulate_io_failures debugfs entry controls both write
failure and erase failure. This patch split io_failures
to write_failure and erase_failure.
Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
---
drivers/mtd/ubi/debug.c | 13 +++++++++----
drivers/mtd/ubi/debug.h | 14 ++++++++------
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 9ca584da32c6..7826bc8166e8 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -14,7 +14,8 @@
#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
static DECLARE_FAULT_ATTR(fault_bitflips_attr);
-static DECLARE_FAULT_ATTR(fault_io_failures_attr);
+static DECLARE_FAULT_ATTR(fault_write_failure_attr);
+static DECLARE_FAULT_ATTR(fault_erase_failure_attr);
static DECLARE_FAULT_ATTR(fault_power_cut_attr);
#define FAIL_ACTION(name, fault_attr) \
@@ -24,7 +25,8 @@ bool should_fail_##name(void) \
}
FAIL_ACTION(bitflips, fault_bitflips_attr)
-FAIL_ACTION(io_failures, fault_io_failures_attr)
+FAIL_ACTION(write_failure, fault_write_failure_attr)
+FAIL_ACTION(erase_failure, fault_erase_failure_attr)
FAIL_ACTION(power_cut, fault_power_cut_attr)
#endif
@@ -245,8 +247,11 @@ static void dfs_create_fault_entry(struct dentry *parent)
fault_create_debugfs_attr("emulate_bitflips", dir,
&fault_bitflips_attr);
- fault_create_debugfs_attr("emulate_io_failures", dir,
- &fault_io_failures_attr);
+ fault_create_debugfs_attr("emulate_write_failure", dir,
+ &fault_write_failure_attr);
+
+ fault_create_debugfs_attr("emulate_erase_failure", dir,
+ &fault_erase_failure_attr);
fault_create_debugfs_attr("emulate_power_cut", dir,
&fault_power_cut_attr);
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index fc4234c9a90a..6bc698b38e35 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -92,10 +92,12 @@ static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
/* Emulate bit-flips */
#define MASK_BITFLIPS (1 << 3)
/* Emulates -EIO during write/erase */
-#define MASK_IO_FAILURE (1 << 4)
+#define MASK_WRITE_FAILURE (1 << 4)
+#define MASK_ERASE_FAILURE (1 << 5)
extern bool should_fail_bitflips(void);
-extern bool should_fail_io_failures(void);
+extern bool should_fail_write_failure(void);
+extern bool should_fail_erase_failure(void);
extern bool should_fail_power_cut(void);
static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
@@ -107,15 +109,15 @@ static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
static inline bool ubi_dbg_fail_write(const struct ubi_device *ubi)
{
- if (ubi->dbg.emulate_failures & MASK_IO_FAILURE)
- return should_fail_io_failures();
+ if (ubi->dbg.emulate_failures & MASK_WRITE_FAILURE)
+ return should_fail_write_failure();
return false;
}
static inline bool ubi_dbg_fail_erase(const struct ubi_device *ubi)
{
- if (ubi->dbg.emulate_failures & MASK_IO_FAILURE)
- return should_fail_io_failures();
+ if (ubi->dbg.emulate_failures & MASK_ERASE_FAILURE)
+ return should_fail_erase_failure();
return false;
}
--
2.31.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V2 3/5] ubi: Add six fault injection type for testing
2023-07-18 8:51 [PATCH V2 0/5] ubi: Enhanced fault injection capability for the UBI driver ZhaoLong Wang
2023-07-18 8:51 ` [PATCH V2 1/5] ubi: Use the fault injection framework to enhance the fault injection capability ZhaoLong Wang
2023-07-18 8:51 ` [PATCH V2 2/5] ubi: Split io_failures into write_failure and erase_failure ZhaoLong Wang
@ 2023-07-18 8:51 ` ZhaoLong Wang
2023-07-31 11:57 ` Zhihao Cheng
` (2 more replies)
2023-07-18 8:51 ` [PATCH V2 4/5] ubi: Reserve sufficient buffer length for the input mask ZhaoLong Wang
2023-07-18 8:51 ` [PATCH V2 5/5] mtd: Add several functions to the fail_function list ZhaoLong Wang
4 siblings, 3 replies; 13+ messages in thread
From: ZhaoLong Wang @ 2023-07-18 8:51 UTC (permalink / raw)
To: richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, chengzhihao1, wangzhaolong1, yi.zhang
This commit adds six fault injection type for testing to cover the
abnormal path of the UBI driver.
Inject the following faults when the UBI reads the LEB:
+----------------------------+-----------------------------------+
| Interface name | emulate behavior |
+----------------------------+-----------------------------------+
| emulate_eccerr | ECC error |
+----------------------------+-----------------------------------+
| emulate_read_failure | read failure |
|----------------------------+-----------------------------------+
| emulate_io_ff | read content as all FF |
|----------------------------+-----------------------------------+
| emulate_io_ff_bitflips | content FF with MTD err reported |
+----------------------------+-----------------------------------+
| emulate_bad_hdr | bad leb header |
|----------------------------+-----------------------------------+
| emulate_bad_hdr_ebadmsg | bad header with ECC err |
+----------------------------+-----------------------------------+
Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
---
drivers/mtd/ubi/debug.c | 30 +++++++++
drivers/mtd/ubi/debug.h | 132 ++++++++++++++++++++++++++++++++++++++--
drivers/mtd/ubi/io.c | 75 ++++++++++++++++++++++-
drivers/mtd/ubi/ubi.h | 31 ++++++----
4 files changed, 248 insertions(+), 20 deletions(-)
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 7826bc8166e8..016a861c5029 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -13,10 +13,16 @@
#include <linux/fault-inject.h>
#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+static DECLARE_FAULT_ATTR(fault_eccerr_attr);
static DECLARE_FAULT_ATTR(fault_bitflips_attr);
+static DECLARE_FAULT_ATTR(fault_read_failure_attr);
static DECLARE_FAULT_ATTR(fault_write_failure_attr);
static DECLARE_FAULT_ATTR(fault_erase_failure_attr);
static DECLARE_FAULT_ATTR(fault_power_cut_attr);
+static DECLARE_FAULT_ATTR(fault_io_ff_attr);
+static DECLARE_FAULT_ATTR(fault_io_ff_bitflips_attr);
+static DECLARE_FAULT_ATTR(fault_bad_hdr_attr);
+static DECLARE_FAULT_ATTR(fault_bad_hdr_ebadmsg_attr);
#define FAIL_ACTION(name, fault_attr) \
bool should_fail_##name(void) \
@@ -24,10 +30,16 @@ bool should_fail_##name(void) \
return should_fail(&fault_attr, 1); \
}
+FAIL_ACTION(eccerr, fault_eccerr_attr)
FAIL_ACTION(bitflips, fault_bitflips_attr)
+FAIL_ACTION(read_failure, fault_read_failure_attr)
FAIL_ACTION(write_failure, fault_write_failure_attr)
FAIL_ACTION(erase_failure, fault_erase_failure_attr)
FAIL_ACTION(power_cut, fault_power_cut_attr)
+FAIL_ACTION(io_ff, fault_io_ff_attr)
+FAIL_ACTION(io_ff_bitflips, fault_io_ff_bitflips_attr)
+FAIL_ACTION(bad_hdr, fault_bad_hdr_attr)
+FAIL_ACTION(bad_hdr_ebadmsg, fault_bad_hdr_ebadmsg_attr)
#endif
/**
@@ -244,6 +256,12 @@ static void dfs_create_fault_entry(struct dentry *parent)
return;
}
+ fault_create_debugfs_attr("emulate_eccerr", dir,
+ &fault_eccerr_attr);
+
+ fault_create_debugfs_attr("emulate_read_failure", dir,
+ &fault_read_failure_attr);
+
fault_create_debugfs_attr("emulate_bitflips", dir,
&fault_bitflips_attr);
@@ -255,6 +273,18 @@ static void dfs_create_fault_entry(struct dentry *parent)
fault_create_debugfs_attr("emulate_power_cut", dir,
&fault_power_cut_attr);
+
+ fault_create_debugfs_attr("emulate_io_ff", dir,
+ &fault_io_ff_attr);
+
+ fault_create_debugfs_attr("emulate_io_ff_bitflips", dir,
+ &fault_io_ff_bitflips_attr);
+
+ fault_create_debugfs_attr("emulate_bad_hdr", dir,
+ &fault_bad_hdr_attr);
+
+ fault_create_debugfs_attr("emulate_bad_hdr_ebadmsg", dir,
+ &fault_bad_hdr_ebadmsg_attr);
}
#endif
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index 6bc698b38e35..29fbd971964a 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -85,20 +85,47 @@ static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
* precisely control the type and process of fault injection.
*/
/* Emulate a power cut when writing EC/VID header */
-#define MASK_POWER_CUT_EC (1 << 1)
-#define MASK_POWER_CUT_VID (1 << 2)
+#define MASK_POWER_CUT_EC (1 << 0)
+#define MASK_POWER_CUT_VID (1 << 1)
#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+/* Emulate a power cut when writing data*/
+#define MASK_POWER_CUT_DATA (1 << 2)
/* Emulate bit-flips */
-#define MASK_BITFLIPS (1 << 3)
-/* Emulates -EIO during write/erase */
-#define MASK_WRITE_FAILURE (1 << 4)
-#define MASK_ERASE_FAILURE (1 << 5)
+#define MASK_BITFLIPS (1 << 3)
+/* Emulate ecc error */
+#define MASK_ECCERR (1 << 4)
+/* Emulates -EIO during data read */
+#define MASK_READ_FAILURE (1 << 5)
+#define MASK_READ_FAILURE_EC (1 << 6)
+#define MASK_READ_FAILURE_VID (1 << 7)
+/* Emulates -EIO during data write */
+#define MASK_WRITE_FAILURE (1 << 8)
+/* Emulates -EIO during erase a PEB*/
+#define MASK_ERASE_FAILURE (1 << 9)
+/* Return UBI_IO_FF when reading EC/VID header */
+#define MASK_IO_FF_EC (1 << 10)
+#define MASK_IO_FF_VID (1 << 11)
+/* Return UBI_IO_FF_BITFLIPS when reading EC/VID header */
+#define MASK_IO_FF_BITFLIPS_EC (1 << 12)
+#define MASK_IO_FF_BITFLIPS_VID (1 << 13)
+/* Return UBI_IO_BAD_HDR when reading EC/VID header */
+#define MASK_BAD_HDR_EC (1 << 14)
+#define MASK_BAD_HDR_VID (1 << 15)
+/* Return UBI_IO_BAD_HDR_EBADMSG when reading EC/VID header */
+#define MASK_BAD_HDR_EBADMSG_EC (1 << 16)
+#define MASK_BAD_HDR_EBADMSG_VID (1 << 17)
+extern bool should_fail_eccerr(void);
extern bool should_fail_bitflips(void);
+extern bool should_fail_read_failure(void);
extern bool should_fail_write_failure(void);
extern bool should_fail_erase_failure(void);
extern bool should_fail_power_cut(void);
+extern bool should_fail_io_ff(void);
+extern bool should_fail_io_ff_bitflips(void);
+extern bool should_fail_bad_hdr(void);
+extern bool should_fail_bad_hdr_ebadmsg(void);
static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
{
@@ -192,6 +219,99 @@ static inline bool ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
return ubi_dbg_fail_erase(ubi);
}
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+/**
+ * ubi_dbg_is_eccerr - if it is time to emulate ECC error.
+ * @ubi: UBI device description object
+ *
+ * Returns true if a ECC error should be emulated, otherwise returns false.
+ */
+static inline bool ubi_dbg_is_eccerr(const struct ubi_device *ubi)
+{
+ if (ubi->dbg.emulate_failures & MASK_ECCERR)
+ return should_fail_eccerr();
+ return false;
+}
+
+/**
+ * ubi_dbg_is_read_failure - if it is time to emulate a read failure.
+ * @ubi: UBI device description object
+ *
+ * Returns true if a read failure should be emulated, otherwise returns
+ * false.
+ */
+static inline bool ubi_dbg_is_read_failure(const struct ubi_device *ubi,
+ unsigned int caller)
+{
+ if (ubi->dbg.emulate_failures & caller)
+ return should_fail_read_failure();
+ return false;
+}
+
+/**
+ * ubi_dbg_is_ff - if it is time to emulate that read region is only 0xFF.
+ * @ubi: UBI device description object
+ *
+ * Returns true if read region should be emulated 0xFF, otherwise
+ * returns false.
+ */
+static inline bool ubi_dbg_is_ff(const struct ubi_device *ubi,
+ unsigned int caller)
+{
+ if (ubi->dbg.emulate_failures & caller)
+ return should_fail_io_ff();
+ return false;
+}
+
+/**
+ * ubi_dbg_is_ff_bitflips - if it is time to emulate that read region is only 0xFF
+ * with error reported by the MTD driver
+ *
+ * @ubi: UBI device description object
+ *
+ * Returns true if read region should be emulated 0xFF and error
+ * reported by the MTD driver, otherwise returns false.
+ */
+static inline bool ubi_dbg_is_ff_bitflips(const struct ubi_device *ubi,
+ unsigned int caller)
+{
+ if (ubi->dbg.emulate_failures & caller)
+ return should_fail_io_ff_bitflips();
+ return false;
+}
+
+/**
+ * ubi_dbg_is_bad_hdr - if it is time to emulate a bad header
+ * @ubi: UBI device description object
+ *
+ * Returns true if a bad header error should be emulated, otherwise
+ * returns false.
+ */
+static inline bool ubi_dbg_is_bad_hdr(const struct ubi_device *ubi,
+ unsigned int caller)
+{
+ if (ubi->dbg.emulate_failures & caller)
+ return should_fail_bad_hdr();
+ return false;
+}
+
+/**
+ * ubi_dbg_is_bad_hdr_ebadmsg - if it is time to emulate a bad header with
+ * ECC error.
+ *
+ * @ubi: UBI device description object
+ *
+ * Returns true if a bad header with ECC error should be emulated, otherwise
+ * returns false.
+ */
+static inline bool ubi_dbg_is_bad_hdr_ebadmsg(const struct ubi_device *ubi,
+ unsigned int caller)
+{
+ if (ubi->dbg.emulate_failures & caller)
+ return should_fail_bad_hdr_ebadmsg();
+ return false;
+}
+#endif
/**
* ubi_dbg_is_bgt_disabled - if the background thread is disabled.
* @ubi: UBI device description object
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index ffa7bbf27bc2..059032132bdd 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -197,6 +197,19 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
dbg_gen("bit-flip (emulated)");
err = UBI_IO_BITFLIPS;
}
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+ if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE)) {
+ ubi_warn(ubi, "cannot read %d bytes from PEB %d:%d (emulated)",
+ len, pnum, offset);
+ return -EIO;
+ }
+
+ if (ubi_dbg_is_eccerr(ubi)) {
+ ubi_warn(ubi, "ECC error (emulated) while reading %d bytes from PEB %d:%d, read %zd bytes",
+ len, pnum, offset, read);
+ return -EBADMSG;
+ }
+#endif
}
return err;
@@ -782,7 +795,36 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
* If there was %-EBADMSG, but the header CRC is still OK, report about
* a bit-flip to force scrubbing on this PEB.
*/
- return read_err ? UBI_IO_BITFLIPS : 0;
+ if (read_err)
+ return UBI_IO_BITFLIPS;
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+ if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_EC)) {
+ ubi_warn(ubi, "cannot read EC header from PEB %d(emulated)",
+ pnum);
+ return -EIO;
+ }
+
+ if (ubi_dbg_is_ff(ubi, MASK_IO_FF_EC)) {
+ ubi_warn(ubi, "bit-all-ff (emulated)");
+ return UBI_IO_FF;
+ }
+
+ if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_EC)) {
+ ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)");
+ return UBI_IO_FF_BITFLIPS;
+ }
+
+ if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_EC)) {
+ ubi_warn(ubi, "bad_hdr (emulated)");
+ return UBI_IO_BAD_HDR;
+ }
+
+ if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_EC)) {
+ ubi_warn(ubi, "bad_hdr with ECC error (emulated)");
+ return UBI_IO_BAD_HDR_EBADMSG;
+ }
+#endif
+ return 0;
}
/**
@@ -1032,7 +1074,36 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
return -EINVAL;
}
- return read_err ? UBI_IO_BITFLIPS : 0;
+ if (read_err)
+ return UBI_IO_BITFLIPS;
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+ if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_VID)) {
+ ubi_warn(ubi, "cannot read VID header from PEB %d(emulated)",
+ pnum);
+ return -EIO;
+ }
+
+ if (ubi_dbg_is_ff(ubi, MASK_IO_FF_VID)) {
+ ubi_warn(ubi, "bit-all-ff (emulated)\n");
+ return UBI_IO_FF;
+ }
+
+ if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_VID)) {
+ ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)\n");
+ return UBI_IO_FF_BITFLIPS;
+ }
+
+ if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_VID)) {
+ ubi_warn(ubi, "bad_hdr (emulated)\n");
+ return UBI_IO_BAD_HDR;
+ }
+
+ if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_VID)) {
+ ubi_warn(ubi, "bad_hdr with ECC error (emulated)\n");
+ return UBI_IO_BAD_HDR_EBADMSG;
+ }
+#endif
+ return 0;
}
/**
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 41f57d5717b2..36d46425ed4c 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -1117,18 +1117,6 @@ static inline struct ubi_vid_hdr *ubi_get_vid_hdr(struct ubi_vid_io_buf *vidb)
return vidb->hdr;
}
-/*
- * This function is equivalent to 'ubi_io_read()', but @offset is relative to
- * the beginning of the logical eraseblock, not to the beginning of the
- * physical eraseblock.
- */
-static inline int ubi_io_read_data(const struct ubi_device *ubi, void *buf,
- int pnum, int offset, int len)
-{
- ubi_assert(offset >= 0);
- return ubi_io_read(ubi, buf, pnum, offset + ubi->leb_start, len);
-}
-
/*
* This function is equivalent to 'ubi_io_write()', but @offset is relative to
* the beginning of the logical eraseblock, not to the beginning of the
@@ -1154,6 +1142,25 @@ static inline void ubi_ro_mode(struct ubi_device *ubi)
}
}
+/*
+ * This function is equivalent to 'ubi_io_read()', but @offset is relative to
+ * the beginning of the logical eraseblock, not to the beginning of the
+ * physical eraseblock.
+ */
+static inline int ubi_io_read_data(struct ubi_device *ubi, void *buf,
+ int pnum, int offset, int len)
+{
+ ubi_assert(offset >= 0);
+#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
+ if (ubi_dbg_power_cut(ubi, MASK_POWER_CUT_DATA)) {
+ ubi_warn(ubi, "XXXXX emulating a power cut when writing data XXXXX");
+ ubi_ro_mode(ubi);
+ return -EROFS;
+ }
+#endif
+ return ubi_io_read(ubi, buf, pnum, offset + ubi->leb_start, len);
+}
+
/**
* vol_id2idx - get table index by volume ID.
* @ubi: UBI device description object
--
2.31.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V2 4/5] ubi: Reserve sufficient buffer length for the input mask
2023-07-18 8:51 [PATCH V2 0/5] ubi: Enhanced fault injection capability for the UBI driver ZhaoLong Wang
` (2 preceding siblings ...)
2023-07-18 8:51 ` [PATCH V2 3/5] ubi: Add six fault injection type for testing ZhaoLong Wang
@ 2023-07-18 8:51 ` ZhaoLong Wang
2023-07-31 12:13 ` Zhihao Cheng
2023-07-18 8:51 ` [PATCH V2 5/5] mtd: Add several functions to the fail_function list ZhaoLong Wang
4 siblings, 1 reply; 13+ messages in thread
From: ZhaoLong Wang @ 2023-07-18 8:51 UTC (permalink / raw)
To: richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, chengzhihao1, wangzhaolong1, yi.zhang
Because the mask received by the emulate_failures interface
is a 32-bit unsigned integer, ensure that there is sufficient
buffer length to receive and display this value.
Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
---
V2:
- A 16-byte buffer is reserved, as implemented by other interfaces.
drivers/mtd/ubi/debug.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 016a861c5029..1c3f1a2436e5 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -332,7 +332,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[8];
+ char buf[16];
int val;
ubi = ubi_get_device(ubi_num);
@@ -400,7 +400,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] = {0};
+ char buf[16] = {0};
int val;
ubi = ubi_get_device(ubi_num);
--
2.31.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V2 5/5] mtd: Add several functions to the fail_function list
2023-07-18 8:51 [PATCH V2 0/5] ubi: Enhanced fault injection capability for the UBI driver ZhaoLong Wang
` (3 preceding siblings ...)
2023-07-18 8:51 ` [PATCH V2 4/5] ubi: Reserve sufficient buffer length for the input mask ZhaoLong Wang
@ 2023-07-18 8:51 ` ZhaoLong Wang
2023-07-31 12:16 ` Zhihao Cheng
4 siblings, 1 reply; 13+ messages in thread
From: ZhaoLong Wang @ 2023-07-18 8:51 UTC (permalink / raw)
To: richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, chengzhihao1, wangzhaolong1, yi.zhang
add mtd_read(), mtd_write(), mtd_erase(), mtd_block_markbad() to
fail_function list for testing purpose
Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
---
drivers/mtd/mtdcore.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index e00b12aa5ec9..ecf1c5e68479 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -30,6 +30,7 @@
#include <linux/debugfs.h>
#include <linux/nvmem-provider.h>
#include <linux/root_dev.h>
+#include <linux/error-injection.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -1396,6 +1397,7 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
return ret;
}
EXPORT_SYMBOL_GPL(mtd_erase);
+ALLOW_ERROR_INJECTION(mtd_erase, ERRNO);
/*
* This stuff for eXecute-In-Place. phys is optional and may be set to NULL.
@@ -1493,6 +1495,7 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
return ret;
}
EXPORT_SYMBOL_GPL(mtd_read);
+ALLOW_ERROR_INJECTION(mtd_read, ERRNO);
int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
const u_char *buf)
@@ -1509,6 +1512,7 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
return ret;
}
EXPORT_SYMBOL_GPL(mtd_write);
+ALLOW_ERROR_INJECTION(mtd_write, ERRNO);
/*
* In blackbox flight recorder like scenarios we want to make successful writes
@@ -2329,7 +2333,7 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
return 0;
}
EXPORT_SYMBOL_GPL(mtd_block_markbad);
-
+ALLOW_ERROR_INJECTION(mtd_block_markbad, ERRNO);
/*
* default_mtd_writev - the default writev method
* @mtd: mtd device description object pointer
--
2.31.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 1/5] ubi: Use the fault injection framework to enhance the fault injection capability
2023-07-18 8:51 ` [PATCH V2 1/5] ubi: Use the fault injection framework to enhance the fault injection capability ZhaoLong Wang
@ 2023-07-31 11:15 ` Zhihao Cheng
0 siblings, 0 replies; 13+ messages in thread
From: Zhihao Cheng @ 2023-07-31 11:15 UTC (permalink / raw)
To: ZhaoLong Wang, richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, yi.zhang
在 2023/7/18 16:51, ZhaoLong Wang 写道:
> To make debug parameters configurable at run time, use the
> fault injection framework to reconstruct the debugfs interface,
> and retain the legacy fault injection interface.
>
> Now, the file emulate_failures and fault_attr files control whether
> to enable fault emmulation.
>
> The file emulate_failures receives a mask that controls type and
> process of fault injection. Generally, for ease of use, you can
> directly enter a mask with all 1s.
>
> echo 0xffff > /sys/kernel/debug/ubi/ubi0/emulate_failures
>
> And you need to configure other fault-injection capabilities for
> testing purpose:
>
> echo 100 > /sys/kernel/debug/ubi/fault_inject/emulate_power_cut/probability
> echo 15 > /sys/kernel/debug/ubi/fault_inject/emulate_power_cut/space
> echo 2 > /sys/kernel/debug/ubi/fault_inject/emulate_power_cut/verbose
> echo -1 > /sys/kernel/debug/ubi/fault_inject/emulate_power_cut/times
>
> The CONFIG_MTD_UBI_FAULT_INJECTION to enable the Fault Injection is
> added to kconfig.
>
> Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
> ---
> V2:
> - Retain the original interface.
> - When both the new and original interfaces are enabled, the original
> interface takes precedence over the new interface.
> - Adjusted the order of masks to be compatible with original interfaces.
>
> drivers/mtd/ubi/Kconfig | 9 +++
> drivers/mtd/ubi/debug.c | 68 +++++++++++++++++--
> drivers/mtd/ubi/debug.h | 142 +++++++++++++++++++++++++++++++++-------
> drivers/mtd/ubi/io.c | 10 ++-
> drivers/mtd/ubi/ubi.h | 15 ++---
> 5 files changed, 202 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
> index 2ed77b7b3fcb..138fae7e8f96 100644
> --- a/drivers/mtd/ubi/Kconfig
> +++ b/drivers/mtd/ubi/Kconfig
> @@ -104,4 +104,13 @@ config MTD_UBI_BLOCK
>
> If in doubt, say "N".
>
> +config MTD_UBI_FAULT_INJECTION
> + bool "Fault injection capability of UBI device"
> + default n
> + depends on FAULT_INJECTION_DEBUG_FS
> + help
> + this option enable fault-injection support for UBI devices for
> + testing purposes.
> +
> + If in doubt, say "N".
> endif # MTD_UBI
> diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
> index 27168f511d6d..9ca584da32c6 100644
> --- a/drivers/mtd/ubi/debug.c
> +++ b/drivers/mtd/ubi/debug.c
> @@ -10,7 +10,23 @@
> #include <linux/uaccess.h>
> #include <linux/module.h>
> #include <linux/seq_file.h>
> +#include <linux/fault-inject.h>
>
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +static DECLARE_FAULT_ATTR(fault_bitflips_attr);
> +static DECLARE_FAULT_ATTR(fault_io_failures_attr);
> +static DECLARE_FAULT_ATTR(fault_power_cut_attr);
> +
> +#define FAIL_ACTION(name, fault_attr) \
> +bool should_fail_##name(void) \
> +{ \
> + return should_fail(&fault_attr, 1); \
> +}
> +
> +FAIL_ACTION(bitflips, fault_bitflips_attr)
> +FAIL_ACTION(io_failures, fault_io_failures_attr)
> +FAIL_ACTION(power_cut, fault_power_cut_attr)
> +#endif
>
> /**
> * ubi_dump_flash - dump a region of flash.
> @@ -212,6 +228,31 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req)
> */
> static struct dentry *dfs_rootdir;
>
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +static void dfs_create_fault_entry(struct dentry *parent)
> +{
> + struct dentry *dir;
> +
> + dir = debugfs_create_dir("fault_inject", parent);
> + if (IS_ERR_OR_NULL(dir)) {
> + int err = dir ? PTR_ERR(dir) : -ENODEV;
> +
> + pr_warn("UBI error: cannot create \"fault_inject\" debugfs directory, error %d\n",
> + err);
> + return;
> + }
> +
> + fault_create_debugfs_attr("emulate_bitflips", dir,
> + &fault_bitflips_attr);
> +
> + fault_create_debugfs_attr("emulate_io_failures", dir,
> + &fault_io_failures_attr);
> +
> + fault_create_debugfs_attr("emulate_power_cut", dir,
> + &fault_power_cut_attr);
> +}
> +#endif
> +
> /**
> * ubi_debugfs_init - create UBI debugfs directory.
> *
> @@ -232,6 +273,10 @@ int ubi_debugfs_init(void)
> return err;
> }
>
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + dfs_create_fault_entry(dfs_rootdir);
> +#endif
> +
> return 0;
> }
>
> @@ -272,7 +317,12 @@ 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) {
> + else if (dent == d->dfs_emulate_failures) {
> + snprintf(buf, sizeof(buf), "%u\n", d->emulate_failures);
> + count = simple_read_from_buffer(user_buf, count, ppos,
> + buf, strlen(buf));
> + goto out;
> + } 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));
> @@ -287,8 +337,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
> count = simple_read_from_buffer(user_buf, count, ppos,
> buf, strlen(buf));
> goto out;
> - }
> - else {
> + } else {
> count = -EINVAL;
> goto out;
> }
> @@ -330,7 +379,11 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
> goto out;
> }
>
> - if (dent == d->dfs_power_cut_min) {
> + if (dent == d->dfs_emulate_failures) {
> + if (kstrtouint(buf, 0, &d->emulate_failures) != 0)
> + count = -EINVAL;
> + goto out;
> + } else if (dent == d->dfs_power_cut_min) {
> if (kstrtouint(buf, 0, &d->power_cut_min) != 0)
> count = -EINVAL;
> goto out;
> @@ -559,6 +612,11 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
> debugfs_create_file("detailed_erase_block_info", S_IRUSR, d->dfs_dir,
> (void *)ubi_num, &eraseblk_count_fops);
>
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + d->dfs_emulate_failures = debugfs_create_file("emulate_failures", mode,
> + d->dfs_dir, (void *)ubi_num,
> + &dfs_fops);
> +#endif
> return 0;
> }
>
> @@ -600,7 +658,5 @@ int ubi_dbg_power_cut(struct ubi_device *ubi, int caller)
> 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 23676f32b681..fc4234c9a90a 100644
> --- a/drivers/mtd/ubi/debug.h
> +++ b/drivers/mtd/ubi/debug.h
> @@ -53,56 +53,153 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi);
> void ubi_debugfs_exit_dev(struct ubi_device *ubi);
>
> /**
> - * ubi_dbg_is_bgt_disabled - if the background thread is disabled.
> + * The following function is a legacy implementation of UBI fault-injection
> + * hook. When using more powerful fault injection capabilities, the legacy
> + * fault injection interface should be retained.
> + */
> +int ubi_dbg_power_cut(struct ubi_device *ubi, int caller);
> +
> +static inline int ubi_dbg_bitflip(const struct ubi_device *ubi)
> +{
> + if (ubi->dbg.emulate_bitflips)
> + return !get_random_u32_below(200);
> + return 0;
> +}
> +
> +static inline int ubi_dbg_write_failure(const struct ubi_device *ubi)
> +{
> + if (ubi->dbg.emulate_io_failures)
> + return !get_random_u32_below(500);
> + return 0;
> +}
> +
> +static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
> +{
> + if (ubi->dbg.emulate_io_failures)
> + return !get_random_u32_below(400);
> + return 0;
> +}
> +
> +/**
> + * MASK_XXX: Mask for emulate_failures in ubi_debug_info.The mask is used to
> + * precisely control the type and process of fault injection.
> + */
> +/* Emulate a power cut when writing EC/VID header */
> +#define MASK_POWER_CUT_EC (1 << 1)
> +#define MASK_POWER_CUT_VID (1 << 2)
POWER_CUT_EC_WRITE=0x1, POWER_CUT_VID_WRITE=0x02
To be compatible with old interface, please define MASK_POWER_CUT_EC as
(1 << 0) and define MASK_POWER_CUT_VID (1<<1)
> +
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +/* Emulate bit-flips */
> +#define MASK_BITFLIPS (1 << 3)
> +/* Emulates -EIO during write/erase */
> +#define MASK_IO_FAILURE (1 << 4)
> +
> +extern bool should_fail_bitflips(void);
> +extern bool should_fail_io_failures(void);
> +extern bool should_fail_power_cut(void);
> +
> +static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
> +{
> + if (ubi->dbg.emulate_failures & MASK_BITFLIPS)
> + return should_fail_bitflips();
> + return false;
> +}
> +
> +static inline bool ubi_dbg_fail_write(const struct ubi_device *ubi)
> +{
> + if (ubi->dbg.emulate_failures & MASK_IO_FAILURE)
> + return should_fail_io_failures();
> + return false;
> +}
> +
> +static inline bool ubi_dbg_fail_erase(const struct ubi_device *ubi)
> +{
> + if (ubi->dbg.emulate_failures & MASK_IO_FAILURE)
> + return should_fail_io_failures();
> + return false;
> +}
> +
> +static inline bool ubi_dbg_fail_power_cut(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_power_cut();
> + return false;
> +}
> +
> +#else /* CONFIG_MTD_UBI_FAULT_INJECTION */
> +
> +#define ubi_dbg_fail_bitflip(u) false
> +#define ubi_dbg_fail_write(u) false
> +#define ubi_dbg_fail_erase(u) false
> +#define ubi_dbg_fail_power_cut(u,c) false
> +#endif
> +
> +/**
> + * ubi_dbg_is_power_cut - if it is time to emulate power cut.
> * @ubi: UBI device description object
> *
> - * Returns non-zero if the UBI background thread is disabled for testing
> - * purposes.
> + * Returns true if power cut should be emulated, otherwise returns false.
> */
> -static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
> +static inline bool ubi_dbg_is_power_cut(struct ubi_device *ubi,
> + unsigned int caller)
> {
> - return ubi->dbg.disable_bgt;
> + if (ubi_dbg_power_cut(ubi, caller))
> + return true;
> + return ubi_dbg_fail_power_cut(ubi, caller);
> }
>
> /**
> * ubi_dbg_is_bitflip - if it is time to emulate a bit-flip.
> * @ubi: UBI device description object
> *
> - * Returns non-zero if a bit-flip should be emulated, otherwise returns zero.
> + * Returns true if a bit-flip should be emulated, otherwise returns false.
> */
> -static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi)
> +static inline bool ubi_dbg_is_bitflip(const struct ubi_device *ubi)
> {
> - if (ubi->dbg.emulate_bitflips)
> - return !get_random_u32_below(200);
> - return 0;
> + if (ubi_dbg_bitflip(ubi))
> + return true;
> + return ubi_dbg_fail_bitflip(ubi);
> }
>
> /**
> * ubi_dbg_is_write_failure - if it is time to emulate a write failure.
> * @ubi: UBI device description object
> *
> - * Returns non-zero if a write failure should be emulated, otherwise returns
> - * zero.
> + * Returns true if a write failure should be emulated, otherwise returns
> + * false.
> */
> -static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi)
> +static inline bool ubi_dbg_is_write_failure(const struct ubi_device *ubi)
> {
> - if (ubi->dbg.emulate_io_failures)
> - return !get_random_u32_below(500);
> - return 0;
> + if (ubi_dbg_write_failure(ubi))
> + return true;;
> + return ubi_dbg_fail_write(ubi);
> }
>
> /**
> * ubi_dbg_is_erase_failure - if its time to emulate an erase failure.
> * @ubi: UBI device description object
> *
> - * Returns non-zero if an erase failure should be emulated, otherwise returns
> - * zero.
> + * Returns true if an erase failure should be emulated, otherwise returns
> + * false.
> */
> -static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
> +static inline bool ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
> {
> - if (ubi->dbg.emulate_io_failures)
> - return !get_random_u32_below(400);
> - return 0;
> + if (ubi_dbg_erase_failure(ubi))
> + return true;
> + return ubi_dbg_fail_erase(ubi);
> +}
> +
> +/**
> + * ubi_dbg_is_bgt_disabled - if the background thread is disabled.
> + * @ubi: UBI device description object
> + *
> + * Returns non-zero if the UBI background thread is disabled for testing
> + * purposes.
> + */
> +static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
> +{
> + return ubi->dbg.disable_bgt;
> }
>
> static inline int ubi_dbg_chk_io(const struct ubi_device *ubi)
> @@ -125,5 +222,4 @@ static inline void ubi_enable_dbg_chk_fastmap(struct ubi_device *ubi)
> ubi->dbg.chk_fastmap = 1;
> }
>
> -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 01b644861253..ffa7bbf27bc2 100644
> --- a/drivers/mtd/ubi/io.c
> +++ b/drivers/mtd/ubi/io.c
> @@ -821,8 +821,11 @@ 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))
> + if (ubi_dbg_is_power_cut(ubi, MASK_POWER_CUT_EC)) {
> + ubi_warn(ubi, "XXXXX emulating a power cut when writing EC header XXXXX");
> + ubi_ro_mode(ubi);
> return -EROFS;
> + }
>
> err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize);
> return err;
> @@ -1071,8 +1074,11 @@ 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))
> + if (ubi_dbg_is_power_cut(ubi, MASK_POWER_CUT_VID)) {
> + ubi_warn(ubi, "XXXXX emulating a power cut when writing VID header XXXXX");
> + ubi_ro_mode(ubi);
> return -EROFS;
> + }
>
> 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 c8f1bd4fa100..41f57d5717b2 100644
> --- a/drivers/mtd/ubi/ubi.h
> +++ b/drivers/mtd/ubi/ubi.h
> @@ -142,17 +142,6 @@ 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_vid_io_buf - VID buffer used to read/write VID info to/from the
> * flash.
> @@ -401,6 +390,7 @@ struct ubi_volume_desc {
> * @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
> + * @emulate_failures: emulate failures for testing purposes
> * @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
> @@ -412,6 +402,7 @@ struct ubi_volume_desc {
> * @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
> + * @dfs_emulate_failures: debugfs entry to control the fault injection type
> */
> struct ubi_debug_info {
> unsigned int chk_gen:1;
> @@ -424,6 +415,7 @@ struct ubi_debug_info {
> unsigned int power_cut_counter;
> unsigned int power_cut_min;
> unsigned int power_cut_max;
> + unsigned int emulate_failures;
> char dfs_dir_name[UBI_DFS_DIR_LEN + 1];
> struct dentry *dfs_dir;
> struct dentry *dfs_chk_gen;
> @@ -435,6 +427,7 @@ struct ubi_debug_info {
> struct dentry *dfs_emulate_power_cut;
> struct dentry *dfs_power_cut_min;
> struct dentry *dfs_power_cut_max;
> + struct dentry *dfs_emulate_failures;
> };
>
> /**
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 2/5] ubi: Split io_failures into write_failure and erase_failure
2023-07-18 8:51 ` [PATCH V2 2/5] ubi: Split io_failures into write_failure and erase_failure ZhaoLong Wang
@ 2023-07-31 11:24 ` Zhihao Cheng
0 siblings, 0 replies; 13+ messages in thread
From: Zhihao Cheng @ 2023-07-31 11:24 UTC (permalink / raw)
To: ZhaoLong Wang, richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, yi.zhang
在 2023/7/18 16:51, ZhaoLong Wang 写道:
> The emulate_io_failures debugfs entry controls both write
> failure and erase failure. This patch split io_failures
> to write_failure and erase_failure.
>
> Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
> ---
> drivers/mtd/ubi/debug.c | 13 +++++++++----
> drivers/mtd/ubi/debug.h | 14 ++++++++------
> 2 files changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
> index 9ca584da32c6..7826bc8166e8 100644
> --- a/drivers/mtd/ubi/debug.c
> +++ b/drivers/mtd/ubi/debug.c
> @@ -14,7 +14,8 @@
>
> #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> static DECLARE_FAULT_ATTR(fault_bitflips_attr);
> -static DECLARE_FAULT_ATTR(fault_io_failures_attr);
> +static DECLARE_FAULT_ATTR(fault_write_failure_attr);
> +static DECLARE_FAULT_ATTR(fault_erase_failure_attr);
> static DECLARE_FAULT_ATTR(fault_power_cut_attr);
>
> #define FAIL_ACTION(name, fault_attr) \
> @@ -24,7 +25,8 @@ bool should_fail_##name(void) \
> }
>
> FAIL_ACTION(bitflips, fault_bitflips_attr)
> -FAIL_ACTION(io_failures, fault_io_failures_attr)
> +FAIL_ACTION(write_failure, fault_write_failure_attr)
> +FAIL_ACTION(erase_failure, fault_erase_failure_attr)
> FAIL_ACTION(power_cut, fault_power_cut_attr)
> #endif
>
> @@ -245,8 +247,11 @@ static void dfs_create_fault_entry(struct dentry *parent)
> fault_create_debugfs_attr("emulate_bitflips", dir,
> &fault_bitflips_attr);
>
> - fault_create_debugfs_attr("emulate_io_failures", dir,
> - &fault_io_failures_attr);
> + fault_create_debugfs_attr("emulate_write_failure", dir,
> + &fault_write_failure_attr);
> +
> + fault_create_debugfs_attr("emulate_erase_failure", dir,
> + &fault_erase_failure_attr);
>
> fault_create_debugfs_attr("emulate_power_cut", dir,
> &fault_power_cut_attr);
> diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
> index fc4234c9a90a..6bc698b38e35 100644
> --- a/drivers/mtd/ubi/debug.h
> +++ b/drivers/mtd/ubi/debug.h
> @@ -92,10 +92,12 @@ static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
> /* Emulate bit-flips */
> #define MASK_BITFLIPS (1 << 3)
> /* Emulates -EIO during write/erase */
> -#define MASK_IO_FAILURE (1 << 4)
> +#define MASK_WRITE_FAILURE (1 << 4)
> +#define MASK_ERASE_FAILURE (1 << 5)
>
> extern bool should_fail_bitflips(void);
> -extern bool should_fail_io_failures(void);
> +extern bool should_fail_write_failure(void);
> +extern bool should_fail_erase_failure(void);
> extern bool should_fail_power_cut(void);
>
> static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
> @@ -107,15 +109,15 @@ static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
>
> static inline bool ubi_dbg_fail_write(const struct ubi_device *ubi)
> {
> - if (ubi->dbg.emulate_failures & MASK_IO_FAILURE)
> - return should_fail_io_failures();
> + if (ubi->dbg.emulate_failures & MASK_WRITE_FAILURE)
> + return should_fail_write_failure();
> return false;
> }
>
> static inline bool ubi_dbg_fail_erase(const struct ubi_device *ubi)
> {
> - if (ubi->dbg.emulate_failures & MASK_IO_FAILURE)
> - return should_fail_io_failures();
> + if (ubi->dbg.emulate_failures & MASK_ERASE_FAILURE)
> + return should_fail_erase_failure();
> return false;
> }
>
>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 3/5] ubi: Add six fault injection type for testing
2023-07-18 8:51 ` [PATCH V2 3/5] ubi: Add six fault injection type for testing ZhaoLong Wang
@ 2023-07-31 11:57 ` Zhihao Cheng
2023-07-31 12:09 ` Zhihao Cheng
2023-07-31 12:21 ` Zhihao Cheng
2 siblings, 0 replies; 13+ messages in thread
From: Zhihao Cheng @ 2023-07-31 11:57 UTC (permalink / raw)
To: ZhaoLong Wang, richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, yi.zhang
在 2023/7/18 16:51, ZhaoLong Wang 写道:
> This commit adds six fault injection type for testing to cover the
> abnormal path of the UBI driver.
>
> Inject the following faults when the UBI reads the LEB:
> +----------------------------+-----------------------------------+
> | Interface name | emulate behavior |
> +----------------------------+-----------------------------------+
> | emulate_eccerr | ECC error |
> +----------------------------+-----------------------------------+
> | emulate_read_failure | read failure |
> |----------------------------+-----------------------------------+
> | emulate_io_ff | read content as all FF |
> |----------------------------+-----------------------------------+
> | emulate_io_ff_bitflips | content FF with MTD err reported |
> +----------------------------+-----------------------------------+
> | emulate_bad_hdr | bad leb header |
> |----------------------------+-----------------------------------+
> | emulate_bad_hdr_ebadmsg | bad header with ECC err |
> +----------------------------+-----------------------------------+
>
> Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
> ---
> drivers/mtd/ubi/debug.c | 30 +++++++++
> drivers/mtd/ubi/debug.h | 132 ++++++++++++++++++++++++++++++++++++++--
> drivers/mtd/ubi/io.c | 75 ++++++++++++++++++++++-
> drivers/mtd/ubi/ubi.h | 31 ++++++----
> 4 files changed, 248 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
> index 7826bc8166e8..016a861c5029 100644
> --- a/drivers/mtd/ubi/debug.c
> +++ b/drivers/mtd/ubi/debug.c
> @@ -13,10 +13,16 @@
> #include <linux/fault-inject.h>
>
> #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +static DECLARE_FAULT_ATTR(fault_eccerr_attr);
> static DECLARE_FAULT_ATTR(fault_bitflips_attr);
> +static DECLARE_FAULT_ATTR(fault_read_failure_attr);
> static DECLARE_FAULT_ATTR(fault_write_failure_attr);
> static DECLARE_FAULT_ATTR(fault_erase_failure_attr);
> static DECLARE_FAULT_ATTR(fault_power_cut_attr);
> +static DECLARE_FAULT_ATTR(fault_io_ff_attr);
> +static DECLARE_FAULT_ATTR(fault_io_ff_bitflips_attr);
> +static DECLARE_FAULT_ATTR(fault_bad_hdr_attr);
> +static DECLARE_FAULT_ATTR(fault_bad_hdr_ebadmsg_attr);
>
> #define FAIL_ACTION(name, fault_attr) \
> bool should_fail_##name(void) \
> @@ -24,10 +30,16 @@ bool should_fail_##name(void) \
> return should_fail(&fault_attr, 1); \
> }
>
> +FAIL_ACTION(eccerr, fault_eccerr_attr)
> FAIL_ACTION(bitflips, fault_bitflips_attr)
> +FAIL_ACTION(read_failure, fault_read_failure_attr)
> FAIL_ACTION(write_failure, fault_write_failure_attr)
> FAIL_ACTION(erase_failure, fault_erase_failure_attr)
> FAIL_ACTION(power_cut, fault_power_cut_attr)
> +FAIL_ACTION(io_ff, fault_io_ff_attr)
> +FAIL_ACTION(io_ff_bitflips, fault_io_ff_bitflips_attr)
> +FAIL_ACTION(bad_hdr, fault_bad_hdr_attr)
> +FAIL_ACTION(bad_hdr_ebadmsg, fault_bad_hdr_ebadmsg_attr)
> #endif
>
> /**
> @@ -244,6 +256,12 @@ static void dfs_create_fault_entry(struct dentry *parent)
> return;
> }
>
> + fault_create_debugfs_attr("emulate_eccerr", dir,
> + &fault_eccerr_attr);
> +
> + fault_create_debugfs_attr("emulate_read_failure", dir,
> + &fault_read_failure_attr);
> +
> fault_create_debugfs_attr("emulate_bitflips", dir,
> &fault_bitflips_attr);
>
> @@ -255,6 +273,18 @@ static void dfs_create_fault_entry(struct dentry *parent)
>
> fault_create_debugfs_attr("emulate_power_cut", dir,
> &fault_power_cut_attr);
> +
> + fault_create_debugfs_attr("emulate_io_ff", dir,
> + &fault_io_ff_attr);
> +
> + fault_create_debugfs_attr("emulate_io_ff_bitflips", dir,
> + &fault_io_ff_bitflips_attr);
> +
> + fault_create_debugfs_attr("emulate_bad_hdr", dir,
> + &fault_bad_hdr_attr);
> +
> + fault_create_debugfs_attr("emulate_bad_hdr_ebadmsg", dir,
> + &fault_bad_hdr_ebadmsg_attr);
> }
> #endif
>
> diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
> index 6bc698b38e35..29fbd971964a 100644
> --- a/drivers/mtd/ubi/debug.h
> +++ b/drivers/mtd/ubi/debug.h
> @@ -85,20 +85,47 @@ static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
> * precisely control the type and process of fault injection.
> */
> /* Emulate a power cut when writing EC/VID header */
> -#define MASK_POWER_CUT_EC (1 << 1)
> -#define MASK_POWER_CUT_VID (1 << 2)
> +#define MASK_POWER_CUT_EC (1 << 0)
> +#define MASK_POWER_CUT_VID (1 << 1)
>
> #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +/* Emulate a power cut when writing data*/
> +#define MASK_POWER_CUT_DATA (1 << 2)
> /* Emulate bit-flips */
> -#define MASK_BITFLIPS (1 << 3)
> -/* Emulates -EIO during write/erase */
> -#define MASK_WRITE_FAILURE (1 << 4)
> -#define MASK_ERASE_FAILURE (1 << 5)
> +#define MASK_BITFLIPS (1 << 3)
> +/* Emulate ecc error */
> +#define MASK_ECCERR (1 << 4)
> +/* Emulates -EIO during data read */
> +#define MASK_READ_FAILURE (1 << 5)
> +#define MASK_READ_FAILURE_EC (1 << 6)
> +#define MASK_READ_FAILURE_VID (1 << 7)
> +/* Emulates -EIO during data write */
> +#define MASK_WRITE_FAILURE (1 << 8)
> +/* Emulates -EIO during erase a PEB*/
> +#define MASK_ERASE_FAILURE (1 << 9)
> +/* Return UBI_IO_FF when reading EC/VID header */
> +#define MASK_IO_FF_EC (1 << 10)
> +#define MASK_IO_FF_VID (1 << 11)
> +/* Return UBI_IO_FF_BITFLIPS when reading EC/VID header */
> +#define MASK_IO_FF_BITFLIPS_EC (1 << 12)
> +#define MASK_IO_FF_BITFLIPS_VID (1 << 13)
> +/* Return UBI_IO_BAD_HDR when reading EC/VID header */
> +#define MASK_BAD_HDR_EC (1 << 14)
> +#define MASK_BAD_HDR_VID (1 << 15)
> +/* Return UBI_IO_BAD_HDR_EBADMSG when reading EC/VID header */
> +#define MASK_BAD_HDR_EBADMSG_EC (1 << 16)
> +#define MASK_BAD_HDR_EBADMSG_VID (1 << 17)
>
> +extern bool should_fail_eccerr(void);
> extern bool should_fail_bitflips(void);
> +extern bool should_fail_read_failure(void);
> extern bool should_fail_write_failure(void);
> extern bool should_fail_erase_failure(void);
> extern bool should_fail_power_cut(void);
> +extern bool should_fail_io_ff(void);
> +extern bool should_fail_io_ff_bitflips(void);
> +extern bool should_fail_bad_hdr(void);
> +extern bool should_fail_bad_hdr_ebadmsg(void);
>
> static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
> {
> @@ -192,6 +219,99 @@ static inline bool ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
> return ubi_dbg_fail_erase(ubi);
> }
>
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +/**
> + * ubi_dbg_is_eccerr - if it is time to emulate ECC error.
> + * @ubi: UBI device description object
> + *
> + * Returns true if a ECC error should be emulated, otherwise returns false.
> + */
> +static inline bool ubi_dbg_is_eccerr(const struct ubi_device *ubi)
> +{
> + if (ubi->dbg.emulate_failures & MASK_ECCERR)
> + return should_fail_eccerr();
> + return false;
> +}
I prefer to keep the same style as ubi_dbg_fail_bitflip, which means
that define two functions corresponding to enabling
CONFIG_MTD_UBI_FAULT_INJECTION and disabling CONFIG_MTD_UBI_FAULT_INJECTION.
> +
> +/**
> + * ubi_dbg_is_read_failure - if it is time to emulate a read failure.
> + * @ubi: UBI device description object
> + *
> + * Returns true if a read failure should be emulated, otherwise returns
> + * false.
> + */
> +static inline bool ubi_dbg_is_read_failure(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_read_failure();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_ff - if it is time to emulate that read region is only 0xFF.
> + * @ubi: UBI device description object
> + *
> + * Returns true if read region should be emulated 0xFF, otherwise
> + * returns false.
> + */
> +static inline bool ubi_dbg_is_ff(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_io_ff();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_ff_bitflips - if it is time to emulate that read region is only 0xFF
> + * with error reported by the MTD driver
> + *
> + * @ubi: UBI device description object
> + *
> + * Returns true if read region should be emulated 0xFF and error
> + * reported by the MTD driver, otherwise returns false.
> + */
> +static inline bool ubi_dbg_is_ff_bitflips(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_io_ff_bitflips();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_bad_hdr - if it is time to emulate a bad header
> + * @ubi: UBI device description object
> + *
> + * Returns true if a bad header error should be emulated, otherwise
> + * returns false.
> + */
> +static inline bool ubi_dbg_is_bad_hdr(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_bad_hdr();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_bad_hdr_ebadmsg - if it is time to emulate a bad header with
> + * ECC error.
> + *
> + * @ubi: UBI device description object
> + *
> + * Returns true if a bad header with ECC error should be emulated, otherwise
> + * returns false.
> + */
> +static inline bool ubi_dbg_is_bad_hdr_ebadmsg(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_bad_hdr_ebadmsg();
> + return false;
> +}
> +#endif
> /**
> * ubi_dbg_is_bgt_disabled - if the background thread is disabled.
> * @ubi: UBI device description object
> diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
> index ffa7bbf27bc2..059032132bdd 100644
> --- a/drivers/mtd/ubi/io.c
> +++ b/drivers/mtd/ubi/io.c
> @@ -197,6 +197,19 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
> dbg_gen("bit-flip (emulated)");
> err = UBI_IO_BITFLIPS;
> }
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE)) {
> + ubi_warn(ubi, "cannot read %d bytes from PEB %d:%d (emulated)",
> + len, pnum, offset);
> + return -EIO;
> + }
> +
> + if (ubi_dbg_is_eccerr(ubi)) {
> + ubi_warn(ubi, "ECC error (emulated) while reading %d bytes from PEB %d:%d, read %zd bytes",
> + len, pnum, offset, read);
> + return -EBADMSG;
> + }
> +#endif
> }
>
> return err;
> @@ -782,7 +795,36 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
> * If there was %-EBADMSG, but the header CRC is still OK, report about
> * a bit-flip to force scrubbing on this PEB.
> */
> - return read_err ? UBI_IO_BITFLIPS : 0;
> + if (read_err)
> + return UBI_IO_BITFLIPS;
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_EC)) {
> + ubi_warn(ubi, "cannot read EC header from PEB %d(emulated)",
> + pnum);
> + return -EIO;
> + }
> +
> + if (ubi_dbg_is_ff(ubi, MASK_IO_FF_EC)) {
> + ubi_warn(ubi, "bit-all-ff (emulated)");
> + return UBI_IO_FF;
> + }
> +
> + if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_EC)) {
> + ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)");
> + return UBI_IO_FF_BITFLIPS;
> + }
> +
> + if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_EC)) {
> + ubi_warn(ubi, "bad_hdr (emulated)");
> + return UBI_IO_BAD_HDR;
> + }
> +
> + if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_EC)) {
> + ubi_warn(ubi, "bad_hdr with ECC error (emulated)");
> + return UBI_IO_BAD_HDR_EBADMSG;
> + }
> +#endif
> + return 0;
> }
>
> /**
> @@ -1032,7 +1074,36 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
> return -EINVAL;
> }
>
> - return read_err ? UBI_IO_BITFLIPS : 0;
> + if (read_err)
> + return UBI_IO_BITFLIPS;
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_VID)) {
> + ubi_warn(ubi, "cannot read VID header from PEB %d(emulated)",
> + pnum);
> + return -EIO;
> + }
> +
> + if (ubi_dbg_is_ff(ubi, MASK_IO_FF_VID)) {
> + ubi_warn(ubi, "bit-all-ff (emulated)\n");
> + return UBI_IO_FF;
> + }
> +
> + if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_VID)) {
> + ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)\n");
> + return UBI_IO_FF_BITFLIPS;
> + }
> +
> + if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_VID)) {
> + ubi_warn(ubi, "bad_hdr (emulated)\n");
> + return UBI_IO_BAD_HDR;
> + }
> +
> + if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_VID)) {
> + ubi_warn(ubi, "bad_hdr with ECC error (emulated)\n");
> + return UBI_IO_BAD_HDR_EBADMSG;
> + }
> +#endif
> + return 0;
> }
>
> /**
> diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
> index 41f57d5717b2..36d46425ed4c 100644
> --- a/drivers/mtd/ubi/ubi.h
> +++ b/drivers/mtd/ubi/ubi.h
> @@ -1117,18 +1117,6 @@ static inline struct ubi_vid_hdr *ubi_get_vid_hdr(struct ubi_vid_io_buf *vidb)
> return vidb->hdr;
> }
>
> -/*
> - * This function is equivalent to 'ubi_io_read()', but @offset is relative to
> - * the beginning of the logical eraseblock, not to the beginning of the
> - * physical eraseblock.
> - */
> -static inline int ubi_io_read_data(const struct ubi_device *ubi, void *buf,
> - int pnum, int offset, int len)
> -{
> - ubi_assert(offset >= 0);
> - return ubi_io_read(ubi, buf, pnum, offset + ubi->leb_start, len);
> -}
> -
> /*
> * This function is equivalent to 'ubi_io_write()', but @offset is relative to
> * the beginning of the logical eraseblock, not to the beginning of the
> @@ -1154,6 +1142,25 @@ static inline void ubi_ro_mode(struct ubi_device *ubi)
> }
> }
>
> +/*
> + * This function is equivalent to 'ubi_io_read()', but @offset is relative to
> + * the beginning of the logical eraseblock, not to the beginning of the
> + * physical eraseblock.
> + */
> +static inline int ubi_io_read_data(struct ubi_device *ubi, void *buf,
> + int pnum, int offset, int len)
I thought you want to modify 'ubi_io_write_data'.
> +{
> + ubi_assert(offset >= 0);
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + if (ubi_dbg_power_cut(ubi, MASK_POWER_CUT_DATA)) {
> + ubi_warn(ubi, "XXXXX emulating a power cut when writing data XXXXX");
> + ubi_ro_mode(ubi);
> + return -EROFS;
> + }
> +#endif
> + return ubi_io_read(ubi, buf, pnum, offset + ubi->leb_start, len);
> +}
> +
> /**
> * vol_id2idx - get table index by volume ID.
> * @ubi: UBI device description object
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 3/5] ubi: Add six fault injection type for testing
2023-07-18 8:51 ` [PATCH V2 3/5] ubi: Add six fault injection type for testing ZhaoLong Wang
2023-07-31 11:57 ` Zhihao Cheng
@ 2023-07-31 12:09 ` Zhihao Cheng
2023-07-31 12:21 ` Zhihao Cheng
2 siblings, 0 replies; 13+ messages in thread
From: Zhihao Cheng @ 2023-07-31 12:09 UTC (permalink / raw)
To: ZhaoLong Wang, richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, yi.zhang
在 2023/7/18 16:51, ZhaoLong Wang 写道:
> This commit adds six fault injection type for testing to cover the
> abnormal path of the UBI driver.
>
> Inject the following faults when the UBI reads the LEB:
> +----------------------------+-----------------------------------+
> | Interface name | emulate behavior |
> +----------------------------+-----------------------------------+
> | emulate_eccerr | ECC error |
> +----------------------------+-----------------------------------+
> | emulate_read_failure | read failure |
> |----------------------------+-----------------------------------+
> | emulate_io_ff | read content as all FF |
> |----------------------------+-----------------------------------+
> | emulate_io_ff_bitflips | content FF with MTD err reported |
> +----------------------------+-----------------------------------+
> | emulate_bad_hdr | bad leb header |
> |----------------------------+-----------------------------------+
> | emulate_bad_hdr_ebadmsg | bad header with ECC err |
> +----------------------------+-----------------------------------+
>
> Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
> ---
> drivers/mtd/ubi/debug.c | 30 +++++++++
> drivers/mtd/ubi/debug.h | 132 ++++++++++++++++++++++++++++++++++++++--
> drivers/mtd/ubi/io.c | 75 ++++++++++++++++++++++-
> drivers/mtd/ubi/ubi.h | 31 ++++++----
> 4 files changed, 248 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
> index 7826bc8166e8..016a861c5029 100644
> --- a/drivers/mtd/ubi/debug.c
> +++ b/drivers/mtd/ubi/debug.c
> @@ -13,10 +13,16 @@
> #include <linux/fault-inject.h>
>
> #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +static DECLARE_FAULT_ATTR(fault_eccerr_attr);
> static DECLARE_FAULT_ATTR(fault_bitflips_attr);
> +static DECLARE_FAULT_ATTR(fault_read_failure_attr);
> static DECLARE_FAULT_ATTR(fault_write_failure_attr);
> static DECLARE_FAULT_ATTR(fault_erase_failure_attr);
> static DECLARE_FAULT_ATTR(fault_power_cut_attr);
> +static DECLARE_FAULT_ATTR(fault_io_ff_attr);
> +static DECLARE_FAULT_ATTR(fault_io_ff_bitflips_attr);
> +static DECLARE_FAULT_ATTR(fault_bad_hdr_attr);
> +static DECLARE_FAULT_ATTR(fault_bad_hdr_ebadmsg_attr);
>
> #define FAIL_ACTION(name, fault_attr) \
> bool should_fail_##name(void) \
> @@ -24,10 +30,16 @@ bool should_fail_##name(void) \
> return should_fail(&fault_attr, 1); \
> }
>
> +FAIL_ACTION(eccerr, fault_eccerr_attr)
> FAIL_ACTION(bitflips, fault_bitflips_attr)
> +FAIL_ACTION(read_failure, fault_read_failure_attr)
> FAIL_ACTION(write_failure, fault_write_failure_attr)
> FAIL_ACTION(erase_failure, fault_erase_failure_attr)
> FAIL_ACTION(power_cut, fault_power_cut_attr)
> +FAIL_ACTION(io_ff, fault_io_ff_attr)
> +FAIL_ACTION(io_ff_bitflips, fault_io_ff_bitflips_attr)
> +FAIL_ACTION(bad_hdr, fault_bad_hdr_attr)
> +FAIL_ACTION(bad_hdr_ebadmsg, fault_bad_hdr_ebadmsg_attr)
> #endif
>
> /**
> @@ -244,6 +256,12 @@ static void dfs_create_fault_entry(struct dentry *parent)
> return;
> }
>
> + fault_create_debugfs_attr("emulate_eccerr", dir,
> + &fault_eccerr_attr);
> +
> + fault_create_debugfs_attr("emulate_read_failure", dir,
> + &fault_read_failure_attr);
> +
> fault_create_debugfs_attr("emulate_bitflips", dir,
> &fault_bitflips_attr);
>
> @@ -255,6 +273,18 @@ static void dfs_create_fault_entry(struct dentry *parent)
>
> fault_create_debugfs_attr("emulate_power_cut", dir,
> &fault_power_cut_attr);
> +
> + fault_create_debugfs_attr("emulate_io_ff", dir,
> + &fault_io_ff_attr);
> +
> + fault_create_debugfs_attr("emulate_io_ff_bitflips", dir,
> + &fault_io_ff_bitflips_attr);
> +
> + fault_create_debugfs_attr("emulate_bad_hdr", dir,
> + &fault_bad_hdr_attr);
> +
> + fault_create_debugfs_attr("emulate_bad_hdr_ebadmsg", dir,
> + &fault_bad_hdr_ebadmsg_attr);
> }
> #endif
>
> diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
> index 6bc698b38e35..29fbd971964a 100644
> --- a/drivers/mtd/ubi/debug.h
> +++ b/drivers/mtd/ubi/debug.h
> @@ -85,20 +85,47 @@ static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
> * precisely control the type and process of fault injection.
> */
> /* Emulate a power cut when writing EC/VID header */
> -#define MASK_POWER_CUT_EC (1 << 1)
> -#define MASK_POWER_CUT_VID (1 << 2)
> +#define MASK_POWER_CUT_EC (1 << 0)
> +#define MASK_POWER_CUT_VID (1 << 1)
>
> #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +/* Emulate a power cut when writing data*/
> +#define MASK_POWER_CUT_DATA (1 << 2)
> /* Emulate bit-flips */
> -#define MASK_BITFLIPS (1 << 3)
> -/* Emulates -EIO during write/erase */
> -#define MASK_WRITE_FAILURE (1 << 4)
> -#define MASK_ERASE_FAILURE (1 << 5)
> +#define MASK_BITFLIPS (1 << 3)
> +/* Emulate ecc error */
> +#define MASK_ECCERR (1 << 4)
> +/* Emulates -EIO during data read */
> +#define MASK_READ_FAILURE (1 << 5)
> +#define MASK_READ_FAILURE_EC (1 << 6)
> +#define MASK_READ_FAILURE_VID (1 << 7)
> +/* Emulates -EIO during data write */
> +#define MASK_WRITE_FAILURE (1 << 8)
> +/* Emulates -EIO during erase a PEB*/
> +#define MASK_ERASE_FAILURE (1 << 9)
> +/* Return UBI_IO_FF when reading EC/VID header */
> +#define MASK_IO_FF_EC (1 << 10)
> +#define MASK_IO_FF_VID (1 << 11)
> +/* Return UBI_IO_FF_BITFLIPS when reading EC/VID header */
> +#define MASK_IO_FF_BITFLIPS_EC (1 << 12)
> +#define MASK_IO_FF_BITFLIPS_VID (1 << 13)
> +/* Return UBI_IO_BAD_HDR when reading EC/VID header */
> +#define MASK_BAD_HDR_EC (1 << 14)
> +#define MASK_BAD_HDR_VID (1 << 15)
> +/* Return UBI_IO_BAD_HDR_EBADMSG when reading EC/VID header */
> +#define MASK_BAD_HDR_EBADMSG_EC (1 << 16)
> +#define MASK_BAD_HDR_EBADMSG_VID (1 << 17)
>
> +extern bool should_fail_eccerr(void);
> extern bool should_fail_bitflips(void);
> +extern bool should_fail_read_failure(void);
> extern bool should_fail_write_failure(void);
> extern bool should_fail_erase_failure(void);
> extern bool should_fail_power_cut(void);
> +extern bool should_fail_io_ff(void);
> +extern bool should_fail_io_ff_bitflips(void);
> +extern bool should_fail_bad_hdr(void);
> +extern bool should_fail_bad_hdr_ebadmsg(void);
>
> static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
> {
> @@ -192,6 +219,99 @@ static inline bool ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
> return ubi_dbg_fail_erase(ubi);
> }
>
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +/**
> + * ubi_dbg_is_eccerr - if it is time to emulate ECC error.
> + * @ubi: UBI device description object
> + *
> + * Returns true if a ECC error should be emulated, otherwise returns false.
> + */
> +static inline bool ubi_dbg_is_eccerr(const struct ubi_device *ubi)
> +{
> + if (ubi->dbg.emulate_failures & MASK_ECCERR)
> + return should_fail_eccerr();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_read_failure - if it is time to emulate a read failure.
> + * @ubi: UBI device description object
> + *
> + * Returns true if a read failure should be emulated, otherwise returns
> + * false.
> + */
> +static inline bool ubi_dbg_is_read_failure(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_read_failure();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_ff - if it is time to emulate that read region is only 0xFF.
> + * @ubi: UBI device description object
> + *
> + * Returns true if read region should be emulated 0xFF, otherwise
> + * returns false.
> + */
> +static inline bool ubi_dbg_is_ff(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_io_ff();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_ff_bitflips - if it is time to emulate that read region is only 0xFF
> + * with error reported by the MTD driver
> + *
> + * @ubi: UBI device description object
> + *
> + * Returns true if read region should be emulated 0xFF and error
> + * reported by the MTD driver, otherwise returns false.
> + */
> +static inline bool ubi_dbg_is_ff_bitflips(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_io_ff_bitflips();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_bad_hdr - if it is time to emulate a bad header
> + * @ubi: UBI device description object
> + *
> + * Returns true if a bad header error should be emulated, otherwise
> + * returns false.
> + */
> +static inline bool ubi_dbg_is_bad_hdr(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_bad_hdr();
> + return false;
> +}
> +
> +/**
> + * ubi_dbg_is_bad_hdr_ebadmsg - if it is time to emulate a bad header with
> + * ECC error.
> + *
> + * @ubi: UBI device description object
> + *
> + * Returns true if a bad header with ECC error should be emulated, otherwise
> + * returns false.
> + */
> +static inline bool ubi_dbg_is_bad_hdr_ebadmsg(const struct ubi_device *ubi,
> + unsigned int caller)
> +{
> + if (ubi->dbg.emulate_failures & caller)
> + return should_fail_bad_hdr_ebadmsg();
> + return false;
> +}
> +#endif
> /**
> * ubi_dbg_is_bgt_disabled - if the background thread is disabled.
> * @ubi: UBI device description object
> diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
> index ffa7bbf27bc2..059032132bdd 100644
> --- a/drivers/mtd/ubi/io.c
> +++ b/drivers/mtd/ubi/io.c
> @@ -197,6 +197,19 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
> dbg_gen("bit-flip (emulated)");
> err = UBI_IO_BITFLIPS;
return UBI_IO_BITFLIPS;
> }
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE)) {
> + ubi_warn(ubi, "cannot read %d bytes from PEB %d:%d (emulated)",
> + len, pnum, offset);
> + return -EIO;
> + }
> +
> + if (ubi_dbg_is_eccerr(ubi)) {
> + ubi_warn(ubi, "ECC error (emulated) while reading %d bytes from PEB %d:%d, read %zd bytes",
> + len, pnum, offset, read);
> + return -EBADMSG;
> + }
> +#endif
> }
>
> return err;
> @@ -782,7 +795,36 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
> * If there was %-EBADMSG, but the header CRC is still OK, report about
> * a bit-flip to force scrubbing on this PEB.
> */
> - return read_err ? UBI_IO_BITFLIPS : 0;
> + if (read_err)
> + return UBI_IO_BITFLIPS;
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_EC)) {
> + ubi_warn(ubi, "cannot read EC header from PEB %d(emulated)",
> + pnum);
> + return -EIO;
> + }
> +
> + if (ubi_dbg_is_ff(ubi, MASK_IO_FF_EC)) {
> + ubi_warn(ubi, "bit-all-ff (emulated)");
> + return UBI_IO_FF;
> + }
> +
> + if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_EC)) {
> + ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)");
> + return UBI_IO_FF_BITFLIPS;
> + }
> +
> + if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_EC)) {
> + ubi_warn(ubi, "bad_hdr (emulated)");
> + return UBI_IO_BAD_HDR;
> + }
> +
> + if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_EC)) {
> + ubi_warn(ubi, "bad_hdr with ECC error (emulated)");
> + return UBI_IO_BAD_HDR_EBADMSG;
> + }
> +#endif
> + return 0;
> }
>
> /**
> @@ -1032,7 +1074,36 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
> return -EINVAL;
> }
>
> - return read_err ? UBI_IO_BITFLIPS : 0;
> + if (read_err)
> + return UBI_IO_BITFLIPS;
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_VID)) {
> + ubi_warn(ubi, "cannot read VID header from PEB %d(emulated)",
> + pnum);
> + return -EIO;
> + }
> +
> + if (ubi_dbg_is_ff(ubi, MASK_IO_FF_VID)) {
> + ubi_warn(ubi, "bit-all-ff (emulated)\n");
> + return UBI_IO_FF;
> + }
> +
> + if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_VID)) {
> + ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)\n");
> + return UBI_IO_FF_BITFLIPS;
> + }
> +
> + if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_VID)) {
> + ubi_warn(ubi, "bad_hdr (emulated)\n");
> + return UBI_IO_BAD_HDR;
> + }
> +
> + if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_VID)) {
> + ubi_warn(ubi, "bad_hdr with ECC error (emulated)\n");
> + return UBI_IO_BAD_HDR_EBADMSG;
> + }
> +#endif
> + return 0;
> }
>
> /**
> diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
> index 41f57d5717b2..36d46425ed4c 100644
> --- a/drivers/mtd/ubi/ubi.h
> +++ b/drivers/mtd/ubi/ubi.h
> @@ -1117,18 +1117,6 @@ static inline struct ubi_vid_hdr *ubi_get_vid_hdr(struct ubi_vid_io_buf *vidb)
> return vidb->hdr;
> }
>
> -/*
> - * This function is equivalent to 'ubi_io_read()', but @offset is relative to
> - * the beginning of the logical eraseblock, not to the beginning of the
> - * physical eraseblock.
> - */
> -static inline int ubi_io_read_data(const struct ubi_device *ubi, void *buf,
> - int pnum, int offset, int len)
> -{
> - ubi_assert(offset >= 0);
> - return ubi_io_read(ubi, buf, pnum, offset + ubi->leb_start, len);
> -}
> -
> /*
> * This function is equivalent to 'ubi_io_write()', but @offset is relative to
> * the beginning of the logical eraseblock, not to the beginning of the
> @@ -1154,6 +1142,25 @@ static inline void ubi_ro_mode(struct ubi_device *ubi)
> }
> }
>
> +/*
> + * This function is equivalent to 'ubi_io_read()', but @offset is relative to
> + * the beginning of the logical eraseblock, not to the beginning of the
> + * physical eraseblock.
> + */
> +static inline int ubi_io_read_data(struct ubi_device *ubi, void *buf,
> + int pnum, int offset, int len)
> +{
> + ubi_assert(offset >= 0);
> +#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> + if (ubi_dbg_power_cut(ubi, MASK_POWER_CUT_DATA)) {
> + ubi_warn(ubi, "XXXXX emulating a power cut when writing data XXXXX");
> + ubi_ro_mode(ubi);
> + return -EROFS;
> + }
> +#endif
> + return ubi_io_read(ubi, buf, pnum, offset + ubi->leb_start, len);
> +}
> +
> /**
> * vol_id2idx - get table index by volume ID.
> * @ubi: UBI device description object
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 4/5] ubi: Reserve sufficient buffer length for the input mask
2023-07-18 8:51 ` [PATCH V2 4/5] ubi: Reserve sufficient buffer length for the input mask ZhaoLong Wang
@ 2023-07-31 12:13 ` Zhihao Cheng
0 siblings, 0 replies; 13+ messages in thread
From: Zhihao Cheng @ 2023-07-31 12:13 UTC (permalink / raw)
To: ZhaoLong Wang, richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, yi.zhang
在 2023/7/18 16:51, ZhaoLong Wang 写道:
> Because the mask received by the emulate_failures interface
> is a 32-bit unsigned integer, ensure that there is sufficient
> buffer length to receive and display this value.
>
> Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
> ---
> V2:
> - A 16-byte buffer is reserved, as implemented by other interfaces.
>
> drivers/mtd/ubi/debug.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
> index 016a861c5029..1c3f1a2436e5 100644
> --- a/drivers/mtd/ubi/debug.c
> +++ b/drivers/mtd/ubi/debug.c
> @@ -332,7 +332,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[8];
> + char buf[16];
> int val;
>
> ubi = ubi_get_device(ubi_num);
> @@ -400,7 +400,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] = {0};
> + char buf[16] = {0};
> int val;
>
> ubi = ubi_get_device(ubi_num);
>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 5/5] mtd: Add several functions to the fail_function list
2023-07-18 8:51 ` [PATCH V2 5/5] mtd: Add several functions to the fail_function list ZhaoLong Wang
@ 2023-07-31 12:16 ` Zhihao Cheng
0 siblings, 0 replies; 13+ messages in thread
From: Zhihao Cheng @ 2023-07-31 12:16 UTC (permalink / raw)
To: ZhaoLong Wang, richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, yi.zhang
在 2023/7/18 16:51, ZhaoLong Wang 写道:
> add mtd_read(), mtd_write(), mtd_erase(), mtd_block_markbad() to
> fail_function list for testing purpose
>
It could be better if you can provide some examples for how to use these
error injection interfaces.
> Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
> ---
> drivers/mtd/mtdcore.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index e00b12aa5ec9..ecf1c5e68479 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -30,6 +30,7 @@
> #include <linux/debugfs.h>
> #include <linux/nvmem-provider.h>
> #include <linux/root_dev.h>
> +#include <linux/error-injection.h>
>
> #include <linux/mtd/mtd.h>
> #include <linux/mtd/partitions.h>
> @@ -1396,6 +1397,7 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
> return ret;
> }
> EXPORT_SYMBOL_GPL(mtd_erase);
> +ALLOW_ERROR_INJECTION(mtd_erase, ERRNO);
>
> /*
> * This stuff for eXecute-In-Place. phys is optional and may be set to NULL.
> @@ -1493,6 +1495,7 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
> return ret;
> }
> EXPORT_SYMBOL_GPL(mtd_read);
> +ALLOW_ERROR_INJECTION(mtd_read, ERRNO);
>
> int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
> const u_char *buf)
> @@ -1509,6 +1512,7 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
> return ret;
> }
> EXPORT_SYMBOL_GPL(mtd_write);
> +ALLOW_ERROR_INJECTION(mtd_write, ERRNO);
>
> /*
> * In blackbox flight recorder like scenarios we want to make successful writes
> @@ -2329,7 +2333,7 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
> return 0;
> }
> EXPORT_SYMBOL_GPL(mtd_block_markbad);
> -
> +ALLOW_ERROR_INJECTION(mtd_block_markbad, ERRNO);
> /*
> * default_mtd_writev - the default writev method
> * @mtd: mtd device description object pointer
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V2 3/5] ubi: Add six fault injection type for testing
2023-07-18 8:51 ` [PATCH V2 3/5] ubi: Add six fault injection type for testing ZhaoLong Wang
2023-07-31 11:57 ` Zhihao Cheng
2023-07-31 12:09 ` Zhihao Cheng
@ 2023-07-31 12:21 ` Zhihao Cheng
2 siblings, 0 replies; 13+ messages in thread
From: Zhihao Cheng @ 2023-07-31 12:21 UTC (permalink / raw)
To: ZhaoLong Wang, richard, miquel.raynal, vigneshr
Cc: linux-mtd, linux-kernel, yi.zhang
在 2023/7/18 16:51, ZhaoLong Wang 写道:
> This commit adds six fault injection type for testing to cover the
> abnormal path of the UBI driver.
>
> Inject the following faults when the UBI reads the LEB:
> +----------------------------+-----------------------------------+
> | Interface name | emulate behavior |
> +----------------------------+-----------------------------------+
> | emulate_eccerr | ECC error |
> +----------------------------+-----------------------------------+
> | emulate_read_failure | read failure |
> |----------------------------+-----------------------------------+
> | emulate_io_ff | read content as all FF |
> |----------------------------+-----------------------------------+
> | emulate_io_ff_bitflips | content FF with MTD err reported |
> +----------------------------+-----------------------------------+
> | emulate_bad_hdr | bad leb header |
> |----------------------------+-----------------------------------+
> | emulate_bad_hdr_ebadmsg | bad header with ECC err |
> +----------------------------+-----------------------------------+
>
> Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
> ---
> drivers/mtd/ubi/debug.c | 30 +++++++++
> drivers/mtd/ubi/debug.h | 132 ++++++++++++++++++++++++++++++++++++++--
> drivers/mtd/ubi/io.c | 75 ++++++++++++++++++++++-
> drivers/mtd/ubi/ubi.h | 31 ++++++----
> 4 files changed, 248 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
> index 7826bc8166e8..016a861c5029 100644
> --- a/drivers/mtd/ubi/debug.c
> +++ b/drivers/mtd/ubi/debug.c
> @@ -13,10 +13,16 @@
> #include <linux/fault-inject.h>
>
> #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +static DECLARE_FAULT_ATTR(fault_eccerr_attr);
> static DECLARE_FAULT_ATTR(fault_bitflips_attr);
> +static DECLARE_FAULT_ATTR(fault_read_failure_attr);
> static DECLARE_FAULT_ATTR(fault_write_failure_attr);
> static DECLARE_FAULT_ATTR(fault_erase_failure_attr);
> static DECLARE_FAULT_ATTR(fault_power_cut_attr);
> +static DECLARE_FAULT_ATTR(fault_io_ff_attr);
> +static DECLARE_FAULT_ATTR(fault_io_ff_bitflips_attr);
> +static DECLARE_FAULT_ATTR(fault_bad_hdr_attr);
> +static DECLARE_FAULT_ATTR(fault_bad_hdr_ebadmsg_attr);
>
> #define FAIL_ACTION(name, fault_attr) \
> bool should_fail_##name(void) \
> @@ -24,10 +30,16 @@ bool should_fail_##name(void) \
> return should_fail(&fault_attr, 1); \
> }
>
> +FAIL_ACTION(eccerr, fault_eccerr_attr)
> FAIL_ACTION(bitflips, fault_bitflips_attr)
> +FAIL_ACTION(read_failure, fault_read_failure_attr)
> FAIL_ACTION(write_failure, fault_write_failure_attr)
> FAIL_ACTION(erase_failure, fault_erase_failure_attr)
> FAIL_ACTION(power_cut, fault_power_cut_attr)
> +FAIL_ACTION(io_ff, fault_io_ff_attr)
> +FAIL_ACTION(io_ff_bitflips, fault_io_ff_bitflips_attr)
> +FAIL_ACTION(bad_hdr, fault_bad_hdr_attr)
> +FAIL_ACTION(bad_hdr_ebadmsg, fault_bad_hdr_ebadmsg_attr)
> #endif
>
> /**
> @@ -244,6 +256,12 @@ static void dfs_create_fault_entry(struct dentry *parent)
> return;
> }
>
> + fault_create_debugfs_attr("emulate_eccerr", dir,
> + &fault_eccerr_attr);
> +
> + fault_create_debugfs_attr("emulate_read_failure", dir,
> + &fault_read_failure_attr);
> +
> fault_create_debugfs_attr("emulate_bitflips", dir,
> &fault_bitflips_attr);
>
> @@ -255,6 +273,18 @@ static void dfs_create_fault_entry(struct dentry *parent)
>
> fault_create_debugfs_attr("emulate_power_cut", dir,
> &fault_power_cut_attr);
> +
> + fault_create_debugfs_attr("emulate_io_ff", dir,
> + &fault_io_ff_attr);
> +
> + fault_create_debugfs_attr("emulate_io_ff_bitflips", dir,
> + &fault_io_ff_bitflips_attr);
> +
> + fault_create_debugfs_attr("emulate_bad_hdr", dir,
> + &fault_bad_hdr_attr);
> +
> + fault_create_debugfs_attr("emulate_bad_hdr_ebadmsg", dir,
> + &fault_bad_hdr_ebadmsg_attr);
> }
> #endif
>
> diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
> index 6bc698b38e35..29fbd971964a 100644
> --- a/drivers/mtd/ubi/debug.h
> +++ b/drivers/mtd/ubi/debug.h
> @@ -85,20 +85,47 @@ static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
> * precisely control the type and process of fault injection.
> */
> /* Emulate a power cut when writing EC/VID header */
> -#define MASK_POWER_CUT_EC (1 << 1)
> -#define MASK_POWER_CUT_VID (1 << 2)
> +#define MASK_POWER_CUT_EC (1 << 0)
> +#define MASK_POWER_CUT_VID (1 << 1)
>
> #ifdef CONFIG_MTD_UBI_FAULT_INJECTION
> +/* Emulate a power cut when writing data*/
> +#define MASK_POWER_CUT_DATA (1 << 2)
> /* Emulate bit-flips */
> -#define MASK_BITFLIPS (1 << 3)
> -/* Emulates -EIO during write/erase */
> -#define MASK_WRITE_FAILURE (1 << 4)
> -#define MASK_ERASE_FAILURE (1 << 5)
> +#define MASK_BITFLIPS (1 << 3)
> +/* Emulate ecc error */
> +#define MASK_ECCERR (1 << 4)
> +/* Emulates -EIO during data read */
> +#define MASK_READ_FAILURE (1 << 5)
> +#define MASK_READ_FAILURE_EC (1 << 6)
> +#define MASK_READ_FAILURE_VID (1 << 7)
> +/* Emulates -EIO during data write */
> +#define MASK_WRITE_FAILURE (1 << 8)
> +/* Emulates -EIO during erase a PEB*/
> +#define MASK_ERASE_FAILURE (1 << 9)
> +/* Return UBI_IO_FF when reading EC/VID header */
> +#define MASK_IO_FF_EC (1 << 10)
> +#define MASK_IO_FF_VID (1 << 11)
> +/* Return UBI_IO_FF_BITFLIPS when reading EC/VID header */
> +#define MASK_IO_FF_BITFLIPS_EC (1 << 12)
> +#define MASK_IO_FF_BITFLIPS_VID (1 << 13)
> +/* Return UBI_IO_BAD_HDR when reading EC/VID header */
> +#define MASK_BAD_HDR_EC (1 << 14)
> +#define MASK_BAD_HDR_VID (1 << 15)
> +/* Return UBI_IO_BAD_HDR_EBADMSG when reading EC/VID header */
> +#define MASK_BAD_HDR_EBADMSG_EC (1 << 16)
> +#define MASK_BAD_HDR_EBADMSG_VID (1 << 17)
>
Now, you add many types of fault injections, it's better to make
dfs_file_read display human-readable context for 'd->emulate_failures',
for example:
value:17409
POWER_CUT_EC,MASK_IO_FF_EC,MASK_BAD_HDR_EC
value:0
None
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2023-07-31 12:22 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-18 8:51 [PATCH V2 0/5] ubi: Enhanced fault injection capability for the UBI driver ZhaoLong Wang
2023-07-18 8:51 ` [PATCH V2 1/5] ubi: Use the fault injection framework to enhance the fault injection capability ZhaoLong Wang
2023-07-31 11:15 ` Zhihao Cheng
2023-07-18 8:51 ` [PATCH V2 2/5] ubi: Split io_failures into write_failure and erase_failure ZhaoLong Wang
2023-07-31 11:24 ` Zhihao Cheng
2023-07-18 8:51 ` [PATCH V2 3/5] ubi: Add six fault injection type for testing ZhaoLong Wang
2023-07-31 11:57 ` Zhihao Cheng
2023-07-31 12:09 ` Zhihao Cheng
2023-07-31 12:21 ` Zhihao Cheng
2023-07-18 8:51 ` [PATCH V2 4/5] ubi: Reserve sufficient buffer length for the input mask ZhaoLong Wang
2023-07-31 12:13 ` Zhihao Cheng
2023-07-18 8:51 ` [PATCH V2 5/5] mtd: Add several functions to the fail_function list ZhaoLong Wang
2023-07-31 12:16 ` Zhihao Cheng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®