1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #include <linux/mm.h> 7 #include <linux/sched/mm.h> 8 #include <linux/highmem.h> 9 #include <linux/slab.h> 10 #include <linux/swap.h> 11 #include <linux/blkdev.h> 12 #include <linux/backing-dev.h> 13 #include "kmem.h" 14 #include "xfs_message.h" 15 16 void * 17 kmem_alloc(size_t size, xfs_km_flags_t flags) 18 { 19 int retries = 0; 20 gfp_t lflags = kmem_flags_convert(flags); 21 void *ptr; 22 23 do { 24 ptr = kmalloc(size, lflags); 25 if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP))) 26 return ptr; 27 if (!(++retries % 100)) 28 xfs_err(NULL, 29 "%s(%u) possible memory allocation deadlock size %u in %s (mode:0x%x)", 30 current->comm, current->pid, 31 (unsigned int)size, __func__, lflags); 32 congestion_wait(BLK_RW_ASYNC, HZ/50); 33 } while (1); 34 } 35 36 void * 37 kmem_alloc_large(size_t size, xfs_km_flags_t flags) 38 { 39 unsigned nofs_flag = 0; 40 void *ptr; 41 gfp_t lflags; 42 43 ptr = kmem_alloc(size, flags | KM_MAYFAIL); 44 if (ptr) 45 return ptr; 46 47 /* 48 * __vmalloc() will allocate data pages and auxillary structures (e.g. 49 * pagetables) with GFP_KERNEL, yet we may be under GFP_NOFS context 50 * here. Hence we need to tell memory reclaim that we are in such a 51 * context via PF_MEMALLOC_NOFS to prevent memory reclaim re-entering 52 * the filesystem here and potentially deadlocking. 53 */ 54 if (flags & KM_NOFS) 55 nofs_flag = memalloc_nofs_save(); 56 57 lflags = kmem_flags_convert(flags); 58 ptr = __vmalloc(size, lflags, PAGE_KERNEL); 59 60 if (flags & KM_NOFS) 61 memalloc_nofs_restore(nofs_flag); 62 63 return ptr; 64 } 65 66 void * 67 kmem_realloc(const void *old, size_t newsize, xfs_km_flags_t flags) 68 { 69 int retries = 0; 70 gfp_t lflags = kmem_flags_convert(flags); 71 void *ptr; 72 73 do { 74 ptr = krealloc(old, newsize, lflags); 75 if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP))) 76 return ptr; 77 if (!(++retries % 100)) 78 xfs_err(NULL, 79 "%s(%u) possible memory allocation deadlock size %zu in %s (mode:0x%x)", 80 current->comm, current->pid, 81 newsize, __func__, lflags); 82 congestion_wait(BLK_RW_ASYNC, HZ/50); 83 } while (1); 84 } 85 86 void * 87 kmem_zone_alloc(kmem_zone_t *zone, xfs_km_flags_t flags) 88 { 89 int retries = 0; 90 gfp_t lflags = kmem_flags_convert(flags); 91 void *ptr; 92 93 do { 94 ptr = kmem_cache_alloc(zone, lflags); 95 if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP))) 96 return ptr; 97 if (!(++retries % 100)) 98 xfs_err(NULL, 99 "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)", 100 current->comm, current->pid, 101 __func__, lflags); 102 congestion_wait(BLK_RW_ASYNC, HZ/50); 103 } while (1); 104 } 105