diff options
Diffstat (limited to 'fs/xfs/kmem.c')
| -rw-r--r-- | fs/xfs/kmem.c | 21 |
1 files changed, 20 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 |
