126 lines
4.0 KiB
Diff
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
|
|
|