virtio-net have two usage of hashes: one is RSS and another is hash
reporting. Conventionally the hash calculation was done by the VMM.
However, computing the hash after the queue was chosen defeats the
purpose of RSS.
Another approach is to use eBPF steering program. This approach has
another downside: it cannot report the calculated hash due to the
restrictive nature of eBPF.
Introduce the code to compute hashes to the kernel in order to overcome
thse challenges.
An alternative solution is to extend the eBPF steering program so that it
will be able to report to the userspace, but it is based on context
rewrites, which is in feature freeze. We can adopt kfuncs, but they will
not be UAPIs. We opt to ioctl to align with other relevant UAPIs (KVM
and vhost_net).
QEMU patched to use this new feature is available at:
https://github.com/daynix/qemu/tree/akihikodaki/rss2
The QEMU patches will soon be submitted to the upstream as RFC too.
This work will be presented at LPC 2024:
https://lpc.events/event/18/contributions/1963/
V1 -> V2:
Changed to introduce a new BPF program type.
Signed-off-by: Akihiko Odaki <akihiko.odaki(a)daynix.com>
---
Changes in v3:
- Reverted back to add ioctl.
- Split patch "tun: Introduce virtio-net hashing feature" into
"tun: Introduce virtio-net hash reporting feature" and
"tun: Introduce virtio-net RSS".
- Changed to reuse hash values computed for automq instead of performing
RSS hashing when hash reporting is requested but RSS is not.
- Extracted relevant data from struct tun_struct to keep it minimal.
- Added kernel-doc.
- Changed to allow calling TUNGETVNETHASHCAP before TUNSETIFF.
- Initialized num_buffers with 1.
- Added a test case for unclassified packets.
- Fixed error handling in tests.
- Changed tests to verify that the queue index will not overflow.
- Rebased.
- Link to v2: https://lore.kernel.org/r/20231015141644.260646-1-akihiko.odaki@daynix.com
---
Akihiko Odaki (9):
skbuff: Introduce SKB_EXT_TUN_VNET_HASH
virtio_net: Add functions for hashing
net: flow_dissector: Export flow_keys_dissector_symmetric
tap: Pad virtio header with zero
tun: Pad virtio header with zero
tun: Introduce virtio-net hash reporting feature
tun: Introduce virtio-net RSS
selftest: tun: Add tests for virtio-net hashing
vhost/net: Support VIRTIO_NET_F_HASH_REPORT
Documentation/networking/tuntap.rst | 7 +
drivers/net/Kconfig | 1 +
drivers/net/tap.c | 2 +-
drivers/net/tun.c | 255 ++++++++++++--
drivers/vhost/net.c | 16 +-
include/linux/skbuff.h | 10 +
include/linux/virtio_net.h | 198 +++++++++++
include/net/flow_dissector.h | 1 +
include/uapi/linux/if_tun.h | 71 ++++
net/core/flow_dissector.c | 3 +-
net/core/skbuff.c | 3 +
tools/testing/selftests/net/Makefile | 2 +-
tools/testing/selftests/net/tun.c | 666 ++++++++++++++++++++++++++++++++++-
13 files changed, 1195 insertions(+), 40 deletions(-)
---
base-commit: 46a0057a5853cbdb58211c19e89ba7777dc6fd50
change-id: 20240403-rss-e737d89efa77
Best regards,
--
Akihiko Odaki <akihiko.odaki(a)daynix.com>
The value of __NR_userfaultfd was changed to 282 when
asm-generic/unistd.h was included. It makes the test to fail every time
as the correct number of this syscall on x86_64 is 323. Fix the header
to asm/unistd.h.
Fixes: a5c6bc590094 ("selftests/mm: remove local __NR_* definitions")
Signed-off-by: Muhammad Usama Anjum <usama.anjum(a)collabora.com>
---
tools/testing/selftests/mm/pagemap_ioctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/mm/pagemap_ioctl.c b/tools/testing/selftests/mm/pagemap_ioctl.c
index fc90af2a97b80..bcc73b4e805c6 100644
--- a/tools/testing/selftests/mm/pagemap_ioctl.c
+++ b/tools/testing/selftests/mm/pagemap_ioctl.c
@@ -15,7 +15,7 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <math.h>
-#include <asm-generic/unistd.h>
+#include <asm/unistd.h>
#include <pthread.h>
#include <sys/resource.h>
#include <assert.h>
--
2.39.2
We recently notice that the step_after_suspend_test would
fail on our plenty devices. The test believesit failed to
enter suspend state with
$ sudo ./step_after_suspend_test
TAP version 13
Bail out! Failed to enter Suspend state
However, in the kernel message, I indeed see the system get
suspended and then wake up later.
[611172.033108] PM: suspend entry (s2idle)
[611172.044940] Filesystems sync: 0.006 seconds
[611172.052254] Freezing user space processes
[611172.059319] Freezing user space processes completed (elapsed 0.001 seconds)
[611172.067920] OOM killer disabled.
[611172.072465] Freezing remaining freezable tasks
[611172.080332] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[611172.089724] printk: Suspending console(s) (use no_console_suspend to debug)
[611172.117126] serial 00:03: disabled
--- some other hardware get reconnected ---
[611203.136277] OOM killer enabled.
[611203.140637] Restarting tasks ...
[611203.141135] usb 1-8.1: USB disconnect, device number 7
[611203.141755] done.
[611203.155268] random: crng reseeded on system resumption
[611203.162059] PM: suspend exit
After investigation, I notice that for the code block
if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem"))
ksft_exit_fail_msg("Failed to enter Suspend state\n");
The write will return -1 and errno is set to 16 (device busy).
It should be caused by the write function is not successfully returned
before the system suspend and the return value get messed when waking up.
As a result, It may be better to check the time passed of those few instructions
to determine whether the suspend is executed correctly for it is pretty hard to
execute those few lines for 5 seconds.
The timer to wake up the system is set to expired after 5 seconds and no-rearm.
If the timer remaining time is 0 second and 0 nano secomd, it means the timer
expired and wake the system up. Otherwise, the system could be considered to
enter the suspend state failed if there is any remaining time.
Fixes: bfd092b8c2728 ("selftests: breakpoint: add step_after_suspend_test")
Reported-by: Sinadin Shan <sinadin.shan(a)oracle.com>
Signed-off-by: Yifei Liu <yifei.l.liu(a)oracle.com>
---
.../testing/selftests/breakpoints/step_after_suspend_test.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c
index dfec31fb9b30d..33f5542bf741d 100644
--- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c
+++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c
@@ -152,7 +152,10 @@ void suspend(void)
if (err < 0)
ksft_exit_fail_msg("timerfd_settime() failed\n");
- if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem"))
+ system("(echo mem > /sys/power/state) 2> /dev/null");
+
+ timerfd_gettime(timerfd,&spec);
+ if (spec.it_value.tv_sec != 0 || spec.it_value.tv_nsec != 0)
ksft_exit_fail_msg("Failed to enter Suspend state\n");
close(timerfd);
--
2.46.0
These variables are never referenced in the code, just remove it.
Signed-off-by: Ba Jing <bajing(a)cmss.chinamobile.com>
---
tools/testing/selftests/damon/access_memory_even.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/tools/testing/selftests/damon/access_memory_even.c b/tools/testing/selftests/damon/access_memory_even.c
index 3be121487432..a9f4e9aaf3a9 100644
--- a/tools/testing/selftests/damon/access_memory_even.c
+++ b/tools/testing/selftests/damon/access_memory_even.c
@@ -14,10 +14,8 @@
int main(int argc, char *argv[])
{
char **regions;
- clock_t start_clock;
int nr_regions;
int sz_region;
- int access_time_ms;
int i;
if (argc != 3) {
--
2.33.0
Currently, sk_lookup allows an ebpf program to run on the ingress socket
lookup path, and accept traffic not only on a range of addresses, but
also on a range of ports. At Cloudflare we use sk_lookup for two main
cases:
1. Sharing a single port between multiple services - i.e. two services
(or more) use disjoint IP ranges but share the same port;
2. Receiving traffic on all ports - i.e. a service which accepts traffic
on specific IP ranges but any port [1].
However, one main challenge we face while using sk_lookup for these use
cases is how to source return UDP traffic:
- On point 1. above, sometimes this range of addresses are not local
(i.e. there's no local routes for these in the server), which means we
need IP_TRANSPARENT set to be able to egress traffic from addresses
we've received traffic on (or simply IP_FREEBIND in the case of IPv6);
- And on point 2. above, allowing traffic to a range of ports means a
service could get traffic on multiple ports, but currently there's no
way to set the source UDP port egress traffic should be sourced from -
it's possible to receive the original destination port using the
IP_ORIGDSTADDR ancilliary message in recvmsg, but not set it in
sendmsg.
Both of these limitations can be worked around, but in a sub-optimal
way. Using IP_TRANSPARENT, for instance, requires special privileges.
And while one could use UDP connected sockets to send return traffic,
creating a connected socket for each different address a UDP traffic is
received on does have performance implications.
Given sk_lookup allows services to accept traffic on a range of
addresses or ports, it seems sensible to also allow return traffic to
proceed through as well, without needing extra configurations / set ups.
This patch sets out to fix both of this issues by:
1. Allowing users to set the src address/port egress traffic should be
sent from, when calling sendmsg();
2. Validating that this egress traffic comes from a socket that matches
an ingress socket in sk_lookup.
- If it does, traffic is allowed to proceed;
- Otherwise it falls back to the regular egress path.
The downsides to this is that this runs on the egress hot path, although
this work tries to minimise its impact by only performing the reverse
socket lookup when necessary (i.e. only when the src address/port are
modified). Further performance measurements are to be taken, but we're
reaching out early for feedback to see what the technical concerns are
and if we can address them.
[1] https://blog.cloudflare.com/how-we-built-spectrum/
Suggested-by: Jakub Sitnicki <jakub(a)cloudflare.com>
Signed-off-by: Tiago Lam <tiagolam(a)cloudflare.com>
---
Changes in v2:
- Amended commit messages and cover letter to make the intent and
implementation clearer (Willem de Bruijn);
- Fixed socket comparison by not using socket cookies and comparing them
directly (Eric Dumazet);
- Fixed misspellings and checkpatch.pl warnings on line lengths (Simon
Horman);
- Fixed usage of start_server_addr() and gcc compilation (Philo Lu);
- Link to v1: https://lore.kernel.org/r/20240913-reverse-sk-lookup-v1-0-e721ea003d4c@clou…
---
Tiago Lam (3):
ipv4: Support setting src port in sendmsg().
ipv6: Support setting src port in sendmsg().
bpf: Add sk_lookup test to use ORIGDSTADDR cmsg.
include/net/ip.h | 1 +
net/ipv4/ip_sockglue.c | 11 +++
net/ipv4/udp.c | 35 +++++++++-
net/ipv6/datagram.c | 79 ++++++++++++++++++++++
net/ipv6/udp.c | 8 ++-
tools/testing/selftests/bpf/prog_tests/sk_lookup.c | 67 ++++++++++++------
6 files changed, 176 insertions(+), 25 deletions(-)
---
base-commit: 6562a89739bbefddb5495c09aaab67c1c3756f36
change-id: 20240909-reverse-sk-lookup-f7bf36292bc4
Best regards,
--
Tiago Lam <tiagolam(a)cloudflare.com>
+CC linux-kselftest
-------
On 22/09/2024 17:16, Gabriela Bittencourt wrote:
> Hey all,
>
> We are making these changes as part of a KUnit Hackathon at LKCamp [1].
>
> This patch sets out to refactor fs/unicode/utf8-selftest.c to KUnit tests.
>
> The first commit is the refactoring itself from self test into KUnit, while
> the second one applies the naming style conventions.
>
> We appreciate any feedback and suggestions. :)
>
> [1] https://lkcamp.dev/about/
>
> Co-developed-by: Pedro Orlando <porlando(a)lkcamp.dev>
> Co-developed-by: Danilo Pereira <dpereira(a)lkcamp.dev>
> Signed-off-by: Pedro Orlando <porlando(a)lkcamp.dev>
> Signed-off-by: Danilo Pereira <dpereira(a)lkcamp.dev>
> Signed-off-by: Gabriela Bittencourt <gbittencourt(a)lkcamp.dev>
>
> Gabriela Bittencourt (2):
> unicode: kunit: refactor selftest to kunit tests
> unicode: kunit: change tests filename and path
>
> fs/unicode/Kconfig | 5 +-
> fs/unicode/Makefile | 2 +-
> fs/unicode/tests/.kunitconfig | 3 +
> .../{utf8-selftest.c => tests/utf8_kunit.c} | 152 ++++++++----------
> 4 files changed, 76 insertions(+), 86 deletions(-)
> create mode 100644 fs/unicode/tests/.kunitconfig
> rename fs/unicode/{utf8-selftest.c => tests/utf8_kunit.c} (63%)
>
We recently notice that the step_after_suspend_test would
fail on our plenty devices. The test believesit failed to
enter suspend state with
$ sudo ./step_after_suspend_test
TAP version 13
Bail out! Failed to enter Suspend state
However, in the kernel message, I indeed see the system get
suspended and then wake up later.
[611172.033108] PM: suspend entry (s2idle)
[611172.044940] Filesystems sync: 0.006 seconds
[611172.052254] Freezing user space processes
[611172.059319] Freezing user space processes completed (elapsed 0.001 seconds)
[611172.067920] OOM killer disabled.
[611172.072465] Freezing remaining freezable tasks
[611172.080332] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[611172.089724] printk: Suspending console(s) (use no_console_suspend to debug)
[611172.117126] serial 00:03: disabled
--- some other hardware get reconnected ---
[611203.136277] OOM killer enabled.
[611203.140637] Restarting tasks ...
[611203.141135] usb 1-8.1: USB disconnect, device number 7
[611203.141755] done.
[611203.155268] random: crng reseeded on system resumption
[611203.162059] PM: suspend exit
After investigation, I notice that for the code block
if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem"))
ksft_exit_fail_msg("Failed to enter Suspend state\n");
The write will return -1 and errno is set to 16 (device busy).
It should be caused by the write function is not successfully returned
before the system suspend and the return value get messed when waking up.
As a result, It may be better to check the time passed of those few instructions
to determine whether the suspend is executed correctly for it is pretty hard to
execute those few lines for 4 seconds, or even more if it is not long enough.
Fixes: bfd092b8c2728 ("selftests: breakpoint: add step_after_suspend_test")
Reported-by: Sinadin Shan <sinadin.shan(a)oracle.com>
Signed-off-by: Yifei Liu <yifei.l.liu(a)oracle.com>
---
.../selftests/breakpoints/step_after_suspend_test.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c
index dfec31fb9b30d..d615f091e5bae 100644
--- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c
+++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c
@@ -18,6 +18,7 @@
#include <sys/timerfd.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <time.h>
#include "../kselftest.h"
@@ -133,6 +134,7 @@ void suspend(void)
int timerfd;
int err;
struct itimerspec spec = {};
+ clock_t t;
if (getuid() != 0)
ksft_exit_skip("Please run the test as root - Exiting.\n");
@@ -152,8 +154,11 @@ void suspend(void)
if (err < 0)
ksft_exit_fail_msg("timerfd_settime() failed\n");
- if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem"))
- ksft_exit_fail_msg("Failed to enter Suspend state\n");
+ t = clock();
+ write(power_state_fd, "mem", strlen("mem"));
+ t = clock()-t;
+ if ((int)(t) < 4)
+ ksft_exit_fail_msg("Failed to enter Suspend state %d\n",errno);
close(timerfd);
close(power_state_fd);
--
2.45.2
grep -rnIF "#define __NR_userfaultfd"
tools/include/uapi/asm-generic/unistd.h:681:#define __NR_userfaultfd 282
arch/x86/include/generated/uapi/asm/unistd_32.h:374:#define
__NR_userfaultfd 374
arch/x86/include/generated/uapi/asm/unistd_64.h:327:#define
__NR_userfaultfd 323
arch/x86/include/generated/uapi/asm/unistd_x32.h:282:#define
__NR_userfaultfd (__X32_SYSCALL_BIT + 323)
arch/arm/include/generated/uapi/asm/unistd-eabi.h:347:#define
__NR_userfaultfd (__NR_SYSCALL_BASE + 388)
arch/arm/include/generated/uapi/asm/unistd-oabi.h:359:#define
__NR_userfaultfd (__NR_SYSCALL_BASE + 388)
include/uapi/asm-generic/unistd.h:681:#define __NR_userfaultfd 282
The number is dependent on the architecture. The above data shows that:
x86 374
x86_64 323
The value of __NR_userfaultfd was changed to 282 when
asm-generic/unistd.h was included. It makes the test to fail every time
as the correct number of this syscall on x86_64 is 323. Fix the header
to asm/unistd.h.
Fixes: a5c6bc590094 ("selftests/mm: remove local __NR_* definitions")
Signed-off-by: Muhammad Usama Anjum <usama.anjum(a)collabora.com>
---
tools/testing/selftests/mm/pagemap_ioctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/mm/pagemap_ioctl.c b/tools/testing/selftests/mm/pagemap_ioctl.c
index fc90af2a97b80..bcc73b4e805c6 100644
--- a/tools/testing/selftests/mm/pagemap_ioctl.c
+++ b/tools/testing/selftests/mm/pagemap_ioctl.c
@@ -15,7 +15,7 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <math.h>
-#include <asm-generic/unistd.h>
+#include <asm/unistd.h>
#include <pthread.h>
#include <sys/resource.h>
#include <assert.h>
--
2.39.2