diff options
| author | Erik Larsson <catacombae@gmail.com> | 2026-02-02 22:16:10 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-02 22:16:10 +0000 |
| commit | 7e33476a7c838eefafe4a8a6ecd1da5220cfacfa (patch) | |
| tree | 50310fae787f988e30f4c28c6f1a8dc38e6a26b7 | |
| parent | 13601e2d24960c4503c69ff3efc159b3a2353c46 (diff) | |
| -rw-r--r-- | config/kernel-mm-page-flags.m4 | 27 | ||||
| -rw-r--r-- | include/os/linux/kernel/linux/dcache_compat.h | 19 |
2 files changed, 42 insertions, 4 deletions
diff --git a/config/kernel-mm-page-flags.m4 b/config/kernel-mm-page-flags.m4 index 0bcac0b5c0a0..1c7397d19256 100644 --- a/config/kernel-mm-page-flags.m4 +++ b/config/kernel-mm-page-flags.m4 @@ -17,9 +17,36 @@ AC_DEFUN([ZFS_AC_KERNEL_MM_PAGE_FLAG_ERROR], [ ]) ]) +dnl # +dnl # Linux 6.18+ uses a struct typedef (memdesc_flags_t) instead of an +dnl # 'unsigned long' for the 'flags' field in 'struct page'. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_MM_PAGE_FLAGS_STRUCT], [ + ZFS_LINUX_TEST_SRC([mm_page_flags_struct], [ + #include <linux/mm.h> + + static const struct page p __attribute__ ((unused)) = { + .flags = { .f = 0 } + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_MM_PAGE_FLAGS_STRUCT], [ + AC_MSG_CHECKING([whether 'flags' in 'struct page' is a struct]) + ZFS_LINUX_TEST_RESULT([mm_page_flags_struct], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_MM_PAGE_FLAGS_STRUCT, 1, + ['flags' in 'struct page' is a struct]) + ],[ + AC_MSG_RESULT([no]) + ]) +]) + AC_DEFUN([ZFS_AC_KERNEL_SRC_MM_PAGE_FLAGS], [ ZFS_AC_KERNEL_SRC_MM_PAGE_FLAG_ERROR + ZFS_AC_KERNEL_SRC_MM_PAGE_FLAGS_STRUCT ]) AC_DEFUN([ZFS_AC_KERNEL_MM_PAGE_FLAGS], [ ZFS_AC_KERNEL_MM_PAGE_FLAG_ERROR + ZFS_AC_KERNEL_MM_PAGE_FLAGS_STRUCT ]) diff --git a/include/os/linux/kernel/linux/dcache_compat.h b/include/os/linux/kernel/linux/dcache_compat.h index 152e5a606f0e..f94dcda6175b 100644 --- a/include/os/linux/kernel/linux/dcache_compat.h +++ b/include/os/linux/kernel/linux/dcache_compat.h @@ -34,6 +34,17 @@ #define d_alias d_u.d_alias +#ifdef HAVE_MM_PAGE_FLAGS_STRUCT +/* + * Starting from Linux 6.18, the 'flags' field in 'struct page' is defined + * to a struct ('memdesc_flags_t' typedef) instead of an unsigned long for + * improved typesafety. + */ +#define page_flags flags.f +#else +#define page_flags flags +#endif + /* * Starting from Linux 5.13, flush_dcache_page() becomes an inline function * and under some configurations, may indirectly referencing GPL-only @@ -44,8 +55,8 @@ #include <linux/simd_powerpc.h> #define flush_dcache_page(page) do { \ if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && \ - test_bit(PG_dcache_clean, &(page)->flags)) \ - clear_bit(PG_dcache_clean, &(page)->flags); \ + test_bit(PG_dcache_clean, &(page)->page_flags)) \ + clear_bit(PG_dcache_clean, &(page)->page_flags);\ } while (0) #endif /* @@ -55,8 +66,8 @@ */ #if defined __riscv && defined HAVE_FLUSH_DCACHE_PAGE_GPL_ONLY #define flush_dcache_page(page) do { \ - if (test_bit(PG_dcache_clean, &(page)->flags)) \ - clear_bit(PG_dcache_clean, &(page)->flags); \ + if (test_bit(PG_dcache_clean, &(page)->page_flags)) \ + clear_bit(PG_dcache_clean, &(page)->page_flags);\ } while (0) #endif |
