From 6657edecc8dd4f294c42339645151006f60b3811 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 30 Nov 2020 11:11:39 -0500 Subject: [PATCH] Introduce lttng smp_store_release smp_load_acquire wrappers Kernels prior to 3.14 do not implement smp_store_release nor smp_load_acquire. Implement our own wrappers with smp_mb instead for those older kernels. Signed-off-by: Mathieu Desnoyers --- include/wrapper/barrier.h | 47 +++++++++++++++++++++++++ src/lttng-abi.c | 3 +- src/lttng-event-notifier-notification.c | 5 +-- 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 include/wrapper/barrier.h diff --git a/include/wrapper/barrier.h b/include/wrapper/barrier.h new file mode 100644 index 00000000..c2f0545b --- /dev/null +++ b/include/wrapper/barrier.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * wrapper/barrier.h + * + * wrapper around asm/barrier.h. + * + * Copyright (C) 2020 Mathieu Desnoyers + */ + +#ifndef _LTTNG_WRAPPER_BARRIER_H +#define _LTTNG_WRAPPER_BARRIER_H + +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) + +#define lttng_smp_store_release(x, v) smp_store_release(x, v) +#define lttng_smp_load_acquire(x) smp_load_acquire(x) + +#else + +/* + * Acquire-release semantics act as a one-way permeable barrier when + * pairing a store with a release. Use a full memory barrier to emulate + * the acquire-release semantic with a stronger barrier on older + * kernels. + */ + +#define lttng_smp_store_release(x, v) \ + do { \ + smp_mb(); \ + ACCESS_ONCE(*(x)) = (v); \ + } while (0) + +#define lttng_smp_load_acquire(x) \ + ({ \ + __typeof__(*(x)) ___ret; \ + \ + ___ret = ACCESS_ONCE(*(x)); \ + smp_mb(); \ + ___ret; \ + }) + +#endif + +#endif /* _LTTNG_WRAPPER_BARRIER_H */ diff --git a/src/lttng-abi.c b/src/lttng-abi.c index 83853436..7096daf7 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -2150,7 +2151,7 @@ long lttng_abi_event_notifier_group_create_error_counter( * in record_error. Ensures the counter is created and the * error_counter_len is set before they are used. */ - smp_store_release(&event_notifier_group->error_counter, counter); + lttng_smp_store_release(&event_notifier_group->error_counter, counter); counter->file = counter_file; counter->owner = event_notifier_group->file; diff --git a/src/lttng-event-notifier-notification.c b/src/lttng-event-notifier-notification.c index 77e72842..52b5593a 100644 --- a/src/lttng-event-notifier-notification.c +++ b/src/lttng-event-notifier-notification.c @@ -11,6 +11,7 @@ #include #include #include +#include /* * The capture buffer size needs to be below 1024 bytes to avoid the @@ -357,11 +358,11 @@ void record_error(struct lttng_event_notifier *event_notifier) int ret; /* - * smp_load_acquire paired with smp_store_release orders + * lttng_smp_load_acquire paired with lttng_smp_store_release orders * creation of the error counter and setting error_counter_len * before the error_counter is used. */ - error_counter = smp_load_acquire(&event_notifier_group->error_counter); + error_counter = lttng_smp_load_acquire(&event_notifier_group->error_counter); /* This group may not have an error counter attached to it. */ if (!error_counter) return; -- 2.34.1