]> git.proxmox.com Git - mirror_zfs.git/blob - include/os/linux/spl/sys/shrinker.h
Linux compat: Minimum kernel version 3.10
[mirror_zfs.git] / include / os / linux / spl / sys / shrinker.h
1 /*
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>.
6 * UCRL-CODE-235197
7 *
8 * This file is part of the SPL, Solaris Porting Layer.
9 * For details, see <http://zfsonlinux.org/>.
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.
15 *
16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
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
22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #ifndef _SPL_SHRINKER_H
26 #define _SPL_SHRINKER_H
27
28 #include <linux/mm.h>
29 #include <linux/fs.h>
30
31 /*
32 * Due to frequent changes in the shrinker API the following
33 * compatibility wrappers should be used. They are as follows:
34 *
35 * SPL_SHRINKER_DECLARE is used to declare the shrinker which is
36 * passed to spl_register_shrinker()/spl_unregister_shrinker(). Use
37 * shrinker_name to set the shrinker variable name, shrinker_callback
38 * to set the callback function, and seek_cost to define the cost of
39 * reclaiming an object.
40 *
41 * SPL_SHRINKER_DECLARE(shrinker_name, shrinker_callback, seek_cost);
42 *
43 * SPL_SHRINKER_CALLBACK_FWD_DECLARE is used when a forward declaration
44 * of the shrinker callback function is required. Only the callback
45 * function needs to be passed.
46 *
47 * SPL_SHRINKER_CALLBACK_FWD_DECLARE(shrinker_callback);
48 *
49 * SPL_SHRINKER_CALLBACK_WRAPPER is used to declare the callback function
50 * which is registered with the shrinker. This function will call your
51 * custom shrinker which must use the following prototype. Notice the
52 * leading __'s, these must be appended to the callback_function name.
53 *
54 * int __shrinker_callback(struct shrinker *, struct shrink_control *)
55 * SPL_SHRINKER_CALLBACK_WRAPPER(shrinker_callback);a
56 *
57 *
58 * Example:
59 *
60 * SPL_SHRINKER_CALLBACK_FWD_DECLARE(my_shrinker_fn);
61 * SPL_SHRINKER_DECLARE(my_shrinker, my_shrinker_fn, 1);
62 *
63 * static int
64 * __my_shrinker_fn(struct shrinker *shrink, struct shrink_control *sc)
65 * {
66 * if (sc->nr_to_scan) {
67 * ...scan objects in the cache and reclaim them...
68 * }
69 *
70 * ...calculate number of objects in the cache...
71 *
72 * return (number of objects in the cache);
73 * }
74 * SPL_SHRINKER_CALLBACK_WRAPPER(my_shrinker_fn);
75 */
76
77 #define spl_register_shrinker(x) register_shrinker(x)
78 #define spl_unregister_shrinker(x) unregister_shrinker(x)
79
80 /*
81 * Linux 3.0 to 3.11 Shrinker API Compatibility.
82 */
83 #if defined(HAVE_SINGLE_SHRINKER_CALLBACK)
84 #define SPL_SHRINKER_DECLARE(s, x, y) \
85 static struct shrinker s = { \
86 .shrink = x, \
87 .seeks = y \
88 }
89
90 #define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
91 static int fn(struct shrinker *, struct shrink_control *)
92
93 #define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
94 static int \
95 fn(struct shrinker *shrink, struct shrink_control *sc) \
96 { \
97 return (__ ## fn(shrink, sc)); \
98 }
99
100 /*
101 * Linux 3.12 and later Shrinker API Compatibility.
102 */
103 #elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
104 #define SPL_SHRINKER_DECLARE(s, x, y) \
105 static struct shrinker s = { \
106 .count_objects = x ## _count_objects, \
107 .scan_objects = x ## _scan_objects, \
108 .seeks = y \
109 }
110
111 #define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
112 static unsigned long fn ## _count_objects(struct shrinker *, \
113 struct shrink_control *); \
114 static unsigned long fn ## _scan_objects(struct shrinker *, \
115 struct shrink_control *)
116
117 #define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
118 static unsigned long \
119 fn ## _count_objects(struct shrinker *shrink, struct shrink_control *sc)\
120 { \
121 int __ret__; \
122 \
123 sc->nr_to_scan = 0; \
124 __ret__ = __ ## fn(NULL, sc); \
125 \
126 /* Errors may not be returned and must be converted to zeros */ \
127 return ((__ret__ < 0) ? 0 : __ret__); \
128 } \
129 \
130 static unsigned long \
131 fn ## _scan_objects(struct shrinker *shrink, struct shrink_control *sc) \
132 { \
133 int __ret__; \
134 \
135 __ret__ = __ ## fn(NULL, sc); \
136 return ((__ret__ < 0) ? SHRINK_STOP : __ret__); \
137 }
138 #else
139 /*
140 * Linux 2.x to 2.6.22, or a newer shrinker API has been introduced.
141 */
142 #error "Unknown shrinker callback"
143 #endif
144
145 #if defined(HAVE_SPLIT_SHRINKER_CALLBACK)
146 typedef unsigned long spl_shrinker_t;
147 #else
148 typedef int spl_shrinker_t;
149 #define SHRINK_STOP (-1)
150 #endif
151
152 #endif /* SPL_SHRINKER_H */