1
2
3
4
5
6#include <linux/sched/mm.h>
7#include <linux/backing-dev.h>
8#include "kmem.h"
9#include "xfs_message.h"
10
11void *
12kmem_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
31void *
32kmem_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
44
45
46
47
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
61void *
62kmem_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
81void *
82kmem_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