]> git.proxmox.com Git - mirror_spl.git/blame - include/sys/kmem.h
Add hooks for disabling direct reclaim
[mirror_spl.git] / include / sys / kmem.h
CommitLineData
b34b9563 1/*
716154c5
BB
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
715f6251 6 * UCRL-CODE-235197
7 *
716154c5 8 * This file is part of the SPL, Solaris Porting Layer.
3d6af2dd 9 * For details, see <http://zfsonlinux.org/>.
716154c5
BB
10 *
11 * The SPL is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
715f6251 15 *
716154c5 16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
715f6251 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
716154c5 22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
b34b9563 23 */
715f6251 24
09b414e8 25#ifndef _SPL_KMEM_H
26#define _SPL_KMEM_H
f1ca4da6 27
c2fa0945 28#include <sys/debug.h>
f1ca4da6 29#include <linux/slab.h>
c3eabc75 30#include <linux/sched.h>
e5b9b344
BB
31
32extern int kmem_debugging(void);
33extern char *kmem_vasprintf(const char *fmt, va_list ap);
34extern char *kmem_asprintf(const char *fmt, ...);
35extern char *strdup(const char *str);
36extern void strfree(char *str);
550f1705 37
f1ca4da6 38/*
39 * Memory allocation interfaces
40 */
c3eabc75
BB
41#define KM_SLEEP 0x0000 /* can block for memory; success guaranteed */
42#define KM_NOSLEEP 0x0001 /* cannot block for memory; may fail */
43#define KM_PUSHPAGE 0x0004 /* can block for memory; may use reserve */
44#define KM_ZERO 0x1000 /* zero the allocation */
45#define KM_VMEM 0x2000 /* caller is vmem_* wrapper */
f1ca4da6 46
c3eabc75 47#define KM_PUBLIC_MASK (KM_SLEEP | KM_NOSLEEP | KM_PUSHPAGE)
3d061e9d 48
c89fdee4 49/*
c3eabc75
BB
50 * Convert a KM_* flags mask to its Linux GFP_* counterpart. The conversion
51 * function is context aware which means that KM_SLEEP allocations can be
52 * safely used in syncing contexts which have set PF_FSTRANS.
c89fdee4 53 */
c3eabc75
BB
54static inline gfp_t
55kmem_flags_convert(int flags)
c89fdee4 56{
c3eabc75 57 gfp_t lflags = __GFP_NOWARN | __GFP_COMP;
c89fdee4 58
c3eabc75
BB
59 if (flags & KM_NOSLEEP) {
60 lflags |= GFP_ATOMIC | __GFP_NORETRY;
61 } else {
62 lflags |= GFP_KERNEL;
63 if ((current->flags & PF_FSTRANS))
64 lflags &= ~(__GFP_IO|__GFP_FS);
65 }
c89fdee4 66
c3eabc75
BB
67 if (flags & KM_PUSHPAGE)
68 lflags |= __GFP_HIGH;
c89fdee4 69
c3eabc75
BB
70 if (flags & KM_ZERO)
71 lflags |= __GFP_ZERO;
c89fdee4 72
c3eabc75 73 return (lflags);
10129680
BB
74}
75
c2fa0945
RY
76typedef struct {
77 struct task_struct *fstrans_thread;
78 unsigned int saved_flags;
79} fstrans_cookie_t;
80
81static inline fstrans_cookie_t
82spl_fstrans_mark(void)
83{
84 fstrans_cookie_t cookie;
85
86 cookie.fstrans_thread = current;
87 cookie.saved_flags = current->flags & PF_FSTRANS;
88 current->flags |= PF_FSTRANS;
89
90 return (cookie);
91}
92
93static inline void
94spl_fstrans_unmark(fstrans_cookie_t cookie)
95{
96 ASSERT3P(cookie.fstrans_thread, ==, current);
97 ASSERT(current->flags & PF_FSTRANS);
98
99 current->flags &= ~(PF_FSTRANS);
100 current->flags |= cookie.saved_flags;
101}
102
103static inline int
104spl_fstrans_check(void)
105{
106 return (current->flags & PF_FSTRANS);
107}
108
b34b9563
BB
109#ifdef HAVE_ATOMIC64_T
110#define kmem_alloc_used_add(size) atomic64_add(size, &kmem_alloc_used)
111#define kmem_alloc_used_sub(size) atomic64_sub(size, &kmem_alloc_used)
112#define kmem_alloc_used_read() atomic64_read(&kmem_alloc_used)
113#define kmem_alloc_used_set(size) atomic64_set(&kmem_alloc_used, size)
10129680 114extern atomic64_t kmem_alloc_used;
d04c8a56 115extern unsigned long long kmem_alloc_max;
b34b9563
BB
116#else /* HAVE_ATOMIC64_T */
117#define kmem_alloc_used_add(size) atomic_add(size, &kmem_alloc_used)
118#define kmem_alloc_used_sub(size) atomic_sub(size, &kmem_alloc_used)
119#define kmem_alloc_used_read() atomic_read(&kmem_alloc_used)
120#define kmem_alloc_used_set(size) atomic_set(&kmem_alloc_used, size)
10129680
BB
121extern atomic_t kmem_alloc_used;
122extern unsigned long long kmem_alloc_max;
b34b9563 123#endif /* HAVE_ATOMIC64_T */
a0f6da3d 124
c3eabc75
BB
125extern unsigned int spl_kmem_alloc_warn;
126extern unsigned int spl_kmem_alloc_max;
f1ca4da6 127
c3eabc75
BB
128#define kmem_alloc(sz, fl) spl_kmem_alloc((sz), (fl), __func__, __LINE__)
129#define kmem_zalloc(sz, fl) spl_kmem_zalloc((sz), (fl), __func__, __LINE__)
130#define kmem_free(ptr, sz) spl_kmem_free((ptr), (sz))
f1ca4da6 131
c3eabc75
BB
132extern void *spl_kmem_alloc(size_t sz, int fl, const char *func, int line);
133extern void *spl_kmem_zalloc(size_t sz, int fl, const char *func, int line);
134extern void spl_kmem_free(const void *ptr, size_t sz);
5d86345d 135
c3eabc75
BB
136/*
137 * The following functions are only available for internal use.
138 */
139extern void *spl_kmem_alloc_impl(size_t size, int flags, int node);
140extern void *spl_kmem_alloc_debug(size_t size, int flags, int node);
141extern void *spl_kmem_alloc_track(size_t size, int flags,
142 const char *func, int line, int node);
143extern void spl_kmem_free_impl(const void *buf, size_t size);
144extern void spl_kmem_free_debug(const void *buf, size_t size);
145extern void spl_kmem_free_track(const void *buf, size_t size);
146
147extern int spl_kmem_init(void);
148extern void spl_kmem_fini(void);
f1ca4da6 149
09b414e8 150#endif /* _SPL_KMEM_H */