rteval-loads/SOURCES/0011-Add-memory-barriers-an...

126 lines
4.0 KiB
Diff

From 9b173976fc1b6fa841cdc617aff26bedbef5282c Mon Sep 17 00:00:00 2001
From: Colin Ian King <colin.king@canonical.com>
Date: Tue, 19 May 2020 10:01:29 +0100
Subject: [PATCH 11/28] Add memory barriers an ready flag to check if counter
is in a sane state
The counter now is protected with a ready flag that is set to false
during the counter update. The ordering of the flag unset, counter
update and flag set is protected with memory barriers to enforce
strict ordering. Add a check at the end of the run to check if
the counter ready flag is in a sane state and fail with an error
if it is set incorrectly. Addresses concerns raised by ELISA.
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
stress-ng.c | 14 ++++++++++++++
stress-ng.h | 22 ++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/stress-ng.c b/stress-ng.c
index c57ab29b49e3..66ee5d15fa37 100644
--- a/stress-ng.c
+++ b/stress-ng.c
@@ -1766,6 +1766,7 @@ again:
if (keep_stressing_flag() && !(g_opt_flags & OPT_FLAGS_DRY_RUN)) {
const stress_args_t args = {
.counter = &stats->counter,
+ .counter_ready = &stats->counter_ready,
.name = name,
.max_ops = g_proc_current->bogo_ops,
.instance = j,
@@ -1775,6 +1776,9 @@ again:
.page_size = stress_get_pagesize(),
};
+ stats->counter_ready = true;
+ stats->counter = 0;
+
(void)memset(checksum, 0, sizeof(*checksum));
rc = g_proc_current->stressor->info->stressor(&args);
pr_fail_check(&rc);
@@ -1782,6 +1786,16 @@ again:
stats->run_ok = true;
checksum->data.run_ok = true;
}
+ /*
+ * Bogo ops counter should be OK for reading,
+ * if not then flag up that the counter may
+ * be untrustyworthy
+ */
+ if (!stats->counter_ready) {
+ pr_fail("%s: bogo-ops counter in non-read state, metrics are untrustworthy\n",
+ name);
+ rc = EXIT_FAILURE;
+ }
stats->checksum = checksum;
checksum->data.counter = *args.counter;
stress_hash_checksum(checksum);
diff --git a/stress-ng.h b/stress-ng.h
index 54986499503d..7449af0c161f 100644
--- a/stress-ng.h
+++ b/stress-ng.h
@@ -979,6 +979,7 @@ typedef uint32_t stress_class_t;
/* stressor args */
typedef struct {
uint64_t *const counter; /* stressor counter */
+ bool *counter_ready; /* counter can be read */
const char *name; /* stressor name */
const uint64_t max_ops; /* max number of bogo ops */
const uint32_t instance; /* stressor instance # */
@@ -1692,10 +1693,20 @@ extern void pr_dbg_lock(bool *locked, const char *fmt, ...) FORMAT(printf, 2, 3
#define HAVE_PRCTL_TIMER_SLACK
#endif
+static inline void ALWAYS_INLINE shim_mb(void)
+{
+ asm volatile ("" ::: "memory");
+}
+
/* increment the stessor bogo ops counter */
static inline void ALWAYS_INLINE inc_counter(const stress_args_t *args)
{
+ *args->counter_ready = false;
+ shim_mb();
(*(args->counter))++;
+ shim_mb();
+ *args->counter_ready = true;
+ shim_mb();
}
static inline uint64_t ALWAYS_INLINE get_counter(const stress_args_t *args)
@@ -1705,12 +1716,22 @@ static inline uint64_t ALWAYS_INLINE get_counter(const stress_args_t *args)
static inline void ALWAYS_INLINE set_counter(const stress_args_t *args, const uint64_t val)
{
+ *args->counter_ready = false;
+ shim_mb();
*args->counter = val;
+ shim_mb();
+ *args->counter_ready = true;
+ shim_mb();
}
static inline void ALWAYS_INLINE add_counter(const stress_args_t *args, const uint64_t inc)
{
+ *args->counter_ready = false;
+ shim_mb();
*args->counter += inc;
+ shim_mb();
+ *args->counter_ready = true;
+ shim_mb();
}
/* pthread porting shims, spinlock or fallback to mutex */
@@ -1842,6 +1863,7 @@ typedef struct {
/* Per process statistics and accounting info */
typedef struct {
uint64_t counter; /* number of bogo ops */
+ bool counter_ready; /* counter can be read */
struct tms tms; /* run time stats of process */
double start; /* wall clock start time */
double finish; /* wall clock stop time */
--
2.21.3