slab.h revision 329972
1248557Sray/*-
2250357Sray * Copyright (c) 2010 Isilon Systems, Inc.
3248557Sray * Copyright (c) 2010 iX Systems, Inc.
4248557Sray * Copyright (c) 2010 Panasas, Inc.
5248557Sray * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
6248557Sray * All rights reserved.
7248557Sray *
8248557Sray * Redistribution and use in source and binary forms, with or without
9248557Sray * modification, are permitted provided that the following conditions
10248557Sray * are met:
11248557Sray * 1. Redistributions of source code must retain the above copyright
12248557Sray *    notice unmodified, this list of conditions, and the following
13248557Sray *    disclaimer.
14248557Sray * 2. Redistributions in binary form must reproduce the above copyright
15248557Sray *    notice, this list of conditions and the following disclaimer in the
16248557Sray *    documentation and/or other materials provided with the distribution.
17248557Sray *
18248557Sray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19248557Sray * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20248557Sray * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21248557Sray * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22248557Sray * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23248557Sray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24248557Sray * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25248557Sray * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26248557Sray * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27248557Sray * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28248557Sray *
29248557Sray * $FreeBSD: stable/11/sys/compat/linuxkpi/common/include/linux/slab.h 329972 2018-02-25 10:35:28Z hselasky $
30248557Sray */
31248557Sray#ifndef	_LINUX_SLAB_H_
32248557Sray#define	_LINUX_SLAB_H_
33248557Sray
34248557Sray#include <sys/param.h>
35248557Sray#include <sys/systm.h>
36248557Sray#include <sys/malloc.h>
37289537Sian#include <sys/limits.h>
38289537Sian#include <vm/uma.h>
39248557Sray
40248557Sray#include <linux/types.h>
41248557Sray#include <linux/gfp.h>
42248557Sray
43248557SrayMALLOC_DECLARE(M_KMALLOC);
44248557Sray
45248557Sray#define	kvmalloc(size)			kmalloc(size, 0)
46248557Sray#define	kzalloc(size, flags)		kmalloc(size, (flags) | __GFP_ZERO)
47248557Sray#define	kzalloc_node(size, flags, node)	kmalloc(size, (flags) | __GFP_ZERO)
48248557Sray#define	kfree_const(ptr)		kfree(ptr)
49289537Sian#define	vzalloc(size)			__vmalloc(size, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, 0)
50248557Sray#define	vfree(arg)			kfree(arg)
51248557Sray#define	kvfree(arg)			kfree(arg)
52289537Sian#define	vmalloc_node(size, node)        __vmalloc(size, GFP_KERNEL, 0)
53248557Sray#define	vmalloc_user(size)              __vmalloc(size, GFP_KERNEL | __GFP_ZERO, 0)
54248557Sray#define	vmalloc(size)                   __vmalloc(size, GFP_KERNEL, 0)
55248557Sray#define	__kmalloc(...)			kmalloc(__VA_ARGS__)
56277996Sloos#define	kmalloc_node(chunk, flags, n)	kmalloc(chunk, flags)
57248557Sray
58248557Sray/*
59248557Sray * Prefix some functions with linux_ to avoid namespace conflict
60248557Sray * with the OpenSolaris code in the kernel.
61248557Sray */
62248557Sray#define	kmem_cache		linux_kmem_cache
63298068Sandrew#define	kmem_cache_create(...)	linux_kmem_cache_create(__VA_ARGS__)
64289537Sian#define	kmem_cache_alloc(...)	linux_kmem_cache_alloc(__VA_ARGS__)
65289537Sian#define	kmem_cache_free(...) 	linux_kmem_cache_free(__VA_ARGS__)
66248557Sray#define	kmem_cache_destroy(...) linux_kmem_cache_destroy(__VA_ARGS__)
67248557Sray
68248557Sray#define	KMEM_CACHE(__struct, flags)					\
69248557Sray	linux_kmem_cache_create(#__struct, sizeof(struct __struct),	\
70248557Sray	__alignof(struct __struct), (flags), NULL)
71248557Sray
72248557Sraytypedef void linux_kmem_ctor_t (void *);
73248557Sray
74248557Sraystruct linux_kmem_cache {
75248557Sray	uma_zone_t cache_zone;
76248557Sray	linux_kmem_ctor_t *cache_ctor;
77248557Sray	unsigned cache_flags;
78248557Sray	unsigned cache_size;
79248557Sray};
80248557Sray
81248557Sray#define	SLAB_HWCACHE_ALIGN	(1 << 0)
82248557Sray#define	SLAB_DESTROY_BY_RCU     (1 << 1)
83248557Sray#define	SLAB_RECLAIM_ACCOUNT	(1 << 2)
84248557Sray
85248557Sraystatic inline gfp_t
86248557Sraylinux_check_m_flags(gfp_t flags)
87300786Sian{
88248557Sray	const gfp_t m = M_NOWAIT | M_WAITOK;
89248557Sray
90248557Sray	/* make sure either M_NOWAIT or M_WAITOK is set */
91248557Sray	if ((flags & m) == 0)
92300529Sskra		flags |= M_NOWAIT;
93300529Sskra	else if ((flags & m) == m)
94300529Sskra		flags &= ~M_WAITOK;
95300786Sian
96300529Sskra	/* mask away LinuxKPI specific flags */
97248557Sray	return (flags & GFP_NATIVE_MASK);
98300529Sskra}
99300529Sskra
100248557Sraystatic inline void *
101248557Sraykmalloc(size_t size, gfp_t flags)
102298068Sandrew{
103297539Sskra	return (malloc(size, M_KMALLOC, linux_check_m_flags(flags)));
104297539Sskra}
105297539Sskra
106300528Sskrastatic inline void *
107297539Sskrakcalloc(size_t n, size_t size, gfp_t flags)
108297539Sskra{
109297539Sskra	flags |= __GFP_ZERO;
110248557Sray	return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
111248557Sray}
112277996Sloos
113248557Sraystatic inline void *
114289537Sian__vmalloc(size_t size, gfp_t flags, int other)
115289537Sian{
116248557Sray	return (malloc(size, M_KMALLOC, linux_check_m_flags(flags)));
117248557Sray}
118248557Sray
119248557Sraystatic inline void *
120298068Sandrewvmalloc_32(size_t size)
121297539Sskra{
122297539Sskra	return (contigmalloc(size, M_KMALLOC, M_WAITOK, 0, UINT_MAX, 1, 1));
123248557Sray}
124248557Sray
125268834Sbrstatic inline void *
126268834Sbrkmalloc_array(size_t n, size_t size, gfp_t flags)
127268834Sbr{
128268834Sbr	return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags)));
129268834Sbr}
130268834Sbr
131268834Sbrstatic inline void *
132248557Sraykrealloc(void *ptr, size_t size, gfp_t flags)
133248557Sray{
134248557Sray	return (realloc(ptr, size, M_KMALLOC, linux_check_m_flags(flags)));
135248557Sray}
136248557Sray
137248557Sraystatic inline void
138248557Sraykfree(const void *ptr)
139248557Sray{
140248557Sray	free(__DECONST(void *, ptr), M_KMALLOC);
141248557Sray}
142248557Sray
143248557Srayextern struct linux_kmem_cache *linux_kmem_cache_create(const char *name,
144248557Sray    size_t size, size_t align, unsigned flags, linux_kmem_ctor_t *ctor);
145248557Sray
146248557Sraystatic inline void *
147248557Sraylinux_kmem_cache_alloc(struct linux_kmem_cache *c, gfp_t flags)
148248557Sray{
149248557Sray	return (uma_zalloc_arg(c->cache_zone, c,
150248557Sray	    linux_check_m_flags(flags)));
151248557Sray}
152248557Sray
153248557Sraystatic inline void *
154248557Sraykmem_cache_zalloc(struct linux_kmem_cache *c, gfp_t flags)
155277996Sloos{
156248557Sray	return (uma_zalloc_arg(c->cache_zone, c,
157248557Sray	    linux_check_m_flags(flags | M_ZERO)));
158248557Sray}
159248557Sray
160248557Srayextern void linux_kmem_cache_free_rcu(struct linux_kmem_cache *, void *);
161248557Sray
162248557Sraystatic inline void
163248557Sraylinux_kmem_cache_free(struct linux_kmem_cache *c, void *m)
164248557Sray{
165298068Sandrew	if (unlikely(c->cache_flags & SLAB_DESTROY_BY_RCU))
166297539Sskra		linux_kmem_cache_free_rcu(c, m);
167300529Sskra	else
168300529Sskra		uma_zfree(c->cache_zone, m);
169289537Sian}
170300529Sskra
171300528Sskraextern void linux_kmem_cache_destroy(struct linux_kmem_cache *);
172289537Sian
173297539Sskra#endif					/* _LINUX_SLAB_H_ */
174297539Sskra