Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Linux 3.12 compat: New shrinker API #307

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 80 additions & 10 deletions config/spl-build.m4
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_TYPE_UINTPTR_T
SPL_AC_2ARGS_REGISTER_SYSCTL
SPL_AC_SET_SHRINKER
SPL_AC_3ARGS_SHRINKER_CALLBACK
SPL_AC_SHRINKER_CALLBACK
SPL_AC_PATH_IN_NAMEIDATA
SPL_AC_TASK_CURR
SPL_AC_CTL_UNNUMBERED
Expand Down Expand Up @@ -904,18 +904,18 @@ AC_DEFUN([SPL_AC_SET_SHRINKER], [
])
])

dnl #
dnl # 2.6.35 API change,
dnl # Add context to shrinker callback
dnl #
AC_DEFUN([SPL_AC_3ARGS_SHRINKER_CALLBACK],
[AC_MSG_CHECKING([whether shrinker callback wants 3 args])
AC_DEFUN([SPL_AC_SHRINKER_CALLBACK],[
tmp_flags="$EXTRA_KCFLAGS"
EXTRA_KCFLAGS="-Werror"
dnl #
dnl # 2.6.23 to 2.6.34 API change
dnl # ->shrink(int nr_to_scan, gfp_t gfp_mask)
dnl #
AC_MSG_CHECKING([for old 2-argument ->shrink callback])
SPL_LINUX_TRY_COMPILE([
#include <linux/mm.h>

int shrinker_cb(struct shrinker *, int, unsigned int);
int shrinker_cb(int nr_to_scan, gfp_t gfp_mask);
],[
struct shrinker cache_shrinker = {
.shrink = shrinker_cb,
Expand All @@ -924,10 +924,80 @@ AC_DEFUN([SPL_AC_3ARGS_SHRINKER_CALLBACK],
register_shrinker(&cache_shrinker);
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1,
[shrinker callback wants 3 args])
AC_DEFINE(HAVE_2ARGS_OLD_SHRINKER_CALLBACK, 1,
[shrinker callback wants 2 args])
],[
AC_MSG_RESULT(no)
dnl #
dnl # 2.6.35 - 2.6.39 API change
dnl # ->shrink(struct shrinker *, int nr_to_scan, gfp_t gfp_mask)
dnl #
AC_MSG_CHECKING([whether shrinker callback wants 3 args])
SPL_LINUX_TRY_COMPILE([
#include <linux/mm.h>

int shrinker_cb(struct shrinker *, int nr_to_scan,
gfp_t gfp_mask);
],[
struct shrinker cache_shrinker = {
.shrink = shrinker_cb,
.seeks = DEFAULT_SEEKS,
};
register_shrinker(&cache_shrinker);
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_3ARGS_SHRINKER_CALLBACK, 1,
[shrinker callback wants 3 args])
],[
AC_MSG_RESULT(no)
dnl #
dnl # 3.0 - 3.11 API change
dnl # ->shrink(struct shrinker *, struct shrink_control *sc)
dnl #
AC_MSG_CHECKING([for new 2-argument ->shrink callback])
SPL_LINUX_TRY_COMPILE([
#include <linux/mm.h>

int shrinker_cb(struct shrinker *,
struct shrink_control *sc);
],[
struct shrinker cache_shrinker = {
.shrink = shrinker_cb,
.seeks = DEFAULT_SEEKS,
};
register_shrinker(&cache_shrinker);
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_2ARGS_NEW_SHRINKER_CALLBACK, 1,
[->shrink defined in linux/shrinker.h])
],[
AC_MSG_RESULT(no)
dnl #
dnl # 3.12 API change,
dnl # ->shrink becomes ->count_objects and ->scan_objects
dnl #
AC_MSG_CHECKING([whether ->count_objects callback exists])
SPL_LINUX_TRY_COMPILE([
#include <linux/mm.h>

unsigned long shrinker_cb(struct shrinker *,
struct shrink_control *sc);
],[
struct shrinker cache_shrinker = {
.count_objects = shrinker_cb,
.scan_objects = shrinker_cb,
.seeks = DEFAULT_SEEKS,
};
register_shrinker(&cache_shrinker);
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, 1,
[->count_objects defined in linux/shrinker.h])
],[
AC_MSG_ERROR(error)
])
])
])
])
EXTRA_KCFLAGS="$tmp_flags"
])
Expand Down
95 changes: 70 additions & 25 deletions include/linux/mm_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ extern shrink_icache_memory_t shrink_icache_memory_fn;
#endif /* HAVE_SHRINK_ICACHE_MEMORY */

/*
* Linux 2.6. - 2.6. Shrinker API Compatibility.
* Linux 2.6.22 and earlier Shrinker API Compatibility.
*/
#ifdef HAVE_SET_SHRINKER
typedef struct spl_shrinker {
Expand Down Expand Up @@ -194,28 +194,38 @@ fn(int nr_to_scan, unsigned int gfp_mask) \

# define spl_register_shrinker(x) register_shrinker(x)
# define spl_unregister_shrinker(x) unregister_shrinker(x)
# define SPL_SHRINKER_DECLARE(s, x, y) \

/*
* Linux 2.6.23 - 2.6.34 Shrinker API Compatibility.
*/
# if defined(HAVE_2ARGS_OLD_SHRINKER_CALLBACK)
# define SPL_SHRINKER_DECLARE(s, x, y) \
static struct shrinker s = { \
.shrink = x, \
.seeks = y \
}

/*
* Linux 2.6. - 2.6. 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); \
# 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); \
}

/*
* Linux 2.6. - 2.6. Shrinker API Compatibility.
* 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 \
}
# define SPL_SHRINKER_CALLBACK_FWD_DECLARE(fn) \
static int fn(struct shrinker *, int, unsigned int)
# define SPL_SHRINKER_CALLBACK_WRAPPER(fn) \
Expand All @@ -231,23 +241,58 @@ fn(struct shrinker *shrink, int nr_to_scan, unsigned int gfp_mask) \
}

/*
* Linux 2.6. - 2.6. Shrinker API Compatibility.
* Linux 3.0 to 3.11 Shrinker API Compatibility.
*/
# else
# 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 3.12 and later Shrinker API Compatibility.
*/
# 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 int fn(int, unsigned int)
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 int \
fn(int nr_to_scan, unsigned int gfp_mask) \
static unsigned long \
fn ## _count_objects(struct shrinker *shrink, \
struct shrink_control *sc) \
{ \
struct shrink_control sc; \
int ret; \
sc->nr_to_scan = 0; \
\
sc.nr_to_scan = nr_to_scan; \
sc.gfp_mask = gfp_mask; \
ret = __ ## fn(NULL, sc); \
return (ret < 0) ? 0 : ret; \
} \
static unsigned long \
fn ## _scan_objects(struct shrinker *shrink, \
struct shrink_control *sc) \
{ \
int ret; \
\
return __ ## fn(NULL, &sc); \
ret = __ ## fn(NULL, sc); \
return (ret < 0) ? 0 : ret; \
}

# else
# error "Unknown shrinker callback"
# endif
#endif /* HAVE_SET_SHRINKER */

Expand Down