linux-kselftest-fixes-5.17-rc3
This Kselftest fixes update for Linux 5.17-rc3 consists of 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEPZKym/RZuOCGeA/kCwJExA0NQxwFAmH8OcAACgkQCwJExA0N QxzTkg//YF+iSc1aao8nmUOvsK6oc1RBwIj3hkLUHjP3H1qFkm9OYxzTcLYGcnyo JahxNjeVoDuVESYx/AyLZ568aCCxRXJEDzNm5eIVNfBrGtVTfFPM19HwC/R3I1Ew KJUruxRx++8AvI1RYMEzsDumKpLVe3bor7sj3CcO1E9/qkOoUAukxt7FVmSNMZlW qYCDgc3yBa/XrImHCbJdZc4CUhbmh+l05sZgG3V3fxQSlgfIClY0Qg8W7Ucu+r4S 6W5nwoEJIG32Zl2avaZ2VTF4T+CTQB70g/n4OBEX8TAxuIIi9W12N6zMZ76q8qbp iRs7UqgUSqPWdz/3ZHiQ5gy0WsCJ/W1379TtiG0doEeU2vwZ6fR8NMn+2FrEH18W xHBPOWeN+PkVAFjUeoyt1c5OGNprK6EEE2kQ6CLoBTwlKWLDQ87ZNPf84uAsez1x G0m7AX/T5adeTLoZfEXNXVY4OROs0nxbAkGC5ghVtKQu1giMcUKj+KHUowgj5OIJ Zaj+uSPiN3hnwj5L2fk+orOEC+3bZxVoQzqSB2Bs6stQOQFZLP18xHIjQIDZoQuC O512ZY+dwMzSyTi2KoQmb/M0Ft3gSfhRVXc7gfEFfOvC3ZbqRGFfeES1ZILup3rZ izMTJBDOe+BGSm/GCFPHxu36YfdPqiAyHBTVSYy5EhLGpxafZvI= =rH2m -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
25b20ae815
|
@ -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
|
||||
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
|
||||
write new tests using the framework on Kselftest wiki:
|
||||
|
||||
|
|
|
@ -194,5 +194,5 @@ prerequisite
|
|||
|
||||
# Run requested functions
|
||||
clear_dumps $OUTFILE
|
||||
do_test >> $OUTFILE.txt
|
||||
do_test | tee -a $OUTFILE.txt
|
||||
dmesg_dumps $OUTFILE
|
||||
|
|
|
@ -5,7 +5,7 @@ CFLAGS += -D_GNU_SOURCE
|
|||
|
||||
TEST_PROGS := binfmt_script non-regular
|
||||
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
|
||||
TEST_FILES := Makefile
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ all:
|
|||
@for DIR in $(SUBDIRS); do \
|
||||
BUILD_TARGET=$(OUTPUT)/$$DIR; \
|
||||
mkdir $$BUILD_TARGET -p; \
|
||||
make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
|
||||
$(MAKE) OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
|
||||
if [ -e $$DIR/$(TEST_PROGS) ]; then \
|
||||
rsync -a $$DIR/$(TEST_PROGS) $$BUILD_TARGET/; \
|
||||
fi \
|
||||
|
@ -32,6 +32,6 @@ override define CLEAN
|
|||
@for DIR in $(SUBDIRS); do \
|
||||
BUILD_TARGET=$(OUTPUT)/$$DIR; \
|
||||
mkdir $$BUILD_TARGET -p; \
|
||||
make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
|
||||
$(MAKE) OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
|
||||
done
|
||||
endef
|
||||
|
|
|
@ -877,7 +877,8 @@ static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
|
|||
}
|
||||
|
||||
t->timed_out = true;
|
||||
kill(t->pid, SIGKILL);
|
||||
// signal process group
|
||||
kill(-(t->pid), SIGKILL);
|
||||
}
|
||||
|
||||
void __wait_for_test(struct __test_metadata *t)
|
||||
|
@ -987,6 +988,7 @@ void __run_test(struct __fixture_metadata *f,
|
|||
ksft_print_msg("ERROR SPAWNING TEST CHILD\n");
|
||||
t->passed = 0;
|
||||
} else if (t->pid == 0) {
|
||||
setpgrp();
|
||||
t->fn(t, variant);
|
||||
if (t->skip)
|
||||
_exit(255);
|
||||
|
|
|
@ -207,15 +207,21 @@ TEST(check_file_mmap)
|
|||
|
||||
errno = 0;
|
||||
fd = open(".", O_TMPFILE | O_RDWR, 0600);
|
||||
ASSERT_NE(-1, fd) {
|
||||
TH_LOG("Can't create temporary file: %s",
|
||||
strerror(errno));
|
||||
if (fd < 0) {
|
||||
ASSERT_EQ(errno, EOPNOTSUPP) {
|
||||
TH_LOG("Can't create temporary file: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
SKIP(goto out_free, "O_TMPFILE not supported by filesystem.");
|
||||
}
|
||||
errno = 0;
|
||||
retval = fallocate(fd, 0, 0, FILE_SIZE);
|
||||
ASSERT_EQ(0, retval) {
|
||||
TH_LOG("Error allocating space for the temporary file: %s",
|
||||
strerror(errno));
|
||||
if (retval) {
|
||||
ASSERT_EQ(errno, EOPNOTSUPP) {
|
||||
TH_LOG("Error allocating space for the temporary file: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
SKIP(goto out_close, "fallocate not supported by filesystem.");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -271,7 +277,9 @@ TEST(check_file_mmap)
|
|||
}
|
||||
|
||||
munmap(addr, FILE_SIZE);
|
||||
out_close:
|
||||
close(fd);
|
||||
out_free:
|
||||
free(vec);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,4 +5,4 @@ TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test
|
|||
|
||||
include ../lib.mk
|
||||
|
||||
$(TEST_GEN_PROGS): helpers.c
|
||||
$(TEST_GEN_PROGS): helpers.c helpers.h
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <linux/types.h>
|
||||
#include "../kselftest.h"
|
||||
|
@ -62,11 +63,12 @@ bool needs_openat2(const struct open_how *how);
|
|||
(similar to chroot(2)). */
|
||||
#endif /* RESOLVE_IN_ROOT */
|
||||
|
||||
#define E_func(func, ...) \
|
||||
do { \
|
||||
if (func(__VA_ARGS__) < 0) \
|
||||
ksft_exit_fail_msg("%s:%d %s failed\n", \
|
||||
__FILE__, __LINE__, #func);\
|
||||
#define E_func(func, ...) \
|
||||
do { \
|
||||
errno = 0; \
|
||||
if (func(__VA_ARGS__) < 0) \
|
||||
ksft_exit_fail_msg("%s:%d %s failed - errno:%d\n", \
|
||||
__FILE__, __LINE__, #func, errno); \
|
||||
} while (0)
|
||||
|
||||
#define E_asprintf(...) E_func(asprintf, __VA_ARGS__)
|
||||
|
|
|
@ -259,6 +259,16 @@ void test_openat2_flags(void)
|
|||
unlink(path);
|
||||
|
||||
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)
|
||||
failed = (fd < 0);
|
||||
else
|
||||
|
@ -303,7 +313,7 @@ skip:
|
|||
else
|
||||
resultfn("openat2 with %s fails with %d (%s)\n",
|
||||
test->name, test->err, strerror(-test->err));
|
||||
|
||||
next:
|
||||
free(fdpath);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
timeout=90
|
||||
timeout=180
|
||||
|
|
|
@ -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 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. */
|
||||
vdso_gettimeofday_t vdso_gettimeofday =
|
||||
(vdso_gettimeofday_t)vdso_sym(version, name[0]);
|
||||
|
||||
if (!vdso_gettimeofday) {
|
||||
printf("Could not find %s\n", name[0]);
|
||||
return KSFT_SKIP;
|
||||
ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
struct timeval tv;
|
||||
long ret = vdso_gettimeofday(&tv, 0);
|
||||
|
||||
if (ret == 0) {
|
||||
printf("The time is %lld.%06lld\n",
|
||||
(long long)tv.tv_sec, (long long)tv.tv_usec);
|
||||
ksft_print_msg("The time is %lld.%06lld\n",
|
||||
(long long)tv.tv_sec, (long long)tv.tv_usec);
|
||||
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
|
||||
} else {
|
||||
printf("%s failed\n", name[0]);
|
||||
return KSFT_FAIL;
|
||||
ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[0]));
|
||||
}
|
||||
|
||||
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. */
|
||||
vdso_clock_gettime_t vdso_clock_gettime =
|
||||
(vdso_clock_gettime_t)vdso_sym(version, name[1]);
|
||||
|
||||
if (!vdso_clock_gettime) {
|
||||
printf("Could not find %s\n", name[1]);
|
||||
return KSFT_SKIP;
|
||||
ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[1]));
|
||||
return;
|
||||
}
|
||||
|
||||
struct timespec ts;
|
||||
long ret = vdso_clock_gettime(clk_id, &ts);
|
||||
|
||||
if (ret == 0) {
|
||||
printf("The time is %lld.%06lld\n",
|
||||
(long long)ts.tv_sec, (long long)ts.tv_nsec);
|
||||
ksft_print_msg("The time is %lld.%06lld\n",
|
||||
(long long)ts.tv_sec, (long long)ts.tv_nsec);
|
||||
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
|
||||
} else {
|
||||
printf("%s failed\n", name[1]);
|
||||
return KSFT_FAIL;
|
||||
ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[1]));
|
||||
}
|
||||
|
||||
return KSFT_PASS;
|
||||
}
|
||||
|
||||
static int vdso_test_time(void)
|
||||
static void vdso_test_time(void)
|
||||
{
|
||||
/* Find time. */
|
||||
vdso_time_t vdso_time =
|
||||
(vdso_time_t)vdso_sym(version, name[2]);
|
||||
|
||||
if (!vdso_time) {
|
||||
printf("Could not find %s\n", name[2]);
|
||||
return KSFT_SKIP;
|
||||
ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[2]));
|
||||
return;
|
||||
}
|
||||
|
||||
long ret = vdso_time(NULL);
|
||||
|
||||
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));
|
||||
ksft_test_result_pass(VDSO_TEST_PASS_MSG());
|
||||
} else {
|
||||
printf("%s failed\n", name[2]);
|
||||
return KSFT_FAIL;
|
||||
ksft_test_result_fail(VDSO_TEST_FAIL_MSG(name[2]));
|
||||
}
|
||||
|
||||
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. */
|
||||
vdso_clock_getres_t vdso_clock_getres =
|
||||
(vdso_clock_getres_t)vdso_sym(version, name[3]);
|
||||
|
||||
if (!vdso_clock_getres) {
|
||||
printf("Could not find %s\n", name[3]);
|
||||
return KSFT_SKIP;
|
||||
ksft_test_result_skip(VDSO_TEST_SKIP_MSG(name[3]));
|
||||
return;
|
||||
}
|
||||
|
||||
struct timespec ts, sys_ts;
|
||||
long ret = vdso_clock_getres(clk_id, &ts);
|
||||
|
||||
if (ret == 0) {
|
||||
printf("The resolution is %lld %lld\n",
|
||||
(long long)ts.tv_sec, (long long)ts.tv_nsec);
|
||||
ksft_print_msg("The vdso resolution is %lld %lld\n",
|
||||
(long long)ts.tv_sec, (long long)ts.tv_nsec);
|
||||
} else {
|
||||
printf("%s failed\n", name[3]);
|
||||
return KSFT_FAIL;
|
||||
clock_getres_fail++;
|
||||
}
|
||||
|
||||
ret = syscall(SYS_clock_getres, clk_id, &sys_ts);
|
||||
|
||||
if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec)) {
|
||||
printf("%s failed\n", name[3]);
|
||||
return KSFT_FAIL;
|
||||
}
|
||||
ksft_print_msg("The syscall resolution is %lld %lld\n",
|
||||
(long long)sys_ts.tv_sec, (long long)sys_ts.tv_nsec);
|
||||
|
||||
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] = {
|
||||
|
@ -158,36 +162,23 @@ const char *vdso_clock_name[12] = {
|
|||
* This function calls vdso_test_clock_gettime and vdso_test_clock_getres
|
||||
* 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;
|
||||
vdso_test_clock_gettime(clock_id);
|
||||
|
||||
ret1 = vdso_test_clock_getres(clock_id);
|
||||
/* A skipped test is considered passed */
|
||||
if (ret1 == KSFT_SKIP)
|
||||
ret1 = KSFT_PASS;
|
||||
|
||||
ret0 += ret1;
|
||||
|
||||
printf("clock_id: %s", vdso_clock_name[clock_id]);
|
||||
|
||||
if (ret0 > 0)
|
||||
printf(" [FAIL]\n");
|
||||
else
|
||||
printf(" [PASS]\n");
|
||||
|
||||
return ret0;
|
||||
vdso_test_clock_getres(clock_id);
|
||||
}
|
||||
|
||||
#define VDSO_TEST_PLAN 16
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
|
||||
int ret;
|
||||
|
||||
ksft_print_header();
|
||||
ksft_set_plan(VDSO_TEST_PLAN);
|
||||
|
||||
if (!sysinfo_ehdr) {
|
||||
printf("AT_SYSINFO_EHDR is not present!\n");
|
||||
|
@ -201,44 +192,42 @@ int main(int argc, char **argv)
|
|||
|
||||
vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
|
||||
|
||||
ret = vdso_test_gettimeofday();
|
||||
vdso_test_gettimeofday();
|
||||
|
||||
#if _POSIX_TIMERS > 0
|
||||
|
||||
#ifdef CLOCK_REALTIME
|
||||
ret += vdso_test_clock(CLOCK_REALTIME);
|
||||
vdso_test_clock(CLOCK_REALTIME);
|
||||
#endif
|
||||
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
ret += vdso_test_clock(CLOCK_BOOTTIME);
|
||||
vdso_test_clock(CLOCK_BOOTTIME);
|
||||
#endif
|
||||
|
||||
#ifdef CLOCK_TAI
|
||||
ret += vdso_test_clock(CLOCK_TAI);
|
||||
vdso_test_clock(CLOCK_TAI);
|
||||
#endif
|
||||
|
||||
#ifdef CLOCK_REALTIME_COARSE
|
||||
ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
|
||||
vdso_test_clock(CLOCK_REALTIME_COARSE);
|
||||
#endif
|
||||
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
ret += vdso_test_clock(CLOCK_MONOTONIC);
|
||||
vdso_test_clock(CLOCK_MONOTONIC);
|
||||
#endif
|
||||
|
||||
#ifdef CLOCK_MONOTONIC_RAW
|
||||
ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
|
||||
vdso_test_clock(CLOCK_MONOTONIC_RAW);
|
||||
#endif
|
||||
|
||||
#ifdef CLOCK_MONOTONIC_COARSE
|
||||
ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
|
||||
vdso_test_clock(CLOCK_MONOTONIC_COARSE);
|
||||
#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 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
TCID="zram.sh"
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
|
||||
. ./zram_lib.sh
|
||||
|
||||
run_zram () {
|
||||
|
@ -18,14 +15,4 @@ echo ""
|
|||
|
||||
check_prereqs
|
||||
|
||||
# check zram module exists
|
||||
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
|
||||
run_zram
|
||||
|
|
|
@ -33,9 +33,7 @@ zram_algs="lzo"
|
|||
|
||||
zram_fill_fs()
|
||||
{
|
||||
local mem_free0=$(free -m | awk 'NR==2 {print $4}')
|
||||
|
||||
for i in $(seq 0 $(($dev_num - 1))); do
|
||||
for i in $(seq $dev_start $dev_end); do
|
||||
echo "fill zram$i..."
|
||||
local b=0
|
||||
while [ true ]; do
|
||||
|
@ -45,29 +43,17 @@ zram_fill_fs()
|
|||
b=$(($b + 1))
|
||||
done
|
||||
echo "zram$i can be filled with '$b' KB"
|
||||
|
||||
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
|
||||
echo "FAIL compression ratio: 0.$v:1"
|
||||
ERR_CODE=-1
|
||||
return
|
||||
fi
|
||||
|
||||
echo "zram compression ratio: $(echo "scale=2; $v / 100 " | bc):1: OK"
|
||||
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))
|
||||
|
||||
if [ "$v" -lt 100 ]; then
|
||||
echo "FAIL compression ratio: 0.$v:1"
|
||||
ERR_CODE=-1
|
||||
zram_cleanup
|
||||
return
|
||||
fi
|
||||
|
||||
echo "zram compression ratio: $(echo "scale=2; $v / 100 " | bc):1: OK"
|
||||
}
|
||||
|
||||
check_prereqs
|
||||
|
@ -81,7 +67,6 @@ zram_mount
|
|||
|
||||
zram_fill_fs
|
||||
zram_cleanup
|
||||
zram_unload
|
||||
|
||||
if [ $ERR_CODE -ne 0 ]; then
|
||||
echo "$TCID : [FAIL]"
|
||||
|
|
|
@ -36,7 +36,6 @@ zram_set_memlimit
|
|||
zram_makeswap
|
||||
zram_swapoff
|
||||
zram_cleanup
|
||||
zram_unload
|
||||
|
||||
if [ $ERR_CODE -ne 0 ]; then
|
||||
echo "$TCID : [FAIL]"
|
||||
|
|
|
@ -5,12 +5,17 @@
|
|||
# Author: Alexey Kodanev <alexey.kodanev@oracle.com>
|
||||
# Modified: Naresh Kamboju <naresh.kamboju@linaro.org>
|
||||
|
||||
MODULE=0
|
||||
dev_makeswap=-1
|
||||
dev_mounted=-1
|
||||
|
||||
dev_start=0
|
||||
dev_end=-1
|
||||
module_load=-1
|
||||
sys_control=-1
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
kernel_version=`uname -r | cut -d'.' -f1,2`
|
||||
kernel_major=${kernel_version%.*}
|
||||
kernel_minor=${kernel_version#*.}
|
||||
|
||||
trap INT
|
||||
|
||||
|
@ -25,68 +30,104 @@ check_prereqs()
|
|||
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()
|
||||
{
|
||||
echo "zram cleanup"
|
||||
local i=
|
||||
for i in $(seq 0 $dev_makeswap); do
|
||||
for i in $(seq $dev_start $dev_makeswap); do
|
||||
swapoff /dev/zram$i
|
||||
done
|
||||
|
||||
for i in $(seq 0 $dev_mounted); do
|
||||
for i in $(seq $dev_start $dev_mounted); do
|
||||
umount /dev/zram$i
|
||||
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
|
||||
rm -rf zram$i
|
||||
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 -ne 0 ] ; then
|
||||
echo "zram rmmod zram"
|
||||
if [ $module_load -eq 1 ]; then
|
||||
rmmod zram > /dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
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)"
|
||||
modprobe zram num_devices=$dev_num
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "failed to insert zram module"
|
||||
exit 1
|
||||
fi
|
||||
echo "create '$dev_num' zram device(s)"
|
||||
|
||||
dev_num_created=$(ls /dev/zram* | wc -w)
|
||||
# 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
|
||||
|
||||
if [ "$dev_num_created" -ne "$dev_num" ]; then
|
||||
echo "unexpected num of devices: $dev_num_created"
|
||||
ERR_CODE=-1
|
||||
else
|
||||
echo "zram load module successful"
|
||||
fi
|
||||
elif [ -b /dev/zram0 ]; then
|
||||
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
|
||||
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
|
||||
if [ ! -d "/sys/class/zram-control" ]; then
|
||||
if grep -q '^zram' /proc/modules; then
|
||||
rmmod zram > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "zram module is being used on old kernel" \
|
||||
"without zram-control interface"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
else
|
||||
echo "test needs CONFIG_ZRAM=m on old kernel without" \
|
||||
"zram-control interface"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
modprobe zram num_devices=$dev_num
|
||||
fi
|
||||
|
||||
module_load=1
|
||||
dev_end=$(($dev_num - 1))
|
||||
echo "all zram devices (/dev/zram0~$dev_end) successfully created"
|
||||
}
|
||||
|
||||
zram_max_streams()
|
||||
{
|
||||
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
|
||||
local sys_path="/sys/block/zram${i}/max_comp_streams"
|
||||
echo $max_s > $sys_path || \
|
||||
|
@ -98,7 +139,7 @@ zram_max_streams()
|
|||
echo "FAIL can't set max_streams '$max_s', get $max_stream"
|
||||
|
||||
i=$(($i + 1))
|
||||
echo "$sys_path = '$max_streams' ($i/$dev_num)"
|
||||
echo "$sys_path = '$max_streams'"
|
||||
done
|
||||
|
||||
echo "zram max streams: OK"
|
||||
|
@ -108,15 +149,16 @@ zram_compress_alg()
|
|||
{
|
||||
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"
|
||||
local i=0
|
||||
|
||||
for alg in $zram_algs; do
|
||||
local sys_path="/sys/block/zram${i}/comp_algorithm"
|
||||
echo "$alg" > $sys_path || \
|
||||
echo "FAIL can't set '$alg' to $sys_path"
|
||||
i=$(($i + 1))
|
||||
echo "$sys_path = '$alg' ($i/$dev_num)"
|
||||
echo "$sys_path = '$alg'"
|
||||
done
|
||||
|
||||
echo "zram set compression algorithm: OK"
|
||||
|
@ -125,14 +167,14 @@ zram_compress_alg()
|
|||
zram_set_disksizes()
|
||||
{
|
||||
echo "set disk size to zram device(s)"
|
||||
local i=0
|
||||
local i=$dev_start
|
||||
for ds in $zram_sizes; do
|
||||
local sys_path="/sys/block/zram${i}/disksize"
|
||||
echo "$ds" > $sys_path || \
|
||||
echo "FAIL can't set '$ds' to $sys_path"
|
||||
|
||||
i=$(($i + 1))
|
||||
echo "$sys_path = '$ds' ($i/$dev_num)"
|
||||
echo "$sys_path = '$ds'"
|
||||
done
|
||||
|
||||
echo "zram set disksizes: OK"
|
||||
|
@ -142,14 +184,14 @@ zram_set_memlimit()
|
|||
{
|
||||
echo "set memory limit to zram device(s)"
|
||||
|
||||
local i=0
|
||||
local i=$dev_start
|
||||
for ds in $zram_mem_limits; do
|
||||
local sys_path="/sys/block/zram${i}/mem_limit"
|
||||
echo "$ds" > $sys_path || \
|
||||
echo "FAIL can't set '$ds' to $sys_path"
|
||||
|
||||
i=$(($i + 1))
|
||||
echo "$sys_path = '$ds' ($i/$dev_num)"
|
||||
echo "$sys_path = '$ds'"
|
||||
done
|
||||
|
||||
echo "zram set memory limit: OK"
|
||||
|
@ -158,8 +200,8 @@ zram_set_memlimit()
|
|||
zram_makeswap()
|
||||
{
|
||||
echo "make swap with zram device(s)"
|
||||
local i=0
|
||||
for i in $(seq 0 $(($dev_num - 1))); do
|
||||
local i=$dev_start
|
||||
for i in $(seq $dev_start $dev_end); do
|
||||
mkswap /dev/zram$i > err.log 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
cat err.log
|
||||
|
@ -182,7 +224,7 @@ zram_makeswap()
|
|||
zram_swapoff()
|
||||
{
|
||||
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
|
||||
if [ $? -ne 0 ]; then
|
||||
cat err.log
|
||||
|
@ -196,7 +238,7 @@ zram_swapoff()
|
|||
|
||||
zram_makefs()
|
||||
{
|
||||
local i=0
|
||||
local i=$dev_start
|
||||
for fs in $zram_filesystems; do
|
||||
# if requested fs not supported default it to ext2
|
||||
which mkfs.$fs > /dev/null 2>&1 || fs=ext2
|
||||
|
@ -215,7 +257,7 @@ zram_makefs()
|
|||
zram_mount()
|
||||
{
|
||||
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"
|
||||
mkdir zram$i
|
||||
mount /dev/zram$i zram$i > /dev/null || \
|
||||
|
|
Loading…
Reference in New Issue