4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 #define DEBUG_SUBSYSTEM S_LNET
39 #include <linux/vmalloc.h>
40 #include <linux/slab.h>
41 #include <linux/highmem.h>
42 #include <libcfs/libcfs.h>
44 static unsigned int cfs_alloc_flags_to_gfp(u_int32_t flags)
46 unsigned int mflags = 0;
48 if (flags & CFS_ALLOC_ATOMIC)
52 if (flags & CFS_ALLOC_NOWARN)
53 mflags |= __GFP_NOWARN;
54 if (flags & CFS_ALLOC_IO)
56 if (flags & CFS_ALLOC_FS)
58 if (flags & CFS_ALLOC_HIGHMEM)
59 mflags |= __GFP_HIGHMEM;
64 cfs_alloc(size_t nr_bytes, u_int32_t flags)
68 ptr = kmalloc(nr_bytes, cfs_alloc_flags_to_gfp(flags));
69 if (ptr != NULL && (flags & CFS_ALLOC_ZERO))
70 memset(ptr, 0, nr_bytes);
81 cfs_alloc_large(size_t nr_bytes)
83 return vmalloc(nr_bytes);
87 cfs_free_large(void *addr)
92 cfs_page_t *cfs_alloc_page(unsigned int flags)
95 * XXX nikita: do NOT call portals_debug_msg() (CDEBUG/ENTRY/EXIT)
96 * from here: this will lead to infinite recursion.
98 return alloc_page(cfs_alloc_flags_to_gfp(flags));
101 void cfs_free_page(cfs_page_t *page)
107 cfs_mem_cache_create (const char *name, size_t size, size_t offset,
110 #ifdef HAVE_KMEM_CACHE_CREATE_DTOR
111 return kmem_cache_create(name, size, offset, flags, NULL, NULL);
113 return kmem_cache_create(name, size, offset, flags, NULL);
118 cfs_mem_cache_destroy (cfs_mem_cache_t * cachep)
120 #ifdef HAVE_KMEM_CACHE_DESTROY_INT
121 return kmem_cache_destroy(cachep);
123 kmem_cache_destroy(cachep);
129 cfs_mem_cache_alloc(cfs_mem_cache_t *cachep, int flags)
131 return kmem_cache_alloc(cachep, cfs_alloc_flags_to_gfp(flags));
135 cfs_mem_cache_free(cfs_mem_cache_t *cachep, void *objp)
137 return kmem_cache_free(cachep, objp);
141 * Returns true if \a addr is an address of an allocated object in a slab \a
142 * kmem. Used in assertions. This check is optimistically imprecise, i.e., it
143 * occasionally returns true for the incorrect addresses, but if it returns
144 * false, then the addresses is guaranteed to be incorrect.
146 int cfs_mem_is_in_cache(const void *addr, const cfs_mem_cache_t *kmem)
152 * XXX Copy of mm/slab.c:virt_to_cache(). It won't work with other
153 * allocators, like slub and slob.
155 page = virt_to_page(addr);
156 if (unlikely(PageCompound(page)))
157 page = (struct page *)page->private;
158 return PageSlab(page) && ((void *)page->lru.next) == kmem;
163 EXPORT_SYMBOL(cfs_mem_is_in_cache);
166 EXPORT_SYMBOL(cfs_alloc);
167 EXPORT_SYMBOL(cfs_free);
168 EXPORT_SYMBOL(cfs_alloc_large);
169 EXPORT_SYMBOL(cfs_free_large);
170 EXPORT_SYMBOL(cfs_alloc_page);
171 EXPORT_SYMBOL(cfs_free_page);
172 EXPORT_SYMBOL(cfs_mem_cache_create);
173 EXPORT_SYMBOL(cfs_mem_cache_destroy);
174 EXPORT_SYMBOL(cfs_mem_cache_alloc);
175 EXPORT_SYMBOL(cfs_mem_cache_free);
178 * NB: we will rename some of above functions in another patch:
179 * - rename cfs_alloc to cfs_malloc
180 * - rename cfs_alloc/free_page to cfs_page_alloc/free
181 * - rename cfs_alloc/free_large to cfs_vmalloc/vfree
185 cfs_cpt_malloc(struct cfs_cpt_table *cptab, int cpt,
186 size_t nr_bytes, unsigned int flags)
190 ptr = kmalloc_node(nr_bytes, cfs_alloc_flags_to_gfp(flags),
191 cfs_cpt_spread_node(cptab, cpt));
192 if (ptr != NULL && (flags & CFS_ALLOC_ZERO) != 0)
193 memset(ptr, 0, nr_bytes);
197 EXPORT_SYMBOL(cfs_cpt_malloc);
200 cfs_cpt_vmalloc(struct cfs_cpt_table *cptab, int cpt, size_t nr_bytes)
202 return vmalloc_node(nr_bytes, cfs_cpt_spread_node(cptab, cpt));
204 EXPORT_SYMBOL(cfs_cpt_vmalloc);
207 cfs_page_cpt_alloc(struct cfs_cpt_table *cptab, int cpt, unsigned int flags)
209 return alloc_pages_node(cfs_cpt_spread_node(cptab, cpt),
210 cfs_alloc_flags_to_gfp(flags), 0);
212 EXPORT_SYMBOL(cfs_page_cpt_alloc);
215 cfs_mem_cache_cpt_alloc(cfs_mem_cache_t *cachep, struct cfs_cpt_table *cptab,
216 int cpt, unsigned int flags)
218 return kmem_cache_alloc_node(cachep, cfs_alloc_flags_to_gfp(flags),
219 cfs_cpt_spread_node(cptab, cpt));
221 EXPORT_SYMBOL(cfs_mem_cache_cpt_alloc);