148
148
#endif /* HAVE_SHRINK_ICACHE_MEMORY */
151
* Linux 2.6. - 2.6. Shrinker API Compatibility.
153
#ifdef HAVE_SET_SHRINKER
154
typedef struct spl_shrinker {
155
struct shrinker *shrinker;
161
spl_register_shrinker(spl_shrinker_t *ss)
163
ss->shrinker = set_shrinker(ss->seeks, ss->fn);
167
spl_unregister_shrinker(spl_shrinker_t *ss)
169
remove_shrinker(ss->shrinker);
172
# define SPL_SHRINKER_DECLARE(s, x, y) \
173
static spl_shrinker_t s = { \
179
# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
180
static int fn(int, unsigned int)
181
# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
183
fn(int nr_to_scan, unsigned int gfp_mask) \
185
struct shrink_control sc; \
187
sc.nr_to_scan = nr_to_scan; \
188
sc.gfp_mask = gfp_mask; \
190
return __ ## fn(NULL, &sc); \
151
* Due to frequent changes in the shrinker API the following
152
* compatibility wrappers should be used. They are as follows:
154
* SPL_SHRINKER_DECLARE is used to declare the shrinker which is
155
* passed to spl_register_shrinker()/spl_unregister_shrinker(). Use
156
* shrinker_name to set the shrinker variable name, shrinker_callback
157
* to set the callback function, and seek_cost to define the cost of
158
* reclaiming an object.
160
* SPL_SHRINKER_DECLARE(shrinker_name, shrinker_callback, seek_cost);
162
* SPL_SHRINKER_CALLBACK_FWD_DECLARE is used when a forward declaration
163
* of the shrinker callback function is required. Only the callback
164
* function needs to be passed.
166
* SPL_SHRINKER_CALLBACK_FWD_DECLARE(shrinker_callback);
168
* SPL_SHRINKER_CALLBACK_WRAPPER is used to declare the callback function
169
* which is registered with the shrinker. This function will call your
170
* custom shrinker which must use the following prototype. Notice the
171
* leading __'s, these must be appended to the callback_function name.
173
* int __shrinker_callback(struct shrinker *, struct shrink_control *)
174
* SPL_SHRINKER_CALLBACK_WRAPPER(shrinker_callback);a
179
* SPL_SHRINKER_CALLBACK_FWD_DECLARE(my_shrinker_fn);
180
* SPL_SHRINKER_DECLARE(my_shrinker, my_shrinker_fn, 1);
183
* __my_shrinker_fn(struct shrinker *shrink, struct shrink_control *sc)
185
* if (sc->nr_to_scan) {
186
* ...scan objects in the cache and reclaim them...
189
* ...calculate number of objects in the cache...
191
* return (number of objects in the cache);
193
* SPL_SHRINKER_CALLBACK_WRAPPER(my_shrinker_fn);
196
#define spl_register_shrinker(x) register_shrinker(x)
197
#define spl_unregister_shrinker(x) unregister_shrinker(x)
200
* Linux 2.6.23 - 2.6.34 Shrinker API Compatibility.
202
#if defined(HAVE_2ARGS_OLD_SHRINKER_CALLBACK)
203
#define SPL_SHRINKER_DECLARE(s, x, y) \
204
static struct shrinker s = { \
209
#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
210
static int fn(int nr_to_scan, unsigned int gfp_mask)
212
#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
214
fn(int nr_to_scan, unsigned int gfp_mask) \
216
struct shrink_control sc; \
218
sc.nr_to_scan = nr_to_scan; \
219
sc.gfp_mask = gfp_mask; \
221
return (__ ## fn(NULL, &sc)); \
225
* Linux 2.6.35 to 2.6.39 Shrinker API Compatibility.
227
#elif defined(HAVE_3ARGS_SHRINKER_CALLBACK)
228
#define SPL_SHRINKER_DECLARE(s, x, y) \
229
static struct shrinker s = { \
234
#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
235
static int fn(struct shrinker *, int, unsigned int)
237
#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
239
fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \
241
struct shrink_control sc; \
243
sc.nr_to_scan = nr_to_scan; \
244
sc.gfp_mask = gfp_mask; \
246
return (__ ## fn(shrink, &sc)); \
250
* Linux 3.0 to 3.11 Shrinker API Compatibility.
252
#elif defined(HAVE_2ARGS_NEW_SHRINKER_CALLBACK)
253
#define SPL_SHRINKER_DECLARE(s, x, y) \
254
static struct shrinker s = { \
259
#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
260
static int fn(struct shrinker *, struct shrink_control *)
262
#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
264
fn(struct shrinker *shrink, struct shrink_control *sc) \
266
return (__ ## fn(shrink, sc)); \
270
* Linux 3.12 and later Shrinker API Compatibility.
272
#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
273
#define SPL_SHRINKER_DECLARE(s, x, y) \
274
static struct shrinker s = { \
275
.count_objects = x ## _count_objects, \
276
.scan_objects = x ## _scan_objects, \
280
#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
281
static unsigned long fn ## _count_objects(struct shrinker *, \
282
struct shrink_control *); \
283
static unsigned long fn ## _scan_objects(struct shrinker *, \
284
struct shrink_control *)
286
#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
287
static unsigned long \
288
fn ## _count_objects(struct shrinker *shrink, struct shrink_control *sc)\
292
sc->nr_to_scan = 0; \
293
__ret__ = __ ## fn(NULL, sc); \
295
/* Errors may not be returned and must be converted to zeros */ \
296
return ((__ret__ < 0) ? 0 : __ret__); \
299
static unsigned long \
300
fn ## _scan_objects(struct shrinker *shrink, struct shrink_control *sc) \
304
__ret__ = __ ## fn(NULL, sc); \
305
return ((__ret__ < 0) ? SHRINK_STOP : __ret__); \
195
# define spl_register_shrinker(x) register_shrinker(x)
196
# define spl_unregister_shrinker(x) unregister_shrinker(x)
197
# define SPL_SHRINKER_DECLARE(s, x, y) \
198
static struct shrinker s = { \
204
* Linux 2.6. - 2.6. Shrinker API Compatibility.
206
# if defined(HAVE_SHRINK_CONTROL_STRUCT)
207
# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
208
static int fn(struct shrinker *, struct shrink_control *)
209
# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
211
fn(struct shrinker *shrink, struct shrink_control *sc) { \
212
return __ ## fn(shrink, sc); \
216
* Linux 2.6. - 2.6. Shrinker API Compatibility.
218
# elif defined(HAVE_3ARGS_SHRINKER_CALLBACK)
219
# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
220
static int fn(struct shrinker *, int, unsigned int)
221
# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
223
fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \
225
struct shrink_control sc; \
227
sc.nr_to_scan = nr_to_scan; \
228
sc.gfp_mask = gfp_mask; \
230
return __ ## fn(shrink, &sc); \
234
* Linux 2.6. - 2.6. Shrinker API Compatibility.
237
# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
238
static int fn(int, unsigned int)
239
# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
241
fn(int nr_to_scan, unsigned int gfp_mask) \
243
struct shrink_control sc; \
245
sc.nr_to_scan = nr_to_scan; \
246
sc.gfp_mask = gfp_mask; \
248
return __ ## fn(NULL, &sc); \
252
#endif /* HAVE_SET_SHRINKER */
309
* Linux 2.x to 2.6.22, or a newer shrinker API has been introduced.
311
#error "Unknown shrinker callback"
254
314
#endif /* SPL_MM_COMPAT_H */