]> git.proxmox.com Git - mirror_spl.git/blobdiff - include/linux/mm_compat.h
Make include/linux/ conform to ZFS style standard
[mirror_spl.git] / include / linux / mm_compat.h
index 21a1ef2c0e5dbccfea151753b1eb9684a46967b9..c10652efd057dcf93ac65f4757de3181a3ab4722 100644 (file)
@@ -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 <http://github.com/behlendorf/spl/>.
+ *  For details, see <http://zfsonlinux.org/>.
  *
  *  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
  *
  *  You should have received a copy of the GNU General Public License along
  *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
-\*****************************************************************************/
+ */
 
 #ifndef _SPL_MM_COMPAT_H
-#define _SPL_MM_COMPAT_H
+#define        _SPL_MM_COMPAT_H
 
 #include <linux/mm.h>
 #include <linux/fs.h>
 
-/*
- * 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 */