This patch series is to refine the memory barriers for AUX ring buffer.
Patches 01 ~ 04 to address the barriers usage in the kernel. The first
patch is to make clear comment for how to use the barriers between the
data store and aux_head store, this asks the driver to make sure the
data is visible. Patches 02 ~ 04 is to refine the drivers for barriers
after the data store.
Patch 05 is to use WRITE_ONCE() for updating aux_tail.
Patches 06 ~ 09 is to drop the legacy __sync functions, and polish for
duplicate code and cleanup the build and feature test after
SYNC_COMPARE_AND_SWAP is not used.
For easier review and more clear patch organization, comparing against
to the previous patch series, the patches for support compat mode for
AUX trace have been left out and will be sent out as a separate patch
set.
This patch set have been tested on Arm64 Juno platform.
Changes from v4:
- Refined comment for CoreSight ETR/ETF drivers (Suzuki/Peter);
- Changed to use compiler barrier for BTS (mentioned by Peter, but have
not received response from Intel developer);
- Refined the coding style for patch 07 (Adrian).
Changes from v3:
- Removed the inapprocate paragraph in the commit log for patch "perf
auxtrace: Drop legacy __sync functions" (Adrian);
- Added new patch to remove feature-sync-compare-and-swap test (Adrian);
- Th patch for "perf auxtrace: Use WRITE_ONCE() for updating aux_tail",
is a standlone and simple change, so moved it ahead in the patch set
for better ordering;
- Minor improvement for commit logs in the last two patches.
Changes from v2:
- Removed auxtrace_mmap__read_snapshot_head(), which has the duplicated
code with auxtrace_mmap__read_head();
- Cleanuped the build for HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT (Adrian);
- Added global variable "kernel_is_64_bit" (Adrian);
- Added compat variants compat_auxtrace_mmap__{read_head|write_tail}
(Adrian).
Leo Yan (9):
perf/ring_buffer: Add comment for barriers on AUX ring buffer
coresight: tmc-etr: Add barrier after updating AUX ring buffer
coresight: tmc-etf: Add comment for store ordering
perf/x86: Add compiler barrier after updating BTS
perf auxtrace: Use WRITE_ONCE() for updating aux_tail
perf auxtrace: Drop legacy __sync functions
perf auxtrace: Remove auxtrace_mmap__read_snapshot_head()
perf: Cleanup for HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT
tools: Remove feature-sync-compare-and-swap feature detection
arch/x86/events/intel/bts.c | 6 ++++
.../hwtracing/coresight/coresight-tmc-etf.c | 5 +++
.../hwtracing/coresight/coresight-tmc-etr.c | 8 +++++
kernel/events/ring_buffer.c | 9 ++++++
tools/build/Makefile.feature | 1 -
tools/build/feature/Makefile | 4 ---
tools/build/feature/test-all.c | 4 ---
.../feature/test-sync-compare-and-swap.c | 15 ---------
tools/perf/Makefile.config | 4 ---
tools/perf/util/auxtrace.c | 18 +++--------
tools/perf/util/auxtrace.h | 31 +------------------
11 files changed, 34 insertions(+), 71 deletions(-)
delete mode 100644 tools/build/feature/test-sync-compare-and-swap.c
--
2.25.1
AUX ring buffer applies almost the same barriers as perf ring buffer,
but there has an exception for ordering between writing the AUX trace
data and updating user_page::aux_head.
This patch adds comment for how to use the barriers on AUX ring buffer,
and gives comment to ask the drivers to flush the trace data into AUX
ring buffer prior to updating user_page::aux_head.
Signed-off-by: Leo Yan <redacted>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
kernel/events/ring_buffer.c | 9 +++++++++
1 file changed, 9 insertions(+)
Since a memory barrier is required between AUX trace data store and
aux_head store, and the AUX trace data is filled with memcpy(), it's
sufficient to use smp_wmb() so can ensure the trace data is visible
prior to updating aux_head.
Signed-off-by: Leo Yan <redacted>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
drivers/hwtracing/coresight/coresight-tmc-etr.c | 8 ++++++++
1 file changed, 8 insertions(+)
Since the function CS_LOCK() has contained memory barrier mb(), it
ensures the visibility of the AUX trace data before updating the
aux_head, thus it's needless to add any explicit barrier anymore.
Add comment to make clear for the barrier usage for ETF.
Signed-off-by: Leo Yan <redacted>
---
drivers/hwtracing/coresight/coresight-tmc-etf.c | 5 +++++
1 file changed, 5 insertions(+)
Since BTS is coherent, simply add a compiler barrier to separate the BTS
update and aux_head store.
Signed-off-by: Leo Yan <redacted>
---
arch/x86/events/intel/bts.c | 6 ++++++
1 file changed, 6 insertions(+)
Use WRITE_ONCE() for updating aux_tail, so can avoid unexpected memory
behaviour.
Signed-off-by: Leo Yan <redacted>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
tools/perf/util/auxtrace.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -480,7 +480,7 @@ static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)/* Ensure all reads are done before we write the tail out */smp_mb();#if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)-pc->aux_tail=tail;+WRITE_ONCE(pc->aux_tail,tail);#elsedo{old_tail=__sync_val_compare_and_swap(&pc->aux_tail,0,0);
The main purpose for using __sync built-in functions is to support
compat mode for 32-bit perf with 64-bit kernel. But using these
built-in functions might cause potential issues.
__sync functions originally support Intel Itanium processoer [1]
but it cannot promise to support all 32-bit archs. Now these
functions have become the legacy functions.
Considering __sync functions cannot really fix the 64-bit value
atomicity on 32-bit archs, thus this patch drops __sync functions.
Credits to Peter for detailed analysis.
[1] https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Leo Yan <redacted>
---
tools/perf/util/auxtrace.h | 19 -------------------
1 file changed, 19 deletions(-)
@@ -459,11 +453,7 @@ static inline u64 auxtrace_mmap__read_snapshot_head(struct auxtrace_mmap *mm)staticinlineu64auxtrace_mmap__read_head(structauxtrace_mmap*mm){structperf_event_mmap_page*pc=mm->userpg;-#if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)u64head=READ_ONCE(pc->aux_head);-#else-u64head=__sync_val_compare_and_swap(&pc->aux_head,0,0);-#endif/* Ensure all reads are done after we read the head */smp_rmb();
@@ -473,19 +463,10 @@ static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)staticinlinevoidauxtrace_mmap__write_tail(structauxtrace_mmap*mm,u64tail){structperf_event_mmap_page*pc=mm->userpg;-#if BITS_PER_LONG != 64 && defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)-u64old_tail;-#endif/* Ensure all reads are done before we write the tail out */smp_mb();-#if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)WRITE_ONCE(pc->aux_tail,tail);-#else-do{-old_tail=__sync_val_compare_and_swap(&pc->aux_tail,0,0);-}while(!__sync_bool_compare_and_swap(&pc->aux_tail,old_tail,tail));-#endif}intauxtrace_mmap__mmap(structauxtrace_mmap*mm,
Since the function auxtrace_mmap__read_snapshot_head() is exactly same
with auxtrace_mmap__read_head(), whether the session is in snapshot mode
or not, it's unified to use function auxtrace_mmap__read_head() for
reading AUX buffer head.
And the function auxtrace_mmap__read_snapshot_head() is unused so this
patch removes it.
Signed-off-by: Leo Yan <redacted>
---
tools/perf/util/auxtrace.c | 13 +++++--------
tools/perf/util/auxtrace.h | 10 ----------
2 files changed, 5 insertions(+), 18 deletions(-)
@@ -440,16 +440,6 @@ struct auxtrace_cache;#ifdef HAVE_AUXTRACE_SUPPORT-staticinlineu64auxtrace_mmap__read_snapshot_head(structauxtrace_mmap*mm)-{-structperf_event_mmap_page*pc=mm->userpg;-u64head=READ_ONCE(pc->aux_head);--/* Ensure all reads are done after we read the head */-smp_rmb();-returnhead;-}-staticinlineu64auxtrace_mmap__read_head(structauxtrace_mmap*mm){structperf_event_mmap_page*pc=mm->userpg;
Since the __sync functions have been dropped, This patch removes unused
build and checking for HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT in perf tool.
Signed-off-by: Leo Yan <redacted>
---
tools/perf/Makefile.config | 4 ----
tools/perf/util/auxtrace.c | 5 -----
2 files changed, 9 deletions(-)
@@ -130,11 +130,6 @@ int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,return0;}-#if BITS_PER_LONG != 64 && !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)-pr_err("Cannot use AUX area tracing mmaps\n");-return-1;-#endif-pc->aux_offset=mp->offset;pc->aux_size=mp->len;
Since the __sync functions have been removed from perf, it's needless
for perf tool to test the feature sync-compare-and-swap.
The feature test is not used by any other components, remove it.
Signed-off-by: Leo Yan <redacted>
---
tools/build/Makefile.feature | 1 -
tools/build/feature/Makefile | 4 ----
tools/build/feature/test-all.c | 4 ----
tools/build/feature/test-sync-compare-and-swap.c | 15 ---------------
4 files changed, 24 deletions(-)
delete mode 100644 tools/build/feature/test-sync-compare-and-swap.c
@@ -106,10 +106,6 @@#include"test-libdw-dwarf-unwind.c"#undef main-#define main main_test_sync_compare_and_swap-#include"test-sync-compare-and-swap.c"-#undef main-#define main main_test_zlib#include"test-zlib.c"#undef main
@@ -480,7 +480,7 @@ static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)/* Ensure all reads are done before we write the tail out */smp_mb();#if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)-pc->aux_tail=tail;+WRITE_ONCE(pc->aux_tail,tail);#elsedo{old_tail=__sync_val_compare_and_swap(&pc->aux_tail,0,0);
From: Arnaldo Carvalho de Melo <acme@kernel.org> Date: 2021-08-09 20:00:32
Em Mon, Aug 09, 2021 at 07:14:04PM +0800, Leo Yan escreveu:
The main purpose for using __sync built-in functions is to support
compat mode for 32-bit perf with 64-bit kernel. But using these
built-in functions might cause potential issues.
__sync functions originally support Intel Itanium processoer [1]
but it cannot promise to support all 32-bit archs. Now these
functions have become the legacy functions.
Considering __sync functions cannot really fix the 64-bit value
atomicity on 32-bit archs, thus this patch drops __sync functions.
Credits to Peter for detailed analysis.
@@ -459,11 +453,7 @@ static inline u64 auxtrace_mmap__read_snapshot_head(struct auxtrace_mmap *mm)staticinlineu64auxtrace_mmap__read_head(structauxtrace_mmap*mm){structperf_event_mmap_page*pc=mm->userpg;-#if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)u64head=READ_ONCE(pc->aux_head);-#else-u64head=__sync_val_compare_and_swap(&pc->aux_head,0,0);-#endif/* Ensure all reads are done after we read the head */smp_rmb();
@@ -473,19 +463,10 @@ static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)staticinlinevoidauxtrace_mmap__write_tail(structauxtrace_mmap*mm,u64tail){structperf_event_mmap_page*pc=mm->userpg;-#if BITS_PER_LONG != 64 && defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)-u64old_tail;-#endif/* Ensure all reads are done before we write the tail out */smp_mb();-#if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)WRITE_ONCE(pc->aux_tail,tail);-#else-do{-old_tail=__sync_val_compare_and_swap(&pc->aux_tail,0,0);-}while(!__sync_bool_compare_and_swap(&pc->aux_tail,old_tail,tail));-#endif}intauxtrace_mmap__mmap(structauxtrace_mmap*mm,
From: Arnaldo Carvalho de Melo <acme@kernel.org> Date: 2021-08-09 20:01:42
Em Mon, Aug 09, 2021 at 07:14:05PM +0800, Leo Yan escreveu:
Since the function auxtrace_mmap__read_snapshot_head() is exactly same
with auxtrace_mmap__read_head(), whether the session is in snapshot mode
or not, it's unified to use function auxtrace_mmap__read_head() for
reading AUX buffer head.
And the function auxtrace_mmap__read_snapshot_head() is unused so this
patch removes it.
Thanks, applied to perf/core.
- Arnaldo
quoted hunk
Signed-off-by: Leo Yan <redacted>
---
tools/perf/util/auxtrace.c | 13 +++++--------
tools/perf/util/auxtrace.h | 10 ----------
2 files changed, 5 insertions(+), 18 deletions(-)
@@ -440,16 +440,6 @@ struct auxtrace_cache;#ifdef HAVE_AUXTRACE_SUPPORT-staticinlineu64auxtrace_mmap__read_snapshot_head(structauxtrace_mmap*mm)-{-structperf_event_mmap_page*pc=mm->userpg;-u64head=READ_ONCE(pc->aux_head);--/* Ensure all reads are done after we read the head */-smp_rmb();-returnhead;-}-staticinlineu64auxtrace_mmap__read_head(structauxtrace_mmap*mm){structperf_event_mmap_page*pc=mm->userpg;
@@ -130,11 +130,6 @@ int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,return0;}-#if BITS_PER_LONG != 64 && !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT)-pr_err("Cannot use AUX area tracing mmaps\n");-return-1;-#endif-pc->aux_offset=mp->offset;pc->aux_size=mp->len;
From: Arnaldo Carvalho de Melo <acme@kernel.org> Date: 2021-08-09 20:02:31
Em Mon, Aug 09, 2021 at 07:14:07PM +0800, Leo Yan escreveu:
Since the __sync functions have been removed from perf, it's needless
for perf tool to test the feature sync-compare-and-swap.
The feature test is not used by any other components, remove it.
@@ -106,10 +106,6 @@#include"test-libdw-dwarf-unwind.c"#undef main-#define main main_test_sync_compare_and_swap-#include"test-sync-compare-and-swap.c"-#undef main-#define main main_test_zlib#include"test-zlib.c"#undef main
Hi Peter,
On Mon, Aug 09, 2021 at 07:13:59PM +0800, Leo Yan wrote:
AUX ring buffer applies almost the same barriers as perf ring buffer,
but there has an exception for ordering between writing the AUX trace
data and updating user_page::aux_head.
This patch adds comment for how to use the barriers on AUX ring buffer,
and gives comment to ask the drivers to flush the trace data into AUX
ring buffer prior to updating user_page::aux_head.
Signed-off-by: Leo Yan <redacted>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
You have given the ACK tag before, could you pick up this patch?
Thanks,
Leo
Hi Mathieu, Suzuki,
On Mon, Aug 09, 2021 at 07:14:00PM +0800, Leo Yan wrote:
Since a memory barrier is required between AUX trace data store and
aux_head store, and the AUX trace data is filled with memcpy(), it's
sufficient to use smp_wmb() so can ensure the trace data is visible
prior to updating aux_head.
Signed-off-by: Leo Yan <redacted>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Could you pick up patches 02 and 03 in this series? Please note,
patch 02 has the review tag from Suzuki, but I didn't receive the
review tag for patch 03.
If anything need to follow up, just let me know. Thanks!
From: Suzuki K Poulose <suzuki.poulose@arm.com> Date: 2021-09-14 08:24:26
On 09/08/2021 12:14, Leo Yan wrote:
quoted hunk
Since the function CS_LOCK() has contained memory barrier mb(), it
ensures the visibility of the AUX trace data before updating the
aux_head, thus it's needless to add any explicit barrier anymore.
Add comment to make clear for the barrier usage for ETF.
Signed-off-by: Leo Yan <redacted>
---
drivers/hwtracing/coresight/coresight-tmc-etf.c | 5 +++++
1 file changed, 5 insertions(+)
From: Suzuki K Poulose <suzuki.poulose@arm.com> Date: 2021-09-14 09:08:57
On 29/08/2021 11:55, Leo Yan wrote:
Hi Mathieu, Suzuki,
On Mon, Aug 09, 2021 at 07:14:00PM +0800, Leo Yan wrote:
quoted
Since a memory barrier is required between AUX trace data store and
aux_head store, and the AUX trace data is filled with memcpy(), it's
sufficient to use smp_wmb() so can ensure the trace data is visible
prior to updating aux_head.
Signed-off-by: Leo Yan <redacted>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Could you pick up patches 02 and 03 in this series? Please note,
patch 02 has the review tag from Suzuki, but I didn't receive the
review tag for patch 03.
If anything need to follow up, just let me know. Thanks!