diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-08-28 14:29:32 -0400 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-10-14 06:10:20 -0400 |
commit | 33818bbb84cd371b63ed8849cc5264d24c8b3aa2 (patch) | |
tree | ecee6a8f02d2d103c6eb33cc6173e74343b1861b /drivers | |
parent | ef6075fbfca9139f428d52d60e671da38aa2e212 (diff) |
UBI: allocate memory with GFP_NOFS
Use GFP_NOFS flag when allocating memory on I/O path, because otherwise
we may deadlock the filesystem which works on top of us. We observed
the deadlocks with UBIFS. Example:
VFS->FS lock a lock->UBI->kmalloc()->VFS writeback->FS locks the same
lock again.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/ubi/eba.c | 12 | ||||
-rw-r--r-- | drivers/mtd/ubi/io.c | 4 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.c | 4 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 2 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 12 |
6 files changed, 21 insertions, 19 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 7c5e29eaf118..89193104c6c8 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -157,7 +157,7 @@ static struct ltree_entry *ltree_add_entry(struct ubi_device *ubi, int vol_id, | |||
157 | { | 157 | { |
158 | struct ltree_entry *le, *le1, *le_free; | 158 | struct ltree_entry *le, *le1, *le_free; |
159 | 159 | ||
160 | le = kmem_cache_alloc(ltree_slab, GFP_KERNEL); | 160 | le = kmem_cache_alloc(ltree_slab, GFP_NOFS); |
161 | if (!le) | 161 | if (!le) |
162 | return ERR_PTR(-ENOMEM); | 162 | return ERR_PTR(-ENOMEM); |
163 | 163 | ||
@@ -397,7 +397,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf, | |||
397 | 397 | ||
398 | retry: | 398 | retry: |
399 | if (check) { | 399 | if (check) { |
400 | vid_hdr = ubi_zalloc_vid_hdr(ubi); | 400 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
401 | if (!vid_hdr) { | 401 | if (!vid_hdr) { |
402 | err = -ENOMEM; | 402 | err = -ENOMEM; |
403 | goto out_unlock; | 403 | goto out_unlock; |
@@ -497,7 +497,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, | |||
497 | struct ubi_vid_hdr *vid_hdr; | 497 | struct ubi_vid_hdr *vid_hdr; |
498 | unsigned char *new_buf; | 498 | unsigned char *new_buf; |
499 | 499 | ||
500 | vid_hdr = ubi_zalloc_vid_hdr(ubi); | 500 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
501 | if (!vid_hdr) { | 501 | if (!vid_hdr) { |
502 | return -ENOMEM; | 502 | return -ENOMEM; |
503 | } | 503 | } |
@@ -627,7 +627,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum, | |||
627 | * The logical eraseblock is not mapped. We have to get a free physical | 627 | * The logical eraseblock is not mapped. We have to get a free physical |
628 | * eraseblock and write the volume identifier header there first. | 628 | * eraseblock and write the volume identifier header there first. |
629 | */ | 629 | */ |
630 | vid_hdr = ubi_zalloc_vid_hdr(ubi); | 630 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
631 | if (!vid_hdr) { | 631 | if (!vid_hdr) { |
632 | leb_write_unlock(ubi, vol_id, lnum); | 632 | leb_write_unlock(ubi, vol_id, lnum); |
633 | return -ENOMEM; | 633 | return -ENOMEM; |
@@ -738,7 +738,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, | |||
738 | else | 738 | else |
739 | ubi_assert(len % ubi->min_io_size == 0); | 739 | ubi_assert(len % ubi->min_io_size == 0); |
740 | 740 | ||
741 | vid_hdr = ubi_zalloc_vid_hdr(ubi); | 741 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
742 | if (!vid_hdr) | 742 | if (!vid_hdr) |
743 | return -ENOMEM; | 743 | return -ENOMEM; |
744 | 744 | ||
@@ -844,7 +844,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, | |||
844 | if (ubi->ro_mode) | 844 | if (ubi->ro_mode) |
845 | return -EROFS; | 845 | return -EROFS; |
846 | 846 | ||
847 | vid_hdr = ubi_zalloc_vid_hdr(ubi); | 847 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
848 | if (!vid_hdr) | 848 | if (!vid_hdr) |
849 | return -ENOMEM; | 849 | return -ENOMEM; |
850 | 850 | ||
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 928476394d55..ba5bc4a5379e 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -1099,7 +1099,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) | |||
1099 | uint32_t crc, hdr_crc; | 1099 | uint32_t crc, hdr_crc; |
1100 | struct ubi_ec_hdr *ec_hdr; | 1100 | struct ubi_ec_hdr *ec_hdr; |
1101 | 1101 | ||
1102 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); | 1102 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
1103 | if (!ec_hdr) | 1103 | if (!ec_hdr) |
1104 | return -ENOMEM; | 1104 | return -ENOMEM; |
1105 | 1105 | ||
@@ -1179,7 +1179,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) | |||
1179 | struct ubi_vid_hdr *vid_hdr; | 1179 | struct ubi_vid_hdr *vid_hdr; |
1180 | void *p; | 1180 | void *p; |
1181 | 1181 | ||
1182 | vid_hdr = ubi_zalloc_vid_hdr(ubi); | 1182 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
1183 | if (!vid_hdr) | 1183 | if (!vid_hdr) |
1184 | return -ENOMEM; | 1184 | return -ENOMEM; |
1185 | 1185 | ||
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 18c347b24e27..1c1401d6958b 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -323,7 +323,7 @@ static int compare_lebs(const struct ubi_device *ubi, | |||
323 | } else { | 323 | } else { |
324 | pnum = seb->pnum; | 324 | pnum = seb->pnum; |
325 | 325 | ||
326 | vh = ubi_zalloc_vid_hdr(ubi); | 326 | vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); |
327 | if (!vh) | 327 | if (!vh) |
328 | return -ENOMEM; | 328 | return -ENOMEM; |
329 | 329 | ||
@@ -948,7 +948,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) | |||
948 | if (!ech) | 948 | if (!ech) |
949 | goto out_si; | 949 | goto out_si; |
950 | 950 | ||
951 | vidh = ubi_zalloc_vid_hdr(ubi); | 951 | vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); |
952 | if (!vidh) | 952 | if (!vidh) |
953 | goto out_ech; | 953 | goto out_ech; |
954 | 954 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 5959f91be240..329663188772 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -439,16 +439,18 @@ int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
439 | /** | 439 | /** |
440 | * ubi_zalloc_vid_hdr - allocate a volume identifier header object. | 440 | * ubi_zalloc_vid_hdr - allocate a volume identifier header object. |
441 | * @ubi: UBI device description object | 441 | * @ubi: UBI device description object |
442 | * @gfp_flags: GFP flags to allocate with | ||
442 | * | 443 | * |
443 | * This function returns a pointer to the newly allocated and zero-filled | 444 | * This function returns a pointer to the newly allocated and zero-filled |
444 | * volume identifier header object in case of success and %NULL in case of | 445 | * volume identifier header object in case of success and %NULL in case of |
445 | * failure. | 446 | * failure. |
446 | */ | 447 | */ |
447 | static inline struct ubi_vid_hdr *ubi_zalloc_vid_hdr(const struct ubi_device *ubi) | 448 | static inline struct ubi_vid_hdr * |
449 | ubi_zalloc_vid_hdr(const struct ubi_device *ubi, gfp_t gfp_flags) | ||
448 | { | 450 | { |
449 | void *vid_hdr; | 451 | void *vid_hdr; |
450 | 452 | ||
451 | vid_hdr = kzalloc(ubi->vid_hdr_alsize, GFP_KERNEL); | 453 | vid_hdr = kzalloc(ubi->vid_hdr_alsize, gfp_flags); |
452 | if (!vid_hdr) | 454 | if (!vid_hdr) |
453 | return NULL; | 455 | return NULL; |
454 | 456 | ||
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index bc5df50813d6..b0a1e8426456 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -264,7 +264,7 @@ static int create_vtbl(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
264 | 264 | ||
265 | ubi_msg("create volume table (copy #%d)", copy + 1); | 265 | ubi_msg("create volume table (copy #%d)", copy + 1); |
266 | 266 | ||
267 | vid_hdr = ubi_zalloc_vid_hdr(ubi); | 267 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); |
268 | if (!vid_hdr) | 268 | if (!vid_hdr) |
269 | return -ENOMEM; | 269 | return -ENOMEM; |
270 | 270 | ||
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 12b25e5b7b81..248ff9e477e7 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -508,7 +508,7 @@ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) | |||
508 | ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || | 508 | ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || |
509 | dtype == UBI_UNKNOWN); | 509 | dtype == UBI_UNKNOWN); |
510 | 510 | ||
511 | pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_KERNEL); | 511 | pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_NOFS); |
512 | if (!pe) | 512 | if (!pe) |
513 | return -ENOMEM; | 513 | return -ENOMEM; |
514 | 514 | ||
@@ -645,7 +645,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, int tortur | |||
645 | if (err > 0) | 645 | if (err > 0) |
646 | return -EINVAL; | 646 | return -EINVAL; |
647 | 647 | ||
648 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); | 648 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
649 | if (!ec_hdr) | 649 | if (!ec_hdr) |
650 | return -ENOMEM; | 650 | return -ENOMEM; |
651 | 651 | ||
@@ -768,7 +768,7 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, | |||
768 | dbg_wl("schedule erasure of PEB %d, EC %d, torture %d", | 768 | dbg_wl("schedule erasure of PEB %d, EC %d, torture %d", |
769 | e->pnum, e->ec, torture); | 769 | e->pnum, e->ec, torture); |
770 | 770 | ||
771 | wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_KERNEL); | 771 | wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); |
772 | if (!wl_wrk) | 772 | if (!wl_wrk) |
773 | return -ENOMEM; | 773 | return -ENOMEM; |
774 | 774 | ||
@@ -802,7 +802,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
802 | if (cancel) | 802 | if (cancel) |
803 | return 0; | 803 | return 0; |
804 | 804 | ||
805 | vid_hdr = ubi_zalloc_vid_hdr(ubi); | 805 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
806 | if (!vid_hdr) | 806 | if (!vid_hdr) |
807 | return -ENOMEM; | 807 | return -ENOMEM; |
808 | 808 | ||
@@ -1028,7 +1028,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi) | |||
1028 | ubi->wl_scheduled = 1; | 1028 | ubi->wl_scheduled = 1; |
1029 | spin_unlock(&ubi->wl_lock); | 1029 | spin_unlock(&ubi->wl_lock); |
1030 | 1030 | ||
1031 | wrk = kmalloc(sizeof(struct ubi_work), GFP_KERNEL); | 1031 | wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); |
1032 | if (!wrk) { | 1032 | if (!wrk) { |
1033 | err = -ENOMEM; | 1033 | err = -ENOMEM; |
1034 | goto out_cancel; | 1034 | goto out_cancel; |
@@ -1631,7 +1631,7 @@ static int paranoid_check_ec(const struct ubi_device *ubi, int pnum, int ec) | |||
1631 | long long read_ec; | 1631 | long long read_ec; |
1632 | struct ubi_ec_hdr *ec_hdr; | 1632 | struct ubi_ec_hdr *ec_hdr; |
1633 | 1633 | ||
1634 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); | 1634 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
1635 | if (!ec_hdr) | 1635 | if (!ec_hdr) |
1636 | return -ENOMEM; | 1636 | return -ENOMEM; |
1637 | 1637 | ||