Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+21 -19
+6 -6
drivers/mtd/ubi/eba.c
··· 157 157 { 158 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 161 if (!le) 162 162 return ERR_PTR(-ENOMEM); 163 163 ··· 397 397 398 398 retry: 399 399 if (check) { 400 - vid_hdr = ubi_zalloc_vid_hdr(ubi); 400 + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 401 401 if (!vid_hdr) { 402 402 err = -ENOMEM; 403 403 goto out_unlock; ··· 497 497 struct ubi_vid_hdr *vid_hdr; 498 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 501 if (!vid_hdr) { 502 502 return -ENOMEM; 503 503 } ··· 627 627 * The logical eraseblock is not mapped. We have to get a free physical 628 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 631 if (!vid_hdr) { 632 632 leb_write_unlock(ubi, vol_id, lnum); 633 633 return -ENOMEM; ··· 738 738 else 739 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 742 if (!vid_hdr) 743 743 return -ENOMEM; 744 744 ··· 844 844 if (ubi->ro_mode) 845 845 return -EROFS; 846 846 847 - vid_hdr = ubi_zalloc_vid_hdr(ubi); 847 + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 848 848 if (!vid_hdr) 849 849 return -ENOMEM; 850 850
+2 -2
drivers/mtd/ubi/io.c
··· 1099 1099 uint32_t crc, hdr_crc; 1100 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 1103 if (!ec_hdr) 1104 1104 return -ENOMEM; 1105 1105 ··· 1179 1179 struct ubi_vid_hdr *vid_hdr; 1180 1180 void *p; 1181 1181 1182 - vid_hdr = ubi_zalloc_vid_hdr(ubi); 1182 + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 1183 1183 if (!vid_hdr) 1184 1184 return -ENOMEM; 1185 1185
+2 -2
drivers/mtd/ubi/scan.c
··· 323 323 } else { 324 324 pnum = seb->pnum; 325 325 326 - vh = ubi_zalloc_vid_hdr(ubi); 326 + vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); 327 327 if (!vh) 328 328 return -ENOMEM; 329 329 ··· 948 948 if (!ech) 949 949 goto out_si; 950 950 951 - vidh = ubi_zalloc_vid_hdr(ubi); 951 + vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); 952 952 if (!vidh) 953 953 goto out_ech; 954 954
+4 -2
drivers/mtd/ubi/ubi.h
··· 439 439 /** 440 440 * ubi_zalloc_vid_hdr - allocate a volume identifier header object. 441 441 * @ubi: UBI device description object 442 + * @gfp_flags: GFP flags to allocate with 442 443 * 443 444 * This function returns a pointer to the newly allocated and zero-filled 444 445 * volume identifier header object in case of success and %NULL in case of 445 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 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 454 if (!vid_hdr) 453 455 return NULL; 454 456
+1 -1
drivers/mtd/ubi/vtbl.c
··· 264 264 265 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 268 if (!vid_hdr) 269 269 return -ENOMEM; 270 270
+6 -6
drivers/mtd/ubi/wl.c
··· 508 508 ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || 509 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 512 if (!pe) 513 513 return -ENOMEM; 514 514 ··· 645 645 if (err > 0) 646 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 649 if (!ec_hdr) 650 650 return -ENOMEM; 651 651 ··· 768 768 dbg_wl("schedule erasure of PEB %d, EC %d, torture %d", 769 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 772 if (!wl_wrk) 773 773 return -ENOMEM; 774 774 ··· 802 802 if (cancel) 803 803 return 0; 804 804 805 - vid_hdr = ubi_zalloc_vid_hdr(ubi); 805 + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 806 806 if (!vid_hdr) 807 807 return -ENOMEM; 808 808 ··· 1028 1028 ubi->wl_scheduled = 1; 1029 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 1032 if (!wrk) { 1033 1033 err = -ENOMEM; 1034 1034 goto out_cancel; ··· 1631 1631 long long read_ec; 1632 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 1635 if (!ec_hdr) 1636 1636 return -ENOMEM; 1637 1637