diff options
author | Richard Weinberger <richard@nod.at> | 2014-09-23 19:29:05 +0200 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2015-03-26 19:30:54 +0100 |
commit | 19371d73c9bd31a8e634ec5a80fc19fcd7714481 (patch) | |
tree | e04e6910c0c98500f74afb8b92cb060404518df1 /drivers/mtd/ubi/wl.c | |
parent | ab6de685221a95392e46d75d0651ac08b8a57689 (diff) | |
download | lwn-19371d73c9bd31a8e634ec5a80fc19fcd7714481.tar.gz lwn-19371d73c9bd31a8e634ec5a80fc19fcd7714481.zip |
UBI: Fastmap: Ensure that only one fastmap work is scheduled
If the WL pool runs out of PEBs we schedule a fastmap write
to refill it as soon as possible.
Ensure that only one at a time is scheduled otherwise we might end in
a fastmap write storm because writing the fastmap can schedule another
write if bitflips are detected.
Signed-off-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Tanya Brokhman <tlinder@codeaurora.org>
Reviewed-by: Guido Martínez <guido@vanguardiasur.com.ar>
Diffstat (limited to 'drivers/mtd/ubi/wl.c')
-rw-r--r-- | drivers/mtd/ubi/wl.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 0bd92d816391..ae174f4ed674 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -149,6 +149,9 @@ static void update_fastmap_work_fn(struct work_struct *wrk) { struct ubi_device *ubi = container_of(wrk, struct ubi_device, fm_work); ubi_update_fastmap(ubi); + spin_lock(&ubi->wl_lock); + ubi->fm_work_scheduled = 0; + spin_unlock(&ubi->wl_lock); } /** @@ -657,7 +660,10 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) /* We cannot update the fastmap here because this * function is called in atomic context. * Let's fail here and refill/update it as soon as possible. */ - schedule_work(&ubi->fm_work); + if (!ubi->fm_work_scheduled) { + ubi->fm_work_scheduled = 1; + schedule_work(&ubi->fm_work); + } return NULL; } else { pnum = pool->pebs[pool->used++]; |