From: Cyril Bur <cyrilbur@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: leitao@debian.org, gromero@linux.vnet.ibm.com
Subject: [PATCH 2/2] selftests/powerpc: Calculate spin time in tm-unavailable
Date: Tue, 21 Nov 2017 18:17:20 +1100 [thread overview]
Message-ID: <20171121071720.24619-2-cyrilbur@gmail.com> (raw)
In-Reply-To: <20171121071720.24619-1-cyrilbur@gmail.com>
Currently the tm-unavailable test spins for a fixed amount of time in
an attempt to ensure the FPU/VMX/VSX facilities are off. This value was
experimentally tested to be long enough.
Problems may arise if kernel heuristics were to change. This patch
should future proof this test.
Signed-off-by: Cyril Bur <cyrilbur@gmail.com>
---
Because the test no longer needs to use such a conservative time for
the busy wait, it actually runs much faster.
.../testing/selftests/powerpc/tm/tm-unavailable.c | 92 ++++++++++++++++++++--
1 file changed, 84 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/powerpc/tm/tm-unavailable.c b/tools/testing/selftests/powerpc/tm/tm-unavailable.c
index e6a0fad2bfd0..54aeb7a7fbb1 100644
--- a/tools/testing/selftests/powerpc/tm/tm-unavailable.c
+++ b/tools/testing/selftests/powerpc/tm/tm-unavailable.c
@@ -33,6 +33,11 @@
#define VEC_UNA_EXCEPTION 1
#define VSX_UNA_EXCEPTION 2
+#define ERR_RETRY 1
+#define ERR_ADJUST 2
+
+#define COUNTER_INCREMENT (0x1000000)
+
#define NUM_EXCEPTIONS 3
#define err_at_line(status, errnum, format, ...) \
error_at_line(status, errnum, __FILE__, __LINE__, format ##__VA_ARGS__)
@@ -45,6 +50,7 @@ struct Flags {
int touch_vec;
int result;
int exception;
+ uint64_t counter;
} flags;
bool expecting_failure(void)
@@ -87,14 +93,12 @@ void *ping(void *input)
* Expected values for vs0 and vs32 after a TM failure. They must never
* change, otherwise they got corrupted.
*/
+ long rc = 0;
uint64_t high_vs0 = 0x5555555555555555;
uint64_t low_vs0 = 0xffffffffffffffff;
uint64_t high_vs32 = 0x5555555555555555;
uint64_t low_vs32 = 0xffffffffffffffff;
- /* Counter for busy wait */
- uint64_t counter = 0x1ff000000;
-
/*
* Variable to keep a copy of CR register content taken just after we
* leave the transactional state.
@@ -217,7 +221,7 @@ void *ping(void *input)
[ex_fp] "i" (FP_UNA_EXCEPTION),
[ex_vec] "i" (VEC_UNA_EXCEPTION),
[ex_vsx] "i" (VSX_UNA_EXCEPTION),
- [counter] "r" (counter)
+ [counter] "r" (flags.counter)
: "cr0", "ctr", "v10", "vs0", "vs10", "vs3", "vs32", "vs33",
"vs34", "fr10"
@@ -232,14 +236,14 @@ void *ping(void *input)
if (expecting_failure() && !is_failure(cr_)) {
printf("\n\tExpecting the transaction to fail, %s",
"but it didn't\n\t");
- flags.result++;
+ rc = ERR_ADJUST;
}
/* Check if we were not expecting a failure and a it occurred. */
if (!expecting_failure() && is_failure(cr_)) {
printf("\n\tUnexpected transaction failure 0x%02lx\n\t",
failure_code());
- return (void *) -1;
+ rc = ERR_RETRY;
}
/*
@@ -249,7 +253,7 @@ void *ping(void *input)
if (is_failure(cr_) && !failure_is_unavailable()) {
printf("\n\tUnexpected failure cause 0x%02lx\n\t",
failure_code());
- return (void *) -1;
+ rc = ERR_RETRY;
}
/* 0x4 is a success and 0xa is a fail. See comment in is_failure(). */
@@ -276,7 +280,7 @@ void *ping(void *input)
putchar('\n');
- return NULL;
+ return (void *)rc;
}
/* Thread to force context switch */
@@ -291,6 +295,55 @@ void *pong(void *not_used)
sched_yield();
}
+static void flags_set_counter(struct Flags *flags)
+{
+ uint64_t cr_;
+ int count = 0;
+
+ do {
+ if (count == 0)
+ printf("\tTrying 0x%08" PRIx64 "... ", flags->counter);
+ else
+ printf("%d, ", count);
+ fflush(stdout);
+ asm (
+ /*
+ * Wait an amount of context switches so
+ * load_fp and load_vec overflow and MSR.FP,
+ * MSR.VEC, and MSR.VSX become zero (off).
+ */
+ " mtctr %[counter] ;"
+
+ /* Decrement CTR branch if CTR non zero. */
+ "1: bdnz 1b ;"
+ " tbegin. ;"
+ " beq tfail ;"
+
+ /* Get a facility unavailable */
+ " fadd 10, 10, 10 ;"
+ " tend. ;"
+ "tfail: ;"
+
+ /*
+ * Give CR back to C so that it can check what
+ * happened.
+ */
+ " mfcr %[cr_] ;"
+
+ : [cr_] "+r" (cr_)
+ : [counter] "r" (flags->counter)
+ : "cr0", "ctr", "fr10"
+ );
+ count++;
+ if (!is_failure(cr_) || !failure_is_unavailable()) {
+ count = 0;
+ flags->counter += COUNTER_INCREMENT;
+ putchar('\n');
+ }
+ } while (count < 3);
+ printf("3\n");
+}
+
/* Function that creates a thread and launches the "ping" task. */
void test_fp_vec(int fp, int vec, pthread_attr_t *attr)
{
@@ -322,6 +375,17 @@ void test_fp_vec(int fp, int vec, pthread_attr_t *attr)
if (rc)
pr_err(rc, "pthread_join");
+ if ((long)ret_value == ERR_ADJUST) {
+ printf("Adjusting the facility unavailable spin time...\n");
+ /*
+ * Be a bit more agressive just now - we'd
+ * really like to have it work
+ */
+ flags.counter += (2 * COUNTER_INCREMENT);
+ flags_set_counter(&flags);
+ printf("Now using 0x%08" PRIx64 "\n", flags.counter);
+ }
+
retries--;
} while (ret_value != NULL && retries);
@@ -340,6 +404,18 @@ int main(int argc, char **argv)
pthread_attr_t attr;
cpu_set_t cpuset;
+ /*
+ * Default counter for busy wait.
+ * 0x18000000 is a good baseline determined by experimentation
+ * on a POWER8
+ * The autodetecting code will bump it up if it too low.
+ */
+ flags.counter = 0x18000000;
+
+ printf("Testing required spin time required for facility unavailable...\n");
+ flags_set_counter(&flags);
+ printf("Spin time required for a reliable facility unavailable TM failure: 0x%" PRIx64 "\n",
+ flags.counter);
/* Set only CPU 0 in the mask. Both threads will be bound to CPU 0. */
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset);
--
2.15.0
next prev parent reply other threads:[~2017-11-21 7:17 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-21 7:17 [PATCH 1/2] selftests/powerpc: Check for pthread errors in tm-unavailable Cyril Bur
2017-11-21 7:17 ` Cyril Bur [this message]
2017-11-21 13:31 ` [PATCH 2/2] selftests/powerpc: Calculate spin time " Gustavo Romero
2017-11-21 23:41 ` Cyril Bur
2017-12-11 2:02 ` Michael Ellerman
2017-12-11 3:40 ` Cyril Bur
2017-11-21 12:56 ` [PATCH 1/2] selftests/powerpc: Check for pthread errors " Gustavo Romero
2017-12-12 11:39 ` [1/2] " Michael Ellerman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171121071720.24619-2-cyrilbur@gmail.com \
--to=cyrilbur@gmail.com \
--cc=gromero@linux.vnet.ibm.com \
--cc=leitao@debian.org \
--cc=linuxppc-dev@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.