diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-08-29 07:51:52 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-10-14 06:10:21 -0400 |
commit | e88d6e10e5c848fd5be8f89e09e3bce2570886b7 (patch) | |
tree | 27b5547a0e24add89deafedaed784328bc3c173e /drivers/mtd/ubi/build.c | |
parent | 33818bbb84cd371b63ed8849cc5264d24c8b3aa2 (diff) |
UBI: do not use vmalloc on I/O path
Similar reason as in case of the previous patch: it causes
deadlocks if a filesystem with writeback support works on top
of UBI. So pre-allocate needed buffers when attaching MTD device.
We also need mutexes to protect the buffers, but they do not
cause much contantion because they are used in recovery, torture,
and WL copy routines, which are called seldom.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r-- | drivers/mtd/ubi/build.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 1cb22bfae750..023653977a1a 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -565,7 +565,7 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, | |||
565 | } | 565 | } |
566 | 566 | ||
567 | ubi = ubi_devices[ubi_devices_cnt] = kzalloc(sizeof(struct ubi_device), | 567 | ubi = ubi_devices[ubi_devices_cnt] = kzalloc(sizeof(struct ubi_device), |
568 | GFP_KERNEL); | 568 | GFP_KERNEL); |
569 | if (!ubi) { | 569 | if (!ubi) { |
570 | err = -ENOMEM; | 570 | err = -ENOMEM; |
571 | goto out_mtd; | 571 | goto out_mtd; |
@@ -583,6 +583,22 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, | |||
583 | if (err) | 583 | if (err) |
584 | goto out_free; | 584 | goto out_free; |
585 | 585 | ||
586 | mutex_init(&ubi->buf_mutex); | ||
587 | ubi->peb_buf1 = vmalloc(ubi->peb_size); | ||
588 | if (!ubi->peb_buf1) | ||
589 | goto out_free; | ||
590 | |||
591 | ubi->peb_buf2 = vmalloc(ubi->peb_size); | ||
592 | if (!ubi->peb_buf2) | ||
593 | goto out_free; | ||
594 | |||
595 | #ifdef CONFIG_MTD_UBI_DEBUG | ||
596 | mutex_init(&ubi->dbg_buf_mutex); | ||
597 | ubi->dbg_peb_buf = vmalloc(ubi->peb_size); | ||
598 | if (!ubi->dbg_peb_buf) | ||
599 | goto out_free; | ||
600 | #endif | ||
601 | |||
586 | err = attach_by_scanning(ubi); | 602 | err = attach_by_scanning(ubi); |
587 | if (err) { | 603 | if (err) { |
588 | dbg_err("failed to attach by scanning, error %d", err); | 604 | dbg_err("failed to attach by scanning, error %d", err); |
@@ -630,6 +646,11 @@ out_detach: | |||
630 | ubi_wl_close(ubi); | 646 | ubi_wl_close(ubi); |
631 | vfree(ubi->vtbl); | 647 | vfree(ubi->vtbl); |
632 | out_free: | 648 | out_free: |
649 | vfree(ubi->peb_buf1); | ||
650 | vfree(ubi->peb_buf2); | ||
651 | #ifdef CONFIG_MTD_UBI_DEBUG | ||
652 | vfree(ubi->dbg_peb_buf); | ||
653 | #endif | ||
633 | kfree(ubi); | 654 | kfree(ubi); |
634 | out_mtd: | 655 | out_mtd: |
635 | put_mtd_device(mtd); | 656 | put_mtd_device(mtd); |
@@ -651,6 +672,11 @@ static void detach_mtd_dev(struct ubi_device *ubi) | |||
651 | ubi_wl_close(ubi); | 672 | ubi_wl_close(ubi); |
652 | vfree(ubi->vtbl); | 673 | vfree(ubi->vtbl); |
653 | put_mtd_device(ubi->mtd); | 674 | put_mtd_device(ubi->mtd); |
675 | vfree(ubi->peb_buf1); | ||
676 | vfree(ubi->peb_buf2); | ||
677 | #ifdef CONFIG_MTD_UBI_DEBUG | ||
678 | vfree(ubi->dbg_peb_buf); | ||
679 | #endif | ||
654 | kfree(ubi_devices[ubi_num]); | 680 | kfree(ubi_devices[ubi_num]); |
655 | ubi_devices[ubi_num] = NULL; | 681 | ubi_devices[ubi_num] = NULL; |
656 | ubi_devices_cnt -= 1; | 682 | ubi_devices_cnt -= 1; |