Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92d124f5 authored by Artem Bityutskiy's avatar Artem Bityutskiy
Browse files

UBI: make self-checks dynamic



This patch adds a possibility to dynamically switch UBI self-checks
on and off, instead of toggling them compile-time from the configuration
menu. This is much more flexible, and consistent with UBIFS, and this
also simplifies UBI Kconfig menu and the code.

This patch introduces two levels of self-checks - general, which
includes all self-checks which are relatively fast, and I/O, which
includes write-verify checks and erase-verify checks, which are
relatively slow and involve flash I/O.

Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent b342efd4
Loading
Loading
Loading
Loading
+0 −6
Original line number Original line Diff line number Diff line
@@ -10,12 +10,6 @@ config MTD_UBI_DEBUG


if MTD_UBI_DEBUG
if MTD_UBI_DEBUG


config MTD_UBI_DEBUG_PARANOID
	bool "Extra self-checks"
	help
	  This option enables extra checks in UBI code. Note this slows UBI down
	  significantly.

config MTD_UBI_DEBUG_DISABLE_BGT
config MTD_UBI_DEBUG_DISABLE_BGT
	bool "Do not enable the UBI background thread"
	bool "Do not enable the UBI background thread"
	help
	help
+3 −0
Original line number Original line Diff line number Diff line
@@ -31,10 +31,13 @@
#include <linux/moduleparam.h>
#include <linux/moduleparam.h>


unsigned int ubi_msg_flags;
unsigned int ubi_msg_flags;
unsigned int ubi_chk_flags;


module_param_named(debug_msgs, ubi_msg_flags, uint, S_IRUGO | S_IWUSR);
module_param_named(debug_msgs, ubi_msg_flags, uint, S_IRUGO | S_IWUSR);
module_param_named(debug_chks, ubi_chk_flags, uint, S_IRUGO | S_IWUSR);


MODULE_PARM_DESC(debug_msgs, "Debug message type flags");
MODULE_PARM_DESC(debug_msgs, "Debug message type flags");
MODULE_PARM_DESC(debug_chks, "Debug check flags");


/**
/**
 * ubi_dbg_dump_ec_hdr - dump an erase counter header.
 * ubi_dbg_dump_ec_hdr - dump an erase counter header.
+13 −5
Original line number Original line Diff line number Diff line
@@ -99,14 +99,22 @@ enum {
/* Initialization and build messages */
/* Initialization and build messages */
#define dbg_bld(fmt, ...) dbg_do_msg(UBI_MSG_BLD, fmt, ##__VA_ARGS__)
#define dbg_bld(fmt, ...) dbg_do_msg(UBI_MSG_BLD, fmt, ##__VA_ARGS__)


#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
extern unsigned int ubi_chk_flags;

/*
 * Debugging check flags.
 *
 * UBI_CHK_GEN: general checks
 * UBI_CHK_IO: check writes and erases
 */
enum {
	UBI_CHK_GEN = 0x1,
	UBI_CHK_IO  = 0x2,
};

int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len);
int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len);
int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
			int offset, int len);
			int offset, int len);
#else
#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0
#endif


#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT
#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT
#define DBG_DISABLE_BGT 1
#define DBG_DISABLE_BGT 1
+24 −3
Original line number Original line Diff line number Diff line
@@ -91,7 +91,7 @@
#include <linux/slab.h>
#include <linux/slab.h>
#include "ubi.h"
#include "ubi.h"


#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
#ifdef CONFIG_MTD_UBI_DEBUG
static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum);
static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum);
static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum);
static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum);
static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
@@ -1126,7 +1126,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
	return err;
	return err;
}
}


#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
#ifdef CONFIG_MTD_UBI_DEBUG


/**
/**
 * paranoid_check_not_bad - ensure that a physical eraseblock is not bad.
 * paranoid_check_not_bad - ensure that a physical eraseblock is not bad.
@@ -1140,6 +1140,9 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
{
{
	int err;
	int err;


	if (!(ubi_chk_flags & UBI_CHK_IO))
		return 0;

	err = ubi_io_is_bad(ubi, pnum);
	err = ubi_io_is_bad(ubi, pnum);
	if (!err)
	if (!err)
		return err;
		return err;
@@ -1164,6 +1167,9 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
	int err;
	int err;
	uint32_t magic;
	uint32_t magic;


	if (!(ubi_chk_flags & UBI_CHK_IO))
		return 0;

	magic = be32_to_cpu(ec_hdr->magic);
	magic = be32_to_cpu(ec_hdr->magic);
	if (magic != UBI_EC_HDR_MAGIC) {
	if (magic != UBI_EC_HDR_MAGIC) {
		ubi_err("bad magic %#08x, must be %#08x",
		ubi_err("bad magic %#08x, must be %#08x",
@@ -1199,6 +1205,9 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
	uint32_t crc, hdr_crc;
	uint32_t crc, hdr_crc;
	struct ubi_ec_hdr *ec_hdr;
	struct ubi_ec_hdr *ec_hdr;


	if (!(ubi_chk_flags & UBI_CHK_IO))
		return 0;

	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
	if (!ec_hdr)
	if (!ec_hdr)
		return -ENOMEM;
		return -ENOMEM;
@@ -1240,6 +1249,9 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
	int err;
	int err;
	uint32_t magic;
	uint32_t magic;


	if (!(ubi_chk_flags & UBI_CHK_IO))
		return 0;

	magic = be32_to_cpu(vid_hdr->magic);
	magic = be32_to_cpu(vid_hdr->magic);
	if (magic != UBI_VID_HDR_MAGIC) {
	if (magic != UBI_VID_HDR_MAGIC) {
		ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x",
		ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x",
@@ -1278,6 +1290,9 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
	struct ubi_vid_hdr *vid_hdr;
	struct ubi_vid_hdr *vid_hdr;
	void *p;
	void *p;


	if (!(ubi_chk_flags & UBI_CHK_IO))
		return 0;

	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
	if (!vid_hdr)
	if (!vid_hdr)
		return -ENOMEM;
		return -ENOMEM;
@@ -1327,6 +1342,9 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
	void *buf1;
	void *buf1;
	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;


	if (!(ubi_chk_flags & UBI_CHK_IO))
		return 0;

	buf1 = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL);
	buf1 = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL);
	if (!buf1) {
	if (!buf1) {
		ubi_err("cannot allocate memory to check writes");
		ubi_err("cannot allocate memory to check writes");
@@ -1388,6 +1406,9 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
	void *buf;
	void *buf;
	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;


	if (!(ubi_chk_flags & UBI_CHK_IO))
		return 0;

	buf = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL);
	buf = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL);
	if (!buf) {
	if (!buf) {
		ubi_err("cannot allocate memory to check for 0xFFs");
		ubi_err("cannot allocate memory to check for 0xFFs");
@@ -1422,4 +1443,4 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
	return err;
	return err;
}
}


#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
#endif /* CONFIG_MTD_UBI_DEBUG */
+6 −3
Original line number Original line Diff line number Diff line
@@ -88,7 +88,7 @@
#include <linux/random.h>
#include <linux/random.h>
#include "ubi.h"
#include "ubi.h"


#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
#ifdef CONFIG_MTD_UBI_DEBUG
static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si);
static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si);
#else
#else
#define paranoid_check_si(ubi, si) 0
#define paranoid_check_si(ubi, si) 0
@@ -1329,7 +1329,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
	kfree(si);
	kfree(si);
}
}


#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
#ifdef CONFIG_MTD_UBI_DEBUG


/**
/**
 * paranoid_check_si - check the scanning information.
 * paranoid_check_si - check the scanning information.
@@ -1347,6 +1347,9 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si)
	struct ubi_scan_leb *seb, *last_seb;
	struct ubi_scan_leb *seb, *last_seb;
	uint8_t *buf;
	uint8_t *buf;


	if (!(ubi_chk_flags & UBI_CHK_GEN))
		return 0;

	/*
	/*
	 * At first, check that scanning information is OK.
	 * At first, check that scanning information is OK.
	 */
	 */
@@ -1599,4 +1602,4 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si)
	return -EINVAL;
	return -EINVAL;
}
}


#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
#endif /* CONFIG_MTD_UBI_DEBUG */
Loading