Commit dfd7a156 authored by Kirill A. Shutemov's avatar Kirill A. Shutemov Committed by Dave Hansen

selftests/x86/lam: Add test cases for LAM vs thread creation

LAM enabling is only allowed when the process has single thread.
LAM mode is inherited into child thread.

Trying to enable LAM after spawning a thread has to fail.
Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20230312112612.31869-18-kirill.shutemov%40linux.intel.com
parent 34821473
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......@@ -12,6 +13,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sched.h>
#include <sys/uio.h>
#include <linux/io_uring.h>
......@@ -50,6 +52,8 @@
#define PAGE_SIZE (4 << 10)
#define STACK_SIZE 65536
#define barrier() ({ \
__asm__ __volatile__("" : : : "memory"); \
})
......@@ -731,6 +735,75 @@ static int handle_inheritance(struct testcases *test)
return 0;
}
static int thread_fn_get_lam(void *arg)
{
return get_lam();
}
static int thread_fn_set_lam(void *arg)
{
struct testcases *test = arg;
return set_lam(test->lam);
}
static int handle_thread(struct testcases *test)
{
char stack[STACK_SIZE];
int ret, child_ret;
int lam = 0;
pid_t pid;
/* Set LAM mode in parent process */
if (!test->later) {
lam = test->lam;
if (set_lam(lam) != 0)
return 1;
}
pid = clone(thread_fn_get_lam, stack + STACK_SIZE,
SIGCHLD | CLONE_FILES | CLONE_FS | CLONE_VM, NULL);
if (pid < 0) {
perror("Clone failed.");
return 1;
}
waitpid(pid, &child_ret, 0);
ret = WEXITSTATUS(child_ret);
if (lam != ret)
return 1;
if (test->later) {
if (set_lam(test->lam) != 0)
return 1;
}
return 0;
}
static int handle_thread_enable(struct testcases *test)
{
char stack[STACK_SIZE];
int ret, child_ret;
int lam = test->lam;
pid_t pid;
pid = clone(thread_fn_set_lam, stack + STACK_SIZE,
SIGCHLD | CLONE_FILES | CLONE_FS | CLONE_VM, test);
if (pid < 0) {
perror("Clone failed.");
return 1;
}
waitpid(pid, &child_ret, 0);
ret = WEXITSTATUS(child_ret);
if (lam != ret)
return 1;
return 0;
}
static void run_test(struct testcases *test, int count)
{
int i, ret = 0;
......@@ -846,6 +919,25 @@ static struct testcases inheritance_cases[] = {
.test_func = handle_inheritance,
.msg = "FORK: LAM_U57, child process should get LAM mode same as parent\n",
},
{
.expected = 0,
.lam = LAM_U57_BITS,
.test_func = handle_thread,
.msg = "THREAD: LAM_U57, child thread should get LAM mode same as parent\n",
},
{
.expected = 1,
.lam = LAM_U57_BITS,
.test_func = handle_thread_enable,
.msg = "THREAD: [NEGATIVE] Enable LAM in child.\n",
},
{
.expected = 1,
.later = 1,
.lam = LAM_U57_BITS,
.test_func = handle_thread,
.msg = "THREAD: [NEGATIVE] Enable LAM in parent after thread created.\n",
},
{
.expected = 0,
.lam = LAM_U57_BITS,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment