Merge remote-tracking branch 'tip/perf/core' into perf/urgent
To pick up fixes. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
perf-y += builtin-test.o
|
||||
perf-y += parse-events.o
|
||||
perf-y += dso-data.o
|
||||
@@ -50,6 +52,8 @@ perf-y += perf-hooks.o
|
||||
perf-y += clang.o
|
||||
perf-y += unit_number__scnprintf.o
|
||||
perf-y += mem2node.o
|
||||
perf-y += map_groups.o
|
||||
perf-y += time-utils-test.o
|
||||
|
||||
$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
|
||||
$(call rule_mkdir)
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
|
||||
* 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* bpf-script-example.c
|
||||
* Test basic LLVM building
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* bpf-script-test-kbuild.c
|
||||
* Test include from kernel header
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* bpf-script-test-prologue.c
|
||||
* Test BPF prologue
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* bpf-script-test-relocation.c
|
||||
* Test BPF loader checking relocation
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/epoll.h>
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "string2.h"
|
||||
#include "symbol.h"
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <subcmd/exec-cmd.h>
|
||||
|
||||
static bool dont_fork;
|
||||
@@ -289,6 +290,14 @@ static struct test generic_tests[] = {
|
||||
.desc = "mem2node",
|
||||
.func = test__mem2node,
|
||||
},
|
||||
{
|
||||
.desc = "time utils",
|
||||
.func = test__time_utils,
|
||||
},
|
||||
{
|
||||
.desc = "map_groups__merge_in",
|
||||
.func = test__map_groups__merge_in,
|
||||
},
|
||||
{
|
||||
.func = NULL,
|
||||
},
|
||||
@@ -430,7 +439,7 @@ static const char *shell_test__description(char *description, size_t size,
|
||||
description = fgets(description, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return description ? trim(description + 1) : NULL;
|
||||
return description ? strim(description + 1) : NULL;
|
||||
}
|
||||
|
||||
#define for_each_shell_test(dir, base, ent) \
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include "sane_ctype.h"
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#define BUFSZ 1024
|
||||
#define READLEN 128
|
||||
|
121
tools/perf/tests/map_groups.c
Normal file
121
tools/perf/tests/map_groups.c
Normal file
@@ -0,0 +1,121 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "tests.h"
|
||||
#include "map.h"
|
||||
#include "map_groups.h"
|
||||
#include "dso.h"
|
||||
#include "debug.h"
|
||||
|
||||
struct map_def {
|
||||
const char *name;
|
||||
u64 start;
|
||||
u64 end;
|
||||
};
|
||||
|
||||
static int check_maps(struct map_def *merged, unsigned int size, struct map_groups *mg)
|
||||
{
|
||||
struct map *map;
|
||||
unsigned int i = 0;
|
||||
|
||||
map = map_groups__first(mg);
|
||||
while (map) {
|
||||
TEST_ASSERT_VAL("wrong map start", map->start == merged[i].start);
|
||||
TEST_ASSERT_VAL("wrong map end", map->end == merged[i].end);
|
||||
TEST_ASSERT_VAL("wrong map name", !strcmp(map->dso->name, merged[i].name));
|
||||
TEST_ASSERT_VAL("wrong map refcnt", refcount_read(&map->refcnt) == 2);
|
||||
|
||||
i++;
|
||||
map = map_groups__next(map);
|
||||
|
||||
TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i == size));
|
||||
}
|
||||
|
||||
return TEST_OK;
|
||||
}
|
||||
|
||||
int test__map_groups__merge_in(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
{
|
||||
struct map_groups mg;
|
||||
unsigned int i;
|
||||
struct map_def bpf_progs[] = {
|
||||
{ "bpf_prog_1", 200, 300 },
|
||||
{ "bpf_prog_2", 500, 600 },
|
||||
{ "bpf_prog_3", 800, 900 },
|
||||
};
|
||||
struct map_def merged12[] = {
|
||||
{ "kcore1", 100, 200 },
|
||||
{ "bpf_prog_1", 200, 300 },
|
||||
{ "kcore1", 300, 500 },
|
||||
{ "bpf_prog_2", 500, 600 },
|
||||
{ "kcore1", 600, 800 },
|
||||
{ "bpf_prog_3", 800, 900 },
|
||||
{ "kcore1", 900, 1000 },
|
||||
};
|
||||
struct map_def merged3[] = {
|
||||
{ "kcore1", 100, 200 },
|
||||
{ "bpf_prog_1", 200, 300 },
|
||||
{ "kcore1", 300, 500 },
|
||||
{ "bpf_prog_2", 500, 600 },
|
||||
{ "kcore1", 600, 800 },
|
||||
{ "bpf_prog_3", 800, 900 },
|
||||
{ "kcore1", 900, 1000 },
|
||||
{ "kcore3", 1000, 1100 },
|
||||
};
|
||||
struct map *map_kcore1, *map_kcore2, *map_kcore3;
|
||||
int ret;
|
||||
|
||||
map_groups__init(&mg, NULL);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bpf_progs); i++) {
|
||||
struct map *map;
|
||||
|
||||
map = dso__new_map(bpf_progs[i].name);
|
||||
TEST_ASSERT_VAL("failed to create map", map);
|
||||
|
||||
map->start = bpf_progs[i].start;
|
||||
map->end = bpf_progs[i].end;
|
||||
map_groups__insert(&mg, map);
|
||||
map__put(map);
|
||||
}
|
||||
|
||||
map_kcore1 = dso__new_map("kcore1");
|
||||
TEST_ASSERT_VAL("failed to create map", map_kcore1);
|
||||
|
||||
map_kcore2 = dso__new_map("kcore2");
|
||||
TEST_ASSERT_VAL("failed to create map", map_kcore2);
|
||||
|
||||
map_kcore3 = dso__new_map("kcore3");
|
||||
TEST_ASSERT_VAL("failed to create map", map_kcore3);
|
||||
|
||||
/* kcore1 map overlaps over all bpf maps */
|
||||
map_kcore1->start = 100;
|
||||
map_kcore1->end = 1000;
|
||||
|
||||
/* kcore2 map hides behind bpf_prog_2 */
|
||||
map_kcore2->start = 550;
|
||||
map_kcore2->end = 570;
|
||||
|
||||
/* kcore3 map hides behind bpf_prog_3, kcore1 and adds new map */
|
||||
map_kcore3->start = 880;
|
||||
map_kcore3->end = 1100;
|
||||
|
||||
ret = map_groups__merge_in(&mg, map_kcore1);
|
||||
TEST_ASSERT_VAL("failed to merge map", !ret);
|
||||
|
||||
ret = check_maps(merged12, ARRAY_SIZE(merged12), &mg);
|
||||
TEST_ASSERT_VAL("merge check failed", !ret);
|
||||
|
||||
ret = map_groups__merge_in(&mg, map_kcore2);
|
||||
TEST_ASSERT_VAL("failed to merge map", !ret);
|
||||
|
||||
ret = check_maps(merged12, ARRAY_SIZE(merged12), &mg);
|
||||
TEST_ASSERT_VAL("merge check failed", !ret);
|
||||
|
||||
ret = map_groups__merge_in(&mg, map_kcore3);
|
||||
TEST_ASSERT_VAL("failed to merge map", !ret);
|
||||
|
||||
ret = check_maps(merged3, ARRAY_SIZE(merged3), &mg);
|
||||
TEST_ASSERT_VAL("merge check failed", !ret);
|
||||
return TEST_OK;
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "util/mem-events.h"
|
||||
#include "util/symbol.h"
|
||||
#include "linux/perf_event.h"
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/bitmap.h>
|
||||
#include "cpumap.h"
|
||||
|
@@ -18,6 +18,32 @@
|
||||
#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \
|
||||
PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD)
|
||||
|
||||
#if defined(__s390x__)
|
||||
/* Return true if kvm module is available and loaded. Test this
|
||||
* and retun success when trace point kvm_s390_create_vm
|
||||
* exists. Otherwise this test always fails.
|
||||
*/
|
||||
static bool kvm_s390_create_vm_valid(void)
|
||||
{
|
||||
char *eventfile;
|
||||
bool rc = false;
|
||||
|
||||
eventfile = get_events_file("kvm-s390");
|
||||
|
||||
if (eventfile) {
|
||||
DIR *mydir = opendir(eventfile);
|
||||
|
||||
if (mydir) {
|
||||
rc = true;
|
||||
closedir(mydir);
|
||||
}
|
||||
put_events_file(eventfile);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test__checkevent_tracepoint(struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
||||
@@ -1642,6 +1668,7 @@ static struct evlist_test test__events[] = {
|
||||
{
|
||||
.name = "kvm-s390:kvm_s390_create_vm",
|
||||
.check = test__checkevent_tracepoint,
|
||||
.valid = kvm_s390_create_vm_valid,
|
||||
.id = 100,
|
||||
},
|
||||
#endif
|
||||
|
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Arnaldo Carvalho de Melo <acme@kernel.org>, 2017
|
||||
|
||||
skip_if_no_perf_probe() {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
# Add vfs_getname probe to get syscall args filenames
|
||||
#
|
||||
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Arnaldo Carvalho de Melo <acme@kernel.org>, 2017
|
||||
|
||||
. $(dirname $0)/lib/probe.sh
|
||||
|
@@ -7,6 +7,7 @@
|
||||
# This needs no debuginfo package, all is done using the libc ELF symtab
|
||||
# and the CFI info in the binaries.
|
||||
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Arnaldo Carvalho de Melo <acme@kernel.org>, 2017
|
||||
|
||||
. $(dirname $0)/lib/probe.sh
|
||||
|
@@ -6,6 +6,7 @@
|
||||
# checks that that was captured by the vfs_getname probe in the generated
|
||||
# perf.data file, with the temp file name as the pathname argument.
|
||||
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Arnaldo Carvalho de Melo <acme@kernel.org>, 2017
|
||||
|
||||
. $(dirname $0)/lib/probe.sh
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
# Zstd perf.data compression/decompression
|
||||
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
trace_file=$(mktemp /tmp/perf.data.XXX)
|
||||
perf_tool=perf
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
# that already handles "probe:vfs_getname" if present, and used in the
|
||||
# "open" syscall "filename" argument beautifier.
|
||||
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Arnaldo Carvalho de Melo <acme@kernel.org>, 2017
|
||||
|
||||
. $(dirname $0)/lib/probe.sh
|
||||
|
@@ -107,6 +107,8 @@ const char *test__clang_subtest_get_desc(int subtest);
|
||||
int test__clang_subtest_get_nr(void);
|
||||
int test__unit_number__scnprint(struct test *test, int subtest);
|
||||
int test__mem2node(struct test *t, int subtest);
|
||||
int test__map_groups__merge_in(struct test *t, int subtest);
|
||||
int test__time_utils(struct test *t, int subtest);
|
||||
|
||||
bool test__bp_signal_is_supported(void);
|
||||
bool test__wp_is_supported(void);
|
||||
|
251
tools/perf/tests/time-utils-test.c
Normal file
251
tools/perf/tests/time-utils-test.c
Normal file
@@ -0,0 +1,251 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/time64.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "time-utils.h"
|
||||
#include "evlist.h"
|
||||
#include "session.h"
|
||||
#include "debug.h"
|
||||
#include "tests.h"
|
||||
|
||||
static bool test__parse_nsec_time(const char *str, u64 expected)
|
||||
{
|
||||
u64 ptime;
|
||||
int err;
|
||||
|
||||
pr_debug("\nparse_nsec_time(\"%s\")\n", str);
|
||||
|
||||
err = parse_nsec_time(str, &ptime);
|
||||
if (err) {
|
||||
pr_debug("error %d\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ptime != expected) {
|
||||
pr_debug("Failed. ptime %" PRIu64 " expected %" PRIu64 "\n",
|
||||
ptime, expected);
|
||||
return false;
|
||||
}
|
||||
|
||||
pr_debug("%" PRIu64 "\n", ptime);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test__perf_time__parse_str(const char *ostr, u64 start, u64 end)
|
||||
{
|
||||
struct perf_time_interval ptime;
|
||||
int err;
|
||||
|
||||
pr_debug("\nperf_time__parse_str(\"%s\")\n", ostr);
|
||||
|
||||
err = perf_time__parse_str(&ptime, ostr);
|
||||
if (err) {
|
||||
pr_debug("Error %d\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ptime.start != start || ptime.end != end) {
|
||||
pr_debug("Failed. Expected %" PRIu64 " to %" PRIu64 "\n",
|
||||
start, end);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TEST_MAX 64
|
||||
|
||||
struct test_data {
|
||||
const char *str;
|
||||
u64 first;
|
||||
u64 last;
|
||||
struct perf_time_interval ptime[TEST_MAX];
|
||||
int num;
|
||||
u64 skip[TEST_MAX];
|
||||
u64 noskip[TEST_MAX];
|
||||
};
|
||||
|
||||
static bool test__perf_time__parse_for_ranges(struct test_data *d)
|
||||
{
|
||||
struct perf_evlist evlist = {
|
||||
.first_sample_time = d->first,
|
||||
.last_sample_time = d->last,
|
||||
};
|
||||
struct perf_session session = { .evlist = &evlist };
|
||||
struct perf_time_interval *ptime = NULL;
|
||||
int range_size, range_num;
|
||||
bool pass = false;
|
||||
int i, err;
|
||||
|
||||
pr_debug("\nperf_time__parse_for_ranges(\"%s\")\n", d->str);
|
||||
|
||||
if (strchr(d->str, '%'))
|
||||
pr_debug("first_sample_time %" PRIu64 " last_sample_time %" PRIu64 "\n",
|
||||
d->first, d->last);
|
||||
|
||||
err = perf_time__parse_for_ranges(d->str, &session, &ptime, &range_size,
|
||||
&range_num);
|
||||
if (err) {
|
||||
pr_debug("error %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (range_size < d->num || range_num != d->num) {
|
||||
pr_debug("bad size: range_size %d range_num %d expected num %d\n",
|
||||
range_size, range_num, d->num);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < d->num; i++) {
|
||||
if (ptime[i].start != d->ptime[i].start ||
|
||||
ptime[i].end != d->ptime[i].end) {
|
||||
pr_debug("bad range %d expected %" PRIu64 " to %" PRIu64 "\n",
|
||||
i, d->ptime[i].start, d->ptime[i].end);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (perf_time__ranges_skip_sample(ptime, d->num, 0)) {
|
||||
pr_debug("failed to keep 0\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < TEST_MAX; i++) {
|
||||
if (d->skip[i] &&
|
||||
!perf_time__ranges_skip_sample(ptime, d->num, d->skip[i])) {
|
||||
pr_debug("failed to skip %" PRIu64 "\n", d->skip[i]);
|
||||
goto out;
|
||||
}
|
||||
if (d->noskip[i] &&
|
||||
perf_time__ranges_skip_sample(ptime, d->num, d->noskip[i])) {
|
||||
pr_debug("failed to keep %" PRIu64 "\n", d->noskip[i]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
pass = true;
|
||||
out:
|
||||
free(ptime);
|
||||
return pass;
|
||||
}
|
||||
|
||||
int test__time_utils(struct test *t __maybe_unused, int subtest __maybe_unused)
|
||||
{
|
||||
bool pass = true;
|
||||
|
||||
pass &= test__parse_nsec_time("0", 0);
|
||||
pass &= test__parse_nsec_time("1", 1000000000ULL);
|
||||
pass &= test__parse_nsec_time("0.000000001", 1);
|
||||
pass &= test__parse_nsec_time("1.000000001", 1000000001ULL);
|
||||
pass &= test__parse_nsec_time("123456.123456", 123456123456000ULL);
|
||||
pass &= test__parse_nsec_time("1234567.123456789", 1234567123456789ULL);
|
||||
pass &= test__parse_nsec_time("18446744073.709551615",
|
||||
0xFFFFFFFFFFFFFFFFULL);
|
||||
|
||||
pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456789",
|
||||
1234567123456789ULL, 1234567123456789ULL);
|
||||
pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456790",
|
||||
1234567123456789ULL, 1234567123456790ULL);
|
||||
pass &= test__perf_time__parse_str("1234567.123456789,",
|
||||
1234567123456789ULL, 0);
|
||||
pass &= test__perf_time__parse_str(",1234567.123456789",
|
||||
0, 1234567123456789ULL);
|
||||
pass &= test__perf_time__parse_str("0,1234567.123456789",
|
||||
0, 1234567123456789ULL);
|
||||
|
||||
{
|
||||
u64 b = 1234567123456789ULL;
|
||||
struct test_data d = {
|
||||
.str = "1234567.123456789,1234567.123456790",
|
||||
.ptime = { {b, b + 1}, },
|
||||
.num = 1,
|
||||
.skip = { b - 1, b + 2, },
|
||||
.noskip = { b, b + 1, },
|
||||
};
|
||||
|
||||
pass &= test__perf_time__parse_for_ranges(&d);
|
||||
}
|
||||
|
||||
{
|
||||
u64 b = 1234567123456789ULL;
|
||||
u64 c = 7654321987654321ULL;
|
||||
u64 e = 8000000000000000ULL;
|
||||
struct test_data d = {
|
||||
.str = "1234567.123456789,1234567.123456790 "
|
||||
"7654321.987654321,7654321.987654444 "
|
||||
"8000000,8000000.000000005",
|
||||
.ptime = { {b, b + 1}, {c, c + 123}, {e, e + 5}, },
|
||||
.num = 3,
|
||||
.skip = { b - 1, b + 2, c - 1, c + 124, e - 1, e + 6 },
|
||||
.noskip = { b, b + 1, c, c + 123, e, e + 5 },
|
||||
};
|
||||
|
||||
pass &= test__perf_time__parse_for_ranges(&d);
|
||||
}
|
||||
|
||||
{
|
||||
u64 b = 7654321ULL * NSEC_PER_SEC;
|
||||
struct test_data d = {
|
||||
.str = "10%/1",
|
||||
.first = b,
|
||||
.last = b + 100,
|
||||
.ptime = { {b, b + 9}, },
|
||||
.num = 1,
|
||||
.skip = { b - 1, b + 10, },
|
||||
.noskip = { b, b + 9, },
|
||||
};
|
||||
|
||||
pass &= test__perf_time__parse_for_ranges(&d);
|
||||
}
|
||||
|
||||
{
|
||||
u64 b = 7654321ULL * NSEC_PER_SEC;
|
||||
struct test_data d = {
|
||||
.str = "10%/2",
|
||||
.first = b,
|
||||
.last = b + 100,
|
||||
.ptime = { {b + 10, b + 19}, },
|
||||
.num = 1,
|
||||
.skip = { b + 9, b + 20, },
|
||||
.noskip = { b + 10, b + 19, },
|
||||
};
|
||||
|
||||
pass &= test__perf_time__parse_for_ranges(&d);
|
||||
}
|
||||
|
||||
{
|
||||
u64 b = 11223344ULL * NSEC_PER_SEC;
|
||||
struct test_data d = {
|
||||
.str = "10%/1,10%/2",
|
||||
.first = b,
|
||||
.last = b + 100,
|
||||
.ptime = { {b, b + 9}, {b + 10, b + 19}, },
|
||||
.num = 2,
|
||||
.skip = { b - 1, b + 20, },
|
||||
.noskip = { b, b + 8, b + 9, b + 10, b + 11, b + 12, b + 19, },
|
||||
};
|
||||
|
||||
pass &= test__perf_time__parse_for_ranges(&d);
|
||||
}
|
||||
|
||||
{
|
||||
u64 b = 11223344ULL * NSEC_PER_SEC;
|
||||
struct test_data d = {
|
||||
.str = "10%/1,10%/3,10%/10",
|
||||
.first = b,
|
||||
.last = b + 100,
|
||||
.ptime = { {b, b + 9}, {b + 20, b + 29}, { b + 90, b + 100}, },
|
||||
.num = 3,
|
||||
.skip = { b - 1, b + 10, b + 19, b + 30, b + 89, b + 101 },
|
||||
.noskip = { b, b + 9, b + 20, b + 29, b + 90, b + 100},
|
||||
};
|
||||
|
||||
pass &= test__perf_time__parse_for_ranges(&d);
|
||||
}
|
||||
|
||||
pr_debug("\n");
|
||||
|
||||
return pass ? 0 : TEST_FAIL;
|
||||
}
|
Reference in New Issue
Block a user