Detect kernels that honor gfp flags passed to vmalloc()

zfsonlinux/spl@2092cf68d8 used
PF_MEMALLOC to workaround a bug in the Linux kernel where
allocations did not honor the gfp flags passed to vmalloc().
Unfortunately, PF_MEMALLOC has the side effect of permitting
allocations to allocate pages outside of ZONE_NORMAL. This
has been observed to result in the depletion of ZONE_DMA32.

A kernel patch is available in the Gentoo bug tracker for
this issue.

  https://bugs.gentoo.org/show_bug.cgi?id=416685

This negates any benefit PF_MEMALLOC provides, so we introduce
an autotools check to disable the use of PF_MEMALLOC on
systems with patched kernels.

Signed-off-by: Richard Yao <ryao@cs.stonybrook.edu>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #126
This commit is contained in:
Richard Yao
2012-06-06 22:38:12 -04:00
committed by Brian Behlendorf
parent 973e8269bd
commit 36811b4430
4 changed files with 199 additions and 0 deletions
+36
View File
@@ -88,6 +88,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
SPL_AC_SHRINK_CONTROL_STRUCT
SPL_AC_RWSEM_SPINLOCK_IS_RAW
SPL_AC_PMD_ALLOC_WITH_MASK
])
AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
@@ -2079,3 +2080,38 @@ AC_DEFUN([SPL_AC_RWSEM_SPINLOCK_IS_RAW], [
])
EXTRA_KCFLAGS="$tmp_flags"
])
dnl #
dnl # Proposed VM Subsystem Bug Fix
dnl # https://bugs.gentoo.org/show_bug.cgi?id=416685
dnl #
dnl # Make __pte_alloc_kernel() honor gfp flags passed to vmalloc()
dnl # This is detected by checking a macro that is changed to support this.
dnl #
AC_DEFUN([SPL_AC_PMD_ALLOC_WITH_MASK], [
AC_MSG_CHECKING([whether pmd_alloc_with_mask exists])
SPL_LINUX_TRY_COMPILE([
#if !defined(CONFIG_MMU)
#define CONFIG_MMU
#endif
#if defined(RCH_HAS_4LEVEL_HACK)
#undef RCH_HAS_4LEVEL_HACK
#endif
#include <linux/mm.h>
],[
struct mm_struct init_mm;
pud_t *pud = NULL;
unsigned long addr = 0;
gfp_t gfp_mask = GFP_KERNEL;
pmd_alloc_with_mask(&init_mm, pud, addr, gfp_mask);
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PMD_ALLOC_WITH_MASK, 1,
[pmd_alloc_with_mask exists])
],[
AC_MSG_RESULT(no)
])
])