])
])
+#
+# RHEL6/2.6.32 want to have pointer to shrinker self pointer in handler function
+#
+AC_DEFUN([LC_SHRINKER_WANT_SHRINK_PTR],
+[AC_MSG_CHECKING([shrinker want self pointer in handler])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/mm.h>
+],[
+ struct shrinker *tmp = NULL;
+ tmp->shrink(tmp, 0, 0);
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SHRINKER_WANT_SHRINK_PTR, 1,
+ [shrinker want self pointer in handler])
+],[
+ AC_MSG_RESULT(no)
+])
+])
+
# 2.6.18 store oom parameters in task struct.
# 2.6.32 store oom parameters in signal struct
AC_DEFUN([LIBCFS_OOMADJ_IN_SIG],
])
])
-# RHEL6/2.6.32 want to have pointer to shrinker self pointer in handler function
-AC_DEFUN([LC_SHRINKER_WANT_SHRINK_PTR],
-[AC_MSG_CHECKING([shrinker want self pointer in handler])
+
+#
+# FC15 2.6.40-5 backported the "shrink_control" parameter to the memory
+# pressure shrinker from Linux 3.0
+#
+AC_DEFUN([LC_SHRINK_CONTROL],
+[AC_MSG_CHECKING([shrink_control is present])
LB_LINUX_TRY_COMPILE([
#include <linux/mm.h>
],[
- struct shrinker tmp = {0};
- tmp.shrink(NULL, 0, 0);
+ struct shrink_control tmp = {0};
+ tmp.nr_to_scan = sizeof(tmp);
],[
AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SHRINKER_WANT_SHRINK_PTR, 1,
- [shrinker want self pointer in handler])
+ AC_DEFINE(HAVE_SHRINK_CONTROL, 1,
+ [shrink_control is present])
],[
AC_MSG_RESULT(no)
])
LIBCFS_OOMADJ_IN_SIG
# 2.6.34
LIBCFS_ADD_WAIT_QUEUE_EXCLUSIVE
+# 2.6.40 fc15
+LC_SHRINK_CONTROL
])
#
*/
#define cfs_shrinker shrinker
-#ifdef HAVE_SHRINKER_WANT_SHRINK_PTR
-#define SHRINKER_FIRST_ARG struct shrinker *shrinker,
+#ifdef HAVE_SHRINK_CONTROL
+# define SHRINKER_ARGS(sc, nr_to_scan, gfp_mask) \
+ struct shrinker *shrinker, \
+ struct shrink_control *sc
+# define shrink_param(sc, var) ((sc)->var)
#else
-#define SHRINKER_FIRST_ARG
+# ifdef HAVE_SHRINKER_WANT_SHRINK_PTR
+# define SHRINKER_ARGS(sc, nr_to_scan, gfp_mask) \
+ struct shrinker *shrinker, \
+ int nr_to_scan, gfp_t gfp_mask
+# else
+# define SHRINKER_ARGS(sc, nr_to_scan, gfp_mask) \
+ int nr_to_scan, gfp_t gfp_mask
+# endif
+# define shrink_param(sc, var) (var)
#endif
#ifdef HAVE_REGISTER_SHRINKER
-typedef int (*cfs_shrinker_t)(SHRINKER_FIRST_ARG int nr_to_scan, gfp_t gfp_mask);
+typedef int (*cfs_shrinker_t)(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask));
static inline
struct cfs_shrinker *cfs_set_shrinker(int seek, cfs_shrinker_t func)
return cached;
}
-static int ldlm_pools_srv_shrink(SHRINKER_FIRST_ARG int nr_to_scan,
- unsigned int gfp_mask)
+static int ldlm_pools_srv_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask))
{
- return ldlm_pools_shrink(LDLM_NAMESPACE_SERVER, nr_to_scan, gfp_mask);
+ return ldlm_pools_shrink(LDLM_NAMESPACE_SERVER,
+ shrink_param(sc, nr_to_scan),
+ shrink_param(sc, gfp_mask));
}
-static int ldlm_pools_cli_shrink(SHRINKER_FIRST_ARG int nr_to_scan,
- unsigned int gfp_mask)
+static int ldlm_pools_cli_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask))
{
- return ldlm_pools_shrink(LDLM_NAMESPACE_CLIENT, nr_to_scan, gfp_mask);
+ return ldlm_pools_shrink(LDLM_NAMESPACE_CLIENT,
+ shrink_param(sc, nr_to_scan),
+ shrink_param(sc, gfp_mask));
}
void ldlm_pools_recalc(ldlm_side_t client)
}
#ifdef __KERNEL__
-static int lu_cache_shrink(SHRINKER_FIRST_ARG int nr_to_scan,
- unsigned int gfp_mask)
+
+static int lu_cache_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask))
{
lu_site_stats_t stats;
struct lu_site *s;
struct lu_site *tmp;
int cached = 0;
- int remain = nr_to_scan;
+ int remain = shrink_param(sc, nr_to_scan);
CFS_LIST_HEAD(splice);
- if (nr_to_scan != 0) {
- if (!(gfp_mask & __GFP_FS))
+ if (remain != 0) {
+ if (!(shrink_param(sc, gfp_mask) & __GFP_FS))
return -1;
- CDEBUG(D_INODE, "Shrink %d objects\n", nr_to_scan);
+ CDEBUG(D_INODE, "Shrink %d objects\n", remain);
}
cfs_down(&lu_sites_guard);
cfs_list_for_each_entry_safe(s, tmp, &lu_sites, ls_linkage) {
- if (nr_to_scan != 0) {
+ if (shrink_param(sc, nr_to_scan) != 0) {
remain = lu_site_purge(&lu_shrink_env, s, remain);
/*
* Move just shrunk site to the tail of site list to
memset(&stats, 0, sizeof(stats));
lu_site_stats_get(s->ls_obj_hash, &stats, 0);
cached += stats.lss_total - stats.lss_busy;
- if (nr_to_scan && remain <= 0)
+ if (shrink_param(sc, nr_to_scan) && remain <= 0)
break;
}
cfs_list_splice(&splice, lu_sites.prev);
cfs_up(&lu_sites_guard);
cached = (cached / 100) * sysctl_vfs_cache_pressure;
- if (nr_to_scan == 0)
+ if (shrink_param(sc, nr_to_scan) == 0)
CDEBUG(D_INODE, "%d objects cached\n", cached);
return cached;
}
* could be called frequently for query (@nr_to_scan == 0).
* we try to keep at least PTLRPC_MAX_BRW_PAGES pages in the pool.
*/
-static int enc_pools_shrink(SHRINKER_FIRST_ARG int nr_to_scan,
- unsigned int gfp_mask)
+static int enc_pools_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask))
{
- if (unlikely(nr_to_scan != 0)) {
+ if (unlikely(shrink_param(sc, nr_to_scan) != 0)) {
cfs_spin_lock(&page_pools.epp_lock);
- nr_to_scan = min(nr_to_scan, (int) page_pools.epp_free_pages -
- PTLRPC_MAX_BRW_PAGES);
- if (nr_to_scan > 0) {
- enc_pools_release_free_pages(nr_to_scan);
- CDEBUG(D_SEC, "released %d pages, %ld left\n",
- nr_to_scan, page_pools.epp_free_pages);
+ shrink_param(sc, nr_to_scan) = min_t(unsigned long,
+ shrink_param(sc, nr_to_scan),
+ page_pools.epp_free_pages -
+ PTLRPC_MAX_BRW_PAGES);
+ if (shrink_param(sc, nr_to_scan) > 0) {
+ enc_pools_release_free_pages(shrink_param(sc,
+ nr_to_scan));
+ CDEBUG(D_SEC, "released %ld pages, %ld left\n",
+ (long)shrink_param(sc, nr_to_scan),
+ page_pools.epp_free_pages);
page_pools.epp_st_shrinks++;
page_pools.epp_last_shrink = cfs_time_current_sec();