Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
kmem.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 #include <linux/mm.h>
19 #include <linux/highmem.h>
20 #include <linux/slab.h>
21 #include <linux/swap.h>
22 #include <linux/blkdev.h>
23 #include <linux/backing-dev.h>
24 #include "time.h"
25 #include "kmem.h"
26 #include "xfs_message.h"
27 
28 /*
29  * Greedy allocation. May fail and may return vmalloced memory.
30  *
31  * Must be freed using kmem_free_large.
32  */
33 void *
34 kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize)
35 {
36  void *ptr;
37  size_t kmsize = maxsize;
38 
39  while (!(ptr = kmem_zalloc_large(kmsize))) {
40  if ((kmsize >>= 1) <= minsize)
41  kmsize = minsize;
42  }
43  if (ptr)
44  *size = kmsize;
45  return ptr;
46 }
47 
48 void *
50 {
51  int retries = 0;
52  gfp_t lflags = kmem_flags_convert(flags);
53  void *ptr;
54 
55  do {
56  ptr = kmalloc(size, lflags);
57  if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
58  return ptr;
59  if (!(++retries % 100))
60  xfs_err(NULL,
61  "possible memory allocation deadlock in %s (mode:0x%x)",
62  __func__, lflags);
64  } while (1);
65 }
66 
67 void *
69 {
70  void *ptr;
71 
72  ptr = kmem_alloc(size, flags);
73  if (ptr)
74  memset((char *)ptr, 0, (int)size);
75  return ptr;
76 }
77 
78 void
79 kmem_free(const void *ptr)
80 {
81  if (!is_vmalloc_addr(ptr)) {
82  kfree(ptr);
83  } else {
84  vfree(ptr);
85  }
86 }
87 
88 void *
89 kmem_realloc(const void *ptr, size_t newsize, size_t oldsize,
91 {
92  void *new;
93 
94  new = kmem_alloc(newsize, flags);
95  if (ptr) {
96  if (new)
97  memcpy(new, ptr,
98  ((oldsize < newsize) ? oldsize : newsize));
99  kmem_free(ptr);
100  }
101  return new;
102 }
103 
104 void *
106 {
107  int retries = 0;
108  gfp_t lflags = kmem_flags_convert(flags);
109  void *ptr;
110 
111  do {
112  ptr = kmem_cache_alloc(zone, lflags);
113  if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
114  return ptr;
115  if (!(++retries % 100))
116  xfs_err(NULL,
117  "possible memory allocation deadlock in %s (mode:0x%x)",
118  __func__, lflags);
120  } while (1);
121 }
122 
123 void *
125 {
126  void *ptr;
127 
128  ptr = kmem_zone_alloc(zone, flags);
129  if (ptr)
130  memset((char *)ptr, 0, kmem_cache_size(zone));
131  return ptr;
132 }