Skip to content

Commit dfd7a15

Browse files
kirylhansendc
authored andcommitted
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: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/all/20230312112612.31869-18-kirill.shutemov%40linux.intel.com
1 parent 3482147 commit dfd7a15

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

  • tools/testing/selftests/x86

tools/testing/selftests/x86/lam.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// SPDX-License-Identifier: GPL-2.0
2+
#define _GNU_SOURCE
23
#include <stdio.h>
34
#include <stdlib.h>
45
#include <string.h>
@@ -12,6 +13,7 @@
1213
#include <sys/stat.h>
1314
#include <fcntl.h>
1415
#include <inttypes.h>
16+
#include <sched.h>
1517

1618
#include <sys/uio.h>
1719
#include <linux/io_uring.h>
@@ -50,6 +52,8 @@
5052

5153
#define PAGE_SIZE (4 << 10)
5254

55+
#define STACK_SIZE 65536
56+
5357
#define barrier() ({ \
5458
__asm__ __volatile__("" : : : "memory"); \
5559
})
@@ -731,6 +735,75 @@ static int handle_inheritance(struct testcases *test)
731735
return 0;
732736
}
733737

738+
static int thread_fn_get_lam(void *arg)
739+
{
740+
return get_lam();
741+
}
742+
743+
static int thread_fn_set_lam(void *arg)
744+
{
745+
struct testcases *test = arg;
746+
747+
return set_lam(test->lam);
748+
}
749+
750+
static int handle_thread(struct testcases *test)
751+
{
752+
char stack[STACK_SIZE];
753+
int ret, child_ret;
754+
int lam = 0;
755+
pid_t pid;
756+
757+
/* Set LAM mode in parent process */
758+
if (!test->later) {
759+
lam = test->lam;
760+
if (set_lam(lam) != 0)
761+
return 1;
762+
}
763+
764+
pid = clone(thread_fn_get_lam, stack + STACK_SIZE,
765+
SIGCHLD | CLONE_FILES | CLONE_FS | CLONE_VM, NULL);
766+
if (pid < 0) {
767+
perror("Clone failed.");
768+
return 1;
769+
}
770+
771+
waitpid(pid, &child_ret, 0);
772+
ret = WEXITSTATUS(child_ret);
773+
774+
if (lam != ret)
775+
return 1;
776+
777+
if (test->later) {
778+
if (set_lam(test->lam) != 0)
779+
return 1;
780+
}
781+
782+
return 0;
783+
}
784+
785+
static int handle_thread_enable(struct testcases *test)
786+
{
787+
char stack[STACK_SIZE];
788+
int ret, child_ret;
789+
int lam = test->lam;
790+
pid_t pid;
791+
792+
pid = clone(thread_fn_set_lam, stack + STACK_SIZE,
793+
SIGCHLD | CLONE_FILES | CLONE_FS | CLONE_VM, test);
794+
if (pid < 0) {
795+
perror("Clone failed.");
796+
return 1;
797+
}
798+
799+
waitpid(pid, &child_ret, 0);
800+
ret = WEXITSTATUS(child_ret);
801+
802+
if (lam != ret)
803+
return 1;
804+
805+
return 0;
806+
}
734807
static void run_test(struct testcases *test, int count)
735808
{
736809
int i, ret = 0;
@@ -846,6 +919,25 @@ static struct testcases inheritance_cases[] = {
846919
.test_func = handle_inheritance,
847920
.msg = "FORK: LAM_U57, child process should get LAM mode same as parent\n",
848921
},
922+
{
923+
.expected = 0,
924+
.lam = LAM_U57_BITS,
925+
.test_func = handle_thread,
926+
.msg = "THREAD: LAM_U57, child thread should get LAM mode same as parent\n",
927+
},
928+
{
929+
.expected = 1,
930+
.lam = LAM_U57_BITS,
931+
.test_func = handle_thread_enable,
932+
.msg = "THREAD: [NEGATIVE] Enable LAM in child.\n",
933+
},
934+
{
935+
.expected = 1,
936+
.later = 1,
937+
.lam = LAM_U57_BITS,
938+
.test_func = handle_thread,
939+
.msg = "THREAD: [NEGATIVE] Enable LAM in parent after thread created.\n",
940+
},
849941
{
850942
.expected = 0,
851943
.lam = LAM_U57_BITS,

0 commit comments

Comments
 (0)