X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=include%2Flinux%2Fmm_compat.h;h=c10652efd057dcf93ac65f4757de3181a3ab4722;hb=ce319db57b1662a21d60550e546592c96c3da7a1;hp=21a1ef2c0e5dbccfea151753b1eb9684a46967b9;hpb=84dd1f4f158c2da72f50d5ee5cd798197303ab23;p=mirror_spl.git diff --git a/include/linux/mm_compat.h b/include/linux/mm_compat.h index 21a1ef2..c10652e 100644 --- a/include/linux/mm_compat.h +++ b/include/linux/mm_compat.h @@ -1,4 +1,4 @@ -/*****************************************************************************\ +/* * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. * Copyright (C) 2007 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). @@ -6,7 +6,7 @@ * UCRL-CODE-235197 * * This file is part of the SPL, Solaris Porting Layer. - * For details, see . + * For details, see . * * The SPL is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -20,30 +20,14 @@ * * You should have received a copy of the GNU General Public License along * with the SPL. If not, see . -\*****************************************************************************/ + */ #ifndef _SPL_MM_COMPAT_H -#define _SPL_MM_COMPAT_H +#define _SPL_MM_COMPAT_H #include #include -/* - * Linux 2.6.31 API Change. - * Individual pages_{min,low,high} moved in to watermark array. - */ -#ifndef min_wmark_pages -#define min_wmark_pages(z) (z->pages_min) -#endif - -#ifndef low_wmark_pages -#define low_wmark_pages(z) (z->pages_low) -#endif - -#ifndef high_wmark_pages -#define high_wmark_pages(z) (z->pages_high) -#endif - #if !defined(HAVE_SHRINK_CONTROL_STRUCT) struct shrink_control { gfp_t gfp_mask; @@ -52,203 +36,174 @@ struct shrink_control { #endif /* HAVE_SHRINK_CONTROL_STRUCT */ /* - * 2.6.xx API compat, - * There currently exists no exposed API to partially shrink the dcache. - * The expected mechanism to shrink the cache is a registered shrinker - * which is called during memory pressure. + * Due to frequent changes in the shrinker API the following + * compatibility wrappers should be used. They are as follows: + * + * SPL_SHRINKER_DECLARE is used to declare the shrinker which is + * passed to spl_register_shrinker()/spl_unregister_shrinker(). Use + * shrinker_name to set the shrinker variable name, shrinker_callback + * to set the callback function, and seek_cost to define the cost of + * reclaiming an object. + * + * SPL_SHRINKER_DECLARE(shrinker_name, shrinker_callback, seek_cost); + * + * SPL_SHRINKER_CALLBACK_FWD_DECLARE is used when a forward declaration + * of the shrinker callback function is required. Only the callback + * function needs to be passed. + * + * SPL_SHRINKER_CALLBACK_FWD_DECLARE(shrinker_callback); + * + * SPL_SHRINKER_CALLBACK_WRAPPER is used to declare the callback function + * which is registered with the shrinker. This function will call your + * custom shrinker which must use the following prototype. Notice the + * leading __'s, these must be appended to the callback_function name. + * + * int __shrinker_callback(struct shrinker *, struct shrink_control *) + * SPL_SHRINKER_CALLBACK_WRAPPER(shrinker_callback);a + * + * + * Example: + * + * SPL_SHRINKER_CALLBACK_FWD_DECLARE(my_shrinker_fn); + * SPL_SHRINKER_DECLARE(my_shrinker, my_shrinker_fn, 1); + * + * static int + * __my_shrinker_fn(struct shrinker *shrink, struct shrink_control *sc) + * { + * if (sc->nr_to_scan) { + * ...scan objects in the cache and reclaim them... + * } + * + * ...calculate number of objects in the cache... + * + * return (number of objects in the cache); + * } + * SPL_SHRINKER_CALLBACK_WRAPPER(my_shrinker_fn); */ -#ifndef HAVE_SHRINK_DCACHE_MEMORY -# if defined(HAVE_SHRINK_CONTROL_STRUCT) -typedef int (*shrink_dcache_memory_t)(struct shrinker *, - struct shrink_control *); -extern shrink_dcache_memory_t shrink_dcache_memory_fn; -# define shrink_dcache_memory(nr, gfp) \ -({ \ - struct shrink_control sc = { .nr_to_scan = nr, .gfp_mask = gfp }; \ - int __ret__ = 0; \ - \ - if (shrink_dcache_memory_fn) \ - __ret__ = shrink_dcache_memory_fn(NULL, &sc); \ - \ - __ret__; \ -}) -# elif defined(HAVE_3ARGS_SHRINKER_CALLBACK) -typedef int (*shrink_dcache_memory_t)(struct shrinker *, int, gfp_t); -extern shrink_dcache_memory_t shrink_dcache_memory_fn; -# define shrink_dcache_memory(nr, gfp) \ -({ \ - int __ret__ = 0; \ - \ - if (shrink_dcache_memory_fn) \ - __ret__ = shrink_dcache_memory_fn(NULL, nr, gfp); \ - \ - __ret__; \ -}) -# else -typedef int (*shrink_dcache_memory_t)(int, gfp_t); -extern shrink_dcache_memory_t shrink_dcache_memory_fn; -# define shrink_dcache_memory(nr, gfp) \ -({ \ - int __ret__ = 0; \ - \ - if (shrink_dcache_memory_fn) \ - __ret__ = shrink_dcache_memory_fn(nr, gfp); \ - \ - __ret__; \ -}) -# endif /* HAVE_3ARGS_SHRINKER_CALLBACK */ -#endif /* HAVE_SHRINK_DCACHE_MEMORY */ -/* - * 2.6.xx API compat, - * There currently exists no exposed API to partially shrink the icache. - * The expected mechanism to shrink the cache is a registered shrinker - * which is called during memory pressure. - */ -#ifndef HAVE_SHRINK_ICACHE_MEMORY -# if defined(HAVE_SHRINK_CONTROL_STRUCT) -typedef int (*shrink_icache_memory_t)(struct shrinker *, - struct shrink_control *); -extern shrink_icache_memory_t shrink_icache_memory_fn; -# define shrink_icache_memory(nr, gfp) \ -({ \ - struct shrink_control sc = { .nr_to_scan = nr, .gfp_mask = gfp }; \ - int __ret__ = 0; \ - \ - if (shrink_icache_memory_fn) \ - __ret__ = shrink_icache_memory_fn(NULL, &sc); \ - \ - __ret__; \ -}) -# elif defined(HAVE_3ARGS_SHRINKER_CALLBACK) -typedef int (*shrink_icache_memory_t)(struct shrinker *, int, gfp_t); -extern shrink_icache_memory_t shrink_icache_memory_fn; -# define shrink_icache_memory(nr, gfp) \ -({ \ - int __ret__ = 0; \ - \ - if (shrink_icache_memory_fn) \ - __ret__ = shrink_icache_memory_fn(NULL, nr, gfp); \ - \ - __ret__; \ -}) -# else -typedef int (*shrink_icache_memory_t)(int, gfp_t); -extern shrink_icache_memory_t shrink_icache_memory_fn; -# define shrink_icache_memory(nr, gfp) \ -({ \ - int __ret__ = 0; \ - \ - if (shrink_icache_memory_fn) \ - __ret__ = shrink_icache_memory_fn(nr, gfp); \ - \ - __ret__; \ -}) -# endif /* HAVE_3ARGS_SHRINKER_CALLBACK */ -#endif /* HAVE_SHRINK_ICACHE_MEMORY */ +#define spl_register_shrinker(x) register_shrinker(x) +#define spl_unregister_shrinker(x) unregister_shrinker(x) /* - * Linux 2.6. - 2.6. Shrinker API Compatibility. + * Linux 2.6.23 - 2.6.34 Shrinker API Compatibility. */ -#ifdef HAVE_SET_SHRINKER -typedef struct spl_shrinker { - struct shrinker *shrinker; - shrinker_t fn; - int seeks; -} spl_shrinker_t; - -static inline void -spl_register_shrinker(spl_shrinker_t *ss) -{ - ss->shrinker = set_shrinker(ss->seeks, ss->fn); +#if defined(HAVE_2ARGS_OLD_SHRINKER_CALLBACK) +#define SPL_SHRINKER_DECLARE(s, x, y) \ +static struct shrinker s = { \ + .shrink = x, \ + .seeks = y \ } -static inline void -spl_unregister_shrinker(spl_shrinker_t *ss) -{ - remove_shrinker(ss->shrinker); +#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ +static int fn(int nr_to_scan, unsigned int gfp_mask) + +#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ +static int \ +fn(int nr_to_scan, unsigned int gfp_mask) \ +{ \ + struct shrink_control sc; \ + \ + sc.nr_to_scan = nr_to_scan; \ + sc.gfp_mask = gfp_mask; \ + \ + return (__ ## fn(NULL, &sc)); \ } -# define SPL_SHRINKER_DECLARE(s, x, y) \ - static spl_shrinker_t s = { \ - .shrinker = NULL, \ - .fn = x, \ - .seeks = y \ - } - -# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ - static int fn(int, unsigned int) -# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ -static int \ -fn(int nr_to_scan, unsigned int gfp_mask) \ -{ \ - struct shrink_control sc; \ - \ - sc.nr_to_scan = nr_to_scan; \ - sc.gfp_mask = gfp_mask; \ - \ - return __ ## fn(NULL, &sc); \ +/* + * Linux 2.6.35 to 2.6.39 Shrinker API Compatibility. + */ +#elif defined(HAVE_3ARGS_SHRINKER_CALLBACK) +#define SPL_SHRINKER_DECLARE(s, x, y) \ +static struct shrinker s = { \ + .shrink = x, \ + .seeks = y \ } -#else - -# define spl_register_shrinker(x) register_shrinker(x) -# define spl_unregister_shrinker(x) unregister_shrinker(x) -# define SPL_SHRINKER_DECLARE(s, x, y) \ - static struct shrinker s = { \ - .shrink = x, \ - .seeks = y \ - } +#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ +static int fn(struct shrinker *, int, unsigned int) + +#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ +static int \ +fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \ +{ \ + struct shrink_control sc; \ + \ + sc.nr_to_scan = nr_to_scan; \ + sc.gfp_mask = gfp_mask; \ + \ + return (__ ## fn(shrink, &sc)); \ +} /* - * Linux 2.6. - 2.6. Shrinker API Compatibility. + * Linux 3.0 to 3.11 Shrinker API Compatibility. */ -# if defined(HAVE_SHRINK_CONTROL_STRUCT) -# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ - static int fn(struct shrinker *, struct shrink_control *) -# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ -static int \ -fn(struct shrinker *shrink, struct shrink_control *sc) { \ - return __ ## fn(shrink, sc); \ +#elif defined(HAVE_2ARGS_NEW_SHRINKER_CALLBACK) +#define SPL_SHRINKER_DECLARE(s, x, y) \ +static struct shrinker s = { \ + .shrink = x, \ + .seeks = y \ +} + +#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ +static int fn(struct shrinker *, struct shrink_control *) + +#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ +static int \ +fn(struct shrinker *shrink, struct shrink_control *sc) \ +{ \ + return (__ ## fn(shrink, sc)); \ } /* - * Linux 2.6. - 2.6. Shrinker API Compatibility. + * Linux 3.12 and later Shrinker API Compatibility. */ -# elif defined(HAVE_3ARGS_SHRINKER_CALLBACK) -# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ - static int fn(struct shrinker *, int, unsigned int) -# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ -static int \ -fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \ -{ \ - struct shrink_control sc; \ - \ - sc.nr_to_scan = nr_to_scan; \ - sc.gfp_mask = gfp_mask; \ - \ - return __ ## fn(shrink, &sc); \ +#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK) +#define SPL_SHRINKER_DECLARE(s, x, y) \ +static struct shrinker s = { \ + .count_objects = x ## _count_objects, \ + .scan_objects = x ## _scan_objects, \ + .seeks = y \ } +#define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ +static unsigned long fn ## _count_objects(struct shrinker *, \ + struct shrink_control *); \ +static unsigned long fn ## _scan_objects(struct shrinker *, \ + struct shrink_control *) + +#define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ +static unsigned long \ +fn ## _count_objects(struct shrinker *shrink, struct shrink_control *sc)\ +{ \ + int __ret__; \ + \ + sc->nr_to_scan = 0; \ + __ret__ = __ ## fn(NULL, sc); \ + \ + /* Errors may not be returned and must be converted to zeros */ \ + return ((__ret__ < 0) ? 0 : __ret__); \ +} \ + \ +static unsigned long \ +fn ## _scan_objects(struct shrinker *shrink, struct shrink_control *sc) \ +{ \ + int __ret__; \ + \ + __ret__ = __ ## fn(NULL, sc); \ + return ((__ret__ < 0) ? SHRINK_STOP : __ret__); \ +} +#else /* - * Linux 2.6. - 2.6. Shrinker API Compatibility. + * Linux 2.x to 2.6.22, or a newer shrinker API has been introduced. */ -# else -# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \ - static int fn(int, unsigned int) -# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \ -static int \ -fn(int nr_to_scan, unsigned int gfp_mask) \ -{ \ - struct shrink_control sc; \ - \ - sc.nr_to_scan = nr_to_scan; \ - sc.gfp_mask = gfp_mask; \ - \ - return __ ## fn(NULL, &sc); \ -} +#error "Unknown shrinker callback" +#endif -# endif -#endif /* HAVE_SET_SHRINKER */ +#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) +typedef unsigned long spl_shrinker_t; +#else +typedef int spl_shrinker_t; +#define SHRINK_STOP (-1) +#endif #endif /* SPL_MM_COMPAT_H */