diff options
-rw-r--r-- | config/spl-build.m4 | 38 | ||||
-rwxr-xr-x | configure | 57 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/sys/vmsystm.h | 30 | ||||
-rw-r--r-- | module/spl/spl-kmem.c | 47 | ||||
-rw-r--r-- | spl_config.h.in | 6 |
6 files changed, 157 insertions, 23 deletions
diff --git a/config/spl-build.m4 b/config/spl-build.m4 index ce798cc74..750218941 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -803,6 +803,31 @@ AC_DEFUN([SPL_AC_GET_VMALLOC_INFO], [ ]) dnl # +dnl # 2.6.17 API change +dnl # The helper functions first_online_pgdat(), next_online_pgdat(), and +dnl # next_zone() are introduced to simplify for_each_zone(). These symbols +dnl # were exported in 2.6.17 for use by modules which was consistent with +dnl # the previous implementation of for_each_zone(). From 2.6.18 - 2.6.19 +dnl # the symbols were exported as 'unused', and by 2.6.20 they exports +dnl # were dropped entirely leaving modules no way to directly iterate over +dnl # the zone list. Because we need access to the zone helpers we check +dnl # if the kernel contains the old or new implementation. Then we check +dnl # to see if the symbols we need for each version are available. If they +dnl # are not, dynamically aquire the addresses with kallsyms_lookup_name(). +dnl # +AC_DEFUN([SPL_AC_PGDAT_HELPERS], [ + AC_MSG_CHECKING([whether symbol *_pgdat exist]) + grep -q -E 'first_online_pgdat' $LINUX/include/linux/mmzone.h 2>/dev/null + rc=$? + if test $rc -eq 0; then + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_PGDAT_HELPERS, 1, [pgdat helpers are available]) + else + AC_MSG_RESULT([no]) + fi +]) + +dnl # dnl # Proposed API change, dnl # This symbol is not available in stock kernels. You may build a dnl # custom kernel with the *-spl-export-symbols.patch which will export @@ -851,6 +876,19 @@ AC_DEFUN([SPL_AC_NEXT_ZONE], [ ]) dnl # +dnl # 2.6.17 API change, +dnl # See SPL_AC_PGDAT_HELPERS for details. +dnl # +AC_DEFUN([SPL_AC_PGDAT_LIST], [ + SPL_CHECK_SYMBOL_EXPORT( + [pgdat_list], + [], + [AC_DEFINE(HAVE_PGDAT_LIST, 1, + [pgdat_list is available])], + []) +]) + +dnl # dnl # Proposed API change, dnl # This symbol is not available in stock kernels. You may build a dnl # custom kernel with the *-spl-export-symbols.patch which will export @@ -20798,6 +20798,24 @@ _ACEOF + echo "$as_me:$LINENO: checking whether symbol *_pgdat exist" >&5 +echo $ECHO_N "checking whether symbol *_pgdat exist... $ECHO_C" >&6 + grep -q -E 'first_online_pgdat' $LINUX/include/linux/mmzone.h 2>/dev/null + rc=$? + if test $rc -eq 0; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_PGDAT_HELPERS 1 +_ACEOF + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + + echo "$as_me:$LINENO: checking whether symbol first_online_pgdat is exported" >&5 echo $ECHO_N "checking whether symbol first_online_pgdat is exported... $ECHO_C" >&6 grep -q -E '[[:space:]]first_online_pgdat[[:space:]]' $LINUX_OBJ/Module.symvers 2>/dev/null @@ -20915,6 +20933,45 @@ _ACEOF + echo "$as_me:$LINENO: checking whether symbol pgdat_list is exported" >&5 +echo $ECHO_N "checking whether symbol pgdat_list is exported... $ECHO_C" >&6 + grep -q -E '[[:space:]]pgdat_list[[:space:]]' $LINUX_OBJ/Module.symvers 2>/dev/null + rc=$? + if test $rc -ne 0; then + export=0 + for file in ; do + grep -q -E "EXPORT_SYMBOL.*(pgdat_list)" "$LINUX_OBJ/$file" 2>/dev/null + rc=$? + if test $rc -eq 0; then + export=1 + break; + fi + done + if test $export -eq 0; then + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + + else + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_PGDAT_LIST 1 +_ACEOF + + fi + else + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_PGDAT_LIST 1 +_ACEOF + + fi + + + echo "$as_me:$LINENO: checking whether symbol get_zone_counts is exported" >&5 echo $ECHO_N "checking whether symbol get_zone_counts is exported... $ECHO_C" >&6 grep -q -E '[[:space:]]get_zone_counts[[:space:]]' $LINUX_OBJ/Module.symvers 2>/dev/null diff --git a/configure.ac b/configure.ac index a073f4297..ecad8cbd0 100644 --- a/configure.ac +++ b/configure.ac @@ -73,9 +73,11 @@ SPL_AC_DIV64_U64 SPL_AC_3ARGS_ON_EACH_CPU SPL_AC_KALLSYMS_LOOKUP_NAME SPL_AC_GET_VMALLOC_INFO +SPL_AC_PGDAT_HELPERS SPL_AC_FIRST_ONLINE_PGDAT SPL_AC_NEXT_ONLINE_PGDAT SPL_AC_NEXT_ZONE +SPL_AC_PGDAT_LIST SPL_AC_GET_ZONE_COUNTS SPL_AC_GLOBAL_PAGE_STATE SPL_AC_ZONE_STAT_ITEM_FIA diff --git a/include/sys/vmsystm.h b/include/sys/vmsystm.h index 71058eef8..75365fde0 100644 --- a/include/sys/vmsystm.h +++ b/include/sys/vmsystm.h @@ -93,26 +93,34 @@ extern get_vmalloc_info_t get_vmalloc_info_fn; #endif /* CONFIG_MMU */ #endif /* HAVE_GET_VMALLOC_INFO */ +#ifdef HAVE_PGDAT_HELPERS /* Source linux/mm/mmzone.c */ -#ifndef HAVE_FIRST_ONLINE_PGDAT +# ifndef HAVE_FIRST_ONLINE_PGDAT typedef struct pglist_data *(*first_online_pgdat_t)(void); extern first_online_pgdat_t first_online_pgdat_fn; -#define first_online_pgdat() first_online_pgdat_fn() -#endif /* HAVE_FIRST_ONLINE_PGDAT */ +# define first_online_pgdat() first_online_pgdat_fn() +# endif /* HAVE_FIRST_ONLINE_PGDAT */ -/* Source linux/mm/mmzone.c */ -#ifndef HAVE_NEXT_ONLINE_PGDAT +# ifndef HAVE_NEXT_ONLINE_PGDAT typedef struct pglist_data *(*next_online_pgdat_t)(struct pglist_data *); extern next_online_pgdat_t next_online_pgdat_fn; -#define next_online_pgdat(pgd) next_online_pgdat_fn(pgd) -#endif /* HAVE_NEXT_ONLINE_PGDAT */ +# define next_online_pgdat(pgd) next_online_pgdat_fn(pgd) +# endif /* HAVE_NEXT_ONLINE_PGDAT */ -/* Source linux/mm/mmzone.c */ -#ifndef HAVE_NEXT_ZONE +# ifndef HAVE_NEXT_ZONE typedef struct zone *(*next_zone_t)(struct zone *); extern next_zone_t next_zone_fn; -#define next_zone(zone) next_zone_fn(zone) -#endif /* HAVE_NEXT_ZONE */ +# define next_zone(zone) next_zone_fn(zone) +# endif /* HAVE_NEXT_ZONE */ + +#else /* HAVE_PGDAT_HELPERS */ + +# ifndef HAVE_PGDAT_LIST +extern struct pglist_data *pgdat_list_addr; +# define pgdat_list pgdat_list_addr +# endif /* HAVE_PGDAT_LIST */ + +#endif /* HAVE_PGDAT_HELPERS */ /* Source linux/mm/vmstat.c */ #ifndef HAVE_ZONE_STAT_ITEM_FIA diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c index 706691929..4009aa3b2 100644 --- a/module/spl/spl-kmem.c +++ b/module/spl/spl-kmem.c @@ -84,20 +84,30 @@ get_vmalloc_info_t get_vmalloc_info_fn = SYMBOL_POISON; EXPORT_SYMBOL(get_vmalloc_info_fn); #endif /* HAVE_GET_VMALLOC_INFO */ -#ifndef HAVE_FIRST_ONLINE_PGDAT +#ifdef HAVE_PGDAT_HELPERS +# ifndef HAVE_FIRST_ONLINE_PGDAT first_online_pgdat_t first_online_pgdat_fn = SYMBOL_POISON; EXPORT_SYMBOL(first_online_pgdat_fn); -#endif /* HAVE_FIRST_ONLINE_PGDAT */ +# endif /* HAVE_FIRST_ONLINE_PGDAT */ -#ifndef HAVE_NEXT_ONLINE_PGDAT +# ifndef HAVE_NEXT_ONLINE_PGDAT next_online_pgdat_t next_online_pgdat_fn = SYMBOL_POISON; EXPORT_SYMBOL(next_online_pgdat_fn); -#endif /* HAVE_NEXT_ONLINE_PGDAT */ +# endif /* HAVE_NEXT_ONLINE_PGDAT */ -#ifndef HAVE_NEXT_ZONE +# ifndef HAVE_NEXT_ZONE next_zone_t next_zone_fn = SYMBOL_POISON; EXPORT_SYMBOL(next_zone_fn); -#endif /* HAVE_NEXT_ZONE */ +# endif /* HAVE_NEXT_ZONE */ + +#else /* HAVE_PGDAT_HELPERS */ + +# ifndef HAVE_PGDAT_LIST +struct pglist_data *pgdat_list_addr = SYMBOL_POISON; +EXPORT_SYMBOL(pgdat_list_addr); +# endif /* HAVE_PGDAT_LIST */ + +#endif /* HAVE_PGDAT_HELPERS */ #ifndef HAVE_ZONE_STAT_ITEM_FIA # ifndef HAVE_GET_ZONE_COUNTS @@ -1806,32 +1816,45 @@ spl_kmem_init_kallsyms_lookup(void) } #endif /* HAVE_GET_VMALLOC_INFO */ -#ifndef HAVE_FIRST_ONLINE_PGDAT +#ifdef HAVE_PGDAT_HELPERS +# ifndef HAVE_FIRST_ONLINE_PGDAT first_online_pgdat_fn = (first_online_pgdat_t) spl_kallsyms_lookup_name("first_online_pgdat"); if (!first_online_pgdat_fn) { printk(KERN_ERR "Error: Unknown symbol first_online_pgdat\n"); return -EFAULT; } -#endif /* HAVE_FIRST_ONLINE_PGDAT */ +# endif /* HAVE_FIRST_ONLINE_PGDAT */ -#ifndef HAVE_NEXT_ONLINE_PGDAT +# ifndef HAVE_NEXT_ONLINE_PGDAT next_online_pgdat_fn = (next_online_pgdat_t) spl_kallsyms_lookup_name("next_online_pgdat"); if (!next_online_pgdat_fn) { printk(KERN_ERR "Error: Unknown symbol next_online_pgdat\n"); return -EFAULT; } -#endif /* HAVE_NEXT_ONLINE_PGDAT */ +# endif /* HAVE_NEXT_ONLINE_PGDAT */ -#ifndef HAVE_NEXT_ZONE +# ifndef HAVE_NEXT_ZONE next_zone_fn = (next_zone_t) spl_kallsyms_lookup_name("next_zone"); if (!next_zone_fn) { printk(KERN_ERR "Error: Unknown symbol next_zone\n"); return -EFAULT; } -#endif /* HAVE_NEXT_ZONE */ +# endif /* HAVE_NEXT_ZONE */ + +#else /* HAVE_PGDAT_HELPERS */ + +# ifndef HAVE_PGDAT_LIST + pgdat_list_addr = (struct pglist_data *) + spl_kallsyms_lookup_name("pgdat_list"); + if (!pgdat_list_addr) { + printk(KERN_ERR "Error: Unknown symbol pgdat_list\n"); + return -EFAULT; + } +# endif /* HAVE_PGDAT_LIST */ +#endif /* HAVE_PGDAT_HELPERS */ #ifndef HAVE_ZONE_STAT_ITEM_FIA # ifndef HAVE_GET_ZONE_COUNTS diff --git a/spl_config.h.in b/spl_config.h.in index 3e9e6b9af..3b07d993c 100644 --- a/spl_config.h.in +++ b/spl_config.h.in @@ -105,6 +105,12 @@ /* struct path used in struct nameidata */ #undef HAVE_PATH_IN_NAMEIDATA +/* pgdat helpers are available */ +#undef HAVE_PGDAT_HELPERS + +/* pgdat_list is available */ +#undef HAVE_PGDAT_LIST + /* set_normalized_timespec() is available as export */ #undef HAVE_SET_NORMALIZED_TIMESPEC_EXPORT |