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