AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = autogen.sh spl.spec.in spl-modules.spec.in META DISCLAIMER
EXTRA_DIST += config/config.awk config/rpm.am config/deb.am config/tgz.am
-noinst_HEADERS = spl_config.h
+noinst_HEADERS = spl_config.h spl.release
distclean-local::
-$(RM) -R autom4te*.cache
install-data-local:
release=$(SPL_META_VERSION)-$(SPL_META_RELEASE); \
instdest=$(DESTDIR)/usr/src/spl-$$release/$(LINUX_VERSION); \
- echo "$$release" >$$instdest/spl.release; \
for instfile in $(noinst_HEADERS) module/$(LINUX_SYMBOLS); do \
$(INSTALL) -D $$instfile $$instdest/$$instfile; \
done
DIST_COMMON = $(am__configure_deps) $(noinst_HEADERS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/PKGBUILD-spl-modules.in $(srcdir)/PKGBUILD-spl.in \
- $(srcdir)/spl-modules.spec.in $(srcdir)/spl.spec.in \
- $(srcdir)/spl_config.h.in $(top_srcdir)/config/arch.am \
- $(top_srcdir)/config/deb.am $(top_srcdir)/config/rpm.am \
- $(top_srcdir)/config/tgz.am $(top_srcdir)/configure \
- $(top_srcdir)/module/Makefile.in \
+ $(srcdir)/spl-modules.spec.in $(srcdir)/spl.release.in \
+ $(srcdir)/spl.spec.in $(srcdir)/spl_config.h.in \
+ $(top_srcdir)/config/arch.am $(top_srcdir)/config/deb.am \
+ $(top_srcdir)/config/rpm.am $(top_srcdir)/config/tgz.am \
+ $(top_srcdir)/configure $(top_srcdir)/module/Makefile.in \
$(top_srcdir)/module/spl/Makefile.in \
$(top_srcdir)/module/splat/Makefile.in AUTHORS COPYING \
ChangeLog INSTALL config/config.guess config/config.sub \
CONFIG_HEADER = spl_config.h
CONFIG_CLEAN_FILES = module/Makefile module/spl/Makefile \
module/splat/Makefile spl.spec spl-modules.spec PKGBUILD-spl \
- PKGBUILD-spl-modules
+ PKGBUILD-spl-modules spl.release
CONFIG_CLEAN_VPATH_FILES =
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
EXTRA_DIST = autogen.sh spl.spec.in spl-modules.spec.in META \
DISCLAIMER config/config.awk config/rpm.am config/deb.am \
config/tgz.am
-noinst_HEADERS = spl_config.h
+noinst_HEADERS = spl_config.h spl.release
all: spl_config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
cd $(top_builddir) && $(SHELL) ./config.status $@
PKGBUILD-spl-modules: $(top_builddir)/config.status $(srcdir)/PKGBUILD-spl-modules.in
cd $(top_builddir) && $(SHELL) ./config.status $@
+spl.release: $(top_builddir)/config.status $(srcdir)/spl.release.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
@CONFIG_KERNEL_TRUE@install-data-local:
@CONFIG_KERNEL_TRUE@ release=$(SPL_META_VERSION)-$(SPL_META_RELEASE); \
@CONFIG_KERNEL_TRUE@ instdest=$(DESTDIR)/usr/src/spl-$$release/$(LINUX_VERSION); \
-@CONFIG_KERNEL_TRUE@ echo "$$release" >$$instdest/spl.release; \
@CONFIG_KERNEL_TRUE@ for instfile in $(noinst_HEADERS) module/$(LINUX_SYMBOLS); do \
@CONFIG_KERNEL_TRUE@ $(INSTALL) -D $$instfile $$instdest/$$instfile; \
@CONFIG_KERNEL_TRUE@ done
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], [
])
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)
+ ])
+])
EXTRA_KCFLAGS="$tmp_flags"
+
+ { $as_echo "$as_me:$LINENO: checking whether pmd_alloc_with_mask exists" >&5
+$as_echo_n "checking whether pmd_alloc_with_mask exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+ #if !defined(CONFIG_MMU)
+ #define CONFIG_MMU
+ #endif
+
+ #if defined(RCH_HAS_4LEVEL_HACK)
+ #undef RCH_HAS_4LEVEL_HACK
+ #endif
+
+ #include <linux/mm.h>
+
+int
+main (void)
+{
+
+ 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);
+
+ ;
+ return 0;
+}
+
+_ACEOF
+
+
+ rm -Rf build && mkdir -p build
+ echo "obj-m := conftest.o" >build/Makefile
+ if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PMD_ALLOC_WITH_MASK 1
+_ACEOF
+
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+
+ rm -Rf build
+
+
+
;;
user) ;;
all)
EXTRA_KCFLAGS="$tmp_flags"
+ { $as_echo "$as_me:$LINENO: checking whether pmd_alloc_with_mask exists" >&5
+$as_echo_n "checking whether pmd_alloc_with_mask exists... " >&6; }
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+ #if !defined(CONFIG_MMU)
+ #define CONFIG_MMU
+ #endif
+
+ #if defined(RCH_HAS_4LEVEL_HACK)
+ #undef RCH_HAS_4LEVEL_HACK
+ #endif
+
+ #include <linux/mm.h>
+
+int
+main (void)
+{
+
+ 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);
+
+ ;
+ return 0;
+}
+
+_ACEOF
+
+
+ rm -Rf build && mkdir -p build
+ echo "obj-m := conftest.o" >build/Makefile
+ if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PMD_ALLOC_WITH_MASK 1
+_ACEOF
+
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+
+ rm -Rf build
+
+
+
+
;;
srpm) ;;
*)
-ac_config_files="$ac_config_files Makefile lib/Makefile cmd/Makefile module/Makefile module/spl/Makefile module/splat/Makefile include/Makefile scripts/Makefile spl.spec spl-modules.spec PKGBUILD-spl PKGBUILD-spl-modules"
+ac_config_files="$ac_config_files Makefile lib/Makefile cmd/Makefile module/Makefile module/spl/Makefile module/splat/Makefile include/Makefile scripts/Makefile spl.spec spl-modules.spec PKGBUILD-spl PKGBUILD-spl-modules spl.release"
cat >confcache <<\_ACEOF
"spl-modules.spec") CONFIG_FILES="$CONFIG_FILES spl-modules.spec" ;;
"PKGBUILD-spl") CONFIG_FILES="$CONFIG_FILES PKGBUILD-spl" ;;
"PKGBUILD-spl-modules") CONFIG_FILES="$CONFIG_FILES PKGBUILD-spl-modules" ;;
+ "spl.release") CONFIG_FILES="$CONFIG_FILES spl.release" ;;
*) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
spl-modules.spec
PKGBUILD-spl
PKGBUILD-spl-modules
+ spl.release
])
AC_OUTPUT
#include <linux/rwsem.h>
-#ifdef RWSEM_SPINLOCK_IS_RAW
-#define spl_rwsem_lock_irqsave(lock, flags) \
-({ \
- raw_spin_lock_irqsave(lock, flags); \
-})
-#define spl_rwsem_unlock_irqrestore(lock, flags) \
-({ \
- raw_spin_unlock_irqrestore(lock, flags); \
-})
+#if defined(RWSEM_SPINLOCK_IS_RAW)
+#define spl_rwsem_lock_irqsave(lk, fl) raw_spin_lock_irqsave(lk, fl)
+#define spl_rwsem_unlock_irqrestore(lk, fl) raw_spin_unlock_irqrestore(lk, fl)
+#define spl_rwsem_trylock_irqsave(lk, fl) raw_spin_trylock_irqsave(lk, fl)
#else
-#define spl_rwsem_lock_irqsave(lock, flags) \
-({ \
- spin_lock_irqsave(lock, flags); \
-})
-#define spl_rwsem_unlock_irqrestore(lock, flags) \
-({ \
- spin_unlock_irqrestore(lock, flags); \
-})
+#define spl_rwsem_lock_irqsave(lk, fl) spin_lock_irqsave(lk, fl)
+#define spl_rwsem_unlock_irqrestore(lk, fl) spin_unlock_irqrestore(lk, fl)
+#define spl_rwsem_trylock_irqsave(lk, fl) spin_trylock_irqsave(lk, fl)
#endif /* RWSEM_SPINLOCK_IS_RAW */
-#ifdef RWSEM_IS_LOCKED_TAKES_WAIT_LOCK
/*
- * A race condition in rwsem_is_locked() was fixed in Linux 2.6.33 and the fix
- * was backported to RHEL5 as of kernel 2.6.18-190.el5. Details can be found
- * here:
+ * Prior to Linux 2.6.33 there existed a race condition in rwsem_is_locked().
+ * The semaphore's activity was checked outside of the wait_lock which
+ * could result in some readers getting the incorrect activity value.
*
- * https://bugzilla.redhat.com/show_bug.cgi?id=526092
-
- * The race condition was fixed in the kernel by acquiring the semaphore's
- * wait_lock inside rwsem_is_locked(). The SPL worked around the race
- * condition by acquiring the wait_lock before calling that function, but
- * with the fix in place we must not do that.
+ * When a kernel without this fix is detected the SPL takes responsibility
+ * for acquiring the wait_lock to avoid this race.
*/
-
-#define spl_rwsem_is_locked(rwsem) \
-({ \
- rwsem_is_locked(rwsem); \
-})
-
+#if defined(RWSEM_IS_LOCKED_TAKES_WAIT_LOCK)
+#define spl_rwsem_is_locked(rwsem) rwsem_is_locked(rwsem)
#else
+static inline int
+spl_rwsem_is_locked(struct rw_semaphore *rwsem)
+{
+ unsigned long flags;
+ int rc = 1;
-#define spl_rwsem_is_locked(rwsem) \
-({ \
- unsigned long _flags_; \
- int _rc_; \
- spl_rwsem_lock_irqsave(&rwsem->wait_lock, _flags_); \
- _rc_ = rwsem_is_locked(rwsem); \
- spl_rwsem_unlock_irqrestore(&rwsem->wait_lock, _flags_); \
- _rc_; \
-})
+ if (spl_rwsem_trylock_irqsave(&rwsem->wait_lock, flags)) {
+ rc = rwsem_is_locked(rwsem);
+ spl_rwsem_unlock_irqrestore(&rwsem->wait_lock, flags);
+ }
+ return (rc);
+}
#endif /* RWSEM_IS_LOCKED_TAKES_WAIT_LOCK */
#endif /* _SPL_RWSEM_COMPAT_H */
# define vmem_free(ptr, sz) vmem_free_track((ptr), (sz))
extern void *kmem_alloc_track(size_t, int, const char *, int, int, int);
-extern void kmem_free_track(void *, size_t);
+extern void kmem_free_track(const void *, size_t);
extern void *vmem_alloc_track(size_t, int, const char *, int);
-extern void vmem_free_track(void *, size_t);
+extern void vmem_free_track(const void *, size_t);
# else /* DEBUG_KMEM_TRACKING */
/*
# define vmem_free(ptr, sz) vmem_free_debug((ptr), (sz))
extern void *kmem_alloc_debug(size_t, int, const char *, int, int, int);
-extern void kmem_free_debug(void *, size_t);
+extern void kmem_free_debug(const void *, size_t);
extern void *vmem_alloc_debug(size_t, int, const char *, int);
-extern void vmem_free_debug(void *, size_t);
+extern void vmem_free_debug(const void *, size_t);
# endif /* DEBUG_KMEM_TRACKING */
#else /* DEBUG_KMEM */
EXPORT_SYMBOL(vmem_list);
static kmem_debug_t *
-kmem_del_init(spinlock_t *lock, struct hlist_head *table, int bits, void *addr)
+kmem_del_init(spinlock_t *lock, struct hlist_head *table, int bits, const void *addr)
{
struct hlist_head *head;
struct hlist_node *node;
EXPORT_SYMBOL(kmem_alloc_track);
void
-kmem_free_track(void *ptr, size_t size)
+kmem_free_track(const void *ptr, size_t size)
{
kmem_debug_t *dptr;
SENTRY;
EXPORT_SYMBOL(vmem_alloc_track);
void
-vmem_free_track(void *ptr, size_t size)
+vmem_free_track(const void *ptr, size_t size)
{
kmem_debug_t *dptr;
SENTRY;
EXPORT_SYMBOL(kmem_alloc_debug);
void
-kmem_free_debug(void *ptr, size_t size)
+kmem_free_debug(const void *ptr, size_t size)
{
SENTRY;
EXPORT_SYMBOL(vmem_alloc_debug);
void
-vmem_free_debug(void *ptr, size_t size)
+vmem_free_debug(const void *ptr, size_t size)
{
SENTRY;
if (skc->skc_flags & KMC_KMEM) {
ptr = (void *)__get_free_pages(flags, get_order(size));
} else {
+#ifdef HAVE_PMD_ALLOC_WITH_MASK
+ ptr = __vmalloc(size, flags|__GFP_HIGHMEM, PAGE_KERNEL);
+#else
/*
* As part of vmalloc() an __pte_alloc_kernel() allocation
* may occur. This internal allocation does not honor the
} else {
ptr = __vmalloc(size, flags|__GFP_HIGHMEM, PAGE_KERNEL);
}
+#endif
}
/* Resulting allocated memory will be page aligned */
--- /dev/null
+@SPL_META_VERSION@-@SPL_META_RELEASE@
/* pgdat_list is available */
#undef HAVE_PGDAT_LIST
+/* pmd_alloc_with_mask exists */
+#undef HAVE_PMD_ALLOC_WITH_MASK
+
/* __put_task_struct() is available */
#undef HAVE_PUT_TASK_STRUCT