diff mbox series

[v7,01/17] mm/slab: Decouple ARCH_KMALLOC_MINALIGN from ARCH_DMA_MINALIGN

Message ID 20230612153201.554742-2-catalin.marinas@arm.com (mailing list archive)
State New
Headers show
Series mm, dma, arm64: Reduce ARCH_KMALLOC_MINALIGN to 8 | expand

Commit Message

Catalin Marinas June 12, 2023, 3:31 p.m. UTC
In preparation for supporting a kmalloc() minimum alignment smaller than
the arch DMA alignment, decouple the two definitions. This requires that
either the kmalloc() caches are aligned to a (run-time) cache-line size
or the DMA API bounces unaligned kmalloc() allocations. Subsequent
patches will implement both options.

After this patch, ARCH_DMA_MINALIGN is expected to be used in static
alignment annotations and defined by an architecture to be the maximum
alignment for all supported configurations/SoCs in a single Image.
Architectures opting in to a smaller ARCH_KMALLOC_MINALIGN will need to
define its value in the arch headers.

Since ARCH_DMA_MINALIGN is now always defined, adjust the #ifdef in
dma_get_cache_alignment() so that there is no change for architectures
not requiring a minimum DMA alignment.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Robin Murphy <robin.murphy@arm.com>
Tested-by: Isaac J. Manjarres <isaacmanjarres@google.com>
---
 include/linux/cache.h       |  6 ++++++
 include/linux/dma-mapping.h |  3 ++-
 include/linux/slab.h        | 14 ++++++++++----
 3 files changed, 18 insertions(+), 5 deletions(-)

Comments

Vlastimil Babka June 13, 2023, 9:46 a.m. UTC | #1
On 6/12/23 17:31, Catalin Marinas wrote:
> In preparation for supporting a kmalloc() minimum alignment smaller than
> the arch DMA alignment, decouple the two definitions. This requires that
> either the kmalloc() caches are aligned to a (run-time) cache-line size
> or the DMA API bounces unaligned kmalloc() allocations. Subsequent
> patches will implement both options.
> 
> After this patch, ARCH_DMA_MINALIGN is expected to be used in static
> alignment annotations and defined by an architecture to be the maximum
> alignment for all supported configurations/SoCs in a single Image.
> Architectures opting in to a smaller ARCH_KMALLOC_MINALIGN will need to
> define its value in the arch headers.
> 
> Since ARCH_DMA_MINALIGN is now always defined, adjust the #ifdef in
> dma_get_cache_alignment() so that there is no change for architectures
> not requiring a minimum DMA alignment.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Vlastimil Babka <vbabka@suse.cz>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Tested-by: Isaac J. Manjarres <isaacmanjarres@google.com>

Acked-by: Vlastimil Babka <vbabka@suse.cz>
Catalin Marinas June 13, 2023, 11:13 a.m. UTC | #2
On Tue, Jun 13, 2023 at 11:46:31AM +0200, Vlastimil Babka wrote:
> On 6/12/23 17:31, Catalin Marinas wrote:
> > In preparation for supporting a kmalloc() minimum alignment smaller than
> > the arch DMA alignment, decouple the two definitions. This requires that
> > either the kmalloc() caches are aligned to a (run-time) cache-line size
> > or the DMA API bounces unaligned kmalloc() allocations. Subsequent
> > patches will implement both options.
> > 
> > After this patch, ARCH_DMA_MINALIGN is expected to be used in static
> > alignment annotations and defined by an architecture to be the maximum
> > alignment for all supported configurations/SoCs in a single Image.
> > Architectures opting in to a smaller ARCH_KMALLOC_MINALIGN will need to
> > define its value in the arch headers.
> > 
> > Since ARCH_DMA_MINALIGN is now always defined, adjust the #ifdef in
> > dma_get_cache_alignment() so that there is no change for architectures
> > not requiring a minimum DMA alignment.
> > 
> > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Vlastimil Babka <vbabka@suse.cz>
> > Cc: Christoph Hellwig <hch@lst.de>
> > Cc: Robin Murphy <robin.murphy@arm.com>
> > Tested-by: Isaac J. Manjarres <isaacmanjarres@google.com>
> 
> Acked-by: Vlastimil Babka <vbabka@suse.cz>

Thanks for the ack.

It looks like moving the ARCH_DMA_MINALIGN definition to linux/cache.h
messes up powerpc32 -
https://lore.kernel.org/r/202306131053.1ybvRRhO-lkp@intel.com - possibly
a few other architecture that define this macro in a file other than
asm/cache.h (I only tested powerpc64 before posting).

At a quick grep, we have:

  arch/microblaze/include/asm/page.h:34: #define ARCH_DMA_MINALIGN       L1_CACHE_BYTES

This could be moved to asm/cache.h. It probably already relies on some
indirect includes.

  arch/mips/include/asm/mach-generic/kmalloc.h:10: #define ARCH_DMA_MINALIGN       128
  arch/mips/include/asm/mach-ip32/kmalloc.h:7: #define ARCH_DMA_MINALIGN       32
  arch/mips/include/asm/mach-ip32/kmalloc.h:9: #define ARCH_DMA_MINALIGN       128
  arch/mips/include/asm/mach-n64/kmalloc.h:6: #define ARCH_DMA_MINALIGN L1_CACHE_BYTES
  arch/mips/include/asm/mach-tx49xx/kmalloc.h:5: #define ARCH_DMA_MINALIGN L1_CACHE_BYTES

These are ok since kmalloc.h is included in asm/cache.h.

  arch/powerpc/include/asm/page_32.h:16: #define ARCH_DMA_MINALIGN       L1_CACHE_BYTES

I'd move this macro to asm/cache.h on powerpc. asm/page_32.h already
includes asm/cache.h.

  arch/sh/include/asm/page.h:181: #define ARCH_DMA_MINALIGN       L1_CACHE_BYTES

Same here. L1_CACHE_BYTES is defined in asm/cache.h but it's not
included in asm/page.h, so I guess it's relying on some indirect
includes.

I'll post three more patches to move the ARCH_DMA_MINALIGN to
asm/cache.h for microblaze, powerpc and sh (once I finished build
testing).
diff mbox series

Patch

diff --git a/include/linux/cache.h b/include/linux/cache.h
index 5da1bbd96154..9900d20b76c2 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -98,4 +98,10 @@  struct cacheline_padding {
 #define CACHELINE_PADDING(name)
 #endif
 
+#ifdef ARCH_DMA_MINALIGN
+#define ARCH_HAS_DMA_MINALIGN
+#else
+#define ARCH_DMA_MINALIGN __alignof__(unsigned long long)
+#endif
+
 #endif /* __LINUX_CACHE_H */
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 0ee20b764000..a50375331eac 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -2,6 +2,7 @@ 
 #ifndef _LINUX_DMA_MAPPING_H
 #define _LINUX_DMA_MAPPING_H
 
+#include <linux/cache.h>
 #include <linux/sizes.h>
 #include <linux/string.h>
 #include <linux/device.h>
@@ -545,7 +546,7 @@  static inline int dma_set_min_align_mask(struct device *dev,
 
 static inline int dma_get_cache_alignment(void)
 {
-#ifdef ARCH_DMA_MINALIGN
+#ifdef ARCH_HAS_DMA_MINALIGN
 	return ARCH_DMA_MINALIGN;
 #endif
 	return 1;
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 6b3e155b70bf..ca53425e9b32 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -12,6 +12,7 @@ 
 #ifndef _LINUX_SLAB_H
 #define	_LINUX_SLAB_H
 
+#include <linux/cache.h>
 #include <linux/gfp.h>
 #include <linux/overflow.h>
 #include <linux/types.h>
@@ -235,12 +236,17 @@  void kmem_dump_obj(void *object);
  * alignment larger than the alignment of a 64-bit integer.
  * Setting ARCH_DMA_MINALIGN in arch headers allows that.
  */
-#if defined(ARCH_DMA_MINALIGN) && ARCH_DMA_MINALIGN > 8
+#ifdef ARCH_HAS_DMA_MINALIGN
+#if ARCH_DMA_MINALIGN > 8 && !defined(ARCH_KMALLOC_MINALIGN)
 #define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN
-#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN
-#define KMALLOC_SHIFT_LOW ilog2(ARCH_DMA_MINALIGN)
-#else
+#endif
+#endif
+
+#ifndef ARCH_KMALLOC_MINALIGN
 #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
+#elif ARCH_KMALLOC_MINALIGN > 8
+#define KMALLOC_MIN_SIZE ARCH_KMALLOC_MINALIGN
+#define KMALLOC_SHIFT_LOW ilog2(KMALLOC_MIN_SIZE)
 #endif
 
 /*