Commit 0f50767d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux-kselftest-next-6.4-rc1' of...

Merge tag 'linux-kselftest-next-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull Kselftest updates from Shuah Khan:

 - several patches to enhance and fix resctrl test

 - nolibc support for kselftest with an addition to vprintf() to
   tools/nolibc/stdio and related test changes

 - Refactor 'peeksiginfo' ptrace test part

 - add 'malloc' failures checks in cgroup test_memcontrol

 - a new prctl test

 - enhancements sched test with additional ore schedule prctl calls

* tag 'linux-kselftest-next-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (25 commits)
  selftests/resctrl: Fix incorrect error return on test complete
  selftests/resctrl: Remove duplicate codes that clear each test result file
  selftests/resctrl: Commonize the signal handler register/unregister for all tests
  selftests/resctrl: Cleanup properly when an error occurs in CAT test
  selftests/resctrl: Flush stdout file buffer before executing fork()
  selftests/resctrl: Return MBA check result and make it to output message
  selftests/resctrl: Fix set up schemata with 100% allocation on first run in MBM test
  selftests/resctrl: Use correct exit code when tests fail
  kselftest/arm64: Convert za-fork to use kselftest.h
  kselftest: Support nolibc
  tools/nolibc/stdio: Implement vprintf()
  selftests/resctrl: Correct get_llc_perf() param in function comment
  selftests/resctrl: Use remount_resctrlfs() consistently with boolean
  selftests/resctrl: Change name from CBM_MASK_PATH to INFO_PATH
  selftests/resctrl: Change initialize_llc_perf() return type to void
  selftests/resctrl: Replace obsolete memalign() with posix_memalign()
  selftests/resctrl: Check for return value after write_schemata()
  selftests/resctrl: Allow ->setup() to return errors
  selftests/resctrl: Move ->setup() call outside of test specific branches
  selftests/resctrl: Return NULL if malloc_and_init_memory() did not alloc mem
  ...
parents 5dfb75e8 50ad2fb7
...@@ -273,6 +273,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args) ...@@ -273,6 +273,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args)
return written; return written;
} }
static __attribute__((unused))
int vprintf(const char *fmt, va_list args)
{
return vfprintf(stdout, fmt, args);
}
static __attribute__((unused, format(printf, 2, 3))) static __attribute__((unused, format(printf, 2, 3)))
int fprintf(FILE *stream, const char *fmt, ...) int fprintf(FILE *stream, const char *fmt, ...)
{ {
......
...@@ -58,6 +58,7 @@ TARGETS += nsfs ...@@ -58,6 +58,7 @@ TARGETS += nsfs
TARGETS += pidfd TARGETS += pidfd
TARGETS += pid_namespace TARGETS += pid_namespace
TARGETS += powerpc TARGETS += powerpc
TARGETS += prctl
TARGETS += proc TARGETS += proc
TARGETS += pstore TARGETS += pstore
TARGETS += ptrace TARGETS += ptrace
......
...@@ -117,7 +117,7 @@ parse_gitsource() ...@@ -117,7 +117,7 @@ parse_gitsource()
printf "Gitsource-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result printf "Gitsource-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result
# Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t # Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t
# senconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J), # seconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
# and t is time measured in seconds(s). This means that performance per watt becomes # and t is time measured in seconds(s). This means that performance per watt becomes
# 1/t 1/t 1 # 1/t 1/t 1
# ----- = ----- = --- # ----- = ----- = ---
...@@ -175,7 +175,7 @@ gather_gitsource() ...@@ -175,7 +175,7 @@ gather_gitsource()
printf "Gitsource-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_GIT.result printf "Gitsource-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_GIT.result
# Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t # Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t
# senconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J), # seconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J),
# and t is time measured in seconds(s). This means that performance per watt becomes # and t is time measured in seconds(s). This means that performance per watt becomes
# 1/t 1/t 1 # 1/t 1/t 1
# ----- = ----- = --- # ----- = ----- = ---
......
...@@ -244,7 +244,7 @@ prerequisite() ...@@ -244,7 +244,7 @@ prerequisite()
if [ "$scaling_driver" != "$CURRENT_TEST" ]; then if [ "$scaling_driver" != "$CURRENT_TEST" ]; then
echo "$0 # Skipped: Test can only run on $CURRENT_TEST driver or run comparative test." echo "$0 # Skipped: Test can only run on $CURRENT_TEST driver or run comparative test."
echo "$0 # Please set X86_AMD_PSTATE enabled or run comparative test." echo "$0 # Please set X86_AMD_PSTATE enabled or run comparative test."
echo "$0 # Current cpufreq scaling drvier is $scaling_driver." echo "$0 # Current cpufreq scaling driver is $scaling_driver."
exit $ksft_skip exit $ksft_skip
fi fi
else else
...@@ -252,7 +252,7 @@ prerequisite() ...@@ -252,7 +252,7 @@ prerequisite()
"tbench" | "gitsource") "tbench" | "gitsource")
if [ "$scaling_driver" != "$COMPARATIVE_TEST" ]; then if [ "$scaling_driver" != "$COMPARATIVE_TEST" ]; then
echo "$0 # Skipped: Comparison test can only run on $COMPARISON_TEST driver." echo "$0 # Skipped: Comparison test can only run on $COMPARISON_TEST driver."
echo "$0 # Current cpufreq scaling drvier is $scaling_driver." echo "$0 # Current cpufreq scaling driver is $scaling_driver."
exit $ksft_skip exit $ksft_skip
fi fi
;; ;;
......
...@@ -38,7 +38,7 @@ $(OUTPUT)/vec-syscfg: vec-syscfg.c $(OUTPUT)/rdvl.o ...@@ -38,7 +38,7 @@ $(OUTPUT)/vec-syscfg: vec-syscfg.c $(OUTPUT)/rdvl.o
$(OUTPUT)/vlset: vlset.c $(OUTPUT)/vlset: vlset.c
$(OUTPUT)/za-fork: za-fork.c $(OUTPUT)/za-fork-asm.o $(OUTPUT)/za-fork: za-fork.c $(OUTPUT)/za-fork-asm.o
$(CC) -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \ $(CC) -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
-include ../../../../include/nolibc/nolibc.h \ -include ../../../../include/nolibc/nolibc.h -I../..\
-static -ffreestanding -Wall $^ -o $@ -static -ffreestanding -Wall $^ -o $@
$(OUTPUT)/za-ptrace: za-ptrace.c $(OUTPUT)/za-ptrace: za-ptrace.c
$(OUTPUT)/za-test: za-test.S $(OUTPUT)/asm-utils.o $(OUTPUT)/za-test: za-test.S $(OUTPUT)/asm-utils.o
......
...@@ -9,42 +9,9 @@ ...@@ -9,42 +9,9 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/wait.h> #include <linux/wait.h>
#define EXPECTED_TESTS 1 #include "kselftest.h"
static void putstr(const char *str)
{
write(1, str, strlen(str));
}
static void putnum(unsigned int num)
{
char c;
if (num / 10)
putnum(num / 10);
c = '0' + (num % 10);
write(1, &c, 1);
}
static int tests_run; #define EXPECTED_TESTS 1
static int tests_passed;
static int tests_failed;
static int tests_skipped;
static void print_summary(void)
{
if (tests_passed + tests_failed + tests_skipped != EXPECTED_TESTS)
putstr("# UNEXPECTED TEST COUNT: ");
putstr("# Totals: pass:");
putnum(tests_passed);
putstr(" fail:");
putnum(tests_failed);
putstr(" xfail:0 xpass:0 skip:");
putnum(tests_skipped);
putstr(" error:0\n");
}
int fork_test(void); int fork_test(void);
int verify_fork(void); int verify_fork(void);
...@@ -63,22 +30,21 @@ int fork_test_c(void) ...@@ -63,22 +30,21 @@ int fork_test_c(void)
if (newpid == 0) { if (newpid == 0) {
/* In child */ /* In child */
if (!verify_fork()) { if (!verify_fork()) {
putstr("# ZA state invalid in child\n"); ksft_print_msg("ZA state invalid in child\n");
exit(0); exit(0);
} else { } else {
exit(1); exit(1);
} }
} }
if (newpid < 0) { if (newpid < 0) {
putstr("# fork() failed: -"); ksft_print_msg("fork() failed: %d\n", newpid);
putnum(-newpid);
putstr("\n");
return 0; return 0;
} }
parent_result = verify_fork(); parent_result = verify_fork();
if (!parent_result) if (!parent_result)
putstr("# ZA state invalid in parent\n"); ksft_print_msg("ZA state invalid in parent\n");
for (;;) { for (;;) {
waiting = waitpid(newpid, &child_status, 0); waiting = waitpid(newpid, &child_status, 0);
...@@ -86,18 +52,16 @@ int fork_test_c(void) ...@@ -86,18 +52,16 @@ int fork_test_c(void)
if (waiting < 0) { if (waiting < 0) {
if (errno == EINTR) if (errno == EINTR)
continue; continue;
putstr("# waitpid() failed: "); ksft_print_msg("waitpid() failed: %d\n", errno);
putnum(errno);
putstr("\n");
return 0; return 0;
} }
if (waiting != newpid) { if (waiting != newpid) {
putstr("# waitpid() returned wrong PID\n"); ksft_print_msg("waitpid() returned wrong PID\n");
return 0; return 0;
} }
if (!WIFEXITED(child_status)) { if (!WIFEXITED(child_status)) {
putstr("# child did not exit\n"); ksft_print_msg("child did not exit\n");
return 0; return 0;
} }
...@@ -105,29 +69,14 @@ int fork_test_c(void) ...@@ -105,29 +69,14 @@ int fork_test_c(void)
} }
} }
#define run_test(name) \
if (name()) { \
tests_passed++; \
} else { \
tests_failed++; \
putstr("not "); \
} \
putstr("ok "); \
putnum(++tests_run); \
putstr(" " #name "\n");
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int ret, i; int ret, i;
putstr("TAP version 13\n"); ksft_print_header();
putstr("1.."); ksft_set_plan(EXPECTED_TESTS);
putnum(EXPECTED_TESTS);
putstr("\n");
putstr("# PID: "); ksft_print_msg("PID: %d\n", getpid());
putnum(getpid());
putstr("\n");
/* /*
* This test is run with nolibc which doesn't support hwcap and * This test is run with nolibc which doesn't support hwcap and
...@@ -136,21 +85,16 @@ int main(int argc, char **argv) ...@@ -136,21 +85,16 @@ int main(int argc, char **argv)
*/ */
ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0); ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0);
if (ret >= 0) { if (ret >= 0) {
run_test(fork_test); ksft_test_result(fork_test(), "fork_test");
} else { } else {
putstr("# SME support not present\n"); ksft_print_msg("SME not supported\n");
for (i = 0; i < EXPECTED_TESTS; i++) { for (i = 0; i < EXPECTED_TESTS; i++) {
putstr("ok "); ksft_test_result_skip("fork_test\n");
putnum(i);
putstr(" skipped\n");
} }
tests_skipped += EXPECTED_TESTS;
} }
print_summary(); ksft_finished();
return 0; return 0;
} }
...@@ -98,6 +98,11 @@ static int alloc_anon_50M_check(const char *cgroup, void *arg) ...@@ -98,6 +98,11 @@ static int alloc_anon_50M_check(const char *cgroup, void *arg)
int ret = -1; int ret = -1;
buf = malloc(size); buf = malloc(size);
if (buf == NULL) {
fprintf(stderr, "malloc() failed\n");
return -1;
}
for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE) for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
*ptr = 0; *ptr = 0;
...@@ -211,6 +216,11 @@ static int alloc_anon_noexit(const char *cgroup, void *arg) ...@@ -211,6 +216,11 @@ static int alloc_anon_noexit(const char *cgroup, void *arg)
char *buf, *ptr; char *buf, *ptr;
buf = malloc(size); buf = malloc(size);
if (buf == NULL) {
fprintf(stderr, "malloc() failed\n");
return -1;
}
for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE) for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
*ptr = 0; *ptr = 0;
...@@ -778,6 +788,11 @@ static int alloc_anon_50M_check_swap(const char *cgroup, void *arg) ...@@ -778,6 +788,11 @@ static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
int ret = -1; int ret = -1;
buf = malloc(size); buf = malloc(size);
if (buf == NULL) {
fprintf(stderr, "malloc() failed\n");
return -1;
}
for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE) for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
*ptr = 0; *ptr = 0;
......
...@@ -43,11 +43,13 @@ ...@@ -43,11 +43,13 @@
#ifndef __KSELFTEST_H #ifndef __KSELFTEST_H
#define __KSELFTEST_H #define __KSELFTEST_H
#ifndef NOLIBC
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#endif
#ifndef ARRAY_SIZE #ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
......
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
disable-tsc-ctxt-sw-stress-test disable-tsc-ctxt-sw-stress-test
disable-tsc-on-off-stress-test disable-tsc-on-off-stress-test
disable-tsc-test disable-tsc-test
set-anon-vma-name-test
...@@ -5,7 +5,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) ...@@ -5,7 +5,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
ifeq ($(ARCH),x86) ifeq ($(ARCH),x86)
TEST_PROGS := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test \ TEST_PROGS := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test \
disable-tsc-test disable-tsc-test set-anon-vma-name-test
all: $(TEST_PROGS) all: $(TEST_PROGS)
include ../lib.mk include ../lib.mk
......
// SPDX-License-Identifier: GPL-2.0
/*
* This test covers the anonymous VMA naming functionality through prctl calls
*/
#include <errno.h>
#include <sys/prctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include "../kselftest_harness.h"
#define AREA_SIZE 1024
#define GOOD_NAME "goodname"
#define BAD_NAME "badname\1"
#ifndef PR_SET_VMA
#define PR_SET_VMA 0x53564d41
#define PR_SET_VMA_ANON_NAME 0
#endif
int rename_vma(unsigned long addr, unsigned long size, char *name)
{
int res;
res = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, addr, size, name);
if (res < 0)
return -errno;
return res;
}
int was_renaming_successful(char *target_name, unsigned long ptr)
{
FILE *maps_file;
char line_buf[512], name[128], mode[8];
unsigned long start_addr, end_addr, offset;
unsigned int major_id, minor_id, node_id;
char target_buf[128];
int res = 0, sscanf_res;
// The entry name in maps will be in format [anon:<target_name>]
sprintf(target_buf, "[anon:%s]", target_name);
maps_file = fopen("/proc/self/maps", "r");
if (!maps_file) {
printf("## /proc/self/maps file opening error\n");
return 0;
}
// Parse the maps file to find the entry we renamed
while (fgets(line_buf, sizeof(line_buf), maps_file)) {
sscanf_res = sscanf(line_buf, "%lx-%lx %7s %lx %u:%u %u %s", &start_addr,
&end_addr, mode, &offset, &major_id,
&minor_id, &node_id, name);
if (sscanf_res == EOF) {
res = 0;
printf("## EOF while parsing the maps file\n");
break;
}
if (!strcmp(name, target_buf) && start_addr == ptr) {
res = 1;
break;
}
}
fclose(maps_file);
return res;
}
FIXTURE(vma) {
void *ptr_anon, *ptr_not_anon;
};
FIXTURE_SETUP(vma) {
self->ptr_anon = mmap(NULL, AREA_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
ASSERT_NE(self->ptr_anon, NULL);
self->ptr_not_anon = mmap(NULL, AREA_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE, 0, 0);
ASSERT_NE(self->ptr_not_anon, NULL);
}
FIXTURE_TEARDOWN(vma) {
munmap(self->ptr_anon, AREA_SIZE);
munmap(self->ptr_not_anon, AREA_SIZE);
}
TEST_F(vma, renaming) {
TH_LOG("Try to rename the VMA with correct parameters");
EXPECT_GE(rename_vma((unsigned long)self->ptr_anon, AREA_SIZE, GOOD_NAME), 0);
EXPECT_TRUE(was_renaming_successful(GOOD_NAME, (unsigned long)self->ptr_anon));
TH_LOG("Try to pass invalid name (with non-printable character \\1) to rename the VMA");
EXPECT_EQ(rename_vma((unsigned long)self->ptr_anon, AREA_SIZE, BAD_NAME), -EINVAL);
TH_LOG("Try to rename non-anonynous VMA");
EXPECT_EQ(rename_vma((unsigned long) self->ptr_not_anon, AREA_SIZE, GOOD_NAME), -EINVAL);
}
TEST_HARNESS_MAIN
...@@ -151,7 +151,7 @@ int check_direct_path(pid_t child, int shared, int nr) ...@@ -151,7 +151,7 @@ int check_direct_path(pid_t child, int shared, int nr)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
siginfo_t siginfo[SIGNR]; siginfo_t siginfo;
int i, exit_code = 1; int i, exit_code = 1;
sigset_t blockmask; sigset_t blockmask;
pid_t child; pid_t child;
...@@ -176,13 +176,13 @@ int main(int argc, char *argv[]) ...@@ -176,13 +176,13 @@ int main(int argc, char *argv[])
/* Send signals in process-wide and per-thread queues */ /* Send signals in process-wide and per-thread queues */
for (i = 0; i < SIGNR; i++) { for (i = 0; i < SIGNR; i++) {
siginfo->si_code = TEST_SICODE_SHARE; siginfo.si_code = TEST_SICODE_SHARE;
siginfo->si_int = i; siginfo.si_int = i;
sys_rt_sigqueueinfo(child, SIGRTMIN, siginfo); sys_rt_sigqueueinfo(child, SIGRTMIN, &siginfo);
siginfo->si_code = TEST_SICODE_PRIV; siginfo.si_code = TEST_SICODE_PRIV;
siginfo->si_int = i; siginfo.si_int = i;
sys_rt_tgsigqueueinfo(child, child, SIGRTMIN, siginfo); sys_rt_tgsigqueueinfo(child, child, SIGRTMIN, &siginfo);
} }
if (sys_ptrace(PTRACE_ATTACH, child, NULL, NULL) == -1) if (sys_ptrace(PTRACE_ATTACH, child, NULL, NULL) == -1)
......
...@@ -48,7 +48,7 @@ static int perf_event_open_llc_miss(pid_t pid, int cpu_no) ...@@ -48,7 +48,7 @@ static int perf_event_open_llc_miss(pid_t pid, int cpu_no)
return 0; return 0;
} }
static int initialize_llc_perf(void) static void initialize_llc_perf(void)
{ {
memset(&pea_llc_miss, 0, sizeof(struct perf_event_attr)); memset(&pea_llc_miss, 0, sizeof(struct perf_event_attr));
memset(&rf_cqm, 0, sizeof(struct read_format)); memset(&rf_cqm, 0, sizeof(struct read_format));
...@@ -59,8 +59,6 @@ static int initialize_llc_perf(void) ...@@ -59,8 +59,6 @@ static int initialize_llc_perf(void)
pea_llc_miss.config = PERF_COUNT_HW_CACHE_MISSES; pea_llc_miss.config = PERF_COUNT_HW_CACHE_MISSES;
rf_cqm.nr = 1; rf_cqm.nr = 1;
return 0;
} }
static int reset_enable_llc_perf(pid_t pid, int cpu_no) static int reset_enable_llc_perf(pid_t pid, int cpu_no)
...@@ -79,7 +77,7 @@ static int reset_enable_llc_perf(pid_t pid, int cpu_no) ...@@ -79,7 +77,7 @@ static int reset_enable_llc_perf(pid_t pid, int cpu_no)
/* /*
* get_llc_perf: llc cache miss through perf events * get_llc_perf: llc cache miss through perf events
* @cpu_no: CPU number that the benchmark PID is binded to * @llc_perf_miss: LLC miss counter that is filled on success
* *
* Perf events like HW_CACHE_MISSES could be used to validate number of * Perf events like HW_CACHE_MISSES could be used to validate number of
* cache lines allocated. * cache lines allocated.
...@@ -234,20 +232,19 @@ int cat_val(struct resctrl_val_param *param) ...@@ -234,20 +232,19 @@ int cat_val(struct resctrl_val_param *param)
if (ret) if (ret)
return ret; return ret;
if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) { if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
ret = initialize_llc_perf(); initialize_llc_perf();
if (ret)
return ret;
}
/* Test runs until the callback setup() tells the test to stop. */ /* Test runs until the callback setup() tells the test to stop. */
while (1) { while (1) {
if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) { if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
ret = param->setup(1, param); ret = param->setup(1, param);
if (ret) { if (ret == END_OF_TESTS) {
ret = 0; ret = 0;
break; break;
} }
if (ret < 0)
break;
ret = reset_enable_llc_perf(bm_pid, param->cpu_no); ret = reset_enable_llc_perf(bm_pid, param->cpu_no);
if (ret) if (ret)
break; break;
......
...@@ -40,7 +40,7 @@ static int cat_setup(int num, ...) ...@@ -40,7 +40,7 @@ static int cat_setup(int num, ...)
/* Run NUM_OF_RUNS times */ /* Run NUM_OF_RUNS times */
if (p->num_of_runs >= NUM_OF_RUNS) if (p->num_of_runs >= NUM_OF_RUNS)
return -1; return END_OF_TESTS;
if (p->num_of_runs == 0) { if (p->num_of_runs == 0) {
sprintf(schemata, "%lx", p->mask); sprintf(schemata, "%lx", p->mask);
...@@ -103,7 +103,6 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) ...@@ -103,7 +103,6 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
unsigned long l_mask, l_mask_1; unsigned long l_mask, l_mask_1;
int ret, pipefd[2], sibling_cpu_no; int ret, pipefd[2], sibling_cpu_no;
char pipe_message; char pipe_message;
pid_t bm_pid;
cache_size = 0; cache_size = 0;
...@@ -145,7 +144,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) ...@@ -145,7 +144,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
struct resctrl_val_param param = { struct resctrl_val_param param = {
.resctrl_val = CAT_STR, .resctrl_val = CAT_STR,
.cpu_no = cpu_no, .cpu_no = cpu_no,
.mum_resctrlfs = 0, .mum_resctrlfs = false,
.setup = cat_setup, .setup = cat_setup,
}; };
...@@ -167,6 +166,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) ...@@ -167,6 +166,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
return errno; return errno;
} }
fflush(stdout);
bm_pid = fork(); bm_pid = fork();
/* Set param values for child thread which will be allocated bitmask /* Set param values for child thread which will be allocated bitmask
...@@ -180,28 +180,31 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) ...@@ -180,28 +180,31 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
strcpy(param.filename, RESULT_FILE_NAME1); strcpy(param.filename, RESULT_FILE_NAME1);
param.num_of_runs = 0; param.num_of_runs = 0;
param.cpu_no = sibling_cpu_no; param.cpu_no = sibling_cpu_no;
} else {
ret = signal_handler_register();
if (ret) {
kill(bm_pid, SIGKILL);
goto out;
}
} }
remove(param.filename); remove(param.filename);
ret = cat_val(&param); ret = cat_val(&param);
if (ret) if (ret == 0)
return ret; ret = check_results(&param);
ret = check_results(&param);
if (ret)
return ret;
if (bm_pid == 0) { if (bm_pid == 0) {
/* Tell parent that child is ready */ /* Tell parent that child is ready */
close(pipefd[0]); close(pipefd[0]);
pipe_message = 1; pipe_message = 1;
if (write(pipefd[1], &pipe_message, sizeof(pipe_message)) < if (write(pipefd[1], &pipe_message, sizeof(pipe_message)) <
sizeof(pipe_message)) { sizeof(pipe_message))
close(pipefd[1]); /*
* Just print the error message.
* Let while(1) run and wait for itself to be killed.
*/
perror("# failed signaling parent process"); perror("# failed signaling parent process");
return errno;
}
close(pipefd[1]); close(pipefd[1]);
while (1) while (1)
...@@ -219,11 +222,13 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) ...@@ -219,11 +222,13 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
} }
close(pipefd[0]); close(pipefd[0]);
kill(bm_pid, SIGKILL); kill(bm_pid, SIGKILL);
signal_handler_unregister();
} }
out:
cat_test_cleanup(); cat_test_cleanup();
if (bm_pid) if (bm_pid)
umount_resctrlfs(); umount_resctrlfs();
return 0; return ret;
} }
...@@ -32,7 +32,7 @@ static int cmt_setup(int num, ...) ...@@ -32,7 +32,7 @@ static int cmt_setup(int num, ...)
/* Run NUM_OF_RUNS times */ /* Run NUM_OF_RUNS times */
if (p->num_of_runs >= NUM_OF_RUNS) if (p->num_of_runs >= NUM_OF_RUNS)
return -1; return END_OF_TESTS;
p->num_of_runs++; p->num_of_runs++;
...@@ -82,12 +82,11 @@ void cmt_test_cleanup(void) ...@@ -82,12 +82,11 @@ void cmt_test_cleanup(void)
int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
{ {
int ret, mum_resctrlfs; int ret;
cache_size = 0; cache_size = 0;
mum_resctrlfs = 1;
ret = remount_resctrlfs(mum_resctrlfs); ret = remount_resctrlfs(true);
if (ret) if (ret)
return ret; return ret;
...@@ -118,7 +117,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) ...@@ -118,7 +117,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
.ctrlgrp = "c1", .ctrlgrp = "c1",
.mongrp = "m1", .mongrp = "m1",
.cpu_no = cpu_no, .cpu_no = cpu_no,
.mum_resctrlfs = 0, .mum_resctrlfs = false,
.filename = RESULT_FILE_NAME, .filename = RESULT_FILE_NAME,
.mask = ~(long_mask << n) & long_mask, .mask = ~(long_mask << n) & long_mask,
.span = cache_size * n / count_of_bits, .span = cache_size * n / count_of_bits,
...@@ -133,13 +132,12 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) ...@@ -133,13 +132,12 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
ret = resctrl_val(benchmark_cmd, &param); ret = resctrl_val(benchmark_cmd, &param);
if (ret) if (ret)
return ret; goto out;
ret = check_results(&param, n); ret = check_results(&param, n);
if (ret)
return ret;
out:
cmt_test_cleanup(); cmt_test_cleanup();
return 0; return ret;
} }
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <inttypes.h> #include <inttypes.h>
#include <malloc.h>
#include <string.h> #include <string.h>
#include "resctrl.h" #include "resctrl.h"
...@@ -33,14 +32,6 @@ static void sb(void) ...@@ -33,14 +32,6 @@ static void sb(void)
#endif #endif
} }
static void ctrl_handler(int signo)
{
free(startptr);
printf("\nEnding\n");
sb();
exit(EXIT_SUCCESS);
}
static void cl_flush(void *p) static void cl_flush(void *p)
{ {
#if defined(__i386) || defined(__x86_64) #if defined(__i386) || defined(__x86_64)
...@@ -64,10 +55,14 @@ static void mem_flush(void *p, size_t s) ...@@ -64,10 +55,14 @@ static void mem_flush(void *p, size_t s)
static void *malloc_and_init_memory(size_t s) static void *malloc_and_init_memory(size_t s)
{ {
void *p = NULL;
uint64_t *p64; uint64_t *p64;
size_t s64; size_t s64;
int ret;
void *p = memalign(PAGE_SIZE, s); ret = posix_memalign(&p, PAGE_SIZE, s);
if (ret < 0)
return NULL;
p64 = (uint64_t *)p; p64 = (uint64_t *)p;
s64 = s / sizeof(uint64_t); s64 = s / sizeof(uint64_t);
...@@ -198,12 +193,6 @@ int run_fill_buf(unsigned long span, int malloc_and_init_memory, ...@@ -198,12 +193,6 @@ int run_fill_buf(unsigned long span, int malloc_and_init_memory,
unsigned long long cache_size = span; unsigned long long cache_size = span;
int ret; int ret;
/* set up ctrl-c handler */
if (signal(SIGINT, ctrl_handler) == SIG_ERR)
printf("Failed to catch SIGINT!\n");
if (signal(SIGHUP, ctrl_handler) == SIG_ERR)
printf("Failed to catch SIGHUP!\n");
ret = fill_cache(cache_size, malloc_and_init_memory, memflush, op, ret = fill_cache(cache_size, malloc_and_init_memory, memflush, op,
resctrl_val); resctrl_val);
if (ret) { if (ret) {
......
...@@ -28,6 +28,7 @@ static int mba_setup(int num, ...) ...@@ -28,6 +28,7 @@ static int mba_setup(int num, ...)
struct resctrl_val_param *p; struct resctrl_val_param *p;
char allocation_str[64]; char allocation_str[64];
va_list param; va_list param;
int ret;
va_start(param, num); va_start(param, num);
p = va_arg(param, struct resctrl_val_param *); p = va_arg(param, struct resctrl_val_param *);
...@@ -41,20 +42,24 @@ static int mba_setup(int num, ...) ...@@ -41,20 +42,24 @@ static int mba_setup(int num, ...)
return 0; return 0;
if (allocation < ALLOCATION_MIN || allocation > ALLOCATION_MAX) if (allocation < ALLOCATION_MIN || allocation > ALLOCATION_MAX)
return -1; return END_OF_TESTS;
sprintf(allocation_str, "%d", allocation); sprintf(allocation_str, "%d", allocation);
write_schemata(p->ctrlgrp, allocation_str, p->cpu_no, p->resctrl_val); ret = write_schemata(p->ctrlgrp, allocation_str, p->cpu_no,
p->resctrl_val);
if (ret < 0)
return ret;
allocation -= ALLOCATION_STEP; allocation -= ALLOCATION_STEP;
return 0; return 0;
} }
static void show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc) static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
{ {
int allocation, runs; int allocation, runs;
bool failed = false; bool ret = false;
ksft_print_msg("Results are displayed in (MB)\n"); ksft_print_msg("Results are displayed in (MB)\n");
/* Memory bandwidth from 100% down to 10% */ /* Memory bandwidth from 100% down to 10% */
...@@ -90,13 +95,15 @@ static void show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc) ...@@ -90,13 +95,15 @@ static void show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc); ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc);
ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc); ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc);
if (avg_diff_per > MAX_DIFF_PERCENT) if (avg_diff_per > MAX_DIFF_PERCENT)
failed = true; ret = true;
} }
ksft_print_msg("%s Check schemata change using MBA\n", ksft_print_msg("%s Check schemata change using MBA\n",
failed ? "Fail:" : "Pass:"); ret ? "Fail:" : "Pass:");
if (failed) if (ret)
ksft_print_msg("At least one test failed\n"); ksft_print_msg("At least one test failed\n");
return ret;
} }
static int check_results(void) static int check_results(void)
...@@ -132,9 +139,7 @@ static int check_results(void) ...@@ -132,9 +139,7 @@ static int check_results(void)
fclose(fp); fclose(fp);
show_mba_info(bw_imc, bw_resc); return show_mba_info(bw_imc, bw_resc);
return 0;
} }
void mba_test_cleanup(void) void mba_test_cleanup(void)
...@@ -149,7 +154,7 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd) ...@@ -149,7 +154,7 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
.ctrlgrp = "c1", .ctrlgrp = "c1",
.mongrp = "m1", .mongrp = "m1",
.cpu_no = cpu_no, .cpu_no = cpu_no,
.mum_resctrlfs = 1, .mum_resctrlfs = true,
.filename = RESULT_FILE_NAME, .filename = RESULT_FILE_NAME,
.bw_report = bw_report, .bw_report = bw_report,
.setup = mba_setup .setup = mba_setup
...@@ -160,13 +165,12 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd) ...@@ -160,13 +165,12 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
ret = resctrl_val(benchmark_cmd, &param); ret = resctrl_val(benchmark_cmd, &param);
if (ret) if (ret)
return ret; goto out;
ret = check_results(); ret = check_results();
if (ret)
return ret;
out:
mba_test_cleanup(); mba_test_cleanup();
return 0; return ret;
} }
...@@ -89,23 +89,24 @@ static int check_results(int span) ...@@ -89,23 +89,24 @@ static int check_results(int span)
static int mbm_setup(int num, ...) static int mbm_setup(int num, ...)
{ {
struct resctrl_val_param *p; struct resctrl_val_param *p;
static int num_of_runs;
va_list param; va_list param;
int ret = 0; int ret = 0;
/* Run NUM_OF_RUNS times */
if (num_of_runs++ >= NUM_OF_RUNS)
return -1;
va_start(param, num); va_start(param, num);
p = va_arg(param, struct resctrl_val_param *); p = va_arg(param, struct resctrl_val_param *);
va_end(param); va_end(param);
/* Run NUM_OF_RUNS times */
if (p->num_of_runs >= NUM_OF_RUNS)
return END_OF_TESTS;
/* Set up shemata with 100% allocation on the first run. */ /* Set up shemata with 100% allocation on the first run. */
if (num_of_runs == 0) if (p->num_of_runs == 0)
ret = write_schemata(p->ctrlgrp, "100", p->cpu_no, ret = write_schemata(p->ctrlgrp, "100", p->cpu_no,
p->resctrl_val); p->resctrl_val);
p->num_of_runs++;
return ret; return ret;
} }
...@@ -122,7 +123,7 @@ int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd) ...@@ -122,7 +123,7 @@ int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd)
.mongrp = "m1", .mongrp = "m1",
.span = span, .span = span,
.cpu_no = cpu_no, .cpu_no = cpu_no,
.mum_resctrlfs = 1, .mum_resctrlfs = true,
.filename = RESULT_FILE_NAME, .filename = RESULT_FILE_NAME,
.bw_report = bw_report, .bw_report = bw_report,
.setup = mbm_setup .setup = mbm_setup
...@@ -133,13 +134,12 @@ int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd) ...@@ -133,13 +134,12 @@ int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd)
ret = resctrl_val(benchmark_cmd, &param); ret = resctrl_val(benchmark_cmd, &param);
if (ret) if (ret)
return ret; goto out;
ret = check_results(span); ret = check_results(span);
if (ret)
return ret;
out:
mbm_test_cleanup(); mbm_test_cleanup();
return 0; return ret;
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define MB (1024 * 1024) #define MB (1024 * 1024)
#define RESCTRL_PATH "/sys/fs/resctrl" #define RESCTRL_PATH "/sys/fs/resctrl"
#define PHYS_ID_PATH "/sys/devices/system/cpu/cpu" #define PHYS_ID_PATH "/sys/devices/system/cpu/cpu"
#define CBM_MASK_PATH "/sys/fs/resctrl/info" #define INFO_PATH "/sys/fs/resctrl/info"
#define L3_PATH "/sys/fs/resctrl/info/L3" #define L3_PATH "/sys/fs/resctrl/info/L3"
#define MB_PATH "/sys/fs/resctrl/info/MB" #define MB_PATH "/sys/fs/resctrl/info/MB"
#define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON" #define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON"
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#define ARCH_INTEL 1 #define ARCH_INTEL 1
#define ARCH_AMD 2 #define ARCH_AMD 2
#define END_OF_TESTS 1
#define PARENT_EXIT(err_msg) \ #define PARENT_EXIT(err_msg) \
do { \ do { \
perror(err_msg); \ perror(err_msg); \
...@@ -62,7 +64,7 @@ struct resctrl_val_param { ...@@ -62,7 +64,7 @@ struct resctrl_val_param {
char mongrp[64]; char mongrp[64];
int cpu_no; int cpu_no;
unsigned long span; unsigned long span;
int mum_resctrlfs; bool mum_resctrlfs;
char filename[64]; char filename[64];
char *bw_report; char *bw_report;
unsigned long mask; unsigned long mask;
...@@ -107,6 +109,8 @@ void mba_test_cleanup(void); ...@@ -107,6 +109,8 @@ void mba_test_cleanup(void);
int get_cbm_mask(char *cache_type, char *cbm_mask); int get_cbm_mask(char *cache_type, char *cbm_mask);
int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size); int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
void ctrlc_handler(int signum, siginfo_t *info, void *ptr); void ctrlc_handler(int signum, siginfo_t *info, void *ptr);
int signal_handler_register(void);
void signal_handler_unregister(void);
int cat_val(struct resctrl_val_param *param); int cat_val(struct resctrl_val_param *param);
void cat_test_cleanup(void); void cat_test_cleanup(void);
int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type); int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type);
......
...@@ -77,7 +77,7 @@ static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span, ...@@ -77,7 +77,7 @@ static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span,
ksft_print_msg("Starting MBM BW change ...\n"); ksft_print_msg("Starting MBM BW change ...\n");
if (!validate_resctrl_feature_request(MBM_STR)) { if (!validate_resctrl_feature_request(MBM_STR) || (get_vendor() != ARCH_INTEL)) {
ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n"); ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n");
return; return;
} }
...@@ -88,7 +88,6 @@ static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span, ...@@ -88,7 +88,6 @@ static void run_mbm_test(bool has_ben, char **benchmark_cmd, int span,
ksft_test_result(!res, "MBM: bw change\n"); ksft_test_result(!res, "MBM: bw change\n");
if ((get_vendor() == ARCH_INTEL) && res) if ((get_vendor() == ARCH_INTEL) && res)
ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n"); ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
mbm_test_cleanup();
} }
static void run_mba_test(bool has_ben, char **benchmark_cmd, int span, static void run_mba_test(bool has_ben, char **benchmark_cmd, int span,
...@@ -98,7 +97,7 @@ static void run_mba_test(bool has_ben, char **benchmark_cmd, int span, ...@@ -98,7 +97,7 @@ static void run_mba_test(bool has_ben, char **benchmark_cmd, int span,
ksft_print_msg("Starting MBA Schemata change ...\n"); ksft_print_msg("Starting MBA Schemata change ...\n");
if (!validate_resctrl_feature_request(MBA_STR)) { if (!validate_resctrl_feature_request(MBA_STR) || (get_vendor() != ARCH_INTEL)) {
ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n"); ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n");
return; return;
} }
...@@ -107,7 +106,6 @@ static void run_mba_test(bool has_ben, char **benchmark_cmd, int span, ...@@ -107,7 +106,6 @@ static void run_mba_test(bool has_ben, char **benchmark_cmd, int span,
sprintf(benchmark_cmd[1], "%d", span); sprintf(benchmark_cmd[1], "%d", span);
res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd); res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd);
ksft_test_result(!res, "MBA: schemata change\n"); ksft_test_result(!res, "MBA: schemata change\n");
mba_test_cleanup();
} }
static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no) static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no)
...@@ -126,7 +124,6 @@ static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no) ...@@ -126,7 +124,6 @@ static void run_cmt_test(bool has_ben, char **benchmark_cmd, int cpu_no)
ksft_test_result(!res, "CMT: test\n"); ksft_test_result(!res, "CMT: test\n");
if ((get_vendor() == ARCH_INTEL) && res) if ((get_vendor() == ARCH_INTEL) && res)
ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n"); ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
cmt_test_cleanup();
} }
static void run_cat_test(int cpu_no, int no_of_bits) static void run_cat_test(int cpu_no, int no_of_bits)
...@@ -142,7 +139,6 @@ static void run_cat_test(int cpu_no, int no_of_bits) ...@@ -142,7 +139,6 @@ static void run_cat_test(int cpu_no, int no_of_bits)
res = cat_perf_miss_val(cpu_no, no_of_bits, "L3"); res = cat_perf_miss_val(cpu_no, no_of_bits, "L3");
ksft_test_result(!res, "CAT: test\n"); ksft_test_result(!res, "CAT: test\n");
cat_test_cleanup();
} }
int main(int argc, char **argv) int main(int argc, char **argv)
...@@ -258,10 +254,10 @@ int main(int argc, char **argv) ...@@ -258,10 +254,10 @@ int main(int argc, char **argv)
ksft_set_plan(tests ? : 4); ksft_set_plan(tests ? : 4);
if ((get_vendor() == ARCH_INTEL) && mbm_test) if (mbm_test)
run_mbm_test(has_ben, benchmark_cmd, span, cpu_no, bw_report); run_mbm_test(has_ben, benchmark_cmd, span, cpu_no, bw_report);
if ((get_vendor() == ARCH_INTEL) && mba_test) if (mba_test)
run_mba_test(has_ben, benchmark_cmd, span, cpu_no, bw_report); run_mba_test(has_ben, benchmark_cmd, span, cpu_no, bw_report);
if (cmt_test) if (cmt_test)
...@@ -272,5 +268,5 @@ int main(int argc, char **argv) ...@@ -272,5 +268,5 @@ int main(int argc, char **argv)
umount_resctrlfs(); umount_resctrlfs();
return ksft_exit_pass(); ksft_finished();
} }
...@@ -476,6 +476,45 @@ void ctrlc_handler(int signum, siginfo_t *info, void *ptr) ...@@ -476,6 +476,45 @@ void ctrlc_handler(int signum, siginfo_t *info, void *ptr)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
/*
* Register CTRL-C handler for parent, as it has to kill
* child process before exiting.
*/
int signal_handler_register(void)
{
struct sigaction sigact;
int ret = 0;
sigact.sa_sigaction = ctrlc_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_SIGINFO;
if (sigaction(SIGINT, &sigact, NULL) ||
sigaction(SIGTERM, &sigact, NULL) ||
sigaction(SIGHUP, &sigact, NULL)) {
perror("# sigaction");
ret = -1;
}
return ret;
}
/*
* Reset signal handler to SIG_DFL.
* Non-Value return because the caller should keep
* the error code of other path even if sigaction fails.
*/
void signal_handler_unregister(void)
{
struct sigaction sigact;
sigact.sa_handler = SIG_DFL;
sigemptyset(&sigact.sa_mask);
if (sigaction(SIGINT, &sigact, NULL) ||
sigaction(SIGTERM, &sigact, NULL) ||
sigaction(SIGHUP, &sigact, NULL)) {
perror("# sigaction");
}
}
/* /*
* print_results_bw: the memory bandwidth results are stored in a file * print_results_bw: the memory bandwidth results are stored in a file
* @filename: file that stores the results * @filename: file that stores the results
...@@ -629,6 +668,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) ...@@ -629,6 +668,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
* Fork to start benchmark, save child's pid so that it can be killed * Fork to start benchmark, save child's pid so that it can be killed
* when needed * when needed
*/ */
fflush(stdout);
bm_pid = fork(); bm_pid = fork();
if (bm_pid == -1) { if (bm_pid == -1) {
perror("# Unable to fork"); perror("# Unable to fork");
...@@ -670,39 +710,28 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) ...@@ -670,39 +710,28 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
ksft_print_msg("Benchmark PID: %d\n", bm_pid); ksft_print_msg("Benchmark PID: %d\n", bm_pid);
/* ret = signal_handler_register();
* Register CTRL-C handler for parent, as it has to kill benchmark if (ret)
* before exiting
*/
sigact.sa_sigaction = ctrlc_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_SIGINFO;
if (sigaction(SIGINT, &sigact, NULL) ||
sigaction(SIGTERM, &sigact, NULL) ||
sigaction(SIGHUP, &sigact, NULL)) {
perror("# sigaction");
ret = errno;
goto out; goto out;
}
value.sival_ptr = benchmark_cmd; value.sival_ptr = benchmark_cmd;
/* Taskset benchmark to specified cpu */ /* Taskset benchmark to specified cpu */
ret = taskset_benchmark(bm_pid, param->cpu_no); ret = taskset_benchmark(bm_pid, param->cpu_no);
if (ret) if (ret)
goto out; goto unregister;
/* Write benchmark to specified control&monitoring grp in resctrl FS */ /* Write benchmark to specified control&monitoring grp in resctrl FS */
ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp, ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp,
resctrl_val); resctrl_val);
if (ret) if (ret)
goto out; goto unregister;
if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) || if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) { !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
ret = initialize_mem_bw_imc(); ret = initialize_mem_bw_imc();
if (ret) if (ret)
goto out; goto unregister;
initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp, initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp,
param->cpu_no, resctrl_val); param->cpu_no, resctrl_val);
...@@ -717,7 +746,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) ...@@ -717,7 +746,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
sizeof(pipe_message)) { sizeof(pipe_message)) {
perror("# failed reading message from child process"); perror("# failed reading message from child process");
close(pipefd[0]); close(pipefd[0]);
goto out; goto unregister;
} }
} }
close(pipefd[0]); close(pipefd[0]);
...@@ -726,7 +755,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) ...@@ -726,7 +755,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
if (sigqueue(bm_pid, SIGUSR1, value) == -1) { if (sigqueue(bm_pid, SIGUSR1, value) == -1) {
perror("# sigqueue SIGUSR1 to child"); perror("# sigqueue SIGUSR1 to child");
ret = errno; ret = errno;
goto out; goto unregister;
} }
/* Give benchmark enough time to fully run */ /* Give benchmark enough time to fully run */
...@@ -734,32 +763,29 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) ...@@ -734,32 +763,29 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
/* Test runs until the callback setup() tells the test to stop. */ /* Test runs until the callback setup() tells the test to stop. */
while (1) { while (1) {
ret = param->setup(1, param);
if (ret == END_OF_TESTS) {
ret = 0;
break;
}
if (ret < 0)
break;
if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) || if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) { !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
ret = param->setup(1, param);
if (ret) {
ret = 0;
break;
}
ret = measure_vals(param, &bw_resc_start); ret = measure_vals(param, &bw_resc_start);
if (ret) if (ret)
break; break;
} else if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) { } else if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
ret = param->setup(1, param);
if (ret) {
ret = 0;
break;
}
sleep(1); sleep(1);
ret = measure_cache_vals(param, bm_pid); ret = measure_cache_vals(param, bm_pid);
if (ret) if (ret)
break; break;
} else {
break;
} }
} }
unregister:
signal_handler_unregister();
out: out:
kill(bm_pid, SIGKILL); kill(bm_pid, SIGKILL);
umount_resctrlfs(); umount_resctrlfs();
......
...@@ -210,7 +210,7 @@ int get_cbm_mask(char *cache_type, char *cbm_mask) ...@@ -210,7 +210,7 @@ int get_cbm_mask(char *cache_type, char *cbm_mask)
if (!cbm_mask) if (!cbm_mask)
return -1; return -1;
sprintf(cbm_mask_path, "%s/%s/cbm_mask", CBM_MASK_PATH, cache_type); sprintf(cbm_mask_path, "%s/%s/cbm_mask", INFO_PATH, cache_type);
fp = fopen(cbm_mask_path, "r"); fp = fopen(cbm_mask_path, "r");
if (!fp) { if (!fp) {
...@@ -498,6 +498,7 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val) ...@@ -498,6 +498,7 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
FILE *fp; FILE *fp;
if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) && if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) &&
strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) &&
strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) && strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) &&
strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
return -ENOENT; return -ENOENT;
...@@ -523,7 +524,8 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val) ...@@ -523,7 +524,8 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) || if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) ||
!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR)))
sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata); sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata);
if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) ||
!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)))
sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata); sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata);
fp = fopen(controlgroup, "w"); fp = fopen(controlgroup, "w");
...@@ -676,6 +678,7 @@ int filter_dmesg(void) ...@@ -676,6 +678,7 @@ int filter_dmesg(void)
perror("pipe"); perror("pipe");
return ret; return ret;
} }
fflush(stdout);
pid = fork(); pid = fork();
if (pid == 0) { if (pid == 0) {
close(pipefds[0]); close(pipefds[0]);
......
...@@ -334,6 +334,12 @@ int main(int argc, char *argv[]) ...@@ -334,6 +334,12 @@ int main(int argc, char *argv[])
validate(get_cs_cookie(pid) != 0); validate(get_cs_cookie(pid) != 0);
validate(get_cs_cookie(pid) == get_cs_cookie(procs[pidx].thr_tids[0])); validate(get_cs_cookie(pid) == get_cs_cookie(procs[pidx].thr_tids[0]));
validate(_prctl(PR_SCHED_CORE, PR_SCHED_CORE_MAX, 0, PIDTYPE_PGID, 0) < 0
&& errno == EINVAL);
validate(_prctl(PR_SCHED_CORE, PR_SCHED_CORE_SHARE_TO, 0, PIDTYPE_PGID, 1) < 0
&& errno == EINVAL);
if (errors) { if (errors) {
printf("TESTS FAILED. errors: %d\n", errors); printf("TESTS FAILED. errors: %d\n", errors);
res = 10; res = 10;
......
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