Skip to content

Commit

Permalink
Introduce cpu_dcache_is_aliasing() across all architectures
Browse files Browse the repository at this point in the history
Introduce a generic way to query whether the data cache is virtually
aliased on all architectures. Its purpose is to ensure that subsystems
which are incompatible with virtually aliased data caches (e.g. FS_DAX)
can reliably query this.

For data cache aliasing, there are three scenarios dependending on the
architecture. Here is a breakdown based on my understanding:

A) The data cache is always aliasing:

* arc
* csky
* m68k (note: shared memory mappings are incoherent ? SHMLBA is missing there.)
* sh
* parisc

B) The data cache aliasing is statically known or depends on querying CPU
   state at runtime:

* arm (cache_is_vivt() || cache_is_vipt_aliasing())
* mips (cpu_has_dc_aliases)
* nios2 (NIOS2_DCACHE_SIZE > PAGE_SIZE)
* sparc32 (vac_cache_size > PAGE_SIZE)
* sparc64 (L1DCACHE_SIZE > PAGE_SIZE)
* xtensa (DCACHE_WAY_SIZE > PAGE_SIZE)

C) The data cache is never aliasing:

* alpha
* arm64 (aarch64)
* hexagon
* loongarch (but with incoherent write buffers, which are disabled since
             commit d23b779 ("LoongArch: Change SHMLBA from SZ_64K to PAGE_SIZE"))
* microblaze
* openrisc
* powerpc
* riscv
* s390
* um
* x86

Require architectures in A) and B) to select ARCH_HAS_CPU_CACHE_ALIASING and
implement "cpu_dcache_is_aliasing()".

Architectures in C) don't select ARCH_HAS_CPU_CACHE_ALIASING, and thus
cpu_dcache_is_aliasing() simply evaluates to "false".

Note that this leaves "cpu_icache_is_aliasing()" to be implemented as future
work. This would be useful to gate features like XIP on architectures
which have aliasing CPU dcache-icache but not CPU dcache-dcache.

Use "cpu_dcache" and "cpu_cache" rather than just "dcache" and "cache"
to clarify that we really mean "CPU data cache" and "CPU cache" to
eliminate any possible confusion with VFS "dentry cache" and "page
cache".

Link: https://lore.kernel.org/lkml/[email protected]/
Link: https://lkml.kernel.org/r/[email protected]
Fixes: d92576f ("dax: does not work correctly with virtual aliasing caches")
Signed-off-by: Mathieu Desnoyers <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Vishal Verma <[email protected]>
Cc: Dave Jiang <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Russell King <[email protected]>
Cc: Alasdair Kergon <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: kernel test robot <[email protected]>
Cc: Michael Sclafani <[email protected]>
Cc: Mike Snitzer <[email protected]>
Cc: Mikulas Patocka <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
compudj authored and akpm00 committed Feb 22, 2024
1 parent 1df4ca0 commit 8690bbc
Show file tree
Hide file tree
Showing 22 changed files with 112 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
config ARC
def_bool y
select ARC_TIMERS
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_CACHE_LINE_SIZE
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DMA_PREP_COHERENT
Expand Down
9 changes: 9 additions & 0 deletions arch/arc/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARC_CACHETYPE_H
#define __ASM_ARC_CACHETYPE_H

#include <linux/types.h>

#define cpu_dcache_is_aliasing() true

#endif
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ config ARM
select ARCH_32BIT_OFF_T
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL if MMU
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/include/asm/cachetype.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ extern unsigned int cacheid;
#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING)
#define icache_is_pipt() cacheid_is(CACHEID_PIPT)

#define cpu_dcache_is_aliasing() (cache_is_vivt() || cache_is_vipt_aliasing())

/*
* __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
* Mask out support which will never be present on newer CPUs.
Expand Down
1 change: 1 addition & 0 deletions arch/csky/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
config CSKY
def_bool y
select ARCH_32BIT_OFF_T
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_SYNC_DMA_FOR_CPU
Expand Down
9 changes: 9 additions & 0 deletions arch/csky/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_CSKY_CACHETYPE_H
#define __ASM_CSKY_CACHETYPE_H

#include <linux/types.h>

#define cpu_dcache_is_aliasing() true

#endif
1 change: 1 addition & 0 deletions arch/m68k/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ config M68K
bool
default y
select ARCH_32BIT_OFF_T
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER
Expand Down
9 changes: 9 additions & 0 deletions arch/m68k/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_M68K_CACHETYPE_H
#define __ASM_M68K_CACHETYPE_H

#include <linux/types.h>

#define cpu_dcache_is_aliasing() true

#endif
1 change: 1 addition & 0 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ config MIPS
default y
select ARCH_32BIT_OFF_T if !64BIT
select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER if !CC_IS_CLANG || CLANG_VERSION >= 140000
select ARCH_HAS_DEBUG_VIRTUAL if !64BIT
Expand Down
9 changes: 9 additions & 0 deletions arch/mips/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MIPS_CACHETYPE_H
#define __ASM_MIPS_CACHETYPE_H

#include <asm/cpu-features.h>

#define cpu_dcache_is_aliasing() cpu_has_dc_aliases

#endif
1 change: 1 addition & 0 deletions arch/nios2/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
config NIOS2
def_bool y
select ARCH_32BIT_OFF_T
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
Expand Down
10 changes: 10 additions & 0 deletions arch/nios2/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_NIOS2_CACHETYPE_H
#define __ASM_NIOS2_CACHETYPE_H

#include <asm/page.h>
#include <asm/cache.h>

#define cpu_dcache_is_aliasing() (NIOS2_DCACHE_SIZE > PAGE_SIZE)

#endif
1 change: 1 addition & 0 deletions arch/parisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ config PARISC
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_SYSCALL_TRACEPOINTS
select ARCH_WANT_FRAME_POINTERS
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_DMA_ALLOC if PA11
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_STRICT_KERNEL_RWX
Expand Down
9 changes: 9 additions & 0 deletions arch/parisc/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_PARISC_CACHETYPE_H
#define __ASM_PARISC_CACHETYPE_H

#include <linux/types.h>

#define cpu_dcache_is_aliasing() true

#endif
1 change: 1 addition & 0 deletions arch/sh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
config SUPERH
def_bool y
select ARCH_32BIT_OFF_T
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM && MMU
select ARCH_ENABLE_MEMORY_HOTREMOVE if SPARSEMEM && MMU
select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
Expand Down
9 changes: 9 additions & 0 deletions arch/sh/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_SH_CACHETYPE_H
#define __ASM_SH_CACHETYPE_H

#include <linux/types.h>

#define cpu_dcache_is_aliasing() true

#endif
1 change: 1 addition & 0 deletions arch/sparc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ config 64BIT
config SPARC
bool
default y
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_MIGHT_HAVE_PC_PARPORT if SPARC64 && PCI
select ARCH_MIGHT_HAVE_PC_SERIO
select DMA_OPS
Expand Down
14 changes: 14 additions & 0 deletions arch/sparc/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_SPARC_CACHETYPE_H
#define __ASM_SPARC_CACHETYPE_H

#include <asm/page.h>

#ifdef CONFIG_SPARC32
extern int vac_cache_size;
#define cpu_dcache_is_aliasing() (vac_cache_size > PAGE_SIZE)
#else
#define cpu_dcache_is_aliasing() (L1DCACHE_SIZE > PAGE_SIZE)
#endif

#endif
1 change: 1 addition & 0 deletions arch/xtensa/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
config XTENSA
def_bool y
select ARCH_32BIT_OFF_T
select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_BINFMT_FLAT if !MMU
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VM_PGTABLE
Expand Down
10 changes: 10 additions & 0 deletions arch/xtensa/include/asm/cachetype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_XTENSA_CACHETYPE_H
#define __ASM_XTENSA_CACHETYPE_H

#include <asm/cache.h>
#include <asm/page.h>

#define cpu_dcache_is_aliasing() (DCACHE_WAY_SIZE > PAGE_SIZE)

#endif
6 changes: 6 additions & 0 deletions include/linux/cacheinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,10 @@ static inline int get_cpu_cacheinfo_id(int cpu, int level)
#define use_arch_cache_info() (false)
#endif

#ifndef CONFIG_ARCH_HAS_CPU_CACHE_ALIASING
#define cpu_dcache_is_aliasing() false
#else
#include <asm/cachetype.h>
#endif

#endif /* _LINUX_CACHEINFO_H */
6 changes: 6 additions & 0 deletions mm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,12 @@ config IDLE_PAGE_TRACKING
See Documentation/admin-guide/mm/idle_page_tracking.rst for
more details.

# Architectures which implement cpu_dcache_is_aliasing() to query
# whether the data caches are aliased (VIVT or VIPT with dcache
# aliasing) need to select this.
config ARCH_HAS_CPU_CACHE_ALIASING
bool

config ARCH_HAS_CACHE_LINE_SIZE
bool

Expand Down

0 comments on commit 8690bbc

Please sign in to comment.