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

Commit 47edb451 authored by Nikhilesh Reddy's avatar Nikhilesh Reddy
Browse files

mtd: ubi: Add kconfig to handle RD at attach



Add a new Kconfig flag to optionally turn on
handling read disturb at ubi attach. Turning on
this flag can cause significant delays at attach.

During the first boot the system would not have acquired
a valid time stamp and all the erase times are marked as
zero (since the clock start at zero).
Then on subsequent bootups if the system has an updated
time stamp it would cause all the PEB's to be marked for
scrubbing as this time difference would be much larger
than the time threshold.

Change-Id: I71c1b87b4407774bbb17f8acfdacbca537d87365
Signed-off-by: default avatarNikhilesh Reddy <reddyn@codeaurora.org>
parent c5564588
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -77,6 +77,19 @@ config MTD_UBI_FASTMAP

	   If in doubt, say "N".

config MTD_UBI_ENABLE_RD_AT_ATTACH
	bool "UBI handle read disturb at attach. (Experimental feature)"
	help
	   Important: this feature is experimental so far and may be removed
	   entirely in the future.

	   Handle the read disturb errors that can happen in NAND devices
	   by checking the last erased timestamp and the read count of the
	   PEB's at attach time in addition to runtime. This can cause
	   significant overhead during attach and must be used with caution.

	   If in doubt, say "N".

config MTD_UBI_GLUEBI
	tristate "MTD devices emulation driver (gluebi)"
	help
+31 −5
Original line number Diff line number Diff line
@@ -2074,6 +2074,21 @@ static void cancel_pending(struct ubi_device *ubi)
	}
}

/**
 * enable_check_rd_at_attach - Enable the check read disturb at attach.
 */
#ifdef CONFIG_MTD_UBI_ENABLE_RD_AT_ATTACH
static bool enable_check_rd_at_attach(void)
{
	return true;
}
#else
static bool enable_check_rd_at_attach(void)
{
	return false;
}
#endif

/**
 * ubi_wl_init - initialize the WL sub-system using attaching information.
 * @ubi: UBI device description object
@@ -2090,6 +2105,13 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
	struct ubi_ainf_peb *aeb, *tmp;
	struct ubi_wl_entry *e;
	struct timeval tv;
	bool check_rd_at_attach;

	check_rd_at_attach = enable_check_rd_at_attach();
	if (check_rd_at_attach)
		ubi_msg(ubi->ubi_num, "Read disturb check ENABLED at attach");
	else
		ubi_msg(ubi->ubi_num, "Read disturb check DISABLED at attach");

	do_gettimeofday(&tv);
	ubi->used = ubi->erroneous = ubi->free = ubi->scrub = RB_ROOT;
@@ -2176,9 +2198,11 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
		ubi_assert(e->ec >= 0);
		ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
		ubi->lookuptbl[e->pnum] = e;

		/* Check last erase time stamp (in days) */
		if (e->last_erase_time + ubi->dt_threshold <
			(tv.tv_sec / NUM_SEC_IN_DAY)) {
		if (check_rd_at_attach &&
			(e->last_erase_time + ubi->dt_threshold <
			(tv.tv_sec / NUM_SEC_IN_DAY))) {
			if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) {
				kmem_cache_free(ubi_wl_entry_slab, e);
				goto out_free;
@@ -2222,14 +2246,16 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
			 * Verify last erase timestamp
			 * (in days) and read counter
			 */
			if (e->last_erase_time + ubi->dt_threshold <
			if (check_rd_at_attach &&
				(e->last_erase_time + ubi->dt_threshold <
				(tv.tv_sec / NUM_SEC_IN_DAY) ||
				e->rc > ubi->rd_threshold) {
				e->rc > ubi->rd_threshold)) {
				ubi_msg(ubi->ubi_num,
					"scrub PEB %d rc = %d",
				       e->pnum, e->rc);
				aeb->scrub = 1;
			}

			if (!aeb->scrub) {
				dbg_wl("add PEB %d EC %d to the used tree",
				       e->pnum, e->ec);