1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
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 (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
49 if (flags & CFS_ALLOC_ATOMIC)
51 else if (flags & CFS_ALLOC_WAIT)
54 mflags |= (__GFP_HIGH | __GFP_WAIT);
55 if (flags & CFS_ALLOC_IO)
56 mflags |= __GFP_IO | __GFP_HIGHIO;
58 if (flags & CFS_ALLOC_ATOMIC)
62 if (flags & CFS_ALLOC_NOWARN)
63 mflags |= __GFP_NOWARN;
64 if (flags & CFS_ALLOC_IO)
67 if (flags & CFS_ALLOC_FS)
69 if (flags & CFS_ALLOC_HIGH)
75 cfs_alloc(size_t nr_bytes, u_int32_t flags)
79 ptr = kmalloc(nr_bytes, cfs_alloc_flags_to_gfp(flags));
80 if (ptr != NULL && (flags & CFS_ALLOC_ZERO))
81 memset(ptr, 0, nr_bytes);
92 cfs_alloc_large(size_t nr_bytes)
94 return vmalloc(nr_bytes);
98 cfs_free_large(void *addr)
103 cfs_page_t *cfs_alloc_pages(unsigned int flags, unsigned int order)
106 * XXX nikita: do NOT call portals_debug_msg() (CDEBUG/ENTRY/EXIT)
107 * from here: this will lead to infinite recursion.
109 return alloc_pages(cfs_alloc_flags_to_gfp(flags), order);
112 void __cfs_free_pages(cfs_page_t *page, unsigned int order)
114 __free_pages(page, order);
118 cfs_mem_cache_create (const char *name, size_t size, size_t offset,
121 #ifdef HAVE_KMEM_CACHE_CREATE_DTOR
122 return kmem_cache_create(name, size, offset, flags, NULL, NULL);
124 return kmem_cache_create(name, size, offset, flags, NULL);
129 cfs_mem_cache_destroy (cfs_mem_cache_t * cachep)
131 #ifdef HAVE_KMEM_CACHE_DESTROY_INT
132 return kmem_cache_destroy(cachep);
134 kmem_cache_destroy(cachep);
140 cfs_mem_cache_alloc(cfs_mem_cache_t *cachep, int flags)
142 return kmem_cache_alloc(cachep, cfs_alloc_flags_to_gfp(flags));
146 cfs_mem_cache_free(cfs_mem_cache_t *cachep, void *objp)
148 return kmem_cache_free(cachep, objp);
152 * Returns true if \a addr is an address of an allocated object in a slab \a
153 * kmem. Used in assertions. This check is optimistically imprecise, i.e., it
154 * occasionally returns true for the incorrect addresses, but if it returns
155 * false, then the addresses is guaranteed to be incorrect.
157 int cfs_mem_is_in_cache(const void *addr, const cfs_mem_cache_t *kmem)
162 * XXX Copy of mm/slab.c:virt_to_cache(). It won't work with other
163 * allocators, like slub and slob.
165 page = virt_to_page(addr);
166 if (unlikely(PageCompound(page)))
167 page = (struct page *)page->private;
168 return PageSlab(page) && ((void *)page->lru.next) == kmem;
170 EXPORT_SYMBOL(cfs_mem_is_in_cache);
173 EXPORT_SYMBOL(cfs_alloc);
174 EXPORT_SYMBOL(cfs_free);
175 EXPORT_SYMBOL(cfs_alloc_large);
176 EXPORT_SYMBOL(cfs_free_large);
177 EXPORT_SYMBOL(cfs_alloc_pages);
178 EXPORT_SYMBOL(__cfs_free_pages);
179 EXPORT_SYMBOL(cfs_mem_cache_create);
180 EXPORT_SYMBOL(cfs_mem_cache_destroy);
181 EXPORT_SYMBOL(cfs_mem_cache_alloc);
182 EXPORT_SYMBOL(cfs_mem_cache_free);