When filtering what tests to run (suites and/or cases) via
kunit.filter_glob (e.g. kunit.py run <glob>), we allocate copies of
suites.
These allocations can fail, and we largely don't handle that.
Note: realistically, this probably doesn't matter much.
We're not allocating much memory and this happens early in boot, so if
we can't do that, then there's likely far bigger problems.
This patch makes us immediately bail out from the top-level function
(kunit_filter_suites) with -ENOMEM if any of the underlying kmalloc()
calls return NULL.
Implementation note: we used to return NULL pointers from some functions
to indicate either that all suites/tests were filtered out or there was
an error allocating the new array.
We'll log a short error in this case and not run any tests or print a
TAP header. From a kunit.py user's perspective, they'll get a message
about missing/invalid TAP output and have to dig into the test.log to
see it. Since hitting this error seems so unlikely, it's probably fine
to not invent a way to plumb this error message more visibly.
See also: https://lore.kernel.org/linux-kselftest/20220329103919.2376818-1-lv.ruyi@zt…
Signed-off-by: Daniel Latypov <dlatypov(a)google.com>
Reported-by: Zeal Robot <zealci(a)zte.com.cn>
Signed-off-by: Lv Ruyi <lv.ruyi(a)zte.com.cn>
---
lib/kunit/executor.c | 27 ++++++++++++++++++++++-----
lib/kunit/executor_test.c | 4 +++-
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c
index 22640c9ee819..2f73a6a35a7e 100644
--- a/lib/kunit/executor.c
+++ b/lib/kunit/executor.c
@@ -71,9 +71,13 @@ kunit_filter_tests(struct kunit_suite *const suite, const char *test_glob)
/* Use memcpy to workaround copy->name being const. */
copy = kmalloc(sizeof(*copy), GFP_KERNEL);
+ if (!copy)
+ return ERR_PTR(-ENOMEM);
memcpy(copy, suite, sizeof(*copy));
filtered = kcalloc(n + 1, sizeof(*filtered), GFP_KERNEL);
+ if (!filtered)
+ return ERR_PTR(-ENOMEM);
n = 0;
kunit_suite_for_each_test_case(suite, test_case) {
@@ -106,14 +110,16 @@ kunit_filter_subsuite(struct kunit_suite * const * const subsuite,
filtered = kmalloc_array(n + 1, sizeof(*filtered), GFP_KERNEL);
if (!filtered)
- return NULL;
+ return ERR_PTR(-ENOMEM);
n = 0;
for (i = 0; subsuite[i] != NULL; ++i) {
if (!glob_match(filter->suite_glob, subsuite[i]->name))
continue;
filtered_suite = kunit_filter_tests(subsuite[i], filter->test_glob);
- if (filtered_suite)
+ if (IS_ERR(filtered_suite))
+ return ERR_CAST(filtered_suite);
+ else if (filtered_suite)
filtered[n++] = filtered_suite;
}
filtered[n] = NULL;
@@ -146,7 +152,8 @@ static void kunit_free_suite_set(struct suite_set suite_set)
}
static struct suite_set kunit_filter_suites(const struct suite_set *suite_set,
- const char *filter_glob)
+ const char *filter_glob,
+ int *err)
{
int i;
struct kunit_suite * const **copy, * const *filtered_subsuite;
@@ -166,6 +173,10 @@ static struct suite_set kunit_filter_suites(const struct suite_set *suite_set,
for (i = 0; i < max; ++i) {
filtered_subsuite = kunit_filter_subsuite(suite_set->start[i], &filter);
+ if (IS_ERR(filtered_subsuite)) {
+ *err = PTR_ERR(filtered_subsuite);
+ return filtered;
+ }
if (filtered_subsuite)
*copy++ = filtered_subsuite;
}
@@ -236,9 +247,15 @@ int kunit_run_all_tests(void)
.start = __kunit_suites_start,
.end = __kunit_suites_end,
};
+ int err;
- if (filter_glob_param)
- suite_set = kunit_filter_suites(&suite_set, filter_glob_param);
+ if (filter_glob_param) {
+ suite_set = kunit_filter_suites(&suite_set, filter_glob_param, &err);
+ if (err) {
+ pr_err("kunit executor: error filtering suites: %d\n", err);
+ return err;
+ }
+ }
if (!action_param)
kunit_exec_run_tests(&suite_set);
diff --git a/lib/kunit/executor_test.c b/lib/kunit/executor_test.c
index 4ed57fd94e42..eac6ff480273 100644
--- a/lib/kunit/executor_test.c
+++ b/lib/kunit/executor_test.c
@@ -137,14 +137,16 @@ static void filter_suites_test(struct kunit *test)
.end = suites + 2,
};
struct suite_set filtered = {.start = NULL, .end = NULL};
+ int err = 0;
/* Emulate two files, each having one suite */
subsuites[0][0] = alloc_fake_suite(test, "suite0", dummy_test_cases);
subsuites[1][0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
/* Filter out suite1 */
- filtered = kunit_filter_suites(&suite_set, "suite0");
+ filtered = kunit_filter_suites(&suite_set, "suite0", &err);
kfree_subsuites_at_end(test, &filtered); /* let us use ASSERTs without leaking */
+ KUNIT_EXPECT_EQ(test, err, 0);
KUNIT_ASSERT_EQ(test, filtered.end - filtered.start, (ptrdiff_t)1);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered.start);
base-commit: b04d1a8dc7e7ff7ca91a20bef053bcc04265d83a
--
2.35.1.1094.g7c7d902a7c-goog
This is in line with Documentation/dev-tools/kunit/style.rst.
Some of these tests predate that so they don't follow this convention.
With this and commit b0841b51cac9 ("kunit: arch/um/configs: Enable
KUNIT_ALL_TESTS by default"), kunit.py will now run these tests by
default. This hopefully makes it easier to run and maintain the tests.
If any of these were to start failing, people would notice much quicker.
Note: this commit doesn't update LINEAR_RANGES_TEST since that would
select its dependency (LINEAR_RANGES). We don't want KUNIT_ALL_TESTS
to enable anything other than test kconfigs.
Signed-off-by: Daniel Latypov <dlatypov(a)google.com>
---
lib/Kconfig.debug | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 075cd25363ac..36865b37b33b 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2140,10 +2140,11 @@ config TEST_DIV64
If unsure, say N.
config KPROBES_SANITY_TEST
- tristate "Kprobes sanity tests"
+ tristate "Kprobes sanity tests" if !KUNIT_ALL_TESTS
depends on DEBUG_KERNEL
depends on KPROBES
depends on KUNIT
+ default KUNIT_ALL_TESTS
help
This option provides for testing basic kprobes functionality on
boot. Samples of kprobe and kretprobe are inserted and
@@ -2417,8 +2418,9 @@ config TEST_SYSCTL
If unsure, say N.
config BITFIELD_KUNIT
- tristate "KUnit test bitfield functions at runtime"
+ tristate "KUnit test bitfield functions at runtime" if !KUNIT_ALL_TESTS
depends on KUNIT
+ default KUNIT_ALL_TESTS
help
Enable this option to test the bitfield functions at boot.
@@ -2452,8 +2454,9 @@ config HASH_KUNIT_TEST
optimized versions. If unsure, say N.
config RESOURCE_KUNIT_TEST
- tristate "KUnit test for resource API"
+ tristate "KUnit test for resource API" if !KUNIT_ALL_TESTS
depends on KUNIT
+ default KUNIT_ALL_TESTS
help
This builds the resource API unit test.
Tests the logic of API provided by resource.c and ioport.h.
@@ -2506,8 +2509,9 @@ config LINEAR_RANGES_TEST
If unsure, say N.
config CMDLINE_KUNIT_TEST
- tristate "KUnit test for cmdline API"
+ tristate "KUnit test for cmdline API" if !KUNIT_ALL_TESTS
depends on KUNIT
+ default KUNIT_ALL_TESTS
help
This builds the cmdline API unit test.
Tests the logic of API provided by cmdline.c.
@@ -2517,8 +2521,9 @@ config CMDLINE_KUNIT_TEST
If unsure, say N.
config BITS_TEST
- tristate "KUnit test for bits.h"
+ tristate "KUnit test for bits.h" if !KUNIT_ALL_TESTS
depends on KUNIT
+ default KUNIT_ALL_TESTS
help
This builds the bits unit test.
Tests the logic of macros defined in bits.h.
base-commit: 3123109284176b1532874591f7c81f3837bbdc17
--
2.35.1.1094.g7c7d902a7c-goog
Before:
$ ./tools/testing/kunit/kunit.py parse /dev/null
...
[ERROR] Test : invalid KTAP input!
After:
$ ./tools/testing/kunit/kunit.py parse /dev/null
...
[ERROR] Test <missing>: could not find any KTAP output!
This error message gets printed out when extract_tap_output() yielded no
lines. So while it could be because of malformed KTAP output from KUnit,
it could also be due to to not having any KTAP output at all.
Try and make the error message here more clear.
Signed-off-by: Daniel Latypov <dlatypov(a)google.com>
---
tools/testing/kunit/kunit_parser.py | 3 ++-
tools/testing/kunit/kunit_tool_test.py | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py
index 05ff334761dd..103d95a66a7e 100644
--- a/tools/testing/kunit/kunit_parser.py
+++ b/tools/testing/kunit/kunit_parser.py
@@ -817,7 +817,8 @@ def parse_run_tests(kernel_output: Iterable[str]) -> Test:
lines = extract_tap_lines(kernel_output)
test = Test()
if not lines:
- test.add_error('invalid KTAP input!')
+ test.name = '<missing>'
+ test.add_error('could not find any KTAP output!')
test.status = TestStatus.FAILURE_TO_PARSE_TESTS
else:
test = parse_test(lines, 0, [])
diff --git a/tools/testing/kunit/kunit_tool_test.py b/tools/testing/kunit/kunit_tool_test.py
index 352369dffbd9..f14934853ea1 100755
--- a/tools/testing/kunit/kunit_tool_test.py
+++ b/tools/testing/kunit/kunit_tool_test.py
@@ -226,7 +226,7 @@ class KUnitParserTest(unittest.TestCase):
with open(crash_log) as file:
result = kunit_parser.parse_run_tests(
kunit_parser.extract_tap_lines(file.readlines()))
- print_mock.assert_any_call(StrContains('invalid KTAP input!'))
+ print_mock.assert_any_call(StrContains('could not find any KTAP output!'))
print_mock.stop()
self.assertEqual(0, len(result.subtests))
@@ -559,7 +559,7 @@ class KUnitMainTest(unittest.TestCase):
self.assertEqual(e.exception.code, 1)
self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
- self.print_mock.assert_any_call(StrContains('invalid KTAP input!'))
+ self.print_mock.assert_any_call(StrContains('could not find any KTAP output!'))
def test_exec_no_tests(self):
self.linux_source_mock.run_kernel = mock.Mock(return_value=['TAP version 14', '1..0'])
base-commit: 13776ebb9964b2ea66ffb8c824c0762eed6da784
--
2.35.1.1021.g381101b075-goog
Our Ref: BG/WA0151/2022
Dear Beneficiary
Subject: An Estate of US$15.8 Million
Blount and Griffin Genealogical Investigators specializes in probate
research to locate missing heirs and beneficiaries to estates in the
United Kingdom and Europe.
We can also help you find wills, obtain copies of certificates, help
you to administer an estate, as well as calculating how an estate,
intestacy or trust should be distributed.
You may be entitled to a large pay out for an inheritance in Europe
worth US$15.8 million. We have discovered an estate belonging to the
late Depositor has remained unclaimed since he died in 2011 and we
have strong reasons to believe you are the closest living relative to
the deceased we can find.
You may unknowingly be the heir of this person who died without
leaving a will (intestate). We will conduct a probate research to
prove your entitlement, and can submit a claim on your behalf all at
no risk to yourselves.
Our service fee of 10% will be paid to us after you have received the estate.
The estate transfer process should take just a matter of days as we
have the mechanism and expertise to get this done very quickly. This
message may come to you as a shock, however we hope to work with you
to transfer the estate to you as quickly as possible.
Feel free to email our senior case worker Mr. Malcolm Casey on email:
malcolmcasey68(a)yahoo.com for further discussions.
With warm regards,
Mr. Blount W. Gort, CEO.
Blount and Griffin Associates Inc
Hi,
Thanks to a substantial contribution by Sevinj Aghayeva during the
Outreachy contribution phase, mbuto (a shell script building initramfs
images that can be loaded by qemu) can now be used to conveniently run
kernel selftests in VMs. The website at:
https://mbuto.sh/
shows examples with kselftests and a link to the man page.
Comments, bug reports and patches are all very welcome!
--
Stefano
On Fri, May 06, 2022 at 04:50:41PM +0200, Cornelia Huck wrote:
> I'm currently trying to run the MTE selftests on the FVP simulator (Base
> Model)[1], mainly to verify things are sane on the host before wiring up
> the KVM support in QEMU. However, I'm seeing some failures (the non-mte
> tests seemed all fine):
> Are the MTE tests supposed to work on the FVP model? Something broken in
> my config? Anything I can debug?
I would expect them to work, they seemed happy when I was doing
the async mode support IIRC and a quick spin with -next in qemu
everything seems fine, I'm travelling so don't have the
environment for models to hand right now.
> [1] Command line:
> "$MODEL" \
> -C cache_state_modelled=0 \
> -C bp.refcounter.non_arch_start_at_default=1 \
> -C bp.secure_memory=false \
> -C cluster0.has_arm_v8-1=1 \
> -C cluster0.has_arm_v8-2=1 \
> -C cluster0.has_arm_v8-3=1 \
> -C cluster0.has_arm_v8-4=1 \
> -C cluster0.has_arm_v8-5=1 \
> -C cluster0.has_amu=1 \
> -C cluster0.NUM_CORES=4 \
> -C cluster0.memory_tagging_support_level=2 \
> -a "cluster0.*=$AXF" \
> where $AXF contains a kernel at v5.18-rc5-16-g107c948d1d3e[2] and an
> initrd built by mbuto[3] from that level with a slightly tweaked "kselftests"
> profile (adding /dev/shm).
What are you using for EL3 with the model? Both TF-A and
boot-wrapper are in regular use, TF-A gets *way* more testing
than boot-wrapper which is mostly used by individual developers.
This is a followup from [1], in which a split of commits was suggested
by Greg. Additionally, the following changes were removed and not
included in this v2 version:
- dropped the binder_transaction_log_entry->strerr[] logic
- dropped the binder_transaction_error() do-it-all function
- dropped the re-work of current binder_user_error() messages
[1] https://lore.kernel.org/r/20220421042040.759068-1-cmllamas@google.com/
Carlos Llamas (5):
binder: add failed transaction logging info
binder: add BINDER_GET_EXTENDED_ERROR ioctl
binderfs: add extended_error feature entry
binder: convert logging macros into functions
binder: additional transaction error logs
drivers/android/binder.c | 153 ++++++++++++++++--
drivers/android/binder_internal.h | 3 +
drivers/android/binderfs.c | 8 +
include/uapi/linux/android/binder.h | 16 ++
.../filesystems/binderfs/binderfs_test.c | 1 +
5 files changed, 165 insertions(+), 16 deletions(-)
base-commit: 8013d1d3d2e33236dee13a133fba49ad55045e79
--
2.36.0.464.gb9c8b46e94-goog
When clatd starts with ebpf offloaing, and NETIF_F_GRO_FRAGLIST is enable,
several skbs are gathered in skb_shinfo(skb)->frag_list. The first skb's
ipv6 header will be changed to ipv4 after bpf_skb_proto_6_to_4,
network_header\transport_header\mac_header have been updated as ipv4 acts,
but other skbs in frag_list didnot update anything, just ipv6 packets.
udp_queue_rcv_skb will call skb_segment_list to traverse other skbs in
frag_list and make sure right udp payload is delivered to user space.
Unfortunately, other skbs in frag_list who are still ipv6 packets are
updated like the first skb and will have wrong transport header length.
e.g.before bpf_skb_proto_6_to_4,the first skb and other skbs in frag_list
has the same network_header(24)& transport_header(64), after
bpf_skb_proto_6_to_4, ipv6 protocol has been changed to ipv4, the first
skb's network_header is 44,transport_header is 64, other skbs in frag_list
didnot change.After skb_segment_list, the other skbs in frag_list has
different network_header(24) and transport_header(44), so there will be 20
bytes different from original,that is difference between ipv6 header and
ipv4 header. Just change transport_header to be the same with original.
Actually, there are two solutions to fix it, one is traversing all skbs
and changing every skb header in bpf_skb_proto_6_to_4, the other is
modifying frag_list skb's header in skb_segment_list. Considering
efficiency, adopt the second one--- when the first skb and other skbs in
frag_list has different network_header length, restore them to make sure
right udp payload is delivered to user space.
Signed-off-by: Lina Wang <lina.wang(a)mediatek.com>
---
net/core/skbuff.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 10bde7c6db44..e8006e0a1b25 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3897,7 +3897,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
unsigned int delta_len = 0;
struct sk_buff *tail = NULL;
struct sk_buff *nskb, *tmp;
- int err;
+ int len_diff, err;
skb_push(skb, -skb_network_offset(skb) + offset);
@@ -3937,9 +3937,11 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
skb_push(nskb, -skb_network_offset(nskb) + offset);
skb_release_head_state(nskb);
+ len_diff = skb_network_header_len(nskb) - skb_network_header_len(skb);
__copy_skb_header(nskb, skb);
skb_headers_offset_update(nskb, skb_headroom(nskb) - skb_headroom(skb));
+ nskb->transport_header += len_diff;
skb_copy_from_linear_data_offset(skb, -tnl_hlen,
nskb->data - tnl_hlen,
offset + tnl_hlen);
--
2.18.0