diff options
-rw-r--r-- | fs/xfs/kmem.c | 21 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.c | 11 |
2 files changed, 31 insertions, 1 deletions
diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index 66a36befc5c0..844e288b9576 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c | |||
@@ -65,12 +65,31 @@ kmem_alloc(size_t size, xfs_km_flags_t flags) | |||
65 | void * | 65 | void * |
66 | kmem_zalloc_large(size_t size, xfs_km_flags_t flags) | 66 | kmem_zalloc_large(size_t size, xfs_km_flags_t flags) |
67 | { | 67 | { |
68 | unsigned noio_flag = 0; | ||
68 | void *ptr; | 69 | void *ptr; |
70 | gfp_t lflags; | ||
69 | 71 | ||
70 | ptr = kmem_zalloc(size, flags | KM_MAYFAIL); | 72 | ptr = kmem_zalloc(size, flags | KM_MAYFAIL); |
71 | if (ptr) | 73 | if (ptr) |
72 | return ptr; | 74 | return ptr; |
73 | return vzalloc(size); | 75 | |
76 | /* | ||
77 | * __vmalloc() will allocate data pages and auxillary structures (e.g. | ||
78 | * pagetables) with GFP_KERNEL, yet we may be under GFP_NOFS context | ||
79 | * here. Hence we need to tell memory reclaim that we are in such a | ||
80 | * context via PF_MEMALLOC_NOIO to prevent memory reclaim re-entering | ||
81 | * the filesystem here and potentially deadlocking. | ||
82 | */ | ||
83 | if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS)) | ||
84 | noio_flag = memalloc_noio_save(); | ||
85 | |||
86 | lflags = kmem_flags_convert(flags); | ||
87 | ptr = __vmalloc(size, lflags | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); | ||
88 | |||
89 | if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS)) | ||
90 | memalloc_noio_restore(noio_flag); | ||
91 | |||
92 | return ptr; | ||
74 | } | 93 | } |
75 | 94 | ||
76 | void | 95 | void |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 9c061ef2b0d9..107f2fdfe41f 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -396,7 +396,17 @@ _xfs_buf_map_pages( | |||
396 | bp->b_addr = NULL; | 396 | bp->b_addr = NULL; |
397 | } else { | 397 | } else { |
398 | int retried = 0; | 398 | int retried = 0; |
399 | unsigned noio_flag; | ||
399 | 400 | ||
401 | /* | ||
402 | * vm_map_ram() will allocate auxillary structures (e.g. | ||
403 | * pagetables) with GFP_KERNEL, yet we are likely to be under | ||
404 | * GFP_NOFS context here. Hence we need to tell memory reclaim | ||
405 | * that we are in such a context via PF_MEMALLOC_NOIO to prevent | ||
406 | * memory reclaim re-entering the filesystem here and | ||
407 | * potentially deadlocking. | ||
408 | */ | ||
409 | noio_flag = memalloc_noio_save(); | ||
400 | do { | 410 | do { |
401 | bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, | 411 | bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, |
402 | -1, PAGE_KERNEL); | 412 | -1, PAGE_KERNEL); |
@@ -404,6 +414,7 @@ _xfs_buf_map_pages( | |||
404 | break; | 414 | break; |
405 | vm_unmap_aliases(); | 415 | vm_unmap_aliases(); |
406 | } while (retried++ <= 1); | 416 | } while (retried++ <= 1); |
417 | memalloc_noio_restore(noio_flag); | ||
407 | 418 | ||
408 | if (!bp->b_addr) | 419 | if (!bp->b_addr) |
409 | return -ENOMEM; | 420 | return -ENOMEM; |