mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Chang S. Bae" <chang.seok.bae@intel.com>
To: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: shuah@kernel.org, tglx@linutronix.de,
	dave.hansen@linux.intel.com, attofari@amazon.de,
	chang.seok.bae@intel.com
Subject: [PATCH] selftests/x86/amx: Add a CPU hotplug test
Date: Sat,  3 Jun 2023 08:24:55 -0700	[thread overview]
Message-ID: <20230603152455.12444-1-chang.seok.bae@intel.com> (raw)
In-Reply-To: <42654300-67cb-254d-22c2-4642a4763ba5@intel.com>

Adamos found the issue with the cached XFD state [1]. Although the XFD
state is reset on the CPU hotplug, the per-CPU XFD cache is missing
the reset. Then, running an AMX thread there, the staled value causes
the kernel crash to kill the thread.

This is reproducible when moving an AMX thread to the hot-plugged CPU.
So, add a test case to ensure no issue with that.

It repeats the test due to possible inconsistencies. Then, along with
the hotplug cost, it will bring a noticeable runtime increase. But,
the overall test has a quick turnaround time.

Link: https://lore.kernel.org/lkml/20230519112315.30616-1-attofari@amazon.de/ [1]
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Adamos Ttofari <attofari@amazon.de>
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-kselftest@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
The overall x86 selftest via "$ make TARGETS='x86' kselftest" takes
about 3.5 -> 5.5 seconds. 'amx_64' itself took about 1.5 more seconds
over 0.x seconds.

But, this overall runtime still takes in a matter of some seconds,
which should be fine I thought.
---
 tools/testing/selftests/x86/amx.c | 133 ++++++++++++++++++++++++++++--
 1 file changed, 126 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c
index d884fd69dd51..6f2f0598c706 100644
--- a/tools/testing/selftests/x86/amx.c
+++ b/tools/testing/selftests/x86/amx.c
@@ -3,6 +3,7 @@
 #define _GNU_SOURCE
 #include <err.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <pthread.h>
 #include <setjmp.h>
 #include <stdio.h>
@@ -25,6 +26,8 @@
 # error This test is 64-bit only
 #endif
 
+#define BUF_LEN			1000
+
 #define XSAVE_HDR_OFFSET	512
 #define XSAVE_HDR_SIZE		64
 
@@ -239,11 +242,10 @@ static inline uint64_t get_fpx_sw_bytes_features(void *buffer)
 }
 
 /* Work around printf() being unsafe in signals: */
-#define SIGNAL_BUF_LEN 1000
-char signal_message_buffer[SIGNAL_BUF_LEN];
+char signal_message_buffer[BUF_LEN];
 void sig_print(char *msg)
 {
-	int left = SIGNAL_BUF_LEN - strlen(signal_message_buffer) - 1;
+	int left = BUF_LEN - strlen(signal_message_buffer) - 1;
 
 	strncat(signal_message_buffer, msg, left);
 }
@@ -767,15 +769,15 @@ static int create_threads(int num, struct futex_info *finfo)
 	return 0;
 }
 
-static void affinitize_cpu0(void)
+static inline void affinitize_cpu(int cpu)
 {
 	cpu_set_t cpuset;
 
 	CPU_ZERO(&cpuset);
-	CPU_SET(0, &cpuset);
+	CPU_SET(cpu, &cpuset);
 
 	if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0)
-		fatal_error("sched_setaffinity to CPU 0");
+		fatal_error("sched_setaffinity to CPU %d", cpu);
 }
 
 static void test_context_switch(void)
@@ -784,7 +786,7 @@ static void test_context_switch(void)
 	int i;
 
 	/* Affinitize to one CPU to force context switches */
-	affinitize_cpu0();
+	affinitize_cpu(0);
 
 	req_xtiledata_perm();
 
@@ -926,6 +928,121 @@ static void test_ptrace(void)
 		err(1, "ptrace test");
 }
 
+/* CPU Hotplug test */
+
+static void __hotplug_cpu(int online, int cpu)
+{
+	char buf[BUF_LEN] = {};
+	int fd, rc;
+
+	strncat(buf, "/sys/devices/system/cpu/cpu", BUF_LEN);
+	snprintf(buf + strlen(buf), BUF_LEN - strlen(buf), "%d", cpu);
+	strncat(buf, "/online", BUF_LEN - strlen(buf));
+
+	fd = open(buf, O_RDWR);
+	if (fd == -1)
+		fatal_error("open()");
+
+	snprintf(buf, BUF_LEN, "%d", online);
+	rc = write(fd, buf, strlen(buf));
+	if (rc == -1)
+		fatal_error("write()");
+
+	rc = close(fd);
+	if (rc == -1)
+		fatal_error("close()");
+}
+
+static void offline_cpu(int cpu)
+{
+	__hotplug_cpu(0, cpu);
+}
+
+static void online_cpu(int cpu)
+{
+	__hotplug_cpu(1, cpu);
+}
+
+static jmp_buf jmpbuf;
+
+static void handle_sigsegv(int sig, siginfo_t *si, void *ctx_void)
+{
+	siglongjmp(jmpbuf, 1);
+}
+
+#define RETRY 5
+
+/*
+ * Sanity-check the hotplug CPU for its (re-)initialization.
+ *
+ * Create an AMX thread on a CPU, while the hotplug CPU went offline.
+ * Then, plug the offlined back, and move the thread to run on it.
+ *
+ * Repeat this multiple times to ensure no inconsistent failure.
+ * If something goes wrong, the thread will get a signal or killed.
+ */
+static void *switch_cpus(void *arg)
+{
+	int *result = (int *)arg;
+	int i = 0;
+
+	affinitize_cpu(0);
+	offline_cpu(1);
+	load_rand_tiledata(stashed_xsave);
+
+	sethandler(SIGSEGV, handle_sigsegv, SA_ONSTACK);
+	for (i = 0; i < RETRY; i++) {
+		if (i > 0) {
+			affinitize_cpu(0);
+			offline_cpu(1);
+		}
+		if (sigsetjmp(jmpbuf, 1) == 0) {
+			online_cpu(1);
+			affinitize_cpu(1);
+		} else {
+			*result = 1;
+			goto out;
+		}
+	}
+	*result = 0;
+out:
+	clearhandler(SIGSEGV);
+	return result;
+}
+
+static void test_cpuhp(void)
+{
+	int max_cpu_num = sysconf(_SC_NPROCESSORS_ONLN) - 1;
+	void *thread_retval;
+	pthread_t thread;
+	int result, rc;
+
+	if (!max_cpu_num) {
+		printf("[SKIP]\tThe running system has no more CPU for the hotplug test.\n");
+		return;
+	}
+
+	printf("[RUN]\tTest AMX use with the CPU hotplug.\n");
+
+	if (pthread_create(&thread, NULL, switch_cpus, &result))
+		fatal_error("pthread_create()");
+
+	rc = pthread_join(thread, &thread_retval);
+
+	if (rc)
+		fatal_error("pthread_join()");
+
+	/*
+	 * Either an invalid retval or a failed result indicates
+	 * the test failure.
+	 */
+	if (thread_retval != &result || result != 0)
+		printf("[FAIL]\tThe AMX thread had an issue (%s).\n",
+		       thread_retval != &result ? "killed" : "signaled");
+	else
+		printf("[OK]\tThe AMX thread had no issue.\n");
+}
+
 int main(void)
 {
 	/* Check hardware availability at first */
@@ -948,6 +1065,8 @@ int main(void)
 
 	test_ptrace();
 
+	test_cpuhp();
+
 	clearhandler(SIGILL);
 	free_stashed_xsave();
 

base-commit: 7877cb91f1081754a1487c144d85dc0d2e2e7fc4
-- 
2.17.1


  reply	other threads:[~2023-06-03 15:38 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-11 15:28 [PATCH] fpu: xstate: Keep xfd_state always in-sync with IA32_XFD MSR Adamos Ttofari
2023-05-11 17:59 ` Dave Hansen
2023-05-11 19:11 ` Thomas Gleixner
2023-05-12 17:46   ` Chang S. Bae
2023-05-12 11:38 ` [PATCH v2] x86: fpu: Keep xfd_state always in sync with MSR_IA32_XFD Adamos Ttofari
2023-05-12 12:52   ` Thomas Gleixner
2023-05-19 11:23     ` [PATCH v3] " Adamos Ttofari
2023-05-19 15:03       ` Thomas Gleixner
2023-05-19 22:21       ` Chang S. Bae
2023-06-03 15:24         ` Chang S. Bae [this message]
2024-03-22 23:04       ` [PATCH v4] x86/fpu: " Chang S. Bae
2024-03-24  3:15         ` [tip: x86/urgent] x86/fpu: Keep xfd_state " tip-bot2 for Adamos Ttofari
2023-05-16 21:35   ` [PATCH v2] x86: fpu: Keep xfd_state always " Chang S. Bae

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=20230603152455.12444-1-chang.seok.bae@intel.com \
    --to=chang.seok.bae@intel.com \
    --cc=attofari@amazon.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=shuah@kernel.org \
    --cc=tglx@linutronix.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®