From 31a033ecd49c2f691d6a377db2882ed941f47481 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 2 Feb 2009 15:12:30 -0800 Subject: [PATCH] 2.6.27+ portability changes - Added SPL_AC_3ARGS_ON_EACH_CPU configure check to determine if the older 4 argument version of on_each_cpu() should be used or the new 3 argument version. The retry argument was dropped in the new API which was never used anyway. - Updated work queue compatibility wrappers. The old way this worked was to pass a data point when initialized the workqueue. The new API assumed the work item is embedding in a structure and we us container_of() to find that data pointer. - Updated skc->skc_flags to be an unsigned long which is now type checked in the bit operations. This silences the warnings. - Updated autogen products and splat tests accordingly --- config/spl-build.m4 | 19 ++++++++++ configure | 61 ++++++++++++++++++++++++++++++++ configure.ac | 1 + include/linux/smp_compat.h | 16 +++++++++ include/linux/workqueue_compat.h | 25 +++++++++++++ include/sys/kmem.h | 3 +- include/sys/types.h | 2 ++ include/sys/workqueue.h | 55 ---------------------------- module/spl/spl-kmem.c | 6 ++-- module/splat/splat-mutex.c | 23 +++++------- spl_config.h.in | 3 ++ 11 files changed, 139 insertions(+), 75 deletions(-) create mode 100644 include/linux/smp_compat.h create mode 100644 include/linux/workqueue_compat.h delete mode 100644 include/sys/workqueue.h diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 993133065..2f346f6c8 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -686,3 +686,22 @@ AC_DEFUN([SPL_AC_DIV64_64], [ AC_MSG_RESULT(no) ]) ]) + +dnl # +dnl # 2.6.27 API change, +dnl # on_each_cpu() uses 3 args, no 'retry' argument +dnl # +AC_DEFUN([SPL_AC_3ARGS_ON_EACH_CPU], [ + AC_MSG_CHECKING([whether on_each_cpu() wants 3 args]) + SPL_LINUX_TRY_COMPILE([ + #include + ],[ + on_each_cpu(NULL, NULL, 0); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_3ARGS_ON_EACH_CPU, 1, + [on_each_cpu wants 3 args]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/configure b/configure index 5ac16ce74..8acd05023 100755 --- a/configure +++ b/configure @@ -20407,6 +20407,67 @@ cat >>confdefs.h <<\_ACEOF _ACEOF +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + +fi +rm -f build/conftest.o build/conftest.mod.c build/conftest.mod.o build/conftest.ko build/conftest.c conftest.c + + + + echo "$as_me:$LINENO: checking whether on_each_cpu() wants 3 args" >&5 +echo $ECHO_N "checking whether on_each_cpu() wants 3 args... $ECHO_C" >&6 + + +cat >conftest.c <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + on_each_cpu(NULL, NULL, 0); + + ; + return 0; +} + +_ACEOF + +rm -f build/conftest.o build/conftest.mod.c build/conftest.ko build/Makefile +echo "obj-m := conftest.o" >build/Makefile +if { ac_try='cp conftest.c build && make modules CC="$CC" LINUXINCLUDE="-Iinclude -include include/linux/autoconf.h" -o tmp_include_depends -o scripts -o include/config/MARKER -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=$? + 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=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_3ARGS_ON_EACH_CPU 1 +_ACEOF + + else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 diff --git a/configure.ac b/configure.ac index 1db1efbf9..e0fcb6077 100644 --- a/configure.ac +++ b/configure.ac @@ -68,6 +68,7 @@ SPL_AC_KMALLOC_NODE SPL_AC_MONOTONIC_CLOCK SPL_AC_INODE_I_MUTEX SPL_AC_DIV64_64 +SPL_AC_3ARGS_ON_EACH_CPU TOPDIR=`/bin/pwd` diff --git a/include/linux/smp_compat.h b/include/linux/smp_compat.h new file mode 100644 index 000000000..4da35f4ad --- /dev/null +++ b/include/linux/smp_compat.h @@ -0,0 +1,16 @@ +#ifndef _SPL_SMP_COMPAT_H +#define _SPL_SMP_COMPAT_H + +#include + +#ifdef HAVE_3ARGS_ON_EACH_CPU + +#define spl_on_each_cpu(func,info,wait) on_each_cpu(func,info,wait) + +#else + +#define spl_on_each_cpu(func,info,wait) on_each_cpu(func,info,0,wait) + +#endif /* HAVE_3ARGS_ON_EACH_CPU */ + +#endif /* _SPL_SMP_COMPAT_H */ diff --git a/include/linux/workqueue_compat.h b/include/linux/workqueue_compat.h new file mode 100644 index 000000000..3dab8776a --- /dev/null +++ b/include/linux/workqueue_compat.h @@ -0,0 +1,25 @@ +#ifndef _SPL_WORKQUEUE_COMPAT_H +#define _SPL_WORKQUEUE_COMPAT_H + +#include +#include + +#ifdef HAVE_3ARGS_INIT_WORK + +#define delayed_work work_struct + +#define spl_init_work(wq, cb, d) INIT_WORK((wq), (void *)(cb), \ + (void *)(d)) +#define spl_init_delayed_work(wq,cb,d) INIT_WORK((wq), (void *)(cb), \ + (void *)(d)) +#define spl_get_work_data(d, t, f) (t *)(d) + +#else + +#define spl_init_work(wq, cb, d) INIT_WORK((wq), (void *)(cb)); +#define spl_init_delayed_work(wq,cb,d) INIT_DELAYED_WORK((wq), (void *)(cb)); +#define spl_get_work_data(d, t, f) (t *)container_of(d, t, f) + +#endif /* HAVE_3ARGS_INIT_WORK */ + +#endif /* _SPL_WORKQUEUE_COMPAT_H */ diff --git a/include/sys/kmem.h b/include/sys/kmem.h index 4f939e0fc..5f2695d52 100644 --- a/include/sys/kmem.h +++ b/include/sys/kmem.h @@ -45,7 +45,6 @@ extern "C" { #include #include #include -#include /* * Memory allocation interfaces @@ -286,7 +285,7 @@ typedef struct spl_kmem_cache { spl_kmem_reclaim_t skc_reclaim; /* Reclaimator */ void *skc_private; /* Private data */ void *skc_vmp; /* Unused */ - uint32_t skc_flags; /* Flags */ + unsigned long skc_flags; /* Flags */ uint32_t skc_obj_size; /* Object size */ uint32_t skc_obj_align; /* Object alignment */ uint32_t skc_slab_objs; /* Objects per slab */ diff --git a/include/sys/types.h b/include/sys/types.h index b67336bae..0b5cae641 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -14,6 +14,8 @@ extern "C" { #include #include #include +#include +#include #ifndef HAVE_UINTPTR_T typedef unsigned long uintptr_t; diff --git a/include/sys/workqueue.h b/include/sys/workqueue.h deleted file mode 100644 index 711c32ed2..000000000 --- a/include/sys/workqueue.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the SPL: Solaris Porting Layer. - * - * Copyright (c) 2008 Lawrence Livermore National Security, LLC. - * Produced at Lawrence Livermore National Laboratory - * Written by: - * Brian Behlendorf , - * Herb Wartens , - * Jim Garlick - * UCRL-CODE-235197 - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef _SPL_WORKQUEUE_H -#define _SPL_WORKQUEUE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#ifdef HAVE_3ARGS_INIT_WORK - -#define delayed_work work_struct - -#define spl_init_work(wq, cb, d) INIT_WORK((wq), (void *)(cb), \ - (void *)(d)) -#define spl_init_delayed_work(wq,cb,d) INIT_WORK((wq), (void *)(cb), \ - (void *)(d)) -#define spl_get_work_data(d, t, f) (t *)(d) - -#else - -#define spl_init_work(wq, cb, d) INIT_WORK((wq), (void *)(cb)); -#define spl_init_delayed_work(wq,cb,d) INIT_DELAYED_WORK((wq), (void *)(cb)); -#define spl_get_work_data(d, t, f) (t *)container_of(d, t, f) - -#endif /* HAVE_3ARGS_INIT_WORK */ - -#endif /* _SPL_WORKQUEUE_H */ diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c index 83eefe293..79f787271 100644 --- a/module/spl/spl-kmem.c +++ b/module/spl/spl-kmem.c @@ -783,7 +783,7 @@ spl_cache_age(void *data) spl_get_work_data(data, spl_kmem_cache_t, skc_work.work); ASSERT(skc->skc_magic == SKC_MAGIC); - on_each_cpu(spl_magazine_age, skc, 0, 1); + spl_on_each_cpu(spl_magazine_age, skc, 1); spl_slab_reclaim(skc, 0); if (!test_bit(KMC_BIT_DESTROY, &skc->skc_flags)) @@ -923,7 +923,7 @@ spl_magazine_create(spl_kmem_cache_t *skc) skc->skc_mag_size = spl_magazine_size(skc); skc->skc_mag_refill = (skc->skc_mag_size + 1) / 2; - on_each_cpu(__spl_magazine_create, skc, 0, 1); + spl_on_each_cpu(__spl_magazine_create, skc, 1); RETURN(0); } @@ -945,7 +945,7 @@ static void spl_magazine_destroy(spl_kmem_cache_t *skc) { ENTRY; - on_each_cpu(__spl_magazine_destroy, skc, 0, 1); + spl_on_each_cpu(__spl_magazine_destroy, skc, 1); EXIT; } diff --git a/module/splat/splat-mutex.c b/module/splat/splat-mutex.c index 640f8f407..c64f27aaf 100644 --- a/module/splat/splat-mutex.c +++ b/module/splat/splat-mutex.c @@ -59,28 +59,26 @@ typedef struct mutex_priv { int mp_rc; } mutex_priv_t; -#ifdef HAVE_3ARGS_INIT_WORK static void splat_mutex_test1_work(void *priv) { - mutex_priv_t *mp = (mutex_priv_t *)priv; + mutex_priv_t *mp; + mp = spl_get_work_data(priv, mutex_priv_t, mp_work.work); ASSERT(mp->mp_magic == SPLAT_MUTEX_TEST_MAGIC); mp->mp_rc = 0; if (!mutex_tryenter(&mp->mp_mtx)) mp->mp_rc = -EBUSY; } -#endif static int splat_mutex_test1(struct file *file, void *arg) { - int rc = 0; -#ifdef HAVE_3ARGS_INIT_WORK struct workqueue_struct *wq; struct work_struct work; mutex_priv_t *mp; + int rc = 0; mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL); if (mp == NULL) @@ -97,7 +95,7 @@ splat_mutex_test1(struct file *file, void *arg) mp->mp_magic = SPLAT_MUTEX_TEST_MAGIC; mp->mp_file = file; - INIT_WORK(&work, splat_mutex_test1_work, mp); + spl_init_work(&work, splat_mutex_test1_work, mp); /* Schedule a work item which will try and aquire the mutex via * mutex_tryenter() while its held. This should fail and the work @@ -143,17 +141,16 @@ out: destroy_workqueue(wq); out2: kfree(mp); -#endif return rc; } -#ifdef HAVE_3ARGS_INIT_WORK static void splat_mutex_test2_work(void *priv) { - mutex_priv_t *mp = (mutex_priv_t *)priv; + mutex_priv_t *mp; int rc; + mp = spl_get_work_data(priv, mutex_priv_t, mp_work.work); ASSERT(mp->mp_magic == SPLAT_MUTEX_TEST_MAGIC); /* Read the value before sleeping and write it after we wake up to @@ -165,16 +162,13 @@ splat_mutex_test2_work(void *priv) mp->mp_rc = rc + 1; mutex_exit(&mp->mp_mtx); } -#endif static int splat_mutex_test2(struct file *file, void *arg) { - int rc = 0; -#ifdef HAVE_3ARGS_INIT_WORK struct workqueue_struct *wq; mutex_priv_t *mp; - int i; + int i, rc = 0; mp = (mutex_priv_t *)kmalloc(sizeof(*mp), GFP_KERNEL); if (mp == NULL) @@ -200,7 +194,7 @@ splat_mutex_test2(struct file *file, void *arg) * critical region at the same time the system will panic. If the * mutex is implemented right this will never happy, that's a pass. */ for (i = 0; i < SPLAT_MUTEX_TEST_COUNT; i++) { - INIT_WORK(&(mp->mp_work[i]), splat_mutex_test2_work, mp); + spl_init_work(&(mp->mp_work[i]), splat_mutex_test2_work, mp); if (!queue_work(wq, &(mp->mp_work[i]))) { splat_vprint(file, SPLAT_MUTEX_TEST2_NAME, @@ -226,7 +220,6 @@ splat_mutex_test2(struct file *file, void *arg) destroy_workqueue(wq); out: kfree(mp); -#endif return rc; } diff --git a/spl_config.h.in b/spl_config.h.in index c19555a06..a4a8ccd32 100644 --- a/spl_config.h.in +++ b/spl_config.h.in @@ -18,6 +18,9 @@ /* INIT_WORK wants 3 args */ #undef HAVE_3ARGS_INIT_WORK +/* on_each_cpu wants 3 args */ +#undef HAVE_3ARGS_ON_EACH_CPU + /* kernel defines atomic64_t */ #undef HAVE_ATOMIC64_T