Skip to content

Commit

Permalink
asm-generic: introduce io_stop_wc() and add implementation for ARM64
Browse files Browse the repository at this point in the history
mainline inclusion
from mainline-v5.16-rc3
commit d5624bb
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4QKQ3
CVE: NA

----------------------

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>

 Conflicts:
	arch/arm64/include/asm/barrier.h
Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
  • Loading branch information
fenghusthu authored and notcarbide committed Mar 22, 2022
1 parent e112bea commit a32a1fd
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Documentation/memory-barriers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
===============================
Expand Down
10 changes: 10 additions & 0 deletions arch/arm64/include/asm/barrier.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
#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 { \
Expand All @@ -46,6 +54,8 @@
#define dma_rmb() dmb(oshld)
#define dma_wmb() dmb(oshst)

#define io_stop_wc() dgh()

/*
* Generate a mask for array_index__nospec() that is ~0UL when 0 <= idx < sz
* and 0 otherwise.
Expand Down
11 changes: 11 additions & 0 deletions include/asm-generic/barrier.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit a32a1fd

Please sign in to comment.