SPL_AC_3ARGS_FILE_FSYNC
SPL_AC_EXPORTED_RWSEM_IS_LOCKED
SPL_AC_KERNEL_INVALIDATE_INODES
+ SPL_AC_SHRINK_DCACHE_MEMORY
+ SPL_AC_SHRINK_ICACHE_MEMORY
])
AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
[invalidate_inodes() is available])],
[])
])
+
+dnl #
+dnl # 2.6.xx API compat,
+dnl # There currently exists no exposed API to partially shrink the dcache.
+dnl # The expected mechanism to shrink the cache is a registered shrinker
+dnl # which is called during memory pressure.
+dnl #
+AC_DEFUN([SPL_AC_SHRINK_DCACHE_MEMORY], [
+ SPL_CHECK_SYMBOL_EXPORT(
+ [shrink_dcache_memory],
+ [fs/dcache.c],
+ [AC_DEFINE(HAVE_SHRINK_DCACHE_MEMORY, 1,
+ [shrink_dcache_memory() is available])],
+ [])
+])
+
+dnl #
+dnl # 2.6.xx API compat,
+dnl # There currently exists no exposed API to partially shrink the icache.
+dnl # The expected mechanism to shrink the cache is a registered shrinker
+dnl # which is called during memory pressure.
+dnl #
+AC_DEFUN([SPL_AC_SHRINK_ICACHE_MEMORY], [
+ SPL_CHECK_SYMBOL_EXPORT(
+ [shrink_icache_memory],
+ [fs/inode.c],
+ [AC_DEFINE(HAVE_SHRINK_ICACHE_MEMORY, 1,
+ [shrink_icache_memory() is available])],
+ [])
+])
fi
+
+ { $as_echo "$as_me:$LINENO: checking whether symbol shrink_dcache_memory is exported" >&5
+$as_echo_n "checking whether symbol shrink_dcache_memory is exported... " >&6; }
+ grep -q -E '[[:space:]]shrink_dcache_memory[[:space:]]' \
+ $LINUX_OBJ/Module*.symvers 2>/dev/null
+ rc=$?
+ if test $rc -ne 0; then
+ export=0
+ for file in fs/dcache.c; do
+ grep -q -E "EXPORT_SYMBOL.*(shrink_dcache_memory)" \
+ "$LINUX_OBJ/$file" 2>/dev/null
+ rc=$?
+ if test $rc -eq 0; then
+ export=1
+ break;
+ fi
+ done
+ if test $export -eq 0; then
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHRINK_DCACHE_MEMORY 1
+_ACEOF
+
+ fi
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHRINK_DCACHE_MEMORY 1
+_ACEOF
+
+ fi
+
+
+
+ { $as_echo "$as_me:$LINENO: checking whether symbol shrink_icache_memory is exported" >&5
+$as_echo_n "checking whether symbol shrink_icache_memory is exported... " >&6; }
+ grep -q -E '[[:space:]]shrink_icache_memory[[:space:]]' \
+ $LINUX_OBJ/Module*.symvers 2>/dev/null
+ rc=$?
+ if test $rc -ne 0; then
+ export=0
+ for file in fs/inode.c; do
+ grep -q -E "EXPORT_SYMBOL.*(shrink_icache_memory)" \
+ "$LINUX_OBJ/$file" 2>/dev/null
+ rc=$?
+ if test $rc -eq 0; then
+ export=1
+ break;
+ fi
+ done
+ if test $export -eq 0; then
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHRINK_ICACHE_MEMORY 1
+_ACEOF
+
+ fi
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHRINK_ICACHE_MEMORY 1
+_ACEOF
+
+ fi
+
+
;;
user)
+ { $as_echo "$as_me:$LINENO: checking whether symbol shrink_dcache_memory is exported" >&5
+$as_echo_n "checking whether symbol shrink_dcache_memory is exported... " >&6; }
+ grep -q -E '[[:space:]]shrink_dcache_memory[[:space:]]' \
+ $LINUX_OBJ/Module*.symvers 2>/dev/null
+ rc=$?
+ if test $rc -ne 0; then
+ export=0
+ for file in fs/dcache.c; do
+ grep -q -E "EXPORT_SYMBOL.*(shrink_dcache_memory)" \
+ "$LINUX_OBJ/$file" 2>/dev/null
+ rc=$?
+ if test $rc -eq 0; then
+ export=1
+ break;
+ fi
+ done
+ if test $export -eq 0; then
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHRINK_DCACHE_MEMORY 1
+_ACEOF
+
+ fi
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHRINK_DCACHE_MEMORY 1
+_ACEOF
+
+ fi
+
+
+
+ { $as_echo "$as_me:$LINENO: checking whether symbol shrink_icache_memory is exported" >&5
+$as_echo_n "checking whether symbol shrink_icache_memory is exported... " >&6; }
+ grep -q -E '[[:space:]]shrink_icache_memory[[:space:]]' \
+ $LINUX_OBJ/Module*.symvers 2>/dev/null
+ rc=$?
+ if test $rc -ne 0; then
+ export=0
+ for file in fs/inode.c; do
+ grep -q -E "EXPORT_SYMBOL.*(shrink_icache_memory)" \
+ "$LINUX_OBJ/$file" 2>/dev/null
+ rc=$?
+ if test $rc -eq 0; then
+ export=1
+ break;
+ fi
+ done
+ if test $export -eq 0; then
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHRINK_ICACHE_MEMORY 1
+_ACEOF
+
+ fi
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SHRINK_ICACHE_MEMORY 1
+_ACEOF
+
+ fi
+
+
+
if test "x$AWK" != xgawk; then
#define invalidate_inodes(sb) invalidate_inodes_fn(sb)
#endif /* HAVE_INVALIDATE_INODES */
+/*
+ * 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.
+ */
+#ifndef HAVE_SHRINK_DCACHE_MEMORY
+# ifdef 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) shrink_dcache_memory_fn(NULL, nr, gfp)
+# 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) shrink_dcache_memory_fn(nr, gfp)
+# 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
+# ifdef 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) shrink_icache_memory_fn(NULL, nr, gfp)
+# 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) shrink_icache_memory_fn(nr, gfp)
+# endif /* HAVE_3ARGS_SHRINKER_CALLBACK */
+#endif /* HAVE_SHRINK_ICACHE_MEMORY */
+
#ifdef HAVE_SET_SHRINKER
typedef struct spl_shrinker {
struct shrinker *shrinker;
#ifndef _SPL_DNLC_H
#define _SPL_DNLC_H
-#define dnlc_reduce_cache(percent) ((void)0)
+/*
+ * Reduce the dcache and icache then reap the free'd slabs. Note the
+ * interface takes a reclaim percentage but we don't have easy access to
+ * the total number of entries to calculate the reclaim count. However,
+ * in practice this doesn't need to be even close to correct. We simply
+ * need to reclaim some useful fraction of the cache. The caller can
+ * determine if more needs to be done.
+ */
+static inline void
+dnlc_reduce_cache(void *reduce_percent)
+{
+ int nr = (uintptr_t)reduce_percent * 10000;
+
+ shrink_dcache_memory(nr, GFP_KERNEL);
+ shrink_icache_memory(nr, GFP_KERNEL);
+ kmem_reap();
+}
#endif /* SPL_DNLC_H */
EXPORT_SYMBOL(invalidate_inodes_fn);
#endif /* HAVE_INVALIDATE_INODES */
+#ifndef HAVE_SHRINK_DCACHE_MEMORY
+shrink_dcache_memory_t shrink_dcache_memory_fn = SYMBOL_POISON;
+EXPORT_SYMBOL(shrink_dcache_memory_fn);
+#endif /* HAVE_SHRINK_DCACHE_MEMORY */
+
+#ifndef HAVE_SHRINK_ICACHE_MEMORY
+shrink_icache_memory_t shrink_icache_memory_fn = SYMBOL_POISON;
+EXPORT_SYMBOL(shrink_icache_memory_fn);
+#endif /* HAVE_SHRINK_ICACHE_MEMORY */
+
pgcnt_t
spl_kmem_availrmem(void)
{
}
#endif /* HAVE_INVALIDATE_INODES */
+#ifndef HAVE_SHRINK_DCACHE_MEMORY
+ shrink_dcache_memory_fn = (shrink_dcache_memory_t)
+ spl_kallsyms_lookup_name("shrink_dcache_memory");
+ if (!shrink_dcache_memory_fn) {
+ printk(KERN_ERR "Error: Unknown symbol shrink_dcache_memory\n");
+ return -EFAULT;
+ }
+#endif /* HAVE_SHRINK_DCACHE_MEMORY */
+
+#ifndef HAVE_SHRINK_ICACHE_MEMORY
+ shrink_icache_memory_fn = (shrink_icache_memory_t)
+ spl_kallsyms_lookup_name("shrink_icache_memory");
+ if (!shrink_icache_memory_fn) {
+ printk(KERN_ERR "Error: Unknown symbol shrink_icache_memory\n");
+ return -EFAULT;
+ }
+#endif /* HAVE_SHRINK_ICACHE_MEMORY */
+
return 0;
}
/* set_shrinker() available */
#undef HAVE_SET_SHRINKER
+/* shrink_dcache_memory() is available */
+#undef HAVE_SHRINK_DCACHE_MEMORY
+
+/* shrink_icache_memory() is available */
+#undef HAVE_SHRINK_ICACHE_MEMORY
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H