Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v6 1/2] bpf, sockmap: handle spurious tcp_msg_wait_data() wakeup
From: Emil Tsalapatis @ 2026-07-20 21:16 UTC (permalink / raw)
  To: Nnamdi Onyeyiri
  Cc: bpf, davem, edumazet, horms, jakub, jiayuan.chen, john.fastabend,
	kuba, kuniyu, ncardwell, netdev, pabeni, sashiko-reviews,
	linux-kernel
In-Reply-To: <20260720171535.67867-2-nnamdio@gmail.com>

On Mon Jul 20, 2026 at 1:15 PM EDT, Nnamdi Onyeyiri wrote:
> recvfrom()/recv() are documented as only returning EAGAIN for blocking sockets
> when they have a receive timeout configured.  However, adding a blocking
> ipv4 tcp socket without a receive timeout to a sockmap will cause EAGAIN errors
> sporadically.  A socket with a receive timeout may return EAGAIN before the
> timeout expires.
>
> There are 2 code paths affected by this:
>
>   1. tcp_bpf_recvmsg() - Used when the socket has been added to a sockmap
>      that has no verdict program attached.
>
>   2. tcp_bpf_recvmsg_parser() - Used when the socket has been added to a
>      sockmap that has a verdict program.  To reproduce this issue, it is
>      enough for the verdict program to do nothing but return SK_PASS.
>
> In both cases this happens when tcp_msg_wait_data() wakes spuriously
> (returning 0).  To fix it, we now loop back to msg_bytes_ready instead
> of returning -EAGAIN on spurious wakeup.
>
> To ensure the looping does not cause sockets with a SO_RCVTIMEO set to
> wait excessively long, tcp_msg_wait_data() now takes a pointer to timeo,
> allowing sk_wait_event() to update it as appropriate.
>
> The logic in tcp_bpf_recvmsg_parser() that allow it to handle signals,
> socket errors and closuers in its loop was also added to tcp_bpf_recvmsg().
>
> Signed-off-by: Nnamdi Onyeyiri <nnamdio@gmail.com>
> ---
>  net/ipv4/tcp_bpf.c | 69 ++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 60 insertions(+), 9 deletions(-)
>
> diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
> index cc0bd73f36b6..aa5c5d741599 100644
> --- a/net/ipv4/tcp_bpf.c
> +++ b/net/ipv4/tcp_bpf.c
> @@ -179,7 +179,7 @@ EXPORT_SYMBOL_GPL(tcp_bpf_sendmsg_redir);
>  
>  #ifdef CONFIG_BPF_SYSCALL
>  static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,
> -			     long timeo)
> +			     long *timeo)
>  {
>  	DEFINE_WAIT_FUNC(wait, woken_wake_function);
>  	int ret = 0;
> @@ -187,12 +187,12 @@ static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,
>  	if (sk->sk_shutdown & RCV_SHUTDOWN)
>  		return 1;
>  
> -	if (!timeo)
> +	if (!*timeo)
>  		return ret;
>  
>  	add_wait_queue(sk_sleep(sk), &wait);
>  	sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
> -	ret = sk_wait_event(sk, &timeo,
> +	ret = sk_wait_event(sk, timeo,
>  			    !list_empty(&psock->ingress_msg) ||
>  			    !skb_queue_empty_lockless(&sk->sk_receive_queue), &wait);
>  	sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
> @@ -229,6 +229,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
>  	int copied_from_self = 0;
>  	int copied = 0;
>  	u32 seq;
> +	long timeo;
>  
>  	if (unlikely(flags & MSG_ERRQUEUE))
>  		return inet_recv_error(sk, msg, len);
> @@ -262,6 +263,8 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
>  		}
>  	}
>  
> +	timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
> +
>  msg_bytes_ready:
>  	copied = __sk_msg_recvmsg(sk, psock, msg, len, flags, &copied_from_self);
>  	/* The typical case for EFAULT is the socket was gracefully
> @@ -280,7 +283,6 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
>  	}
>  	seq += copied_from_self;
>  	if (!copied) {
> -		long timeo;
>  		int data;
>  
>  		if (sock_flag(sk, SOCK_DONE))
> @@ -299,7 +301,6 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
>  			goto out;
>  		}
>  
> -		timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
>  		if (!timeo) {
>  			copied = -EAGAIN;
>  			goto out;
> @@ -310,13 +311,15 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
>  			goto out;
>  		}
>  
> -		data = tcp_msg_wait_data(sk, psock, timeo);
> +		data = tcp_msg_wait_data(sk, psock, &timeo);
>  		if (data < 0) {
>  			copied = data;
>  			goto unlock;
>  		}
>  		if (data && !sk_psock_queue_empty(psock))
>  			goto msg_bytes_ready;
> +		if (!data && timeo > 0)
> +			goto msg_bytes_ready;
>  		copied = -EAGAIN;
>  	}
>  out:
> @@ -355,6 +358,7 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>  {
>  	struct sk_psock *psock;
>  	int copied, ret;
> +	long timeo;
>  
>  	if (unlikely(flags & MSG_ERRQUEUE))
>  		return inet_recv_error(sk, msg, len);
> @@ -371,14 +375,59 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>  		return tcp_recvmsg(sk, msg, len, flags);
>  	}
>  	lock_sock(sk);
> +
> +	timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
> +
>  msg_bytes_ready:
>  	copied = sk_msg_recvmsg(sk, psock, msg, len, flags);
>  	if (!copied) {
> -		long timeo;
>  		int data;
>  
> -		timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
> -		data = tcp_msg_wait_data(sk, psock, timeo);
> +		if (sock_flag(sk, SOCK_DONE)) {
> +			ret = 0;
> +			goto unlock;
> +		}
> +
> +		if (sk->sk_err) {
> +			if (!sk_psock_queue_empty(psock))
> +				goto msg_bytes_ready;
> +			if (!skb_queue_empty(&sk->sk_receive_queue)) {
> +				release_sock(sk);
> +				sk_psock_put(sk, psock);
> +				return tcp_recvmsg(sk, msg, len, flags);
> +			}
> +			ret = sock_error(sk);
> +			goto unlock;
> +		}
> +
> +		if (sk->sk_shutdown & RCV_SHUTDOWN) {
> +			if (!sk_psock_queue_empty(psock))
> +				goto msg_bytes_ready;
> +			if (!skb_queue_empty(&sk->sk_receive_queue)) {
> +				release_sock(sk);
> +				sk_psock_put(sk, psock);
> +				return tcp_recvmsg(sk, msg, len, flags);
> +			}
> +			ret = 0;
> +			goto unlock;

These two error handling routines above look identical. Can you refactor
them?

> +		}
> +
> +		if (sk->sk_state == TCP_CLOSE) {
> +			ret = -ENOTCONN;
> +			goto unlock;
> +		}
> +
> +		if (!timeo) {
> +			ret = -EAGAIN;
> +			goto unlock;
> +		}
> +

Since this handling (which Sashiko flags by the way, correctly AFAICT) 
are taken from tcp_bpf_recvmsg, there is obvious overlap between the two
functions. Please factor those out so that they share the logic between
them.

pw-bot: cr

> +		if (signal_pending(current)) {
> +			ret = sock_intr_errno(timeo);
> +			goto unlock;
> +		}
> +
> +		data = tcp_msg_wait_data(sk, psock, &timeo);
>  		if (data < 0) {
>  			ret = data;
>  			goto unlock;
> @@ -390,6 +439,8 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>  			sk_psock_put(sk, psock);
>  			return tcp_recvmsg(sk, msg, len, flags);
>  		}
> +		if (!data && timeo > 0)
> +			goto msg_bytes_ready;
>  		copied = -EAGAIN;
>  	}
>  	ret = copied;


^ permalink raw reply

* Re: [PATCH net-next v5 2/3] selftests/net: ncdevmem: add -b option to set rx-buf-size on bind
From: Mina Almasry @ 2026-07-20 21:15 UTC (permalink / raw)
  To: Bobby Eshleman
  Cc: Donald Hunter, Jakub Kicinski, David S. Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, Andrew Lunn, Gerd Hoffmann,
	Vivek Kasireddy, Sumit Semwal, Christian König, Shuah Khan,
	netdev, linux-kernel, dri-devel, linux-media, linaro-mm-sig,
	linux-kselftest, sdf, razor, daniel, matttbe, skhawaja, dw,
	Joe Damato, Bobby Eshleman
In-Reply-To: <20260708-tcpdm-large-niovs-v5-2-34bf6fac941b@meta.com>

On Wed, Jul 8, 2026 at 3:55 PM Bobby Eshleman <bobbyeshleman@gmail.com> wrote:
>
> From: Bobby Eshleman <bobbyeshleman@meta.com>
>
> Add -b <bytes> to request a non-default niov size via
> NETDEV_A_DMABUF_RX_BUF_SIZE. When the value exceeds PAGE_SIZE,
> udmabuf_alloc() switches to an MFD_HUGETLB-backed memfd so each 2 MB
> hugepage produces one naturally-aligned sg entry.
>
> Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
> Acked-by: Stanislav Fomichev <sdf@fomichev.me>

Reviewed-by: Mina Almasry <almasrymina@google.com>


> ---
>  tools/testing/selftests/drivers/net/hw/ncdevmem.c | 36 +++++++++++++++++++++--
>  1 file changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/tools/testing/selftests/drivers/net/hw/ncdevmem.c b/tools/testing/selftests/drivers/net/hw/ncdevmem.c
> index d96e8a3b5a65..a16e55af51ee 100644
> --- a/tools/testing/selftests/drivers/net/hw/ncdevmem.c
> +++ b/tools/testing/selftests/drivers/net/hw/ncdevmem.c
> @@ -40,6 +40,7 @@
>
>  #include <linux/uio.h>
>  #include <stdarg.h>
> +#include <stdint.h>
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <unistd.h>
> @@ -61,6 +62,7 @@
>  #include <sys/time.h>
>
>  #include <linux/memfd.h>
> +#include <sys/param.h>
>  #include <linux/dma-buf.h>
>  #include <linux/errqueue.h>
>  #include <linux/udmabuf.h>
> @@ -79,6 +81,7 @@
>  #define PAGE_SHIFT 12
>  #define TEST_PREFIX "ncdevmem"
>  #define NUM_PAGES 16000
> +#define MB(x) ((x) << 20)
>
>  #ifndef MSG_SOCK_DEVMEM
>  #define MSG_SOCK_DEVMEM 0x2000000
> @@ -100,6 +103,7 @@ static unsigned int dmabuf_id;
>  static uint32_t tx_dmabuf_id;
>  static int waittime_ms = 500;
>  static bool fail_on_linear;
> +static uint32_t rx_buf_size;
>
>  /* System state loaded by current_config_load() */
>  #define MAX_FLOWS      8
> @@ -142,6 +146,7 @@ static struct memory_buffer *udmabuf_alloc(size_t size)
>  {
>         struct udmabuf_create create;
>         struct memory_buffer *ctx;
> +       unsigned int memfd_flags;
>         int ret;
>
>         ctx = malloc(sizeof(*ctx));
> @@ -156,9 +161,14 @@ static struct memory_buffer *udmabuf_alloc(size_t size)
>                 goto err_free_ctx;
>         }
>
> -       ctx->memfd = memfd_create("udmabuf-test", MFD_ALLOW_SEALING);
> +       memfd_flags = MFD_ALLOW_SEALING;
> +       if (rx_buf_size > getpagesize())
> +               memfd_flags |= MFD_HUGETLB | MFD_HUGE_2MB;
> +

The fact that you are using HUGETLM and 2MB mappings here made me
realize there is a pathological edge case in the code where the netmem
size you're requesting is greater than the mapping size, so you
actually get no netmems. So like if you ask for a 64KB netmem size but
actually you did a normal udambuf mapping and all the maps (sg len
entries) are 4K or something. IDK if the code already handles this
well with an error or what not. Worth checking.

--
Thanks,
Mina

^ permalink raw reply

* [PATCH net-next v2] net/sched: sch_cake: skip clearing unused tins during rate adjustment
From: Jonas Köppeler @ 2026-07-20 21:14 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Jamal Hadi Salim, Jiri Pirko,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: cake, netdev, linux-kernel, Jonas Köppeler, Mike Pham

When cake_configure_rates() is called from the dequeue path with
rate_adjust=true, it only needs to update the rate parameters. The
loop that clears the unused tins is both unnecessary and harmful in
this path:

 - cake_clear_tin() overwrites q->cur_tin and q->cur_flow, which are
   actively used by cake_dequeue(), corrupting the dequeue state.
 - iterating over the unused tins and their internal queues to purge
   packets adds needless overhead to the hot path.

Skip the entire loop when rate_adjust is set, as neither
cake_clear_tin() nor the mtu_time update are needed when only the
rate changes.

The clearing loop runs on every rate adjustment from the dequeue path,
clearing (max_tins - cur_tins) tins each time, so the cost grows the
fewer tins the configured mode actually uses. Testing cake_mq over veth
(8 rx/tx queues, 2 Gbit limit) with flent's [1] rrul and tcp_nup tests and
32 TCP upstreams shows a large drop in loaded latency and a throughput
gain, restoring behaviour to pre-15c2715a5264 levels:

  +------------+------+------+-------+-------+---------+
  | kernel     | mode | test |  base |  load |    tput |
  |            |      |      |  (ms) |  (ms) |  (Mbit) |
  +------------+------+------+-------+-------+---------+
  | net-next   | be   | rrul | 0.810 | 11.78 | 1469.67 |
  | net-next   | be   | nup  | 0.637 | 85.71 | 1243.15 |
  | net-next   | ds3  | rrul | 0.397 | 15.28 | 1770.06 |
  | net-next   | ds3  | nup  | 0.351 | 15.98 | 1799.39 |
  +------------+------+------+-------+-------+---------+
  | patched    | be   | rrul | 0.092 |  0.56 | 1873.40 |
  | patched    | be   | nup  | 0.109 |  1.82 | 1869.12 |
  | patched    | ds3  | rrul | 0.097 |  0.98 | 1866.10 |
  | patched    | ds3  | nup  | 0.101 |  0.51 | 1861.79 |
  +------------+------+------+-------+-------+---------+

The same trend holds on real hardware (IPQ8074A, 4 rx/tx queues,
OpenWrt): in besteffort mode the tcp_nup loaded latency drops from
~470 ms to ~4 ms.

[1] https://flent.org

Fixes: 15c2715a5264 ("net/sched: sch_cake: fixup cake_mq rate adjustment for diffserv config")
Signed-off-by: Jonas Köppeler <j.koeppeler@tu-berlin.de>
Tested-by: Mike Pham <mikepham4321@gmail.com>
---
Changes in v2:
- added performance data to commit message, no code changes
- Link to v1: https://patch.msgid.link/20260716-sch_cake-skip-clearing-tins-v1-1-d9787df20c28@tu-berlin.de
---
 net/sched/sch_cake.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index f78f8e950776..845e1c017714 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -2609,9 +2609,11 @@ static void cake_configure_rates(struct Qdisc *sch, u64 rate, bool rate_adjust)
 		break;
 	}
 
-	for (c = qd->tin_cnt; c < CAKE_MAX_TINS; c++) {
-		cake_clear_tin(sch, c);
-		qd->tins[c].cparams.mtu_time = qd->tins[ft].cparams.mtu_time;
+	if (!rate_adjust) {
+		for (c = qd->tin_cnt; c < CAKE_MAX_TINS; c++) {
+			cake_clear_tin(sch, c);
+			qd->tins[c].cparams.mtu_time = qd->tins[ft].cparams.mtu_time;
+		}
 	}
 
 	qd->rate_ns   = qd->tins[ft].tin_rate_ns;

---
base-commit: f6f3b36c15ed44de1fbb44e645e4fae8c4a4453e
change-id: 20260716-sch_cake-skip-clearing-tins-856812586cde

Best regards,
--  
Jonas Köppeler <j.koeppeler@tu-berlin.de>


^ permalink raw reply related

* Re: [RFC PATCH net-next 08/13] drm/amdkfd: add GPU instruction emitter and disassembler
From: Andrew Lunn @ 2026-07-20 20:53 UTC (permalink / raw)
  To: Natalie Vock
  Cc: Taehee Yoo, Alex Deucher, Alexei Starovoitov, amd-gfx,
	Andrew Lunn, Andrii Nakryiko, Bill Wendling, bpf,
	Christian König, Daniel Borkmann, David Airlie,
	David S. Miller, Donald Hunter, dri-devel, Eduard Zingerman,
	Emil Tsalapatis, Eric Dumazet, Felix Kuehling, Hoyeon Lee,
	Ilias Apalodimas, Jakub Kicinski, Jesper Dangaard Brouer,
	Jiri Olsa, John Fastabend, Justin Stitt, Kees Cook,
	Kumar Kartikeya Dwivedi, Leon Romanovsky, linaro-mm-sig,
	linux-hardening, linux-kernel, linux-kselftest, linux-media,
	linux-rdma, llvm, Mark Bloch, Martin KaFai Lau, Michael Chan,
	Nathan Chancellor, netdev, Nick Desaulniers, Paolo Abeni,
	Pavan Chebbi, Saeed Mahameed, Shuah Khan, Simona Vetter,
	Simon Horman, Song Liu, Stanislav Fomichev, Sumit Semwal,
	Tariq Toukan, Yonghong Song
In-Reply-To: <41e73be8-242a-4e7b-b085-439375303590@pixelcluster.dev>

On Mon, Jul 20, 2026 at 10:05:33PM +0200, Natalie Vock wrote:
> On 7/19/26 19:58, Taehee Yoo wrote:
> > Add the AMD GCN (gfx9/gfx10) instruction encoder used to build the GPU
> > shaders that knod dispatches, plus a matching disassembler used for
> > debugging the generated code.
> 
> Is it really necessary to have a full-on compiler and disassembler in the
> kernel driver? This patch is massive and I'm wondering how much benefit it
> really provides. Is there really no way to move GPU compilation out of the
> kernel, one way or another? Could you get acceptable perf with a static
> shader that interprets BPF programs at runtime? Such a shader can be
> compiled beforehand and just embedded into the kernel - there's prior art
> there with the CWSR trap handler in amdkfd.
> 
> In case you really, really need to compile the BPF to native ISA, could you
> still have userspace take care of that in one way or another?

There was a long and painful discussion about P4, and offloading it to
hardware. The proponents of that wanted to do the compilation stage in
user space to produce a binary blob, but it was hard to prove that the
P4 passed to the kernel for software processing, and the binary blob
passed to the hardware actually where the same. It opened up the path
for closed source P4 where the kernel never got to see the actual P4
code. So it was not really offload, but kernel bypass.

So having a compiler in the kernel is probably the correct way to go,
if you want to be friendly to open source.

The other option is to get the GPU to do the compilation itself, so
you pass BPF byte codes to the GPU and it generates its own native
code. I've no idea if that is possible, but clang can target OpenMP,
so maybe it is possible to move this compiler into the GPU?

      Andrew

^ permalink raw reply

* [PATCH net] seg6: fix NULL deref in input_action_end_dx{4,6}_finish() after nf hook
From: Xiang Mei (Microsoft) @ 2026-07-20 20:44 UTC (permalink / raw)
  To: Andrea Mayer, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: netdev, linux-kernel, Pablo Neira Ayuso, Ryoga Saito,
	AutonomousCodeSecurity, tgopinath, kys, Xiang Mei (Microsoft)

When nf_hooks_lwtunnel is enabled, the End.DX4/End.DX6 actions dispatch
the decapsulated inner packet through the NF_INET_PRE_ROUTING hook chain
with input_action_end_dx{4,6}_finish() as the okfn. Both functions read
the lwtunnel state via orig_dst = skb_dst(skb) and dereference
orig_dst->lwtstate.

A hook in that chain can legitimately drop the dst: nf_nat_ipv{4,6}_in()
calls skb_dst_drop(skb) when a DNAT rule rewrites the destination
address, leaving skb_dst(skb) NULL. The okfn then dereferences a NULL
orig_dst, causing a general protection fault and a panic (the fault
happens in softirq NAPI receive context).

Free the skb and bail out when the dst was dropped, instead of
proceeding with a lost lwtunnel state.

  Oops: general protection fault, probably for non-canonical address...
  KASAN: null-ptr-deref in range [0x0000000000000080-0x0000000000000087]
  RIP: 0010:input_action_end_dx6_finish (net/ipv6/seg6_local.c:912)
  Call Trace:
   input_action_end_dx6 (net/ipv6/seg6_local.c:946)
   seg6_local_input_core (net/ipv6/seg6_local.c:1621)
   seg6_local_input (net/ipv6/seg6_local.c:1643)
   lwtunnel_input (net/core/lwtunnel.c:465)
   ipv6_rcv (net/ipv6/ip6_input.c:351)
   __netif_receive_skb_core.constprop.0 (net/core/dev.c:6165)
  Kernel panic - not syncing: Fatal exception in interrupt

Fixes: 7a3f5b0de364 ("netfilter: add netfilter hooks to SRv6 data plane")
Reported-by: AutonomousCodeSecurity@microsoft.com
Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
---
 net/ipv6/seg6_local.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 2b41e4c0dddd..45e66ba306ca 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -909,6 +909,11 @@ static int input_action_end_dx6_finish(struct net *net, struct sock *sk,
 	struct in6_addr *nhaddr = NULL;
 	struct seg6_local_lwt *slwt;
 
+	if (!orig_dst) {
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
 	slwt = seg6_local_lwtunnel(orig_dst->lwtstate);
 
 	/* The inner packet is not associated to any local interface,
@@ -962,6 +967,11 @@ static int input_action_end_dx4_finish(struct net *net, struct sock *sk,
 	struct iphdr *iph;
 	__be32 nhaddr;
 
+	if (!orig_dst) {
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
 	slwt = seg6_local_lwtunnel(orig_dst->lwtstate);
 
 	iph = ip_hdr(skb);
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net v3 2/3] net: ethernet: oa_tc6: Improvement in buffer overflow handling
From: Andrew Lunn @ 2026-07-20 20:32 UTC (permalink / raw)
  To: Selvamani Rajagopal
  Cc: Simon Horman, parthiban.veerasooran@microchip.com,
	andrew+netdev@lunn.ch, Piergiorgio Beruto, davem@davemloft.net,
	edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <DM5PR02MB33693344BE338A70BC70FDD283C32@DM5PR02MB3369.namprd02.prod.outlook.com>

On Mon, Jul 20, 2026 at 07:09:22PM +0000, Selvamani Rajagopal wrote:
> > 
> > [High]
> > Now that oa_tc6_prcs_rx_frame_end() returns int (and can return -EAGAIN
> > via oa_tc6_update_rx_skb() when tail + size > end), should the
> > "previous rx frame end + next rx frame start" branch also observe the
> > return value? That branch is not shown in the diff, but in the
> > resulting file it reads:
> > 
> > if (start_valid && end_valid && start_byte_offset > end_byte_offset) {
> 
> 
> Andew and others,
> 
> I don't know why my v3 submission is under "Archived" flag. "state" is still new and I was waiting
> for it to move to "Change requested" before submitting the next patch set. May be my understanding
> is wrong.  Hope I can submit the following patch. 

You should probably repost it.

The last couple of weeks things have been falling through the cracks
due to vacation and conferences. Reviewer time has been limited.

It might also help if all the TC6 developers work together and review
each others patches. Patchset having Reviewed-by: is more likely to
get accepted without one of "big" reviewers looking at it.

    Andrew

^ permalink raw reply

* Re: [PATCH net-next] net/sched: sch_cake: skip clearing unused tins during rate adjustment
From: Toke Høiland-Jørgensen @ 2026-07-20 20:30 UTC (permalink / raw)
  To: Jonas Köppeler, Jamal Hadi Salim, Jiri Pirko,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: cake, netdev, linux-kernel, Mike Pham
In-Reply-To: <431c1b00-1fd3-41e1-8e8e-9cc1738ae387@tu-berlin.de>



On 18 July 2026 17.06.28 CEST, "Jonas Köppeler" <j.koeppeler@tu-berlin.de> wrote:
>On 7/17/26 10:31, Toke Høiland-Jørgensen wrote:
>> Jonas Köppeler <j.koeppeler@tu-berlin.de> writes:
>> 
>>> When cake_configure_rates() is called from the dequeue path with
>>> rate_adjust=true, it only needs to update the rate parameters. The
>>> loop that clears the unused tins is both unnecessary and harmful in
>>> this path:
>>> 
>>>   - cake_clear_tin() overwrites q->cur_tin and q->cur_flow, which are
>>>     actively used by cake_dequeue(), corrupting the dequeue state.
>>>   - iterating over the unused tins and their internal queues to purge
>>>     packets adds needless overhead to the hot path.
>>> 
>>> Skip the entire loop when rate_adjust is set, as neither
>>> cake_clear_tin() nor the mtu_time update are needed when only the
>>> rate changes.
>>> 
>>> Fixes: 15c2715a5264 ("net/sched: sch_cake: fixup cake_mq rate adjustment for diffserv config")
>>> Signed-off-by: Jonas Köppeler <j.koeppeler@tu-berlin.de>
>>> Tested-by: Mike Pham <mikepham4321@gmail.com>
>> 
>> Do you have any performance numbers to show the impact of this?
>Yes, the table below shows results from a test setup using vng with
>2 network namespaces, with cake/cake_mq attached in one of them:
>
>    ns1 -> cake/cake_mq -> ns2
>
>- veth devices are configured with 8 rx/tx queues.
>- cake/cake_mq is configured with a 2 Gbit rate limit.
>- Running flent's rrul and tcp_nup tests with 32 TCP upstreams:
>
>legend: qdisc mq = cake_mq; mode be = besteffort, ds3 = diffserv3
>        test nup = tcp_nup; base/load = idle/loaded RTT (ms); tput = Mbit/s
>
>+---------------------+-------+------+------+-------+-------+---------+
>| kernel              | qdisc | mode | test |  base |  load |    tput |
>+---------------------+-------+------+------+-------+-------+---------+
>| net-next            | cake  | be   | rrul | 0.075 |  4.76 | 1473.69 |
>| net-next            | cake  | be   | nup  | 0.078 |  6.23 | 1550.79 |
>| net-next            | cake  | ds3  | rrul | 0.063 |  5.81 | 1526.75 |
>| net-next            | cake  | ds3  | nup  | 0.046 |  6.09 | 1761.45 |
>+---------------------+-------+------+------+-------+-------+---------+
>| net-next            | mq    | be   | rrul | 0.810 | 11.78 | 1469.67 |
>| net-next            | mq    | be   | nup  | 0.637 | 85.71 | 1243.15 |
>| net-next            | mq    | ds3  | rrul | 0.397 | 15.28 | 1770.06 |
>| net-next            | mq    | ds3  | nup  | 0.351 | 15.98 | 1799.39 |
>+---------------------+-------+------+------+-------+-------+---------+
>| this patch          | mq    | be   | rrul | 0.092 |  0.56 | 1873.40 |
>| this patch          | mq    | be   | nup  | 0.109 |  1.82 | 1869.12 |
>| this patch          | mq    | ds3  | rrul | 0.097 |  0.98 | 1866.10 |
>| this patch          | mq    | ds3  | nup  | 0.101 |  0.51 | 1861.79 |
>+---------------------+-------+------+------+-------+-------+---------+
>| before 15c2715a5264 | mq    | be   | rrul | 0.073 |  0.30 | 1895.45 |
>| before 15c2715a5264 | mq    | be   | nup  | 0.076 |  0.49 | 1905.57 |
>| before 15c2715a5264 | mq    | ds3  | rrul | 0.069 |  0.31 | 1896.59 |
>| before 15c2715a5264 | mq    | ds3  | nup  | 0.058 |  0.86 | 1884.01 |
>+---------------------+-------+------+------+-------+-------+---------+
>
>Not only is p99 latency drastically reduced -- nearly matching
>pre-15c2715a5264 results -- but on current upstream cake_mq,
>throughput also increases as a cake mode uses more tins. This points
>directly to cake_clear_tin() during reconfig as the cause, since it
>clears (max_tins - cur_tins) tins each time. So the fewer tins the
>current mode uses, the more get cleared on every reconfig.
>
>Mike ran also some test on OpenWrt, on an IPQ8074A with 4 rx/tx
>queues, and saw similar trends. cake_mq is configured with a 2.2 Gbit
>rate limit.
>
>Unfortunately, we only have data for 128 TCP upstreams on net-next,
>and 64 TCP upstreams for 'this patch'.
>
>+---------------------+-------+------+------+---------+----------+
>| kernel              | qdisc | mode | test |    load |     tput |
>+---------------------+-------+------+------+---------+----------+
>| net-next            | mq    | be   | nup  |  468.50 |    50.90 |
>| net-next            | mq    | ds3  | nup  |  355.22 |    98.21 |
>| net-next            | mq    | ds4  | nup  |  268.28 |   255.84 |
>| net-next            | mq    | ds8  | nup  |    7.48 |  2023.66 |
>+---------------------+-------+------+------+---------+----------+
>| this patch          | mq    | be   | nup  |    4.24 |   944.35 |
>| this patch          | mq    | ds3  | nup  |    4.27 |   937.75 |
>| this patch          | mq    | ds4  | nup  |    4.24 |   936.97 |
>| this patch          | mq    | ds8  | nup  |    4.32 |   927.89 |
>+---------------------+-------+------+------+---------+----------+
>
>This again shows the same trend: throughput increases and latency
>drops as cake_mq is configured with more tins. We're still looking
>into why net-next+ds8 reaches close to 2 Gbit/s, while this patch
>tops out around 928 Mbit/s.
>
>That said, this patch doesn't solve every issue yet, but it does
>remove the regression introduced by commit 15c2715a5264
>("net/sched: sch_cake: fixup cake_mq rate adjustment for diffserv
>config").
>
>We're continuing to look into further improvements. Let us know if
>you'd like to see additional tests :)

Cool! Could you please respin the patch with this data in the commit message?

Doesn't have to be all of it, but some indication of the benefit would be good to have on hand for future reference :)

-Toke

^ permalink raw reply

* Re: [PATCH bpf v2] veth: convert frag_list skbs before running XDP
From: Toke Høiland-Jørgensen @ 2026-07-20 20:28 UTC (permalink / raw)
  To: Matt Fleming, Alexei Starovoitov, Daniel Borkmann
  Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jesper Dangaard Brouer, John Fastabend,
	Stanislav Fomichev, Lorenzo Bianconi, bpf, netdev, stable,
	kernel-team, Matt Fleming
In-Reply-To: <20260720140545.461747-1-matt@readmodwrite.com>



On 20 July 2026 16.05.45 CEST, Matt Fleming <matt@readmodwrite.com> wrote:
>From: Matt Fleming <mfleming@cloudflare.com>
>
>A frag_list skb can reach veth with data_len set but nr_frags zero.
>veth_convert_skb_to_xdp_buff() only converts skbs that are shared,
>locked, have frags[], or do not have enough headroom. It later uses
>skb_is_nonlinear() to decide whether to set XDP_FLAGS_HAS_FRAGS and
>xdp_frags_size.
>
>That exposes frag_list data to XDP as if it were stored in frags[], but
>frags[] is empty. AF_XDP copy mode can then trust the bogus XDP fragment
>metadata, walk an empty fragment entry, and crash in memcpy() from
>__xsk_rcv().
>
>Route non-linear skbs through skb_pp_cow_data() before exposing them to
>XDP, and only advertise XDP frags when the resulting skb has frags[].
>skb_copy_bits() already handles frag_list input, and skb_pp_cow_data()
>builds frags[] output with skb_add_rx_frag(), which is the
>representation XDP multi-buffer expects.
>
>Fixes: 718a18a0c8a6 ("veth: Rework veth_xdp_rcv_skb in order to accept non-linear skb")
>Cc: stable@vger.kernel.org
>Signed-off-by: Matt Fleming <mfleming@cloudflare.com>

Reviewed-by: Toke Høiland-Jørgensen <toke@toke.dk>

^ permalink raw reply

* [PATCH net] net: x25: fix use-after-free in x25_kill_by_neigh()
From: Ibrahim Hashimov @ 2026-07-20 20:27 UTC (permalink / raw)
  To: ms, davem, edumazet, kuba, pabeni
  Cc: horms, linma, duoming, linux-x25, netdev, linux-kernel, stable

x25_kill_by_neigh() walks x25_list under x25_list_lock and, for each
socket whose neighbour matches the one going down, drops the list lock,
calls lock_sock()/x25_disconnect()/release_sock() on the socket
(x25_disconnect() can sleep and must not be called with a bh-disabled
spinlock held), and then re-acquires x25_list_lock before continuing the
sk_for_each() walk. No reference is taken on the socket before the list
lock is dropped.

A concurrent close() of that same socket runs x25_release() ->
__x25_destroy_socket() -> x25_remove_socket() (unlinks it from x25_list)
-> eventually the final sock_put(), which frees the kmalloc-2k sock
object. If this happens while x25_kill_by_neigh() has dropped
x25_list_lock, both the lock_sock(s) call right after the unlock and,
once x25_list_lock is re-taken, the sk_for_each() walk's implicit read of
s->sk_node.next can dereference the freed socket.

Reproduced on a v6.19 KASAN kernel under -smp 4 with a killer thread
free-running NETDEV_DOWN toggles (driving x25_device_event() ->
x25_kill_by_neigh()) against several threads closing/recreating
neighbour-bound AF_X25 sockets: KASAN slab-use-after-free in
x25_kill_by_neigh()+0xfd/0x110, "Read of size 8" at offset 104 into a
freed kmalloc-2k object -- exactly the sk->sk_node.next field of the
socket concurrently freed by close(). 145 splats fired over roughly
64,400 kill rounds in the racing configuration; a serialized control run
(single kill, sockets closed sequentially, no concurrent free) produced
zero KASAN reports. With this patch applied the same free-running
reproducer no longer triggers the report.

Fix this the same way the rest of net/x25 protects a socket found by
walking x25_list under x25_list_lock (see x25_find_listener() and
__x25_find_socket(), which sock_hold() the socket before dropping the
list lock): take a reference on the socket before dropping x25_list_lock,
and release it with sock_put() once lock_sock() / x25_disconnect() /
release_sock() are done. Since a concurrent x25_remove_socket() can still
unlink the socket from x25_list (and reinitialize its list node) while
the lock is dropped, simply re-acquiring x25_list_lock and resuming the
sk_for_each() walk from the old s is not safe either way, so restart the
scan from the head of x25_list instead of trying to resume it.
x25_disconnect() clears x25_sk(s)->neighbour, so the just-handled socket
will not match nb again and the restarted scan makes forward progress on
each pass.

Fixes: 7781607938c8 ("net/x25: Fix null-ptr-deref caused by x25_disconnect")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
---
 net/x25/af_x25.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index c31d2af5dd22..725d35596e3f 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1768,15 +1768,18 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
 {
 	struct sock *s;
 
+restart:
 	write_lock_bh(&x25_list_lock);
 
 	sk_for_each(s, &x25_list) {
 		if (x25_sk(s)->neighbour == nb) {
+			sock_hold(s);
 			write_unlock_bh(&x25_list_lock);
 			lock_sock(s);
 			x25_disconnect(s, ENETUNREACH, 0, 0);
 			release_sock(s);
-			write_lock_bh(&x25_list_lock);
+			sock_put(s);
+			goto restart;
 		}
 	}
 	write_unlock_bh(&x25_list_lock);
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* Re: [PATCH net] xsk: reject tx_metadata_len smaller than struct xsk_tx_metadata
From: Stanislav Fomichev @ 2026-07-20 20:24 UTC (permalink / raw)
  To: Cen Zhang (Microsoft)
  Cc: magnus.karlsson, maciej.fijalkowski, davem, edumazet, kuba,
	pabeni, sdf, horms, netdev, bpf, linux-kernel,
	AutonomousCodeSecurity, tgopinath, kys
In-Reply-To: <20260720155210.34229-1-blbllhy@gmail.com>

On 07/20, Cen Zhang (Microsoft) wrote:
> xdp_umem_reg() validates tx_metadata_len for upper bound (<256) and
> alignment (%8) but not a lower bound.  xsk_skb_metadata() computes
> meta = buffer - pool->tx_metadata_len then unconditionally accesses
> the full 24-byte struct xsk_tx_metadata, so any value less than
> sizeof(struct xsk_tx_metadata) allows an out-of-bounds read.
> 
> KASAN reports this as:
> 
>   BUG: KASAN: vmalloc-out-of-bounds in xsk_skb_metadata+0x4b2/0x500
>   Read of size 8 at addr ffffc90000f11000 by task exploit/148
> 
>   xsk_skb_metadata (net/xdp/xsk.c:837)
>   xsk_build_skb (net/xdp/xsk.c)
>   __xsk_generic_xmit (net/xdp/xsk.c)
>   xsk_sendmsg (net/xdp/xsk.c)
> 
> Add a lower-bound check in xdp_umem_reg() to reject tx_metadata_len
> values that cannot cover the full metadata struct.
> 
> Fixes: 341ac980eab9 ("xsk: Support tx_metadata_len")
> Reported-by: AutonomousCodeSecurity@microsoft.com
> Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
> ---
>  net/xdp/xdp_umem.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
> index 58da2f4f4397..d16ad9d8f919 100644
> --- a/net/xdp/xdp_umem.c
> +++ b/net/xdp/xdp_umem.c
> @@ -208,7 +208,8 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
>  		return -EINVAL;
>  
>  	if (mr->flags & XDP_UMEM_TX_METADATA_LEN) {
> -		if (mr->tx_metadata_len >= 256 || mr->tx_metadata_len % 8)
> +		if (mr->tx_metadata_len < sizeof(struct xsk_tx_metadata) ||
> +		    mr->tx_metadata_len >= 256 || mr->tx_metadata_len % 8)
>  			return -EINVAL;
>  		umem->tx_metadata_len = mr->tx_metadata_len;
>  	}
> -- 
> 2.53.0
> 

This will make adding new tx metadata types harder (and will require all
userspace to be updated whenever we do so), will the following be
a bit nicer? (but, obviously, paying more per-packet at runtime)

(untested)

diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h
index 46797645a0c2..b55b878949d5 100644
--- a/include/net/xdp_sock_drv.h
+++ b/include/net/xdp_sock_drv.h
@@ -260,9 +260,21 @@ xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
 	0)
 
 static inline bool
-xsk_buff_valid_tx_metadata(const struct xsk_tx_metadata *meta)
+xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool,
+			   const struct xsk_tx_metadata *meta)
 {
-	return !(meta->flags & ~XDP_TXMD_FLAGS_VALID);
+	/* covers flags, XDP_TXMD_FLAGS_CHECKSUM & XDP_TXMD_FLAGS_TIMESTAMP */
+	if (unlikely(pool->tx_metadata_len < 16))
+		return false;
+
+	if (unlikely(meta->flags & ~XDP_TXMD_FLAGS_VALID))
+		return false;
+
+	if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
+		if (unlikely(pool->tx_metadata_len < offsetofend(struct xsk_tx_metadata, launch_time)))
+			return false;
+
+	return true;
 }
 
 static inline struct xsk_tx_metadata *
@@ -274,7 +286,7 @@ __xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data)
 		return NULL;
 
 	meta = data - pool->tx_metadata_len;
-	if (unlikely(!xsk_buff_valid_tx_metadata(meta)))
+	if (unlikely(!xsk_buff_valid_tx_metadata(pool, meta)))
 		return NULL; /* no way to signal the error to the user */
 
 	return meta;
@@ -469,7 +481,8 @@ xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
 	return (struct xdp_desc_ctx){ };
 }
 
-static inline bool xsk_buff_valid_tx_metadata(struct xsk_tx_metadata *meta)
+static inline bool xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool,
+					      struct xsk_tx_metadata *meta)
 {
 	return false;
 }
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index b970f30ea9b9..75b2c97e41e4 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -809,7 +809,7 @@ static int xsk_skb_metadata(struct sk_buff *skb, void *buffer,
 		return -EINVAL;
 
 	meta = buffer - pool->tx_metadata_len;
-	if (unlikely(!xsk_buff_valid_tx_metadata(meta)))
+	if (unlikely(!xsk_buff_valid_tx_metadata(pool, meta)))
 		return -EINVAL;
 
 	if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) {

^ permalink raw reply related

* Re: short description of GeoNetworking
From: Andrew Lunn @ 2026-07-20 20:16 UTC (permalink / raw)
  To: Simon Dietz
  Cc: andrew+netdev, davem, dietz23838, edumazet, johannes, kuniyu,
	linux-wireless, netdev
In-Reply-To: <20260720183613.2020886-1-simon.dietz@plantwatch.de>

On Mon, Jul 20, 2026 at 08:36:13PM +0200, Simon Dietz wrote:
> Hi Andrew,
> 
> > Is there an architecture documentation somewhere?
> No really available one, at least not public. The ETSI ITS standard is
> public available and there are research papers, but that would be a lot
> to read.

Sorry, i was meaning Linux architecture. Something is feeding in GPS
location information. I assume there is some daemon talking to gpsd on
one side, and the kernel and the other? What other user space pieces
are there?

> > One of my comments was about routing tables.
> I agree that cosine calculations may not belong to the kernel space.
> Before we continue talking about routing tables, let me give a short
> 
> Description of the GeoNetworking (gn) protocol
> 
> GeoNetworking is used in a vehicle2x context where vehicles exchange
> position information (and other data in higher protocol layers like
> BTP) for use cases like trafic jam notifications, or railroad crossing

BTP?

> communication with cars or trains.
> 
> gn transmitts packets in various possible 'modes', including:
> * broadcast (all recievers in range, like ip)

Hold on. IP broadcast, not L2 broadcast. So if you have a mash, this
broadcast is L2 multi hop, but stays within the same IP subnet.

> * single hop broadcast (all recievers in direct range, like ip, if the
>   reviever is in the same network and no default gateway is used)

Given the previous definition, this makes no sense. IP broadcast never
leaves the IP subnet. You need to use IP multicast, and an IP
multicast gateway for such packets to go into other subnets. And then
you need PIM or some other multicast routing protocol.

> * unicast (one reciever out of range, packet is sent to the closest
>   intermediary; only here a routing decision is involved)

Closest intermediary. So the idea is the maximise the number of L2
hops?  That can make sense, assuming the underlying WiFi network is
using different coding rates. A short hop can use a high coding rate,
making the use of air time shorter. If the furthest intermediary was
used, you need to use a lower coding rate, which takes up more air
time.

And only unicast needs routing? So broadcast is dumb flood everywhere,
and the receiver needs to remove duplicates, and not reflood
duplicates. And broadcast uses the lowest coding rate, so giving the
biggest coverage, but takes up the most air time.

> gn packets contain a gps position and a geographic target scope, which
> can be one of predefined shapes (rectangle, circle, ellipsis) and
> dimensions of that shape (radius if circle, length and width if
> rectangle). Hosts with a position outside the shape may recieve, e.g.
> a broadcast, but drop the packet (because it's out of the target scope)

So the sender does not care about the shape, it is the receiver which
does the filtering. And there is no concept of a receiver which is
outside the shape being able to fill dead spots by transmitting back
towards the shape?

> There are location service (ls) requests, which are used to query
> nearby hosts for the location of a host out of the sender's own range,
> which are answered with ls reply packets.

So this is a flood search? Is the outward path recorded in each LS
request packet as it hops away from the sender?  So when it reaches
the target, the reply can be hop-by-hop unicast back to the requester?

> I would suggest to handle them in kernel space and only notify the user
> space, if something happens (previously unknown beacon recieved, ls
> reply recieved, ...) instead of passing all the beacon and ls packets
> to user space.

We generally split policy from mechanical actions. Doing a routing
table lookup is mechanical, and goes in the kernel. The policy of what
to put in the routing table is generally in userspace. If you think
about IP routing, we have a couple of different OSPF versions, BGP,
IS-IS, RIP, EIGRP, etc. Each implement a different policy.

It also seems like there is some scope for experimentation here with
routing. A node at the edge of the shape receiving from a node in the
middle of the shape could consider where its neighbours are within the
same, and set the coding rate for the broadcast based on the unicast
coding rates to pick the highest rate which should work for all
neighbours, so saving air time? And rather than trying to maximise
hops, you could try to find an intermediary somewhere in the middle,
so you balance hops and coding rate/air time?

That sort of experimentation is a lot harder to do in the kernel, it
is more natural to do in userspace.

> > There also seems to be a need for location information. How does that
> > get into the kernel? Is there a daemon for that? Patches to gpsd?
> In the first version /proc has been used, after that ioctl; today
> netlink generic seems to be the most reasonable option. We used
> standard u-blox gps recievers and wrote a little userspace tool to
> inject the location information into the kernel space (via ioctl).

So it would be good to include a link to your git repo. We generally
want open user spaces tools. And i would expect a generic solution,
e.g. using gpsd, so any of the GPSes supported by gpds can be used.
However, given the simplicity of the API, this is not a GPU after all,
this is less important.

> That brings me to the question, how the ideal interface between user
> and kernel space should look like for this module/functionality.
> 
> For short term, it should be possible to strip the routing stuff incl.
> the cos table from the module and return -EOPNOTSUPP and/or -EINVAL
> when using advanced stuff like routing and only support recieving gn
> packets and send broadcast and beacon packets. Routing could then be
> added in a v2 patch series.

How useful is the stack without unicast?

    Andrew

^ permalink raw reply

* Re: [PATCH] bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg()
From: Emil Tsalapatis @ 2026-07-20 20:12 UTC (permalink / raw)
  To: Chengfeng Ye, Eric Dumazet, Neal Cardwell, Kuniyuki Iwashima,
	John Fastabend, Jakub Sitnicki, Jiayuan Chen, David S. Miller,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Alexei Starovoitov,
	Daniel Borkmann, open list:BPF [L7 FRAMEWORK] (sockmap)
  Cc: netdev, linux-kernel, stable
In-Reply-To: <20260719161630.2901208-1-nicoyip.dev@gmail.com>

On Sun Jul 19, 2026 at 12:16 PM EDT, Chengfeng Ye wrote:
> tcp_bpf_sendmsg() keeps msg_tx across sk_stream_wait_memory(), which
> drops and reacquires the socket lock.  Its error path tries to decide
> whether msg_tx names the local temporary message by comparing it with
> the current value of psock->cork.
>
> This comparison is unsafe when two threads send on the same socket:
>
>   Thread A                         Thread B
>   msg_tx = psock->cork
>   sk_msg_alloc() fails
>   sk_stream_wait_memory()
>     releases the socket lock      acquires the socket lock
>                                   completes the cork
>                                   psock->cork = NULL
>                                   frees the cork
>     reacquires the socket lock
>   msg_tx != psock->cork
>   sk_msg_free(msg_tx)
>
> The stale cork is therefore mistaken for the local temporary message
> and freed again.  KASAN reported:
>
>   BUG: KASAN: slab-use-after-free in sk_msg_free+0x49/0x50
>   Read of size 4 at addr ffff88810c908800 by task poc/90
>   Call Trace:
>    sk_msg_free+0x49/0x50
>    tcp_bpf_sendmsg+0x14f5/0x1cc0
>    __sys_sendto+0x32c/0x3a0
>    __x64_sys_sendto+0xdb/0x1b0
>   Allocated by task 89:
>    __kasan_kmalloc+0x8f/0xa0
>    tcp_bpf_sendmsg+0x16b3/0x1cc0
>   Freed by task 91:
>    __kasan_slab_free+0x43/0x70
>    kfree+0x131/0x3c0
>    tcp_bpf_sendmsg+0xec3/0x1cc0
>
> msg_tx can only name the stack-local tmp or the shared cork.  Test for
> tmp directly so a changed psock->cork cannot turn a shared message into
> an apparent local one.
>
> Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
> ---

Hi Chengfeng,

The patch looks good:

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>

There is one caveat: Normally we ignore pre-existing issues Sashiko
finds while reviewing the patch that are unrelated to the change itself.
For this function, however, I think we should make an exception because
it has multiple glaring issues we can fix more cleanly if we do it all
at once. E.g., tmp never gets cleaned up even if there are allocations
hanging off of it.

Would you be willing to expand the patch that addresses the Sashiko
comments, even if unrelated to your fix? That would save us the time
to review the inevitable followups and provide more coherent
refactoring.

>  net/ipv4/tcp_bpf.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
> index 8e905b50dead..a30475afb6f8 100644
> --- a/net/ipv4/tcp_bpf.c
> +++ b/net/ipv4/tcp_bpf.c
> @@ -604,7 +604,7 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
>  wait_for_memory:
>  		err = sk_stream_wait_memory(sk, &timeo);
>  		if (err) {
> -			if (msg_tx && msg_tx != psock->cork)
> +			if (msg_tx == &tmp)
>  				sk_msg_free(sk, msg_tx);
>  			goto out_err;
>  		}


^ permalink raw reply

* Re: [PATCH] net: mana: cap HWC init max message size to HW_CHANNEL_MAX_REQUEST_SIZE
From: Erni Sri Satya Vennela @ 2026-07-20 20:07 UTC (permalink / raw)
  To: Michael Bommarito
  Cc: Haiyang Zhang, Dexuan Cui, Long Li, K . Y . Srinivasan, Wei Liu,
	Andrew Lunn, Jakub Kicinski, Paolo Abeni, netdev, linux-hyperv,
	linux-kernel, stable
In-Reply-To: <20260711150628.2914205-1-michael.bommarito@gmail.com>

On Sat, Jul 11, 2026 at 11:06:28AM -0400, Michael Bommarito wrote:
> mana_hwc_init_event_handler() in hw_channel.c stores device-advertised
> HWC_INIT_DATA_MAX_REQUEST and HWC_INIT_DATA_MAX_RESPONSE values
> without bounds checking. mana_hwc_alloc_dma_buf() later computes the
> DMA buffer size as MANA_PAGE_ALIGN(q_depth * max_msg_size) in 32-bit
> arithmetic. A malicious device returning a large max_msg_size causes
> the product to wrap, allocating a small buffer while laying out
> q_depth request slots at the unwrapped stride, placing slots outside
> the allocation.

I don't think the described data flow actually
exists in the current tree, so the security framing looks inaccurate.
Please check the comment below.
> 
> Impact: a compromised hypervisor device model or malicious MANA PCI
> device can cause out-of-bounds DMA buffer writes during HWC channel
> initialization. A reproducer is available on request.
> 
> Clamp both values to HW_CHANNEL_MAX_REQUEST_SIZE (4096), consistent
> with the cap already applied at the channel-create callsite.
> 
> Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-4-7
> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
> ---
>  drivers/net/ethernet/microsoft/mana/hw_channel.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> index 48a9acea4ab6c..a0916b50cffce 100644
> --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
> +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> @@ -152,10 +152,14 @@ static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
>  			break;
>  
>  		case HWC_INIT_DATA_MAX_REQUEST:
> +			if (val == 0 || val > HW_CHANNEL_MAX_REQUEST_SIZE)
> +				val = HW_CHANNEL_MAX_REQUEST_SIZE;
>  			hwc->hwc_init_max_req_msg_size = val;
>  			break;
>  
>  		case HWC_INIT_DATA_MAX_RESPONSE:
> +			if (val == 0 || val > HW_CHANNEL_MAX_REQUEST_SIZE)
> +				val = HW_CHANNEL_MAX_REQUEST_SIZE;
>  			hwc->hwc_init_max_resp_msg_size = val;
>  			break;
>  

The clamp is applied to hwc->hwc_init_max_req_msg_size and
hwc->hwc_init_max_resp_msg_size. Tracing where those two fields are
consumed:

  mana_hwc_init_event_handler()
	|
  mana_hwc_establish_channel() // copies them out to *max_req_msg_size
        |                          and *max_resp_msg_size
  mana_hwc_create_channel()    // passes those locals only to
        |                          mana_hwc_test_channel()
  mana_hwc_test_channel()      // passed as parameters but never
                                   used them

The DMA buffers that alloc_dma_buf() sizes are created from
mana_hwc_init_queues(), which is called with the compile-time constants:

    err = mana_hwc_init_queues(hwc, HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH,
                   HW_CHANNEL_MAX_REQUEST_SIZE,
                   HW_CHANNEL_MAX_RESPONSE_SIZE);

Therefore, q_depth * max_msg_size cannot wrap from a device-controlled
value here.

Thanks,
Vennela
> -- 
> 2.53.0
> 

> 

^ permalink raw reply

* Re: [RFC PATCH net-next 02/13] net: devmem: extend memory provider for knod
From: Mina Almasry @ 2026-07-20 19:43 UTC (permalink / raw)
  To: Taehee Yoo
  Cc: Alex Deucher, Alexei Starovoitov, amd-gfx, Andrew Lunn,
	Andrii Nakryiko, Bill Wendling, bpf, Christian König,
	Daniel Borkmann, David Airlie, David S. Miller, Donald Hunter,
	dri-devel, Eduard Zingerman, Emil Tsalapatis, Eric Dumazet,
	Felix Kuehling, Hoyeon Lee, Ilias Apalodimas, Jakub Kicinski,
	Jesper Dangaard Brouer, Jiri Olsa, John Fastabend, Justin Stitt,
	Kees Cook, Kumar Kartikeya Dwivedi, Leon Romanovsky,
	linaro-mm-sig, linux-hardening, linux-kernel, linux-kselftest,
	linux-media, linux-rdma, llvm, Mark Bloch, Martin KaFai Lau,
	Michael Chan, Nathan Chancellor, netdev, Nick Desaulniers,
	Paolo Abeni, Pavan Chebbi, Saeed Mahameed, Shuah Khan,
	Simona Vetter, Simon Horman, Song Liu, Stanislav Fomichev,
	Sumit Semwal, Tariq Toukan, Yonghong Song
In-Reply-To: <20260719175857.4071636-3-ap420073@gmail.com>

On Sun, Jul 19, 2026 at 11:03 AM Taehee Yoo <ap420073@gmail.com> wrote:
>
> Extend the devmem memory-provider path so a knod accelerator can back a
> NIC page_pool with accelerator-exported memory (dma-buf), letting the
> NIC DMA received packets directly into accelerator memory.
>
> Signed-off-by: Taehee Yoo <ap420073@gmail.com>

Changes look fine in general but I do not understand in the design how
the page_pool not bound to rx queue would be used. Maybe elaborate on
the design in the commit message or cover letter in the next
iteration.

> (cherry picked from commit d511a8cb3e229f8f5cf060985880d45bd384db87)

I guess remove unintended cherry-pick tag.

> ---
>  include/net/devmem.h                    |  58 +++++++++++++
>  include/net/netmem.h                    |   9 +++
>  include/net/page_pool/memory_provider.h |   4 +
>  include/net/page_pool/types.h           |  23 +++++-
>  net/core/devmem.c                       | 103 +++++++++++++++++++-----
>  net/core/devmem.h                       |   7 +-
>  net/core/page_pool.c                    |  22 ++++-
>  7 files changed, 198 insertions(+), 28 deletions(-)
>  create mode 100644 include/net/devmem.h
>
> diff --git a/include/net/devmem.h b/include/net/devmem.h
> new file mode 100644
> index 000000000000..f1c3895d7833
> --- /dev/null
> +++ b/include/net/devmem.h

Try to keep only include/net/netmem.h and net/core/devmem.h rather
than add an include/net/devmem.h

> @@ -0,0 +1,58 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Device memory TCP support
> + *
> + * Authors:    Mina Almasry <almasrymina@google.com>
> + *             Willem de Bruijn <willemb@google.com>
> + *             Kaiyuan Zhang <kaiyuanz@google.com>
> + *
> + */
> +#ifndef _NET_DEVMEM_H
> +#define _NET_DEVMEM_H
> +
> +#include <linux/dma-direction.h>
> +#include <linux/err.h>
> +#include <linux/types.h>
> +
> +struct device;
> +struct dma_buf;
> +struct dma_buf_attach_ops;
> +struct net_device;
> +struct net_devmem_dmabuf_binding;
> +struct netlink_ext_ack;
> +
> +#if defined(CONFIG_NET_DEVMEM)
> +struct net_devmem_dmabuf_binding *
> +__net_devmem_binding_create(struct net_device *dev, struct device *dma_dev,
> +                           struct dma_buf *dmabuf,
> +                           enum dma_data_direction direction,
> +                           const struct dma_buf_attach_ops *importer_ops,
> +                           struct netlink_ext_ack *extack);
> +int net_devmem_bind_dmabuf_to_queue_direct(struct net_device *dev, u32 rxq_idx,
> +                                          struct net_devmem_dmabuf_binding *binding);
> +void net_devmem_unbind_dmabuf_direct(struct net_devmem_dmabuf_binding *binding);
> +#else
> +static inline struct net_devmem_dmabuf_binding *
> +__net_devmem_binding_create(struct net_device *dev, struct device *dma_dev,
> +                           struct dma_buf *dmabuf,
> +                           enum dma_data_direction direction,
> +                           const struct dma_buf_attach_ops *importer_ops,
> +                           struct netlink_ext_ack *extack)
> +{
> +       return ERR_PTR(-EOPNOTSUPP);
> +}
> +
> +static inline int
> +net_devmem_bind_dmabuf_to_queue_direct(struct net_device *dev, u32 rxq_idx,
> +                                      struct net_devmem_dmabuf_binding *binding)
> +{
> +       return -EOPNOTSUPP;
> +}
> +
> +static inline void
> +net_devmem_unbind_dmabuf_direct(struct net_devmem_dmabuf_binding *binding)
> +{
> +}
> +#endif
> +
> +#endif /* _NET_DEVMEM_H */
> diff --git a/include/net/netmem.h b/include/net/netmem.h
> index bccacd21b6c3..3ddfbd37500f 100644
> --- a/include/net/netmem.h
> +++ b/include/net/netmem.h
> @@ -127,6 +127,15 @@ static inline void net_iov_init(struct net_iov *niov,
>         niov->type = type;
>  }
>
> +/* Global page index within the dma-buf, accounting for multi-chunk
> + * scatter-gather layouts where each chunk owner's niovs start at 0.
> + */
> +static inline unsigned int net_iov_binding_idx(const struct net_iov *niov)
> +{
> +       return (net_iov_owner(niov)->base_virtual >> PAGE_SHIFT) +
> +              net_iov_idx(niov);
> +}
> +
>  /* netmem */
>
>  /**
> diff --git a/include/net/page_pool/memory_provider.h b/include/net/page_pool/memory_provider.h
> index 255ce4cfd975..4b58a9702fb7 100644
> --- a/include/net/page_pool/memory_provider.h
> +++ b/include/net/page_pool/memory_provider.h
> @@ -23,6 +23,10 @@ bool net_mp_niov_set_dma_addr(struct net_iov *niov, dma_addr_t addr);
>  void net_mp_niov_set_page_pool(struct page_pool *pool, struct net_iov *niov);
>  void net_mp_niov_clear_page_pool(struct net_iov *niov);
>
> +void page_pool_provider_set_netmem(struct page_pool *pool, netmem_ref netmem,
> +                                  dma_addr_t addr);
> +void page_pool_clear_pp_info(netmem_ref netmem);
> +
>  int netif_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
>                       const struct pp_memory_provider_params *p,
>                       struct netlink_ext_ack *extack);
> diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h
> index 03da138722f5..3e866f249768 100644
> --- a/include/net/page_pool/types.h
> +++ b/include/net/page_pool/types.h
> @@ -31,8 +31,16 @@
>   */
>  #define PP_FLAG_ALLOW_UNREADABLE_NETMEM BIT(3)
>
> +/* Driver-managed pool with a directly-supplied memory provider, not bound to a
> + * netdev rx queue. Setting this flag requires page_pool_params.mp_ops and
> + * .mp_priv to both be set.
> + */
> +#define PP_FLAG_CUSTOM_MEMORY_PROVIDER BIT(4)
> +
>  #define PP_FLAG_ALL            (PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV | \
> -                                PP_FLAG_SYSTEM_POOL | PP_FLAG_ALLOW_UNREADABLE_NETMEM)
> +                                PP_FLAG_SYSTEM_POOL | \
> +                                PP_FLAG_ALLOW_UNREADABLE_NETMEM | \
> +                                PP_FLAG_CUSTOM_MEMORY_PROVIDER)
>
>  /* Index limit to stay within PP_DMA_INDEX_BITS for DMA indices */
>  #define PP_DMA_INDEX_LIMIT XA_LIMIT(1, BIT(PP_DMA_INDEX_BITS) - 1)
> @@ -54,11 +62,11 @@
>   * would have to take a slower code path.
>   */
>  #if PAGE_SIZE >= SZ_64K
> -#define PP_ALLOC_CACHE_REFILL  4
> +#define PP_ALLOC_CACHE_REFILL  256
>  #elif PAGE_SIZE >= SZ_16K
> -#define PP_ALLOC_CACHE_REFILL  16
> +#define PP_ALLOC_CACHE_REFILL  1024
>  #else
> -#define PP_ALLOC_CACHE_REFILL  64
> +#define PP_ALLOC_CACHE_REFILL  4096
>  #endif
>

I'm guessing this is just a workaround/optimization. You need a proper
change for this, maybe make it configurable arguments when creating a
pp or something.

>  #define PP_ALLOC_CACHE_SIZE    (PP_ALLOC_CACHE_REFILL * 2)
> @@ -67,6 +75,8 @@ struct pp_alloc_cache {
>         netmem_ref cache[PP_ALLOC_CACHE_SIZE];
>  };
>
> +struct memory_provider_ops;
> +
>  /**
>   * struct page_pool_params - page pool parameters
>   * @fast:      params accessed frequently on hotpath
> @@ -83,6 +93,9 @@ struct pp_alloc_cache {
>   * @queue_idx: queue idx this page_pool is being created for.
>   * @flags:     PP_FLAG_DMA_MAP, PP_FLAG_DMA_SYNC_DEV, PP_FLAG_SYSTEM_POOL,
>   *             PP_FLAG_ALLOW_UNREADABLE_NETMEM.
> + * @mp_ops:    driver-supplied memory provider for a pool not bound to a
> + *             netdev rx queue (NULL to use rxq->mp_params instead)
> + * @mp_priv:   context passed to @mp_ops
>   */
>  struct page_pool_params {
>         struct_group_tagged(page_pool_params_fast, fast,
> @@ -99,6 +112,8 @@ struct page_pool_params {
>                 struct net_device *netdev;
>                 unsigned int queue_idx;
>                 unsigned int    flags;
> +               const struct memory_provider_ops *mp_ops;
> +               void *mp_priv;
>  /* private: used by test code only */
>                 void (*init_callback)(netmem_ref netmem, void *arg);
>                 void *init_arg;
> diff --git a/net/core/devmem.c b/net/core/devmem.c
> index 957d6b96216b..9e21cffc9643 100644
> --- a/net/core/devmem.c
> +++ b/net/core/devmem.c
> @@ -121,12 +121,9 @@ void net_devmem_free_dmabuf(struct net_iov *niov)
>         gen_pool_free(binding->chunk_pool, dma_addr, PAGE_SIZE);
>  }
>
> -void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
> +static void
> +net_devmem_binding_unpublish(struct net_devmem_dmabuf_binding *binding)
>  {
> -       struct netdev_rx_queue *rxq;
> -       unsigned long xa_idx;
> -       unsigned int rxq_idx;
> -
>         xa_erase(&net_devmem_dmabuf_bindings, binding->id);
>
>         /* Ensure no tx net_devmem_lookup_dmabuf() are in flight after the
> @@ -136,6 +133,15 @@ void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
>
>         if (binding->list.next)
>                 list_del(&binding->list);
> +}
> +
> +void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
> +{
> +       struct netdev_rx_queue *rxq;
> +       unsigned long xa_idx;
> +       unsigned int rxq_idx;
> +
> +       net_devmem_binding_unpublish(binding);
>
>         xa_for_each(&binding->bound_rxqs, xa_idx, rxq) {
>                 const struct pp_memory_provider_params mp_params = {
> @@ -151,6 +157,47 @@ void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
>         percpu_ref_kill(&binding->ref);
>  }
>
> +/* Bind/unbind variants for in-kernel offload importers that drive the rx
> + * queue lifecycle themselves. The mp_params are poked directly, without the
> + * tcp-data-split/XDP guards or the queue reconfigure that the netlink control
> + * plane applies through netif_mp_open_rxq()/netif_mp_close_rxq().
> + */
> +int net_devmem_bind_dmabuf_to_queue_direct(struct net_device *dev, u32 rxq_idx,
> +                                          struct net_devmem_dmabuf_binding *binding)
> +{

The LLM says in this function you need to check if the queue is
already bound to a devmem tcp memory provider.

-- 
Thanks,
Mina

^ permalink raw reply

* [PATCH v2] nfc: llcp: Fix nfc_dev refcount leak in connect
From: Shuangpeng Bai @ 2026-07-20 19:37 UTC (permalink / raw)
  To: david, oe-linux-nfc
  Cc: davem, edumazet, kuba, pabeni, horms, netdev, linux-kernel,
	Shuangpeng Bai

llcp_sock_connect() takes a reference to the NFC device and keeps it
while a connection is active. For a nonblocking connection,
sock_wait_state() returns -EINPROGRESS while the socket remains in
LLCP_CONNECTING.

If the socket is released before reaching LLCP_CONNECTED,
llcp_sock_destruct() does not drop the reference because it only handles
connected sockets.

Drop the device reference in llcp_sock_release() when unlinking a
connecting socket. At this point llcp_sock->dev is still valid, unlike
after a failed blocking connection has cleared it.

Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
Link: https://lore.kernel.org/r/20260707183518.1888697-1-shuangpeng.kernel@gmail.com
Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
---
Changes in v2:
- Move the device put from llcp_sock_destruct() to llcp_sock_release()
  to avoid dereferencing a NULL llcp_sock->dev after a failed blocking
  connect.
- Add Fixes and Link tags.

 net/nfc/llcp_sock.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index feab29fc62f4..0a3d87c2c9b3 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -633,10 +633,12 @@ static int llcp_sock_release(struct socket *sock)
 
 	if (sock->type == SOCK_RAW)
 		nfc_llcp_sock_unlink(&local->raw_sockets, sk);
-	else if (sk->sk_state == LLCP_CONNECTING)
+	else if (sk->sk_state == LLCP_CONNECTING) {
 		nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
-	else
+		nfc_put_device(llcp_sock->dev);
+	} else {
 		nfc_llcp_sock_unlink(&local->sockets, sk);
+	}
 
 	if (llcp_sock->reserved_ssap < LLCP_SAP_MAX)
 		nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
-- 
2.43.0

^ permalink raw reply related

* Re: [PATCH bpf-next v5 8/8] selftests: net: add test for XDP_PASS skb checksum invalidation
From: Stanislav Fomichev @ 2026-07-20 19:32 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Donald Hunter, Jakub Kicinski, David S. Miller, Eric Dumazet,
	Paolo Abeni, Simon Horman, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev,
	Andrew Lunn, Tony Nguyen, Przemek Kitszel, Alexander Lobakin,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Hao Luo, Jiri Olsa, Shuah Khan,
	Maciej Fijalkowski, Jonathan Corbet, Shuah Khan,
	Kumar Kartikeya Dwivedi, Emil Tsalapatis, Vladimir Vdovin,
	Jakub Sitnicki, netdev, bpf, intel-wired-lan, linux-kselftest,
	linux-doc
In-Reply-To: <alkBnI3XcH0XGjEo@lore-desk>

On 07/16, Lorenzo Bianconi wrote:
> On Jul 16, Stanislav Fomichev wrote:
> > On 07/15, Lorenzo Bianconi wrote:
> > > Add a test that verifies skb->ip_summed is set to CHECKSUM_NONE
> > > when a device running in XDP mode creates an skb from a xdp_buff
> > > if the attached ebpf program returns an XDP_PASS.
> > > The test attaches an XDP program returning XDP_PASS, and a TC
> > > ingress program that runs the bpf_skb_rx_checksum() kfunc to
> > > inspect the resulting skb. After XDP_PASS the driver must invalidate
> > > any previously computed hardware RX checksum since XDP may have
> > > modified the packet data.
> > > The BPF program counts packets per checksum type in a map, and the
> > > test runner verifies that after sending traffic the CHECKSUM_NONE
> > > counter is non-zero while CHECKSUM_UNNECESSARY and CHECKSUM_COMPLETE
> > > counters are zero.
> > > 
> > > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > > ---
> > >  Documentation/networking/xdp-rx-metadata.rst       |  5 ++
> > >  .../selftests/drivers/net/hw/xdp_metadata.py       | 55 +++++++++++++++-
> > >  .../selftests/net/lib/skb_metadata_csum.bpf.c      | 73 ++++++++++++++++++++++
> > >  3 files changed, 132 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/Documentation/networking/xdp-rx-metadata.rst b/Documentation/networking/xdp-rx-metadata.rst
> > > index 93918b3769a3..7434ac98242a 100644
> > > --- a/Documentation/networking/xdp-rx-metadata.rst
> > > +++ b/Documentation/networking/xdp-rx-metadata.rst
> > > @@ -90,6 +90,11 @@ conversion, and the XDP metadata is not used by the kernel when building
> > >  ``skbs``. However, TC-BPF programs can access the XDP metadata area using
> > >  the ``data_meta`` pointer.
> > 
> > [..]
> > 
> > > +If a driver is running in XDP mode, any existing hardware RX checksum
> > > +(``CHECKSUM_UNNECESSARY`` or ``CHECKSUM_COMPLETE``) must be invalidated
> > > +by setting ``skb->ip_summed`` to ``CHECKSUM_NONE`` before passing the
> > > +skb to the kernel, since XDP may have modified the packet data.
> > > +
> > >  In the future, we'd like to support a case where an XDP program
> > >  can override some of the metadata used for building ``skbs``.
> > 
> > Sorry for keeping nitpicking on this, but I'm still not convinced that
> > it is what we currently do. From my previous reply:
> 
> no worries :)
> My current take-away from the previous discussion is we just need to document
> what would be the driver expected behaviour adding a kselftest for it (without
> modifying any driver).
> 
> > 
> > > > Looking at a few drivers:
> > > > - bnxt (bnxt_rx_pkt) does UNNECESSARY - ok
> > > > - mlx5 (mlx5e_handle_csum) does UNNECESSARY and skips COMPLETE if there is
> > > >   bpf prog attached
> > > > - fbnic (fbnic_rx_csum) - can do COMPLETE even with xdp attached?
> > > > - gve (gve_rx) - can do COMPLETE even with xdp attached?
> > 
> > (although for gve I might be wrong, there is also gve_rx_skb_csum that only
> > does UNNECESSARY).
> > 
> > I'd wait for Jakub to chime in, but it feels like we should just document
> > what we currently do as a recommended approach: for the drivers
> > that support COMPLETE, do not report it when the bpf program is attached.
> > Both NONE and UNNECESSARY are ok.
> 
> I am not completely sure the UNNECESSARY case is different from the COMPLETE
> one. What are we supposed to do if the driver reports UNNECESSARY and the ebpf
> program modifies some fields covered by the rx-checksum?

For unnecessary, I think the safe expectation is that the bpf program
will update the value of the checksum in the packet if it touches the data?

> > Also, did you run this test on real HW? NIPA now has HW tests, maybe it
> > makes sense to route this series via net-next to get the real coverage?
> 
> What about splitting this series and have two different series:
> - bpf-next: add xdp rx kfunc and related selftest
> - net-next: add kselftest for the driver expected behaviour.
> 
> What do you think?

I'd post everything to net-next to get the HW coverage. Once you get all
the acks we can ask the maintainers' guidance.

^ permalink raw reply

* Re: [PATCH v4 net 0/6] xsk: fix AF_XDP multi-buffer Tx descriptor reclaim
From: Stanislav Fomichev @ 2026-07-20 19:30 UTC (permalink / raw)
  To: Maciej Fijalkowski
  Cc: netdev, bpf, magnus.karlsson, stfomichev, kuba, pabeni, horms,
	bjorn, kerneljasonxing
In-Reply-To: <20260719135609.147823-1-maciej.fijalkowski@intel.com>

On 07/19, Maciej Fijalkowski wrote:
> v3:
> https://lore.kernel.org/netdev/20260714140722.111645-1-maciej.fijalkowski@intel.com/T/
> v3->v4:
> 
> * Return standalone invalid Tx descriptors through the completion ring in
>   both the generic and zero-copy Tx paths. Advancing the Tx-ring consumer
>   releases only the ring slot; returning the descriptor address through
>   the CQ also transfers ownership of the corresponding UMEM frame back to
>   userspace.
> 
> * Remove xsk_tx_batch::consumed_descs. With standalone invalid descriptors
>   now reclaimed through the CQ, every descriptor permanently removed from
>   the Tx ring is represented by either tx_descs or reclaim_descs. Use
>   their sum for Tx-consumer advancement, shared-UMEM fairness accounting,
>   and progress detection.
> 
> * Ensure that generic reclaim-only processing publishes the updated
>   Tx-ring consumer even when no packet was submitted to the networking
>   stack.
> 
> * Update the XSK selftests to count every descriptor submitted to the Tx
>   ring as an expected CQ entry, while continuing to count only valid
>   packets as expected Rx traffic. This covers standalone invalid
>   descriptors, invalid multi-buffer packets, oversized packets, and the
>   non-verbatim STAT_TX_INVALID tests.
> 
> * Update the AF_XDP documentation to describe the completion ring as an
>   ownership-transfer mechanism and document that standalone, invalid
>   multi-buffer, and oversized Tx packets are reclaimed through the CQ.
> 
> * Add Jason's tags

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

Kudos for updating the doc with the new expectations! (and I still hope
that we can separately redo the generic tx path)

^ permalink raw reply

* Re: [PATCH net 1/1] openvswitch: Fix CT limit teardown use-after-free
From: Aaron Conole @ 2026-07-20 19:29 UTC (permalink / raw)
  To: andrew
  Cc: Yuan Tan, Ren Wei, xuyuqiabc, netdev, dev, echaudro, i.maximets,
	davem, edumazet, pabeni, horms, pshelar, yihung.wei, tonanli66
In-Reply-To: <c9a39c7f-cdad-4e8d-b516-b727806525a0@lunn.ch>

Andrew Lunn <andrew@lunn.ch> writes:

> On Sun, Jul 19, 2026 at 11:54:31PM -0700, Yuan Tan wrote:
> > 
> > On 7/19/26 19:52, Andrew Lunn wrote:
> > > On Mon, Jul 20, 2026 at 10:14:16AM +0800, Ren Wei wrote:
> > >> From: Yuqi Xu <xuyuqiabc@gmail.com>
> > >>
> > >> Packet processing uses CT limit state under RCU, while netns teardown
> > >> frees that state under ovs_mutex. The CT limit pointer was neither removed
> > >> from readers nor protected by a grace period, allowing packet processing to
> > >> dereference the freed state.
> > >>
> > >> Replace the pointer before freeing the CT limit state. Wait for in-flight
> > >> RCU readers before freeing its contents. Serialize CT limit netlink
> > >> operations with teardown for the full lifetime of their state accesses.
> > >>
> > >> Fixes: 11efd5cb04a1 ("openvswitch: Support conntrack zone limit")
> > >> Cc: stable@vger.kernel.org
> > >> Reported-by: Vega <vega@nebusec.ai>
> > > Is Vega a person?
> > 
> > Hi Andrew,
> > 
> > Thank you very much for your review!
> > For context, we had previously understood that using the tool name in
> > the Reported-by tag was acceptable, based on examples such as
> > Reported-by: AutonomousCodeSecurity@microsoft.com and Reported-by:
> > Anthropic.
> > 
> > https://lore.kernel.org/all/20260630171016.11c02dec@kernel.org/
> 
> https://docs.kernel.org/process/submitting-patches.html
> 
>   The Reported-by tag gives credit to people who find bugs and report
>   them and it hopefully inspires them to help us again in the
>   future. The tag is intended for bugs; please do not use it to credit
>   feature requests. The tag should be followed by a Closes: tag
>   pointing to the report, unless the report is not available on the
>   web.
> 
> If you believe this is out of date, please submit a patch with new
> text to this document.

It is common practice to accept syzbot reports as well, which look like:

    Reported-by: syzbot+36256deb69a588e9290e@syzkaller.appspotmail.com
    Closes: https://syzkaller.appspot.com/bug?extid=36256deb69a588e9290e

(see commit 539dfcf69105d8d3d4d677b71de6e5ede2e6dfa0 for example).

> I find it valuable being a person. It indicate somebody is bothered by
> the problem you are fixing. We see a lot theoretical bug fixes, which
> in practice nobody ever hit. I would prefer to spend my time reviewing
> real issues, not theoretical issues, and the Reported-by: is a quick
> indicator of this.

+1

In the case of syzbot reports, they are real actionable reports that we
can look at and address (and I agree with your sentiment of wanting to
focus on real issues).  They include the 'Closes:' tag as well, and a
reviewer can just visit the link and see the splat.  If there is a
report link that this Vega tool pushes, maybe that would be acceptable
since it's the way syzbot works as well.  It also makes sense to update
the documentation to reflect how it is used currently.

As for the v2, it would help my review to include some kind of
reproducer description - I usually try to experience OVS splats for
myself.


^ permalink raw reply

* Re: [RFC PATCH net-next 00/13] net: knod: in-kernel network offload device
From: Mina Almasry @ 2026-07-20 19:18 UTC (permalink / raw)
  To: Taehee Yoo
  Cc: Alex Deucher, Alexei Starovoitov, amd-gfx, Andrew Lunn,
	Andrii Nakryiko, Bill Wendling, bpf, Christian König,
	Daniel Borkmann, David Airlie, David S. Miller, Donald Hunter,
	dri-devel, Eduard Zingerman, Emil Tsalapatis, Eric Dumazet,
	Felix Kuehling, Hoyeon Lee, Ilias Apalodimas, Jakub Kicinski,
	Jesper Dangaard Brouer, Jiri Olsa, John Fastabend, Justin Stitt,
	Kees Cook, Kumar Kartikeya Dwivedi, Leon Romanovsky,
	linaro-mm-sig, linux-hardening, linux-kernel, linux-kselftest,
	linux-media, linux-rdma, llvm, Mark Bloch, Martin KaFai Lau,
	Michael Chan, Nathan Chancellor, netdev, Nick Desaulniers,
	Paolo Abeni, Pavan Chebbi, Saeed Mahameed, Shuah Khan,
	Simona Vetter, Simon Horman, Song Liu, Stanislav Fomichev,
	Sumit Semwal, Tariq Toukan, Yonghong Song
In-Reply-To: <20260719175857.4071636-1-ap420073@gmail.com>

On Sun, Jul 19, 2026 at 11:01 AM Taehee Yoo <ap420073@gmail.com> wrote:
>
> knod (in-kernel network offload device) drives a GPU directly from the
> Linux kernel - with no userspace GPU runtime such as CUDA or ROCm, and
> no userspace component in the data path - to accelerate packet
> processing.
>
> The kernel itself allocates the GPU's queues, JIT-compiles the
> per-packet program to GPU machine code, and dispatches it; the NIC DMAs
> received packets straight into GPU memory and the GPU returns a verdict.
> The GPU is programmed like any other in-kernel offload, not through a
> userspace framework, so existing XDP programs and IPsec SAs can be
> offloaded to it transparently.
>
> The design and motivation were presented at Linux Plumbers Conference
> 2025:
>
>   https://lpc.events/event/19/contributions/2267/
>
> Motivation
> ==========
>
> Line-rate packet processing that does non-trivial per-packet work - an
> XDP program doing L4 load balancing, or IPsec crypto - is bound by the
> host CPU: each core handles one packet at a time, so scaling means
> spending more cores. A GPU is the opposite shape - thousands of lanes
> running the same small program over many packets at once (SIMT) - which
> happens to match the per-packet-program model of XDP.
>
> knod moves that per-packet compute off the host CPU and onto a GPU. The
> NIC DMAs received packets directly into GPU memory, the GPU runs the
> program across a batch of packets in parallel, and only the result
> comes back: a verdict for every packet, plus the packet itself for the
> ones destined to the host. The CPU no longer pays the per-packet
> program cost, and throughput scales with GPU occupancy rather than core
> count.
>
> Crucially this happens entirely inside the kernel. GPU packet processing
> today generally launches work from a userspace GPU runtime (CUDA and
> friends) and keeps that runtime in the data path; knod instead builds
> the GPU queues, compiles the program, and dispatches it from the kernel,
> so it plugs into existing offload paths (XDP, xfrm) with nothing to
> install or keep running in userspace.
>

TBH I found this motivation weak, especially since IIUC you're asking
for almost ~50K lines of code to be merged to the kernel. My thinking
is that (a) it's true that Native XDP takes up CPU cores, but
HW-offload XDP already exists and takes up no CPU. (b) with AI, GPUs
are very expensive and the work they're doing is critical, so you're
unlikely to buy a GPU and use it for knod-offloaded XDP; you'd
probably buy a cheaper smart-NIC? And in the cases where you do have a
GPU, it's likely your system's money-maker, and you probably want to
offload work from the GPU, not to your GPU.

But as far as I can tell there should be much more interesting
applications for what you're doing rather than offloading XDP. Like
wouldn't you with this feature be able to implement ML collectively
like all-to-all/all-reduce/all-gather as purely XDP programs offloaded
to the GPU? If you have that implemented and can positively compare
performance to RoCE or RDMA that would be a much more interesting use
case IMO.

> Model
> =====
>
> knod binds two endpoints through a third object:
>
>   - a NIC-side netdev, registered by the NIC driver;
>   - an accelerator (the GPU), registered by a provider built into the
>     GPU driver;
>   - an offload device, created on attach, that connects them and owns
>     the per-queue data-path state.
>
> The accelerator ops are feature-agnostic, so different per-packet
> programs plug in behind one interface. This series ships two features
> to show the framework is not tied to a single use case (the accel-type
> uAPI also reserves "dpu" for future non-GPU backends):
>
>   - BPF:   an XDP program attached in offload mode is JIT-compiled from
>            eBPF to an AMD GCN shader and executed on the GPU.
>   - IPsec: RX ESP full-packet decrypt on the GPU (proof of concept,
>            see below).
>
> Data path
> =========
>
> For a NIC RX queue bound to an accelerator, a received packet flows as
> follows:
>
>   1. Attach reconfigures the NIC's page_pool so its pages come from GPU
>      memory, exported as a dma-buf and plugged in through the devmem
>      memory provider. The NIC therefore DMAs the packet straight into
>      GPU memory - there is no host-side copy on RX.
>
>   2. Instead of building an skb and entering the stack, the NIC's NAPI
>      pushes a small descriptor (memory ref + offset + length) onto a
>      per-queue lock-free SPSC ring shared with the GPU.
>
>   3. A persistent GPU worker drains descriptors and runs the active
>      feature's shader over a batch of packets in parallel - one
>      workgroup per packet - then writes a per-packet verdict back onto
>      the ring: PASS, DROP or TX.
>
>   4. Back on the NIC NAPI, each verdict is applied:
>        - DROP: the GPU page is recycled to the pool;
>        - TX:   the packet is sent back out the NIC directly from GPU
>                memory (XDP_TX), with no host round-trip;
>        - PASS: the packet is copied out of GPU memory into a host
>                delivery page by the GPU's DMA engine (async SDMA),
>                wrapped as an skb, and handed to the normal stack.
>
> So only PASS packets ever touch host memory, and even then the copy is
> done by the GPU, not the CPU.
>
> The control plane is a generic netlink family ("knod") for
> attach/detach, accelerator/NIC inventory, and per-accelerator feature
> selection, with notifications on bind/unbind.
>
> Code layout
> ===========
>
> knod separates into a subsystem-neutral core and a GPU-specific
> provider; nothing in the core knows about GPUs. Roughly:
>
>   - core + control plane + NIC drivers   net/, kernel/bpf/       (~4.4k)
>   - GPU provider (queues, JIT, shaders)  drivers/gpu/drm/amd/    (~39k)
>

Since the changes are so large, I would break this work into many
series, the first which only supports a very minimal set of work
(which I would guess would be XDP_DROP and XDP_TX), and then follow up
with another series which adds XDP_PASS support, and then IPSec, etc.

-- 
Thanks,
Mina

^ permalink raw reply

* RE: [PATCH net v3 2/3] net: ethernet: oa_tc6: Improvement in buffer overflow handling
From: Selvamani Rajagopal @ 2026-07-20 19:09 UTC (permalink / raw)
  To: Simon Horman
  Cc: parthiban.veerasooran@microchip.com, andrew+netdev@lunn.ch,
	Piergiorgio Beruto, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, andrew@lunn.ch,
	Parthiban.Veerasooran@microchip.com
In-Reply-To: <20260710142019.1619159-1-horms@kernel.org>

> 
> [High]
> Now that oa_tc6_prcs_rx_frame_end() returns int (and can return -EAGAIN
> via oa_tc6_update_rx_skb() when tail + size > end), should the
> "previous rx frame end + next rx frame start" branch also observe the
> return value? That branch is not shown in the diff, but in the
> resulting file it reads:
> 
> if (start_valid && end_valid && start_byte_offset > end_byte_offset) {


Andew and others,

I don't know why my v3 submission is under "Archived" flag. "state" is still new and I was waiting
for it to move to "Change requested" before submitting the next patch set. May be my understanding
is wrong.  Hope I can submit the following patch. 

FYI:
https://patchwork.kernel.org/project/netdevbpf/list/?series=&submitter=rajagopal&state=&q=&archive=true&delegate=

Sincerely
Selva





^ permalink raw reply

* [PATCH] rds: synchronize info callbacks with connection teardown
From: Chengfeng Ye @ 2026-07-20 18:49 UTC (permalink / raw)
  To: Allison Henderson, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Santosh Shilimkar, Ka-Cheong Poon,
	Dan Carpenter
  Cc: netdev, linux-rdma, rds-devel, linux-kernel, Chengfeng Ye, stable

rds_info_getsockopt() reads an info callback without holding
rds_info_lock across its invocation.  At the same time, rds_exit()
destroys all connections before unregistering the socket info callbacks.

This permits the following interleaving:

  CPU0                              CPU1
  rds_info_getsockopt()
    func = rds6_sock_inc_info
                                    rds_exit()
                                      rds_conn_exit()
                                        rds_conn_destroy()
                                          kmem_cache_free(conn)
    func()
      rds6_inc_info_copy()
        inc->i_conn->c_tos

The receive queue lock keeps the incoming message on its socket queue,
but it does not keep inc->i_conn alive.  KASAN reports:

  BUG: KASAN: slab-use-after-free in rds6_inc_info_copy+0x459/0x530 [rds]
  Read of size 1 at addr ffff888106031c50 by task poc/101
  Call Trace:
   rds6_inc_info_copy+0x459/0x530 [rds]
   rds6_sock_inc_info+0x2b9/0x3c0 [rds]
   rds_info_getsockopt+0x19d/0x380 [rds]
   do_sock_getsockopt+0x2ac/0x480
   __sys_getsockopt+0x128/0x210
  Allocated by task 99:
   kmem_cache_alloc_noprof+0x11a/0x360
   __rds_conn_create+0x7e/0xd60 [rds]
   rds_conn_create_outgoing+0x61/0x80 [rds]
   rds_sendmsg+0xb83/0x1d00 [rds]
  Freed by task 102:
   kmem_cache_free+0x1b5/0x3d0
   rds_conn_destroy+0x484/0x600 [rds]
   rds_loop_exit_net+0x32/0x50 [rds]
   unregister_pernet_device+0x2c/0x50
   rds_conn_exit+0x13/0xa0 [rds]
   rds_exit+0x1a/0xc40 [rds]
   __do_sys_delete_module+0x30a/0x4d0

Publish and clear callback pointers with SRCU, and keep the SRCU read-side
critical section across callback execution. SRCU permits callbacks such as
RDS_INFO_COUNTERS to sleep, unlike classic RCU. After clearing a slot,
synchronize_srcu() waits for every in-flight callback.
Move socket callback deregistration ahead of protocol and connection
teardown. This prevents callbacks from reaching a connection after it is
freed.

Fixes: 7d0a06586b26 ("net/rds: Fix info leak in rds6_inc_info_copy()")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
 net/rds/af_rds.c | 12 ++++++------
 net/rds/info.c   | 20 ++++++++++++++------
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index d5defe9172e3..b3fe2bd6ea35 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -925,6 +925,12 @@ static void rds6_sock_info(struct socket *sock, unsigned int len,
 static void rds_exit(void)
 {
 	sock_unregister(rds_family_ops.family);
+	rds_info_deregister_func(RDS_INFO_SOCKETS, rds_sock_info);
+	rds_info_deregister_func(RDS_INFO_RECV_MESSAGES, rds_sock_inc_info);
+#if IS_ENABLED(CONFIG_IPV6)
+	rds_info_deregister_func(RDS6_INFO_SOCKETS, rds6_sock_info);
+	rds_info_deregister_func(RDS6_INFO_RECV_MESSAGES, rds6_sock_inc_info);
+#endif
 	proto_unregister(&rds_proto);
 	rds_conn_exit();
 	rds_cong_exit();
@@ -933,12 +939,6 @@ static void rds_exit(void)
 	rds_stats_exit();
 	rds_page_exit();
 	rds_bind_lock_destroy();
-	rds_info_deregister_func(RDS_INFO_SOCKETS, rds_sock_info);
-	rds_info_deregister_func(RDS_INFO_RECV_MESSAGES, rds_sock_inc_info);
-#if IS_ENABLED(CONFIG_IPV6)
-	rds_info_deregister_func(RDS6_INFO_SOCKETS, rds6_sock_info);
-	rds_info_deregister_func(RDS6_INFO_RECV_MESSAGES, rds6_sock_inc_info);
-#endif
 }
 module_exit(rds_exit);
 
diff --git a/net/rds/info.c b/net/rds/info.c
index 21b32eb16559..7d6f3552d65b 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -32,6 +32,7 @@
  */
 #include <linux/percpu.h>
 #include <linux/seq_file.h>
+#include <linux/srcu.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/export.h>
@@ -68,8 +69,9 @@ struct rds_info_iterator {
 	unsigned long offset;
 };
 
+DEFINE_STATIC_SRCU(rds_info_srcu);
 static DEFINE_SPINLOCK(rds_info_lock);
-static rds_info_func rds_info_funcs[RDS_INFO_LAST - RDS_INFO_FIRST + 1];
+static rds_info_func __rcu rds_info_funcs[RDS_INFO_LAST - RDS_INFO_FIRST + 1];
 
 void rds_info_register_func(int optname, rds_info_func func)
 {
@@ -78,8 +80,8 @@ void rds_info_register_func(int optname, rds_info_func func)
 	BUG_ON(optname < RDS_INFO_FIRST || optname > RDS_INFO_LAST);
 
 	spin_lock(&rds_info_lock);
-	BUG_ON(rds_info_funcs[offset]);
-	rds_info_funcs[offset] = func;
+	BUG_ON(rcu_access_pointer(rds_info_funcs[offset]));
+	rcu_assign_pointer(rds_info_funcs[offset], func);
 	spin_unlock(&rds_info_lock);
 }
 EXPORT_SYMBOL_GPL(rds_info_register_func);
@@ -91,9 +93,10 @@ void rds_info_deregister_func(int optname, rds_info_func func)
 	BUG_ON(optname < RDS_INFO_FIRST || optname > RDS_INFO_LAST);
 
 	spin_lock(&rds_info_lock);
-	BUG_ON(rds_info_funcs[offset] != func);
-	rds_info_funcs[offset] = NULL;
+	BUG_ON(rcu_access_pointer(rds_info_funcs[offset]) != func);
+	RCU_INIT_POINTER(rds_info_funcs[offset], NULL);
 	spin_unlock(&rds_info_lock);
+	synchronize_srcu(&rds_info_srcu);
 }
 EXPORT_SYMBOL_GPL(rds_info_deregister_func);
 
@@ -165,6 +168,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, sockopt_t *opt)
 	int npages = 0;
 	int ret;
 	int len;
+	int srcu_idx;
 	int total;
 
 	len = opt->optlen;
@@ -214,8 +218,11 @@ int rds_info_getsockopt(struct socket *sock, int optname, sockopt_t *opt)
 	rdsdebug("len %d nr_pages %lu\n", len, nr_pages);
 
 call_func:
-	func = rds_info_funcs[optname - RDS_INFO_FIRST];
+	srcu_idx = srcu_read_lock(&rds_info_srcu);
+	func = srcu_dereference(rds_info_funcs[optname - RDS_INFO_FIRST],
+				&rds_info_srcu);
 	if (!func) {
+		srcu_read_unlock(&rds_info_srcu, srcu_idx);
 		ret = -ENOPROTOOPT;
 		goto out;
 	}
@@ -225,6 +232,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, sockopt_t *opt)
 	iter.offset = offset0;
 
 	func(sock, len, &iter, &lens);
+	srcu_read_unlock(&rds_info_srcu, srcu_idx);
 	BUG_ON(lens.each == 0);
 
 	total = lens.nr * lens.each;
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-next 2/2] selftests: net: add test for IPv4 address scope ordering
From: Tim Wong @ 2026-07-20 18:21 UTC (permalink / raw)
  To: netdev; +Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms,
	linux-kernel
In-Reply-To: <CAPT8rhu_NGbLd54RFWRxO+=7BHhJ0pS5yeOgo5kNmq4qtQ=t8w@mail.gmail.com>

Add a selftest verifying that IPv4 addresses on an interface are
enumerated with global-scope addresses listed before link-scope
addresses, regardless of the order in which the addresses were
configured. This exercises the ordering fixed in the preceding
patch ("ipv4: devinet: list global scope addresses before link
scope addresses") and guards against regression.

Signed-off-by: kanman.wong <kanman.wong@dish.com>
---
 tools/testing/selftests/net/Makefile          |  1 +
 .../selftests/net/fib_ipv4_scope_order.sh     | 55 +++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100755 tools/testing/selftests/net/fib_ipv4_scope_order.sh

diff --git a/tools/testing/selftests/net/Makefile
b/tools/testing/selftests/net/Makefile
index 708d960ae07d..66a79c915961 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -33,6 +33,7 @@ TEST_PROGS := \
  fdb_flush.sh \
  fdb_notify.sh \
  fib-onlink-tests.sh \
+ fib_ipv4_scope_order.sh \
  fib_nexthop_multiprefix.sh \
  fib_nexthop_nongw.sh \
  fib_nexthops.sh \
diff --git a/tools/testing/selftests/net/fib_ipv4_scope_order.sh
b/tools/testing/selftests/net/fib_ipv4_scope_order.sh
new file mode 100755
index 000000000000..3bbb7eefa2d8
--- /dev/null
+++ b/tools/testing/selftests/net/fib_ipv4_scope_order.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Verify IPv4 addresses are enumerated with global-scope addresses
+# listed before link-scope addresses on the same interface,
+# regardless of the order in which they were configured -- matching
+# existing IPv6 address enumeration behavior.
+
+source lib.sh
+
+ret=0
+
+setup() {
+ setup_ns TEST_NS
+ ip -n "$TEST_NS" link add dummy0 type dummy
+ ip -n "$TEST_NS" link set dummy0 up
+}
+
+cleanup() {
+ cleanup_ns "$TEST_NS"
+}
+
+check_order() {
+ local desc="$1"
+ local order
+ local first
+
+ order=$(ip -n "$TEST_NS" -o addr show dev dummy0 | grep -oP
'(?<=scope )(global|link)')
+ first=$(echo "$order" | head -1)
+
+ if [ "$first" != "global" ]; then
+ echo "FAIL: $desc: link-scope address listed before global-scope address"
+ ret=1
+ else
+ echo "PASS: $desc"
+ fi
+}
+
+trap cleanup EXIT
+setup
+
+# Case 1: link-scope address added before global-scope address.
+ip -n "$TEST_NS" addr add 169.254.1.1/16 dev dummy0 scope link
+ip -n "$TEST_NS" addr add 192.0.2.1/24 dev dummy0 scope global
+check_order "link added before global"
+
+ip -n "$TEST_NS" addr flush dev dummy0
+
+# Case 2: global-scope address added before link-scope address
+# (sanity check -- should already pass even without the fix).
+ip -n "$TEST_NS" addr add 192.0.2.1/24 dev dummy0 scope global
+ip -n "$TEST_NS" addr add 169.254.1.1/16 dev dummy0 scope link
+check_order "global added before link"
+
+exit $ret
-- 
2.51.0

^ permalink raw reply related

* short description of GeoNetworking
From: Simon Dietz @ 2026-07-20 18:36 UTC (permalink / raw)
  To: andrew
  Cc: andrew+netdev, davem, dietz23838, edumazet, johannes, kuniyu,
	linux-wireless, netdev, simon.dietz
In-Reply-To: <89b3aa8c-f2ec-4b27-b5b0-5891d870e001@lunn.ch>

Hi Andrew,

> Is there an architecture documentation somewhere?
No really available one, at least not public. The ETSI ITS standard is
public available and there are research papers, but that would be a lot
to read.

> One of my comments was about routing tables.
I agree that cosine calculations may not belong to the kernel space.
Before we continue talking about routing tables, let me give a short

Description of the GeoNetworking (gn) protocol

GeoNetworking is used in a vehicle2x context where vehicles exchange
position information (and other data in higher protocol layers like
BTP) for use cases like trafic jam notifications, or railroad crossing
communication with cars or trains.

gn transmitts packets in various possible 'modes', including:
* broadcast (all recievers in range, like ip)
* single hop broadcast (all recievers in direct range, like ip, if the
  reviever is in the same network and no default gateway is used)
* unicast (one reciever out of range, packet is sent to the closest
  intermediary; only here a routing decision is involved)

gn packets contain a gps position and a geographic target scope, which
can be one of predefined shapes (rectangle, circle, ellipsis) and
dimensions of that shape (radius if circle, length and width if
rectangle). Hosts with a position outside the shape may recieve, e.g.
a broadcast, but drop the packet (because it's out of the target scope)

There are beacon packets, which are continously sent by each host,
which contain the gps position of the host in order for the other hosts
to be able to perform distance calculations necessary for the routing
and (if no beacon packet has been recieved for a certain while) for
pruning the routing tables from other hosts which are no longer there.

There are location service (ls) requests, which are used to query
nearby hosts for the location of a host out of the sender's own range,
which are answered with ls reply packets.

There is an address rotation mechanism for privacy reasons, so it may
occur, that a vehicle disappears at a point and reappears as different
vehicle (without advertisement of the address change, so a correlation
of old/new address is not feasable).


So regarding routing there is the question where (user or kernel space)
the beacons and location service should be handled.

I would suggest to handle them in kernel space and only notify the user
space, if something happens (previously unknown beacon recieved, ls
reply recieved, ...) instead of passing all the beacon and ls packets
to user space.

> There also seems to be a need for location information. How does that
> get into the kernel? Is there a daemon for that? Patches to gpsd?
In the first version /proc has been used, after that ioctl; today
netlink generic seems to be the most reasonable option. We used
standard u-blox gps recievers and wrote a little userspace tool to
inject the location information into the kernel space (via ioctl).

That brings me to the question, how the ideal interface between user
and kernel space should look like for this module/functionality.

For short term, it should be possible to strip the routing stuff incl.
the cos table from the module and return -EOPNOTSUPP and/or -EINVAL
when using advanced stuff like routing and only support recieving gn
packets and send broadcast and beacon packets. Routing could then be
added in a v2 patch series.

What do you think?

Simon


^ permalink raw reply

* Re: [PATCH 1/3] mm: move internal mempolicy APIs to new internal header
From: Vlastimil Babka (SUSE) @ 2026-07-20 18:34 UTC (permalink / raw)
  To: Matthew Wilcox, Brendan Jackman
  Cc: Brendan Jackman, Andrew Morton, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Johannes Weiner, Zi Yan,
	Jan Kara, Joshua Hahn, Byungchul Park, Gregory Price, Ying Huang,
	Alistair Popple, Hugh Dickins, Baolin Wang, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Joerg Roedel (AMD), Will Deacon, Robin Murphy, Huacai Chen,
	WANG Xuerui, Thomas Gleixner, Chuck Lever, Jeff Layton, NeilBrown,
	Olga Kornievskaia, Dai Ngo, Tom Talpey, Trond Myklebust,
	Anna Schumaker, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, linux-kernel, linux-mm, linux-fsdevel,
	iommu, loongarch, linux-nfs, netdev
In-Reply-To: <al5gQgnBCjNCSD_4@casper.infradead.org>

On 7/20/26 19:52, Matthew Wilcox wrote:
> On Thu, Jul 16, 2026 at 04:57:37PM +0000, Brendan Jackman wrote:
>> On Thu Jul 16, 2026 at 4:48 PM UTC, Matthew Wilcox wrote:
>> > On Thu, Jul 16, 2026 at 02:30:10PM +0000, Brendan Jackman wrote:
>> >> There are no external users for this surface, reduce the scope.
>> >> -struct folio *folio_alloc_mpol_noprof(gfp_t gfp, unsigned int order,
>> >> -		struct mempolicy *mpol, pgoff_t ilx, int nid);
>> >
>> > Hm.  So what we're saying is that allocations which respect mempolicy are
>> > only for core mm and not for, eg, device drivers to do.  Is that really
>> > what we want to say?  I don't think so, because that's inconsistent
>> > with having just widened __filemap_get_folio_mpol to allow guest_memfd
>> > to specify a mempolicy.

guest_memfd is practically mm internal though, IMHO.

>> Yeah I agree, mempolicy definitely seems like a "public concept".  All
>> I'm saying here is this specific function doesn't have any external
>> users so it doesn't need to be an external header. 
> 
> I don't think that should be the metric for moving things to internal.h.
> To me, internal.h is a signifier that these interfaces should only be
> used by the MM.  Not that "all current users are within the MM".

Perhaps. It can be also useful to move them outside only when someone asks.

>> ... With the ulterior motive that I want to add a new parameter to it
>> that actually _is_ mm-internal. Namely, alloc_flags, so I can add
>> ALLOC_UNMAPPED to implement AS_NO_DIRECT_MAP, i.e. the next iteration of
>> [0]. So basically this is
>> about trying to extend the allocator without creating a GFP flag.
> 
> Yeah.  I'm not sold on the whole alloc_flags thing, but I'm too busy to
> sit down and think it through properly to get involved in a proper
> argument about how it should work.

Well it's basically a workaround for limited gfp flags space. So we can
extend it without making that a cost for everybody, as long as those that
need the new functionality are limited.

> My entirely unresearched and ill-considered opinion is that the __GFP
> flags should _be_ the ALLOC flags.  We shoudn't be translating GFP flags
> into ALLOC flags that are what the allocator actually uses, the

It uses both.

> translation should be done at compile time.  So if GFP_KERNEL and

That would assume the gfp flags are also known at compile time, which is not
always the case.

> GFP_ATOMIC need to be composed of different flags with different

The flags we are adding/considering to add are not about GFP_KERNEL vs
GFP_ATOMIC context, however.

> semantics, then we should do that, not invent a different set of flags
> that special people can use for special purposes.

Yep it's ugly and pragmatic, as usual. At least it's not immortalized as an
UAPI, so we can deal with exploring in a wrong direction and fixing it later.

>> So I'm envisaging if an external user arises for it later, we'd slap two
>> underscores on the beginning of the internal one, (with the alloc_flags
>> arg), and then bring back the public one as a wrapper.
>> 
>> Does that make sense?
> 
> We have a long history of people just moving stuff around in patches
> without knowing what the intent was if it should be moved.

I guess this patch is not critical to the rest, if that's an issue.

^ permalink raw reply

* Re: [PATCH 1/3] mm: move internal mempolicy APIs to new internal header
From: Gregory Price @ 2026-07-20 18:29 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Brendan Jackman, Brendan Jackman, Andrew Morton,
	David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Johannes Weiner, Zi Yan, Jan Kara, Joshua Hahn, Byungchul Park,
	Ying Huang, Alistair Popple, Hugh Dickins, Baolin Wang, Chris Li,
	Kairui Song, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
	Youngjun Park, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
	Huacai Chen, WANG Xuerui, Thomas Gleixner, Chuck Lever,
	Jeff Layton, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
	Trond Myklebust, Anna Schumaker, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel, linux-mm,
	linux-fsdevel, iommu, loongarch, linux-nfs, netdev
In-Reply-To: <al5gQgnBCjNCSD_4@casper.infradead.org>

On Mon, Jul 20, 2026 at 06:52:02PM +0100, Matthew Wilcox wrote:
> 
> > ... With the ulterior motive that I want to add a new parameter to it
> > that actually _is_ mm-internal. Namely, alloc_flags, so I can add
> > ALLOC_UNMAPPED to implement AS_NO_DIRECT_MAP, i.e. the next iteration of
> > [0]. So basically this is
> > about trying to extend the allocator without creating a GFP flag.
> 
> Yeah.  I'm not sold on the whole alloc_flags thing, but I'm too busy to
> sit down and think it through properly to get involved in a proper
> argument about how it should work.
> 
> My entirely unresearched and ill-considered opinion is that the __GFP
> flags should _be_ the ALLOC flags.  We shoudn't be translating GFP flags
> into ALLOC flags that are what the allocator actually uses, the
> translation should be done at compile time.  So if GFP_KERNEL and
> GFP_ATOMIC need to be composed of different flags with different
> semantics, then we should do that, not invent a different set of flags
> that special people can use for special purposes.
> 

alloc_flags is putting me between a rock and a hard place.

I figured out a clean isolation mechanism with zonelists (new rfc is
posting today, i'm doing one last proofread), but it required me to
extend some of the mm/ internal interfaces with a zonelist selector.

Since Brendan's base work made it in mm-new, i decided to replace
the zonelist selector with ALLOC_ZONELIST_PRIVATE as the selector
to avoid *yet more* arguments.

I'll be posting with ALLOC_ZONELIST_PRIVATE on top of mm-new, but
the churn is getting painful.

It really seems like we just want an mm/ internal interface that
exposes struct alloc_context for specific *mm/* callers
(see: compaction_context, migration_context, etc), and interfaces
that keep this nonsense transparent for everyone else.

Then if you want access to alloc_context interface, you need to get
export approval for that component (similar to EXPORT_FOR_MODULES).

Just spitballing here, but the churn is killing me.

~Gregory


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox