Skip to content

Commit

Permalink
Merge tag 'linux-kselftest-next-6.4-rc1' of git://git.kernel.org/pub/…
Browse files Browse the repository at this point in the history
…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
  ...
  • Loading branch information
torvalds committed Apr 24, 2023
2 parents 5dfb75e + 50ad2fb commit 0f50767
Show file tree
Hide file tree
Showing 24 changed files with 306 additions and 204 deletions.
6 changes: 6 additions & 0 deletions tools/include/nolibc/stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args)
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)))
int fprintf(FILE *stream, const char *fmt, ...)
{
Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ TARGETS += nsfs
TARGETS += pidfd
TARGETS += pid_namespace
TARGETS += powerpc
TARGETS += prctl
TARGETS += proc
TARGETS += pstore
TARGETS += ptrace
Expand Down
4 changes: 2 additions & 2 deletions tools/testing/selftests/amd-pstate/gitsource.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ parse_gitsource()
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
# 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
# 1/t 1/t 1
# ----- = ----- = ---
Expand Down Expand Up @@ -175,7 +175,7 @@ gather_gitsource()
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
# 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
# 1/t 1/t 1
# ----- = ----- = ---
Expand Down
4 changes: 2 additions & 2 deletions tools/testing/selftests/amd-pstate/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -244,15 +244,15 @@ prerequisite()
if [ "$scaling_driver" != "$CURRENT_TEST" ]; then
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 # Current cpufreq scaling drvier is $scaling_driver."
echo "$0 # Current cpufreq scaling driver is $scaling_driver."
exit $ksft_skip
fi
else
case "$FUNC" in
"tbench" | "gitsource")
if [ "$scaling_driver" != "$COMPARATIVE_TEST" ]; then
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
fi
;;
Expand Down
2 changes: 1 addition & 1 deletion tools/testing/selftests/arm64/fp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ $(OUTPUT)/vec-syscfg: vec-syscfg.c $(OUTPUT)/rdvl.o
$(OUTPUT)/vlset: vlset.c
$(OUTPUT)/za-fork: za-fork.c $(OUTPUT)/za-fork-asm.o
$(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 $@
$(OUTPUT)/za-ptrace: za-ptrace.c
$(OUTPUT)/za-test: za-test.S $(OUTPUT)/asm-utils.o
Expand Down
88 changes: 16 additions & 72 deletions tools/testing/selftests/arm64/fp/za-fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,9 @@
#include <linux/sched.h>
#include <linux/wait.h>

#define EXPECTED_TESTS 1

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);
}
#include "kselftest.h"

static int tests_run;
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");
}
#define EXPECTED_TESTS 1

int fork_test(void);
int verify_fork(void);
Expand All @@ -63,71 +30,53 @@ int fork_test_c(void)
if (newpid == 0) {
/* In child */
if (!verify_fork()) {
putstr("# ZA state invalid in child\n");
ksft_print_msg("ZA state invalid in child\n");
exit(0);
} else {
exit(1);
}
}
if (newpid < 0) {
putstr("# fork() failed: -");
putnum(-newpid);
putstr("\n");
ksft_print_msg("fork() failed: %d\n", newpid);

return 0;
}

parent_result = verify_fork();
if (!parent_result)
putstr("# ZA state invalid in parent\n");
ksft_print_msg("ZA state invalid in parent\n");

for (;;) {
waiting = waitpid(newpid, &child_status, 0);

if (waiting < 0) {
if (errno == EINTR)
continue;
putstr("# waitpid() failed: ");
putnum(errno);
putstr("\n");
ksft_print_msg("waitpid() failed: %d\n", errno);
return 0;
}
if (waiting != newpid) {
putstr("# waitpid() returned wrong PID\n");
ksft_print_msg("waitpid() returned wrong PID\n");
return 0;
}

if (!WIFEXITED(child_status)) {
putstr("# child did not exit\n");
ksft_print_msg("child did not exit\n");
return 0;
}

return WEXITSTATUS(child_status) && parent_result;
}
}

#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 ret, i;

putstr("TAP version 13\n");
putstr("1..");
putnum(EXPECTED_TESTS);
putstr("\n");
ksft_print_header();
ksft_set_plan(EXPECTED_TESTS);

putstr("# PID: ");
putnum(getpid());
putstr("\n");
ksft_print_msg("PID: %d\n", getpid());

/*
* This test is run with nolibc which doesn't support hwcap and
Expand All @@ -136,21 +85,16 @@ int main(int argc, char **argv)
*/
ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0);
if (ret >= 0) {
run_test(fork_test);
ksft_test_result(fork_test(), "fork_test");

} else {
putstr("# SME support not present\n");

ksft_print_msg("SME not supported\n");
for (i = 0; i < EXPECTED_TESTS; i++) {
putstr("ok ");
putnum(i);
putstr(" skipped\n");
ksft_test_result_skip("fork_test\n");
}

tests_skipped += EXPECTED_TESTS;
}

print_summary();
ksft_finished();

return 0;
}
15 changes: 15 additions & 0 deletions tools/testing/selftests/cgroup/test_memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ static int alloc_anon_50M_check(const char *cgroup, void *arg)
int ret = -1;

buf = malloc(size);
if (buf == NULL) {
fprintf(stderr, "malloc() failed\n");
return -1;
}

for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
*ptr = 0;

Expand Down Expand Up @@ -211,6 +216,11 @@ static int alloc_anon_noexit(const char *cgroup, void *arg)
char *buf, *ptr;

buf = malloc(size);
if (buf == NULL) {
fprintf(stderr, "malloc() failed\n");
return -1;
}

for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
*ptr = 0;

Expand Down Expand Up @@ -778,6 +788,11 @@ static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
int ret = -1;

buf = malloc(size);
if (buf == NULL) {
fprintf(stderr, "malloc() failed\n");
return -1;
}

for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
*ptr = 0;

Expand Down
2 changes: 2 additions & 0 deletions tools/testing/selftests/kselftest.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@
#ifndef __KSELFTEST_H
#define __KSELFTEST_H

#ifndef NOLIBC
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#endif

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/prctl/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
disable-tsc-ctxt-sw-stress-test
disable-tsc-on-off-stress-test
disable-tsc-test
set-anon-vma-name-test
2 changes: 1 addition & 1 deletion tools/testing/selftests/prctl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)

ifeq ($(ARCH),x86)
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)

include ../lib.mk
Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/prctl/config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_ANON_VMA_NAME=y
104 changes: 104 additions & 0 deletions tools/testing/selftests/prctl/set-anon-vma-name-test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// 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
Loading

0 comments on commit 0f50767

Please sign in to comment.