Commit 25b20ae8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux-kselftest-fixes-5.17-rc3' of...

Merge tag 'linux-kselftest-fixes-5.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull Kselftest fixes from Shuah Khan:
 "Important fixes to several tests and documentation clarification on
  running mainline kselftest on stable releases. A few notable fixes:

   - fix kselftest run hang due to child processes that haven't been
     terminated. Fix signals all child processes

   - fix false pass/fail results from vdso_test_abi, openat2, mincore

   - build failures when using -j (multiple jobs) option

   - exec test build failure due to incorrect build rule for a run-time
     created "pipe"

   - zram test fixes related to interaction with zram-generator to make
     sure zram test to coordinate deleted with zram-generator

   - zram test compression ratio calculation fix and skipping
     max_comp_streams.

   - increasing rtc test timeout

   - cpufreq test to write test results to stdout which will necessary
     on automated test systems"

* tag 'linux-kselftest-fixes-5.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
  kselftest: Fix vdso_test_abi return status
  selftests: skip mincore.check_file_mmap when fs lacks needed support
  selftests: openat2: Skip testcases that fail with EOPNOTSUPP
  selftests: openat2: Add missing dependency in Makefile
  selftests: openat2: Print also errno in failure messages
  selftests: futex: Use variable MAKE instead of make
  selftests/exec: Remove pipe from TEST_GEN_FILES
  selftests/zram: Adapt the situation that /dev/zram0 is being used
  selftests/zram01.sh: Fix compression ratio calculation
  selftests/zram: Skip max_comp_streams interface on newer kernel
  docs/kselftest: clarify running mainline tests on stables
  kselftest: signal all child processes
  selftests: cpufreq: Write test output to stdout as well
  selftests: rtc: Increase test timeout so that all tests run
parents 1f2cfdd3 ec049891
...@@ -7,6 +7,14 @@ directory. These are intended to be small tests to exercise individual code ...@@ -7,6 +7,14 @@ directory. These are intended to be small tests to exercise individual code
paths in the kernel. Tests are intended to be run after building, installing paths in the kernel. Tests are intended to be run after building, installing
and booting a kernel. and booting a kernel.
Kselftest from mainline can be run on older stable kernels. Running tests
from mainline offers the best coverage. Several test rings run mainline
kselftest suite on stable releases. The reason is that when a new test
gets added to test existing code to regression test a bug, we should be
able to run that test on an older kernel. Hence, it is important to keep
code that can still test an older kernel and make sure it skips the test
gracefully on newer releases.
You can find additional information on Kselftest framework, how to You can find additional information on Kselftest framework, how to
write new tests using the framework on Kselftest wiki: write new tests using the framework on Kselftest wiki:
......
...@@ -194,5 +194,5 @@ prerequisite ...@@ -194,5 +194,5 @@ prerequisite
# Run requested functions # Run requested functions
clear_dumps $OUTFILE clear_dumps $OUTFILE
do_test >> $OUTFILE.txt do_test | tee -a $OUTFILE.txt
dmesg_dumps $OUTFILE dmesg_dumps $OUTFILE
...@@ -5,7 +5,7 @@ CFLAGS += -D_GNU_SOURCE ...@@ -5,7 +5,7 @@ CFLAGS += -D_GNU_SOURCE
TEST_PROGS := binfmt_script non-regular TEST_PROGS := binfmt_script non-regular
TEST_GEN_PROGS := execveat load_address_4096 load_address_2097152 load_address_16777216 TEST_GEN_PROGS := execveat load_address_4096 load_address_2097152 load_address_16777216
TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir pipe TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir
# Makefile is a run-time dependency, since it's accessed by the execveat test # Makefile is a run-time dependency, since it's accessed by the execveat test
TEST_FILES := Makefile TEST_FILES := Makefile
......
...@@ -11,7 +11,7 @@ all: ...@@ -11,7 +11,7 @@ all:
@for DIR in $(SUBDIRS); do \ @for DIR in $(SUBDIRS); do \
BUILD_TARGET=$(OUTPUT)/$$DIR; \ BUILD_TARGET=$(OUTPUT)/$$DIR; \
mkdir $$BUILD_TARGET -p; \ mkdir $$BUILD_TARGET -p; \
make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
if [ -e $$DIR/$(TEST_PROGS) ]; then \ if [ -e $$DIR/$(TEST_PROGS) ]; then \
rsync -a $$DIR/$(TEST_PROGS) $$BUILD_TARGET/; \ rsync -a $$DIR/$(TEST_PROGS) $$BUILD_TARGET/; \
fi \ fi \
...@@ -32,6 +32,6 @@ override define CLEAN ...@@ -32,6 +32,6 @@ override define CLEAN
@for DIR in $(SUBDIRS); do \ @for DIR in $(SUBDIRS); do \
BUILD_TARGET=$(OUTPUT)/$$DIR; \ BUILD_TARGET=$(OUTPUT)/$$DIR; \
mkdir $$BUILD_TARGET -p; \ mkdir $$BUILD_TARGET -p; \
make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
done done
endef endef
...@@ -877,7 +877,8 @@ static void __timeout_handler(int sig, siginfo_t *info, void *ucontext) ...@@ -877,7 +877,8 @@ static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
} }
t->timed_out = true; t->timed_out = true;
kill(t->pid, SIGKILL); // signal process group
kill(-(t->pid), SIGKILL);
} }
void __wait_for_test(struct __test_metadata *t) void __wait_for_test(struct __test_metadata *t)
...@@ -987,6 +988,7 @@ void __run_test(struct __fixture_metadata *f, ...@@ -987,6 +988,7 @@ void __run_test(struct __fixture_metadata *f,
ksft_print_msg("ERROR SPAWNING TEST CHILD\n"); ksft_print_msg("ERROR SPAWNING TEST CHILD\n");
t->passed = 0; t->passed = 0;
} else if (t->pid == 0) { } else if (t->pid == 0) {
setpgrp();
t->fn(t, variant); t->fn(t, variant);
if (t->skip) if (t->skip)
_exit(255); _exit(255);
......
...@@ -207,16 +207,22 @@ TEST(check_file_mmap) ...@@ -207,16 +207,22 @@ TEST(check_file_mmap)
errno = 0; errno = 0;
fd = open(".", O_TMPFILE | O_RDWR, 0600); fd = open(".", O_TMPFILE | O_RDWR, 0600);
ASSERT_NE(-1, fd) { if (fd < 0) {
ASSERT_EQ(errno, EOPNOTSUPP) {
TH_LOG("Can't create temporary file: %s", TH_LOG("Can't create temporary file: %s",
strerror(errno)); strerror(errno));
} }
SKIP(goto out_free, "O_TMPFILE not supported by filesystem.");
}
errno = 0; errno = 0;
retval = fallocate(fd, 0, 0, FILE_SIZE); retval = fallocate(fd, 0, 0, FILE_SIZE);
ASSERT_EQ(0, retval) { if (retval) {
ASSERT_EQ(errno, EOPNOTSUPP) {
TH_LOG("Error allocating space for the temporary file: %s", TH_LOG("Error allocating space for the temporary file: %s",
strerror(errno)); strerror(errno));
} }
SKIP(goto out_close, "fallocate not supported by filesystem.");
}
/* /*
* Map the whole file, the pages shouldn't be fetched yet. * Map the whole file, the pages shouldn't be fetched yet.
...@@ -271,7 +277,9 @@ TEST(check_file_mmap) ...@@ -271,7 +277,9 @@ TEST(check_file_mmap)
} }
munmap(addr, FILE_SIZE); munmap(addr, FILE_SIZE);
out_close:
close(fd); close(fd);
out_free:
free(vec); free(vec);
} }
......
...@@ -5,4 +5,4 @@ TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test ...@@ -5,4 +5,4 @@ TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test
include ../lib.mk include ../lib.mk
$(TEST_GEN_PROGS): helpers.c $(TEST_GEN_PROGS): helpers.c helpers.h
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include <errno.h> #include <errno.h>
#include <linux/types.h> #include <linux/types.h>
#include "../kselftest.h" #include "../kselftest.h"
...@@ -64,9 +65,10 @@ bool needs_openat2(const struct open_how *how); ...@@ -64,9 +65,10 @@ bool needs_openat2(const struct open_how *how);
#define E_func(func, ...) \ #define E_func(func, ...) \
do { \ do { \
errno = 0; \
if (func(__VA_ARGS__) < 0) \ if (func(__VA_ARGS__) < 0) \
ksft_exit_fail_msg("%s:%d %s failed\n", \ ksft_exit_fail_msg("%s:%d %s failed - errno:%d\n", \
__FILE__, __LINE__, #func);\ __FILE__, __LINE__, #func, errno); \
} while (0) } while (0)
#define E_asprintf(...) E_func(asprintf, __VA_ARGS__) #define E_asprintf(...) E_func(asprintf, __VA_ARGS__)
......
...@@ -259,6 +259,16 @@ void test_openat2_flags(void) ...@@ -259,6 +259,16 @@ void test_openat2_flags(void)
unlink(path); unlink(path);
fd = sys_openat2(AT_FDCWD, path, &test->how); fd = sys_openat2(AT_FDCWD, path, &test->how);
if (fd < 0 && fd == -EOPNOTSUPP) {
/*
* Skip the testcase if it failed because not supported
* by FS. (e.g. a valid O_TMPFILE combination on NFS)
*/
ksft_test_result_skip("openat2 with %s fails with %d (%s)\n",
test->name, fd, strerror(-fd));
goto next;
}
if (test->err >= 0) if (test->err >= 0)
failed = (fd < 0); failed = (fd < 0);
else else
...@@ -303,7 +313,7 @@ void test_openat2_flags(void) ...@@ -303,7 +313,7 @@ void test_openat2_flags(void)
else else
resultfn("openat2 with %s fails with %d (%s)\n", resultfn("openat2 with %s fails with %d (%s)\n",
test->name, test->err, strerror(-test->err)); test->name, test->err, strerror(-test->err));
next:
free(fdpath); free(fdpath);
fflush(stdout); fflush(stdout);
} }
......
...@@ -33,110 +33,114 @@ typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts); ...@@ -33,110 +33,114 @@ typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts);
typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts); typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts);
typedef time_t (*vdso_time_t)(time_t *t); typedef time_t (*vdso_time_t)(time_t *t);
static int vdso_test_gettimeofday(void) #define VDSO_TEST_PASS_MSG() "\n%s(): PASS\n", __func__
#define VDSO_TEST_FAIL_MSG(x) "\n%s(): %s FAIL\n", __func__, x
#define VDSO_TEST_SKIP_MSG(x) "\n%s(): SKIP: Could not find %s\n", __func__, x
static void vdso_test_gettimeofday(void)
{ {
/* Find gettimeofday. */ /* Find gettimeofday. */
vdso_gettimeofday_t vdso_gettimeofday = vdso_gettimeofday_t vdso_gettimeofday =
(vdso_gettimeofday_t)vdso_sym(version, name[0]); (vdso_gettimeofday_t)vdso_sym(version, name[0]);
if (!vdso_gettimeofday) { if (!vdso_gettimeofday) {
printf("Could not find %s\n", name[0]); ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[0]));
return KSFT_SKIP; return;
} }
struct timeval tv; struct timeval tv;
long ret = vdso_gettimeofday(&tv, 0); long ret = vdso_gettimeofday(&tv, 0);
if (ret == 0) { if (ret == 0) {
printf("The time is %lld.%06lld\n", ksft_print_msg("The time is %lld.%06lld\n",
(long long)tv.tv_sec, (long long)tv.tv_usec); (long long)tv.tv_sec, (long long)tv.tv_usec);
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
} else { } else {
printf("%s failed\n", name[0]); ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[0]));
return KSFT_FAIL;
} }
return KSFT_PASS;
} }
static int vdso_test_clock_gettime(clockid_t clk_id) static void vdso_test_clock_gettime(clockid_t clk_id)
{ {
/* Find clock_gettime. */ /* Find clock_gettime. */
vdso_clock_gettime_t vdso_clock_gettime = vdso_clock_gettime_t vdso_clock_gettime =
(vdso_clock_gettime_t)vdso_sym(version, name[1]); (vdso_clock_gettime_t)vdso_sym(version, name[1]);
if (!vdso_clock_gettime) { if (!vdso_clock_gettime) {
printf("Could not find %s\n", name[1]); ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[1]));
return KSFT_SKIP; return;
} }
struct timespec ts; struct timespec ts;
long ret = vdso_clock_gettime(clk_id, &ts); long ret = vdso_clock_gettime(clk_id, &ts);
if (ret == 0) { if (ret == 0) {
printf("The time is %lld.%06lld\n", ksft_print_msg("The time is %lld.%06lld\n",
(long long)ts.tv_sec, (long long)ts.tv_nsec); (long long)ts.tv_sec, (long long)ts.tv_nsec);
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
} else { } else {
printf("%s failed\n", name[1]); ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[1]));
return KSFT_FAIL;
} }
return KSFT_PASS;
} }
static int vdso_test_time(void) static void vdso_test_time(void)
{ {
/* Find time. */ /* Find time. */
vdso_time_t vdso_time = vdso_time_t vdso_time =
(vdso_time_t)vdso_sym(version, name[2]); (vdso_time_t)vdso_sym(version, name[2]);
if (!vdso_time) { if (!vdso_time) {
printf("Could not find %s\n", name[2]); ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[2]));
return KSFT_SKIP; return;
} }
long ret = vdso_time(NULL); long ret = vdso_time(NULL);
if (ret > 0) { if (ret > 0) {
printf("The time in hours since January 1, 1970 is %lld\n", ksft_print_msg("The time in hours since January 1, 1970 is %lld\n",
(long long)(ret / 3600)); (long long)(ret / 3600));
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
} else { } else {
printf("%s failed\n", name[2]); ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[2]));
return KSFT_FAIL;
} }
return KSFT_PASS;
} }
static int vdso_test_clock_getres(clockid_t clk_id) static void vdso_test_clock_getres(clockid_t clk_id)
{ {
int clock_getres_fail = 0;
/* Find clock_getres. */ /* Find clock_getres. */
vdso_clock_getres_t vdso_clock_getres = vdso_clock_getres_t vdso_clock_getres =
(vdso_clock_getres_t)vdso_sym(version, name[3]); (vdso_clock_getres_t)vdso_sym(version, name[3]);
if (!vdso_clock_getres) { if (!vdso_clock_getres) {
printf("Could not find %s\n", name[3]); ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[3]));
return KSFT_SKIP; return;
} }
struct timespec ts, sys_ts; struct timespec ts, sys_ts;
long ret = vdso_clock_getres(clk_id, &ts); long ret = vdso_clock_getres(clk_id, &ts);
if (ret == 0) { if (ret == 0) {
printf("The resolution is %lld %lld\n", ksft_print_msg("The vdso resolution is %lld %lld\n",
(long long)ts.tv_sec, (long long)ts.tv_nsec); (long long)ts.tv_sec, (long long)ts.tv_nsec);
} else { } else {
printf("%s failed\n", name[3]); clock_getres_fail++;
return KSFT_FAIL;
} }
ret = syscall(SYS_clock_getres, clk_id, &sys_ts); ret = syscall(SYS_clock_getres, clk_id, &sys_ts);
if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec)) { ksft_print_msg("The syscall resolution is %lld %lld\n",
printf("%s failed\n", name[3]); (long long)sys_ts.tv_sec, (long long)sys_ts.tv_nsec);
return KSFT_FAIL;
}
return KSFT_PASS; if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec))
clock_getres_fail++;
if (clock_getres_fail > 0) {
ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[3]));
} else {
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
}
} }
const char *vdso_clock_name[12] = { const char *vdso_clock_name[12] = {
...@@ -158,36 +162,23 @@ const char *vdso_clock_name[12] = { ...@@ -158,36 +162,23 @@ const char *vdso_clock_name[12] = {
* This function calls vdso_test_clock_gettime and vdso_test_clock_getres * This function calls vdso_test_clock_gettime and vdso_test_clock_getres
* with different values for clock_id. * with different values for clock_id.
*/ */
static inline int vdso_test_clock(clockid_t clock_id) static inline void vdso_test_clock(clockid_t clock_id)
{ {
int ret0, ret1; ksft_print_msg("\nclock_id: %s\n", vdso_clock_name[clock_id]);
ret0 = vdso_test_clock_gettime(clock_id);
/* A skipped test is considered passed */
if (ret0 == KSFT_SKIP)
ret0 = KSFT_PASS;
ret1 = vdso_test_clock_getres(clock_id);
/* A skipped test is considered passed */
if (ret1 == KSFT_SKIP)
ret1 = KSFT_PASS;
ret0 += ret1; vdso_test_clock_gettime(clock_id);
printf("clock_id: %s", vdso_clock_name[clock_id]); vdso_test_clock_getres(clock_id);
if (ret0 > 0)
printf(" [FAIL]\n");
else
printf(" [PASS]\n");
return ret0;
} }
#define VDSO_TEST_PLAN 16
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR); unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
int ret;
ksft_print_header();
ksft_set_plan(VDSO_TEST_PLAN);
if (!sysinfo_ehdr) { if (!sysinfo_ehdr) {
printf("AT_SYSINFO_EHDR is not present!\n"); printf("AT_SYSINFO_EHDR is not present!\n");
...@@ -201,44 +192,42 @@ int main(int argc, char **argv) ...@@ -201,44 +192,42 @@ int main(int argc, char **argv)
vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR)); vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
ret = vdso_test_gettimeofday(); vdso_test_gettimeofday();
#if _POSIX_TIMERS > 0 #if _POSIX_TIMERS > 0
#ifdef CLOCK_REALTIME #ifdef CLOCK_REALTIME
ret += vdso_test_clock(CLOCK_REALTIME); vdso_test_clock(CLOCK_REALTIME);
#endif #endif
#ifdef CLOCK_BOOTTIME #ifdef CLOCK_BOOTTIME
ret += vdso_test_clock(CLOCK_BOOTTIME); vdso_test_clock(CLOCK_BOOTTIME);
#endif #endif
#ifdef CLOCK_TAI #ifdef CLOCK_TAI
ret += vdso_test_clock(CLOCK_TAI); vdso_test_clock(CLOCK_TAI);
#endif #endif
#ifdef CLOCK_REALTIME_COARSE #ifdef CLOCK_REALTIME_COARSE
ret += vdso_test_clock(CLOCK_REALTIME_COARSE); vdso_test_clock(CLOCK_REALTIME_COARSE);
#endif #endif
#ifdef CLOCK_MONOTONIC #ifdef CLOCK_MONOTONIC
ret += vdso_test_clock(CLOCK_MONOTONIC); vdso_test_clock(CLOCK_MONOTONIC);
#endif #endif
#ifdef CLOCK_MONOTONIC_RAW #ifdef CLOCK_MONOTONIC_RAW
ret += vdso_test_clock(CLOCK_MONOTONIC_RAW); vdso_test_clock(CLOCK_MONOTONIC_RAW);
#endif #endif
#ifdef CLOCK_MONOTONIC_COARSE #ifdef CLOCK_MONOTONIC_COARSE
ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE); vdso_test_clock(CLOCK_MONOTONIC_COARSE);
#endif #endif
#endif #endif
ret += vdso_test_time(); vdso_test_time();
if (ret > 0)
return KSFT_FAIL;
return KSFT_PASS; ksft_print_cnts();
return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;
} }
...@@ -2,9 +2,6 @@ ...@@ -2,9 +2,6 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
TCID="zram.sh" TCID="zram.sh"
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
. ./zram_lib.sh . ./zram_lib.sh
run_zram () { run_zram () {
...@@ -18,14 +15,4 @@ echo "" ...@@ -18,14 +15,4 @@ echo ""
check_prereqs check_prereqs
# check zram module exists run_zram
MODULE_PATH=/lib/modules/`uname -r`/kernel/drivers/block/zram/zram.ko
if [ -f $MODULE_PATH ]; then
run_zram
elif [ -b /dev/zram0 ]; then
run_zram
else
echo "$TCID : No zram.ko module or /dev/zram0 device file not found"
echo "$TCID : CONFIG_ZRAM is not set"
exit $ksft_skip
fi
...@@ -33,9 +33,7 @@ zram_algs="lzo" ...@@ -33,9 +33,7 @@ zram_algs="lzo"
zram_fill_fs() zram_fill_fs()
{ {
local mem_free0=$(free -m | awk 'NR==2 {print $4}') for i in $(seq $dev_start $dev_end); do
for i in $(seq 0 $(($dev_num - 1))); do
echo "fill zram$i..." echo "fill zram$i..."
local b=0 local b=0
while [ true ]; do while [ true ]; do
...@@ -45,29 +43,17 @@ zram_fill_fs() ...@@ -45,29 +43,17 @@ zram_fill_fs()
b=$(($b + 1)) b=$(($b + 1))
done done
echo "zram$i can be filled with '$b' KB" echo "zram$i can be filled with '$b' KB"
done
local mem_free1=$(free -m | awk 'NR==2 {print $4}')
local used_mem=$(($mem_free0 - $mem_free1))
local total_size=0
for sm in $zram_sizes; do
local s=$(echo $sm | sed 's/M//')
total_size=$(($total_size + $s))
done
echo "zram used ${used_mem}M, zram disk sizes ${total_size}M"
local v=$((100 * $total_size / $used_mem))
local mem_used_total=`awk '{print $3}' "/sys/block/zram$i/mm_stat"`
local v=$((100 * 1024 * $b / $mem_used_total))
if [ "$v" -lt 100 ]; then if [ "$v" -lt 100 ]; then
echo "FAIL compression ratio: 0.$v:1" echo "FAIL compression ratio: 0.$v:1"
ERR_CODE=-1 ERR_CODE=-1
zram_cleanup
return return
fi fi
echo "zram compression ratio: $(echo "scale=2; $v / 100 " | bc):1: OK" echo "zram compression ratio: $(echo "scale=2; $v / 100 " | bc):1: OK"
done
} }
check_prereqs check_prereqs
...@@ -81,7 +67,6 @@ zram_mount ...@@ -81,7 +67,6 @@ zram_mount
zram_fill_fs zram_fill_fs
zram_cleanup zram_cleanup
zram_unload
if [ $ERR_CODE -ne 0 ]; then if [ $ERR_CODE -ne 0 ]; then
echo "$TCID : [FAIL]" echo "$TCID : [FAIL]"
......
...@@ -36,7 +36,6 @@ zram_set_memlimit ...@@ -36,7 +36,6 @@ zram_set_memlimit
zram_makeswap zram_makeswap
zram_swapoff zram_swapoff
zram_cleanup zram_cleanup
zram_unload
if [ $ERR_CODE -ne 0 ]; then if [ $ERR_CODE -ne 0 ]; then
echo "$TCID : [FAIL]" echo "$TCID : [FAIL]"
......
...@@ -5,12 +5,17 @@ ...@@ -5,12 +5,17 @@
# Author: Alexey Kodanev <alexey.kodanev@oracle.com> # Author: Alexey Kodanev <alexey.kodanev@oracle.com>
# Modified: Naresh Kamboju <naresh.kamboju@linaro.org> # Modified: Naresh Kamboju <naresh.kamboju@linaro.org>
MODULE=0
dev_makeswap=-1 dev_makeswap=-1
dev_mounted=-1 dev_mounted=-1
dev_start=0
dev_end=-1
module_load=-1
sys_control=-1
# Kselftest framework requirement - SKIP code is 4. # Kselftest framework requirement - SKIP code is 4.
ksft_skip=4 ksft_skip=4
kernel_version=`uname -r | cut -d'.' -f1,2`
kernel_major=${kernel_version%.*}
kernel_minor=${kernel_version#*.}
trap INT trap INT
...@@ -25,68 +30,104 @@ check_prereqs() ...@@ -25,68 +30,104 @@ check_prereqs()
fi fi
} }
kernel_gte()
{
major=${1%.*}
minor=${1#*.}
if [ $kernel_major -gt $major ]; then
return 0
elif [[ $kernel_major -eq $major && $kernel_minor -ge $minor ]]; then
return 0
fi
return 1
}
zram_cleanup() zram_cleanup()
{ {
echo "zram cleanup" echo "zram cleanup"
local i= local i=
for i in $(seq 0 $dev_makeswap); do for i in $(seq $dev_start $dev_makeswap); do
swapoff /dev/zram$i swapoff /dev/zram$i
done done
for i in $(seq 0 $dev_mounted); do for i in $(seq $dev_start $dev_mounted); do
umount /dev/zram$i umount /dev/zram$i
done done
for i in $(seq 0 $(($dev_num - 1))); do for i in $(seq $dev_start $dev_end); do
echo 1 > /sys/block/zram${i}/reset echo 1 > /sys/block/zram${i}/reset
rm -rf zram$i rm -rf zram$i
done done
} if [ $sys_control -eq 1 ]; then
for i in $(seq $dev_start $dev_end); do
echo $i > /sys/class/zram-control/hot_remove
done
fi
zram_unload() if [ $module_load -eq 1 ]; then
{
if [ $MODULE -ne 0 ] ; then
echo "zram rmmod zram"
rmmod zram > /dev/null 2>&1 rmmod zram > /dev/null 2>&1
fi fi
} }
zram_load() zram_load()
{ {
# check zram module exists
MODULE_PATH=/lib/modules/`uname -r`/kernel/drivers/block/zram/zram.ko
if [ -f $MODULE_PATH ]; then
MODULE=1
echo "create '$dev_num' zram device(s)" echo "create '$dev_num' zram device(s)"
# zram module loaded, new kernel
if [ -d "/sys/class/zram-control" ]; then
echo "zram modules already loaded, kernel supports" \
"zram-control interface"
dev_start=$(ls /dev/zram* | wc -w)
dev_end=$(($dev_start + $dev_num - 1))
sys_control=1
for i in $(seq $dev_start $dev_end); do
cat /sys/class/zram-control/hot_add > /dev/null
done
echo "all zram devices (/dev/zram$dev_start~$dev_end" \
"successfully created"
return 0
fi
# detect old kernel or built-in
modprobe zram num_devices=$dev_num modprobe zram num_devices=$dev_num
if [ ! -d "/sys/class/zram-control" ]; then
if grep -q '^zram' /proc/modules; then
rmmod zram > /dev/null 2>&1
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "failed to insert zram module" echo "zram module is being used on old kernel" \
exit 1 "without zram-control interface"
exit $ksft_skip
fi fi
dev_num_created=$(ls /dev/zram* | wc -w)
if [ "$dev_num_created" -ne "$dev_num" ]; then
echo "unexpected num of devices: $dev_num_created"
ERR_CODE=-1
else else
echo "zram load module successful" echo "test needs CONFIG_ZRAM=m on old kernel without" \
"zram-control interface"
exit $ksft_skip
fi fi
elif [ -b /dev/zram0 ]; then modprobe zram num_devices=$dev_num
echo "/dev/zram0 device file found: OK"
else
echo "ERROR: No zram.ko module or no /dev/zram0 device found"
echo "$TCID : CONFIG_ZRAM is not set"
exit 1
fi fi
module_load=1
dev_end=$(($dev_num - 1))
echo "all zram devices (/dev/zram0~$dev_end) successfully created"
} }
zram_max_streams() zram_max_streams()
{ {
echo "set max_comp_streams to zram device(s)" echo "set max_comp_streams to zram device(s)"
local i=0 kernel_gte 4.7
if [ $? -eq 0 ]; then
echo "The device attribute max_comp_streams was"\
"deprecated in 4.7"
return 0
fi
local i=$dev_start
for max_s in $zram_max_streams; do for max_s in $zram_max_streams; do
local sys_path="/sys/block/zram${i}/max_comp_streams" local sys_path="/sys/block/zram${i}/max_comp_streams"
echo $max_s > $sys_path || \ echo $max_s > $sys_path || \
...@@ -98,7 +139,7 @@ zram_max_streams() ...@@ -98,7 +139,7 @@ zram_max_streams()
echo "FAIL can't set max_streams '$max_s', get $max_stream" echo "FAIL can't set max_streams '$max_s', get $max_stream"
i=$(($i + 1)) i=$(($i + 1))
echo "$sys_path = '$max_streams' ($i/$dev_num)" echo "$sys_path = '$max_streams'"
done done
echo "zram max streams: OK" echo "zram max streams: OK"
...@@ -108,15 +149,16 @@ zram_compress_alg() ...@@ -108,15 +149,16 @@ zram_compress_alg()
{ {
echo "test that we can set compression algorithm" echo "test that we can set compression algorithm"
local algs=$(cat /sys/block/zram0/comp_algorithm) local i=$dev_start
local algs=$(cat /sys/block/zram${i}/comp_algorithm)
echo "supported algs: $algs" echo "supported algs: $algs"
local i=0
for alg in $zram_algs; do for alg in $zram_algs; do
local sys_path="/sys/block/zram${i}/comp_algorithm" local sys_path="/sys/block/zram${i}/comp_algorithm"
echo "$alg" > $sys_path || \ echo "$alg" > $sys_path || \
echo "FAIL can't set '$alg' to $sys_path" echo "FAIL can't set '$alg' to $sys_path"
i=$(($i + 1)) i=$(($i + 1))
echo "$sys_path = '$alg' ($i/$dev_num)" echo "$sys_path = '$alg'"
done done
echo "zram set compression algorithm: OK" echo "zram set compression algorithm: OK"
...@@ -125,14 +167,14 @@ zram_compress_alg() ...@@ -125,14 +167,14 @@ zram_compress_alg()
zram_set_disksizes() zram_set_disksizes()
{ {
echo "set disk size to zram device(s)" echo "set disk size to zram device(s)"
local i=0 local i=$dev_start
for ds in $zram_sizes; do for ds in $zram_sizes; do
local sys_path="/sys/block/zram${i}/disksize" local sys_path="/sys/block/zram${i}/disksize"
echo "$ds" > $sys_path || \ echo "$ds" > $sys_path || \
echo "FAIL can't set '$ds' to $sys_path" echo "FAIL can't set '$ds' to $sys_path"
i=$(($i + 1)) i=$(($i + 1))
echo "$sys_path = '$ds' ($i/$dev_num)" echo "$sys_path = '$ds'"
done done
echo "zram set disksizes: OK" echo "zram set disksizes: OK"
...@@ -142,14 +184,14 @@ zram_set_memlimit() ...@@ -142,14 +184,14 @@ zram_set_memlimit()
{ {
echo "set memory limit to zram device(s)" echo "set memory limit to zram device(s)"
local i=0 local i=$dev_start
for ds in $zram_mem_limits; do for ds in $zram_mem_limits; do
local sys_path="/sys/block/zram${i}/mem_limit" local sys_path="/sys/block/zram${i}/mem_limit"
echo "$ds" > $sys_path || \ echo "$ds" > $sys_path || \
echo "FAIL can't set '$ds' to $sys_path" echo "FAIL can't set '$ds' to $sys_path"
i=$(($i + 1)) i=$(($i + 1))
echo "$sys_path = '$ds' ($i/$dev_num)" echo "$sys_path = '$ds'"
done done
echo "zram set memory limit: OK" echo "zram set memory limit: OK"
...@@ -158,8 +200,8 @@ zram_set_memlimit() ...@@ -158,8 +200,8 @@ zram_set_memlimit()
zram_makeswap() zram_makeswap()
{ {
echo "make swap with zram device(s)" echo "make swap with zram device(s)"
local i=0 local i=$dev_start
for i in $(seq 0 $(($dev_num - 1))); do for i in $(seq $dev_start $dev_end); do
mkswap /dev/zram$i > err.log 2>&1 mkswap /dev/zram$i > err.log 2>&1
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
cat err.log cat err.log
...@@ -182,7 +224,7 @@ zram_makeswap() ...@@ -182,7 +224,7 @@ zram_makeswap()
zram_swapoff() zram_swapoff()
{ {
local i= local i=
for i in $(seq 0 $dev_makeswap); do for i in $(seq $dev_start $dev_end); do
swapoff /dev/zram$i > err.log 2>&1 swapoff /dev/zram$i > err.log 2>&1
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
cat err.log cat err.log
...@@ -196,7 +238,7 @@ zram_swapoff() ...@@ -196,7 +238,7 @@ zram_swapoff()
zram_makefs() zram_makefs()
{ {
local i=0 local i=$dev_start
for fs in $zram_filesystems; do for fs in $zram_filesystems; do
# if requested fs not supported default it to ext2 # if requested fs not supported default it to ext2
which mkfs.$fs > /dev/null 2>&1 || fs=ext2 which mkfs.$fs > /dev/null 2>&1 || fs=ext2
...@@ -215,7 +257,7 @@ zram_makefs() ...@@ -215,7 +257,7 @@ zram_makefs()
zram_mount() zram_mount()
{ {
local i=0 local i=0
for i in $(seq 0 $(($dev_num - 1))); do for i in $(seq $dev_start $dev_end); do
echo "mount /dev/zram$i" echo "mount /dev/zram$i"
mkdir zram$i mkdir zram$i
mount /dev/zram$i zram$i > /dev/null || \ mount /dev/zram$i zram$i > /dev/null || \
......
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