]> git.baikalelectronics.ru Git - kernel.git/commitdiff
asm-generic: introduce io_stop_wc() and add implementation for ARM64
authorXiongfeng Wang <wangxiongfeng2@huawei.com>
Tue, 21 Dec 2021 03:55:56 +0000 (11:55 +0800)
committerCatalin Marinas <catalin.marinas@arm.com>
Wed, 22 Dec 2021 10:44:53 +0000 (10:44 +0000)
For memory accesses with write-combining attributes (e.g. those returned
by ioremap_wc()), the CPU may wait for prior accesses to be merged with
subsequent ones. But in some situation, such wait is bad for the
performance.

We introduce io_stop_wc() to prevent the merging of write-combining
memory accesses before this macro with those after it.

We add implementation for ARM64 using DGH instruction and provide NOP
implementation for other architectures.

Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Suggested-by: Will Deacon <will@kernel.org>
Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20211221035556.60346-1-wangxiongfeng2@huawei.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Documentation/memory-barriers.txt
arch/arm64/include/asm/barrier.h
include/asm-generic/barrier.h

index 7367ada13208c7338f4724d4fa986ebde780b85c..b12df9137e1c176f841f270f7829bdd1fa34e728 100644 (file)
@@ -1950,6 +1950,14 @@ There are some more advanced barrier functions:
      For load from persistent memory, existing read memory barriers are sufficient
      to ensure read ordering.
 
+ (*) io_stop_wc();
+
+     For memory accesses with write-combining attributes (e.g. those returned
+     by ioremap_wc(), the CPU may wait for prior accesses to be merged with
+     subsequent ones. io_stop_wc() can be used to prevent the merging of
+     write-combining memory accesses before this macro with those after it when
+     such wait has performance implications.
+
 ===============================
 IMPLICIT KERNEL MEMORY BARRIERS
 ===============================
index 1c5a005984582ed600fd7df3924383208c0dc1ef..62217be36217340248550ed10834587e4a4dbe4c 100644 (file)
 #define __tsb_csync()  asm volatile("hint #18" : : : "memory")
 #define csdb()         asm volatile("hint #20" : : : "memory")
 
+/*
+ * Data Gathering Hint:
+ * This instruction prevents merging memory accesses with Normal-NC or
+ * Device-GRE attributes before the hint instruction with any memory accesses
+ * appearing after the hint instruction.
+ */
+#define dgh()          asm volatile("hint #6" : : : "memory")
+
 #ifdef CONFIG_ARM64_PSEUDO_NMI
 #define pmr_sync()                                             \
        do {                                                    \
@@ -46,6 +54,7 @@
 #define dma_rmb()      dmb(oshld)
 #define dma_wmb()      dmb(oshst)
 
+#define io_stop_wc()   dgh()
 
 #define tsb_csync()                                                            \
        do {                                                                    \
index 640f09479bdf7984799d7ecdf40d7da17d83e26c..4c2c1b8303442d346b156d3e6a09e0f3fa4f0691 100644 (file)
@@ -251,5 +251,16 @@ do {                                                                       \
 #define pmem_wmb()     wmb()
 #endif
 
+/*
+ * ioremap_wc() maps I/O memory as memory with write-combining attributes. For
+ * this kind of memory accesses, the CPU may wait for prior accesses to be
+ * merged with subsequent ones. In some situation, such wait is bad for the
+ * performance. io_stop_wc() can be used to prevent the merging of
+ * write-combining memory accesses before this macro with those after it.
+ */
+#ifndef io_stop_wc
+#define io_stop_wc do { } while (0)
+#endif
+
 #endif /* !__ASSEMBLY__ */
 #endif /* __ASM_GENERIC_BARRIER_H */