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