x86: Stop using weak symbols for __iowrite32_copy()
authorJason Gunthorpe <jgg@nvidia.com>
Thu, 11 Apr 2024 16:46:14 +0000 (13:46 -0300)
committerJason Gunthorpe <jgg@nvidia.com>
Mon, 22 Apr 2024 20:11:19 +0000 (17:11 -0300)
Start switching iomap_copy routines over to use #define and arch provided
inline/macro functions instead of weak symbols.

Inline functions allow more compiler optimization and this is often a
driver hot path.

x86 has the only weak implementation for __iowrite32_copy(), so replace it
with a static inline containing the same single instruction inline
assembly. The compiler will generate the "mov edx,ecx" in a more optimal
way.

Remove iomap_copy_64.S

Link: https://lore.kernel.org/r/1-v3-1893cd8b9369+1925-mlx5_arm_wc_jgg@nvidia.com
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
arch/x86/include/asm/io.h
arch/x86/lib/Makefile
arch/x86/lib/iomap_copy_64.S [deleted file]
include/linux/io.h
lib/iomap_copy.c

index 294cd2a40818129a1032f24b7d3ba89a99258e23..4b99ed326b17489cc0df9b13328a5425b7196f2d 100644 (file)
@@ -209,6 +209,23 @@ void memset_io(volatile void __iomem *, int, size_t);
 #define memcpy_toio memcpy_toio
 #define memset_io memset_io
 
+#ifdef CONFIG_X86_64
+/*
+ * Commit 0f07496144c2 ("[PATCH] Add faster __iowrite32_copy routine for
+ * x86_64") says that circa 2006 rep movsl is noticeably faster than a copy
+ * loop.
+ */
+static inline void __iowrite32_copy(void __iomem *to, const void *from,
+                                   size_t count)
+{
+       asm volatile("rep ; movsl"
+                    : "=&c"(count), "=&D"(to), "=&S"(from)
+                    : "0"(count), "1"(to), "2"(from)
+                    : "memory");
+}
+#define __iowrite32_copy __iowrite32_copy
+#endif
+
 /*
  * ISA space is 'always mapped' on a typical x86 system, no need to
  * explicitly ioremap() it. The fact that the ISA IO space is mapped
index 6da73513f02668ab5c178b3f5a01668691b79403..98583a9dbab337e09a2e58905e5200499a496a07 100644 (file)
@@ -53,7 +53,6 @@ ifneq ($(CONFIG_X86_CMPXCHG64),y)
         lib-y += atomic64_386_32.o
 endif
 else
-        obj-y += iomap_copy_64.o
 ifneq ($(CONFIG_GENERIC_CSUM),y)
         lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
 endif
diff --git a/arch/x86/lib/iomap_copy_64.S b/arch/x86/lib/iomap_copy_64.S
deleted file mode 100644 (file)
index 6ff2f56..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright 2006 PathScale, Inc.  All Rights Reserved.
- */
-
-#include <linux/linkage.h>
-
-/*
- * override generic version in lib/iomap_copy.c
- */
-SYM_FUNC_START(__iowrite32_copy)
-       movl %edx,%ecx
-       rep movsl
-       RET
-SYM_FUNC_END(__iowrite32_copy)
index 235ba7d80a8f0d76e9d33b772226ebab40bfe8fd..ce86120ce9d52677aadb407ce0f4e21e3ce0d677 100644 (file)
 struct device;
 struct resource;
 
-__visible void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
+#ifndef __iowrite32_copy
+void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
+#endif
+
 void __ioread32_copy(void *to, const void __iomem *from, size_t count);
 void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
 
index 5de7c04e05ef56f53e15430f6882eac4fb55113d..8ddcbb53507dfe1546e6740db874a1d815f62073 100644 (file)
@@ -16,9 +16,8 @@
  * time.  Order of access is not guaranteed, nor is a memory barrier
  * performed afterwards.
  */
-void __attribute__((weak)) __iowrite32_copy(void __iomem *to,
-                                           const void *from,
-                                           size_t count)
+#ifndef __iowrite32_copy
+void __iowrite32_copy(void __iomem *to, const void *from, size_t count)
 {
        u32 __iomem *dst = to;
        const u32 *src = from;
@@ -28,6 +27,7 @@ void __attribute__((weak)) __iowrite32_copy(void __iomem *to,
                __raw_writel(*src++, dst++);
 }
 EXPORT_SYMBOL_GPL(__iowrite32_copy);
+#endif
 
 /**
  * __ioread32_copy - copy data from MMIO space, in 32-bit units