Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net 3/5] net/sched: sch_cake: annotate data-races in cake_dump_stats() (III)
From: Toke Høiland-Jørgensen @ 2026-04-23 12:11 UTC (permalink / raw)
  To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Jamal Hadi Salim, Jiri Pirko, netdev, eric.dumazet,
	Eric Dumazet
In-Reply-To: <20260423102324.3172448-4-edumazet@google.com>

Eric Dumazet <edumazet@google.com> writes:

> cake_dump_stats() runs without qdisc spinlock being held.
>
> In this third patch, I add READ_ONCE()/WRITE_ONCE() annotations
> for the following fields:
>
> - packets
> - tin_dropped
> - tin_ecn_mark
> - ack_drops
> - peak_delay
> - avge_delay
> - base_delay
>
> Other annotations are added in following patches, to ease code review.
>
> Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: "Toke Høiland-Jørgensen" <toke@toke.dk>

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

^ permalink raw reply

* Re: [PATCH net 4/5] net/sched: sch_cake: annotate data-races in cake_dump_stats() (IV)
From: Toke Høiland-Jørgensen @ 2026-04-23 12:12 UTC (permalink / raw)
  To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Jamal Hadi Salim, Jiri Pirko, netdev, eric.dumazet,
	Eric Dumazet
In-Reply-To: <20260423102324.3172448-5-edumazet@google.com>

Eric Dumazet <edumazet@google.com> writes:

> cake_dump_stats() runs without qdisc spinlock being held.
>
> In this fourth patch, I add READ_ONCE()/WRITE_ONCE() annotations
> for the following fields:
>
> - avg_peak_bandwidth
> - buffer_limit
> - buffer_max_used
> - avg_netoff
> - max_netlen
> - max_adjlen
> - min_netlen
> - min_adjlen
> - active_queues
> - tin_rate_bps
> - bytes
> - tin_backlog
>
> Other annotations are added in following patch, to ease code review.
>
> Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: "Toke Høiland-Jørgensen" <toke@toke.dk>
> ---
>  net/sched/sch_cake.c | 90 ++++++++++++++++++++++----------------------
>  1 file changed, 46 insertions(+), 44 deletions(-)
>
> diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
> index c5aae31565e984e40937b55201b498174a37180e..c3b09f67f0fdbc51d23b3d22df9ab89a716c7e2b 100644
> --- a/net/sched/sch_cake.c
> +++ b/net/sched/sch_cake.c
> @@ -1379,9 +1379,9 @@ static u32 cake_calc_overhead(struct cake_sched_data *qd, u32 len, u32 off)
>  		len -= off;
>  
>  	if (qd->max_netlen < len)
> -		qd->max_netlen = len;
> +		WRITE_ONCE(qd->max_netlen, len);
>  	if (qd->min_netlen > len)
> -		qd->min_netlen = len;
> +		WRITE_ONCE(qd->min_netlen, len);
>  
>  	len += q->rate_overhead;
>  
> @@ -1401,9 +1401,9 @@ static u32 cake_calc_overhead(struct cake_sched_data *qd, u32 len, u32 off)
>  	}
>  
>  	if (qd->max_adjlen < len)
> -		qd->max_adjlen = len;
> +		WRITE_ONCE(qd->max_adjlen, len);
>  	if (qd->min_adjlen > len)
> -		qd->min_adjlen = len;
> +		WRITE_ONCE(qd->min_adjlen, len);
>  
>  	return len;
>  }
> @@ -1416,7 +1416,7 @@ static u32 cake_overhead(struct cake_sched_data *q, const struct sk_buff *skb)
>  	u16 segs = qdisc_pkt_segs(skb);
>  	u32 len = qdisc_pkt_len(skb);
>  
> -	q->avg_netoff = cake_ewma(q->avg_netoff, off << 16, 8);
> +	WRITE_ONCE(q->avg_netoff, cake_ewma(q->avg_netoff, off << 16, 8));
>  
>  	if (segs == 1)
>  		return cake_calc_overhead(q, len, off);
> @@ -1596,7 +1596,7 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
>  	len = qdisc_pkt_len(skb);
>  	q->buffer_used      -= skb->truesize;
>  	b->backlogs[idx]    -= len;
> -	b->tin_backlog      -= len;
> +	WRITE_ONCE(b->tin_backlog, b->tin_backlog - len);
>  	sch->qstats.backlog -= len;
>  
>  	flow->dropped++;
> @@ -1824,9 +1824,9 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>  		}
>  
>  		/* stats */
> -		b->bytes	    += slen;
> +		WRITE_ONCE(b->bytes, b->bytes + slen);
>  		b->backlogs[idx]    += slen;
> -		b->tin_backlog      += slen;
> +		WRITE_ONCE(b->tin_backlog, b->tin_backlog + slen);
>  		sch->qstats.backlog += slen;
>  		q->avg_window_bytes += slen;

nit: these break up the aligned block, which hurts readability, IMO. Can
we keep the WRITE_ONCE() lines at the top or the bottom of the block?

> @@ -1847,7 +1847,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>  			WRITE_ONCE(b->ack_drops, b->ack_drops + 1);
>  			sch->qstats.drops++;
>  			ack_pkt_len = qdisc_pkt_len(ack);
> -			b->bytes += ack_pkt_len;
> +			WRITE_ONCE(b->bytes, b->bytes + ack_pkt_len);
>  			q->buffer_used += skb->truesize - ack->truesize;
>  			if (q->config->rate_flags & CAKE_FLAG_INGRESS)
>  				cake_advance_shaper(q, b, ack, now, true);
> @@ -1861,9 +1861,9 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>  
>  		/* stats */
>  		WRITE_ONCE(b->packets, b->packets + 1);
> -		b->bytes	    += len - ack_pkt_len;
> +		WRITE_ONCE(b->bytes, b->bytes + len - ack_pkt_len);
>  		b->backlogs[idx]    += len - ack_pkt_len;
> -		b->tin_backlog      += len - ack_pkt_len;
> +		WRITE_ONCE(b->tin_backlog, b->tin_backlog + len - ack_pkt_len);
>  		sch->qstats.backlog += len - ack_pkt_len;
>  		q->avg_window_bytes += len - ack_pkt_len;

same here
>  	}
> @@ -1895,9 +1895,9 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>  			u64 b = q->avg_window_bytes * (u64)NSEC_PER_SEC;
>  
>  			b = div64_u64(b, window_interval);
> -			q->avg_peak_bandwidth =
> -				cake_ewma(q->avg_peak_bandwidth, b,
> -					  b > q->avg_peak_bandwidth ? 2 : 8);
> +			WRITE_ONCE(q->avg_peak_bandwidth,
> +				   cake_ewma(q->avg_peak_bandwidth, b,
> +					     b > q->avg_peak_bandwidth ? 2 : 8));
>  			q->avg_window_bytes = 0;
>  			q->avg_window_begin = now;
>  
> @@ -1938,7 +1938,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>  	}
>  
>  	if (q->buffer_used > q->buffer_max_used)
> -		q->buffer_max_used = q->buffer_used;
> +		WRITE_ONCE(q->buffer_max_used, q->buffer_used);
>  
>  	if (q->buffer_used <= q->buffer_limit)
>  		return NET_XMIT_SUCCESS;
> @@ -1978,7 +1978,7 @@ static struct sk_buff *cake_dequeue_one(struct Qdisc *sch)
>  		skb = dequeue_head(flow);
>  		len = qdisc_pkt_len(skb);
>  		b->backlogs[q->cur_flow] -= len;
> -		b->tin_backlog		 -= len;
> +		WRITE_ONCE(b->tin_backlog, b->tin_backlog - len);
>  		sch->qstats.backlog      -= len;
>  		q->buffer_used		 -= skb->truesize;
>  		sch->q.qlen--;

and here


-Toke

^ permalink raw reply

* Re: [PATCH net 5/5] net/sched: sch_cake: annotate data-races in cake_dump_stats() (V)
From: Toke Høiland-Jørgensen @ 2026-04-23 12:12 UTC (permalink / raw)
  To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Jamal Hadi Salim, Jiri Pirko, netdev, eric.dumazet,
	Eric Dumazet
In-Reply-To: <20260423102324.3172448-6-edumazet@google.com>

Eric Dumazet <edumazet@google.com> writes:

> cake_dump_stats() runs without qdisc spinlock being held.
>
> In this final patch, I add READ_ONCE()/WRITE_ONCE() annotations
> for cparams.target and cparams.interval.
>
> Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: "Toke Høiland-Jørgensen" <toke@toke.dk>

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

^ permalink raw reply

* Re: [PATCH 5.10.y] rxrpc: Fix recvmsg() unconditional requeue
From: Greg KH @ 2026-04-23 12:13 UTC (permalink / raw)
  To: Jay Wang
  Cc: stable, dhowells, marc.dionne, davem, edumazet, kuba, pabeni,
	netdev, linux-afs, jay.wang.upstream, Faith, Pumpkin Chang
In-Reply-To: <20260422222432.7236-1-wanjay@amazon.com>

On Wed, Apr 22, 2026 at 10:24:32PM +0000, Jay Wang wrote:
> From: David Howells <dhowells@redhat.com>
> 
> [ Upstream commit 2c28769a51deb6022d7fbd499987e237a01dd63a ]
> 
> If rxrpc_recvmsg() fails because MSG_DONTWAIT was specified but the call
> at the front of the recvmsg queue already has its mutex locked, it
> requeues the call - whether or not the call is already queued.  The call
> may be on the queue because MSG_PEEK was also passed and so the call was
> not dequeued or because the I/O thread requeued it.

Why did you reformat the changelog text?  Please do not.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH] net/stmmac: Fix typos: 'tx_undeflow_irq' -> 'tx_underflow_irq'
From: Andrew Lunn @ 2026-04-23 12:14 UTC (permalink / raw)
  To: Jakub Raczynski
  Cc: netdev, linux-kernel, kuba, davem, andrew+netdev, kernel-janitors,
	linux-arm-kernel, linux-stm32
In-Reply-To: <aenhiHCZge2dMBFw@AMDC4622.eu.corp.samsungelectronics.net>

> Question is whether this should then remain that way forever?
> And was it really part of some ABI if no one noticed?

Hard to say. I could also be that people did notice, but after it got
released in a kernel, which makes it ABI. It can be very hard to fix
these issues, if you don't catch them in -rcX kernels.

The other patches in this series look O.K, please drop this one and
repost once net-next is open.

https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html

      Andrew

^ permalink raw reply

* Re: [PATCH net v3 8/8] xsk: don't support AF_XDP on 32-bit architectures
From: Alexander Lobakin @ 2026-04-23 12:14 UTC (permalink / raw)
  To: Jason Xing, Maciej Fijalkowski
  Cc: davem, edumazet, kuba, pabeni, bjorn, magnus.karlsson,
	jonathan.lemon, sdf, ast, daniel, hawk, john.fastabend, bpf,
	netdev, Jason Xing
In-Reply-To: <CAL+tcoBH9qm0Ce=vBuCResVEbC_9a1D2VofTW73Uo+t519Ui0A@mail.gmail.com>

From: Jason Xing <kerneljasonxing@gmail.com>
Date: Thu, 23 Apr 2026 07:49:58 +0800

> On Thu, Apr 23, 2026 at 12:58 AM Maciej Fijalkowski
> <maciej.fijalkowski@intel.com> wrote:
>>
>> On Thu, Apr 23, 2026 at 12:37:07AM +0800, Jason Xing wrote:
>>> On Thu, Apr 23, 2026 at 12:10 AM Alexander Lobakin
>>> <aleksander.lobakin@intel.com> wrote:
>>>>
>>>> From: Jason Xing <kerneljasonxing@gmail.com>
>>>> Date: Wed, 22 Apr 2026 11:36:50 +0800
>>>>
>>>>> From: Jason Xing <kernelxing@tencent.com>
>>>>>
>>>>> In copy mode TX, xsk_skb_destructor_set_addr() stores the 64-bit
>>>>> descriptor address into skb_shinfo(skb)->destructor_arg (void *) via a
>>>>> uintptr_t cast:
>>>>>
>>>>>     skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t)addr | 0x1UL);
>>>>>
>>>>> On 32-bit architectures uintptr_t is 32 bits, so the upper 32 bits of
>>>>> the descriptor address are silently dropped. In XDP_ZEROCOPY unaligned
>>>>> mode the chunk offset is encoded in bits 48-63 of the descriptor
>>>>> address (XSK_UNALIGNED_BUF_OFFSET_SHIFT = 48), meaning the offset is
>>>>> lost entirely. The completion queue then returns a truncated address to
>>>>> userspace, making buffer recycling impossible.
>>>>
>>>> What if we relax the restriction a bit? For example, refuse to configure
>>>
>>> As to the bug itself, yes, It only affects the unaligned mode.
>>>
>>> I wonder if we can support this after someone requires us to support
>>> 32-bit arch and use it in the real world, then we can use the previous
>>> patch to complete the full support (which doesn't harm the path on
>>> 64-bit arch).
>>>
>>> The code looks like this based on your suggestion. Just for the record.
>>> diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
>>> index 58da2f4f4397..03417b04592f 100644
>>> --- a/net/xdp/xdp_umem.c
>>> +++ b/net/xdp/xdp_umem.c
>>> @@ -177,6 +177,9 @@ static int xdp_umem_reg(struct xdp_umem *umem,
>>> struct xdp_umem_reg *mr)
>>> if (mr->flags & ~XDP_UMEM_FLAGS_VALID)
>>> return -EINVAL;
>>> + if (!IS_ENABLED(CONFIG_64BIT) && unaligned_chunks)
>>> + return -EOPNOTSUPP;
>>> +
>>> if (!unaligned_chunks && !is_power_of_2(chunk_size))
>>> return -EINVAL;
>>>
>>> Actually I'm fine with either of them. Right now I'm not so sure which
>>> direction this patch should take :)
>>
>> Abstracting from discussion, that is not a patch we would want against
>> -net. We should not forbid 32bit on stable kernels, maybe there is someone
>> in the 'basement' using 32bit xsk on stable kernel. Plus the fixes tag vs
>> patch's content looks weird ;)
> 
> Sorry, I don't follow this. Any specific suggestions on how to move forward?

Maciej just says that if we go the first route (forbid 32-bit arches),
then this commit should not go to the stable/LTS kernels.
But

> 
> Now we have three approaches w/o the fixes tag:
> 1. completely forbid 32-bit arch
> 2. only forbid unaligned mode on 32-bit arch
> 3. completely fix/modify the allocation logic of the first frag on
> 32-bit (see the v2-0008 patch)
> 
> I'm wondering how to proceed with that?

I've just reread the v2 thread (I realized I missed it earlier) and to
me, the v2-0008 (route 3) solution looks good. It introduces a bit of
overhead, but only for 32-bit arches, where the XSk performance will
never be push-it-to-the-limit anyway (esp. given that this is skb mode).

So I'd personally vote for number 3. 47 insertions(+), 7 deletions(-) is
not a big deal. And for 64-bit arches, there won't be any object code
changes at all (unconditional `return 0` and checking the return value
of xsk_skb_init_misc() will be optimized out by the compiler).

Number 2 is also okay-ish, if we're sure that addr is always 32-bit on
32-bit arches in the aligned mode. But given that you already has a
proper fix (n. 3) which allows to not forbid anything at all, I believe
it's more preferred to fix rather than disable.

+ as mentioned above, if you go route number 3, the series could be sent
to -net and the fix would eventually hit the stable/LTS trees, but I
don't think we can disable/forbid something in the stable kernels.

> 
> Thanks,
> Jason
Thanks,
Olek

^ permalink raw reply

* Re: [PATCH net 1/1] ovpn: fix race between deleting interface and adding new peer
From: Antonio Quartulli @ 2026-04-23 12:16 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, Sabrina Dubroca, Ralf Lici, Paolo Abeni, Andrew Lunn,
	David S. Miller, Eric Dumazet, Hyunwoo Kim
In-Reply-To: <20260422192050.7c4ca760@kernel.org>

On 23/04/2026 04:20, Jakub Kicinski wrote:
> On Wed, 22 Apr 2026 14:32:42 +0200 Antonio Quartulli wrote:
>> +	/* Prevent adding new peers while destroying the ovpn interface.
>> +	 * Failing to do so would end up holding the device reference
>> +	 * endlessly hostage of the new peer object with no chance of
>> +	 * release..
>> +	 */
>> +	if (ovpn->dev->reg_state >= NETREG_UNREGISTERING)
>> +		return -ENODEV;
> 
> AI review suggests wrapping reg_state read in READ_ONCE(), I think
> that's legit. Also nit: I think > or != REGISTERED would be more
> idiomatic than comparing >= UNREGSITERING ?

Agreed on READ_ONCE. Will fix it.

As for your second point, I am fine with "!= REGISTERED" as that's the 
only state we should be accepting new peers in any case.

> 
> If you agree make sure Sashiko doesn't complain about anything else
> once it's public:
> https://sashiko.dev/#/patchset/20260422123242.530882-2-antonio@openvpn.net

Is there any way to get earlier access to these reviews? (at least for 
patches somehow related to me/ovpn)


Thanks!
Regards,

-- 
Antonio Quartulli
OpenVPN Inc.


^ permalink raw reply

* Re: [RFC PATCH] net: skb: on zero-copy formatted output to skb
From: Andrew Lunn @ 2026-04-23 12:24 UTC (permalink / raw)
  To: Dmitry Antipov
  Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	netdev, linux-bluetooth
In-Reply-To: <20260423073638.778334-1-dmantipov@yandex.ru>

On Thu, Apr 23, 2026 at 10:36:38AM +0300, Dmitry Antipov wrote:
> Some code, most notably the Bluetooth drivers, uses something like
> the following:
> 
> char buf[80];
> snprintf(buf, sizeof(buf), "Driver: %s\n", driver_name);
> skb_put_data(skb, buf, strlen(buf));
> 
> This looks suboptimal at least because:
> 
> 1) It yields in BUG() just in case the developer underestimates
>    the size of an skb being used;
> 2) It requires extra data copy from an external buffer;
> 3) It uses 'strlen()' redundantly because actual data length
>    is calculated by 'snprintf()' itself.
> 
> So introduce 'skb_printf()' which aims to address all of these
> issues. As usual, thoughts and comments are highly appreciated.

Please always include at least one user of a new helper.

Do you plan to modify all the bluetooth drivers to use this?

	Andrew

^ permalink raw reply

* [PATCH net V3 0/4] net/mlx5: Fixes for Socket-Direct
From: Tariq Toukan @ 2026-04-23 12:31 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Shay Drory, Simon Horman, Kees Cook, Patrisious Haddad,
	Parav Pandit, Gal Pressman, netdev, linux-rdma, linux-kernel,
	Dragos Tatulea

Hi,

This series fixes several race conditions and bugs in the mlx5
Socket-Direct (SD) single netdev flow.

Patch 1 serializes mlx5_sd_init()/mlx5_sd_cleanup() with
mlx5_devcom_comp_lock() and tracks the SD group state on the primary
device, preventing concurrent or duplicate bring-up/tear-down.

Patch 2 fixes the debugfs "multi-pf" directory being stored on the
calling device's sd struct instead of the primary's, which caused
memory leaks and recreation errors when cleanup ran from a different PF.

Patch 3 fixes a race where a secondary PF could access the primary's
auxiliary device after it had been unbound, by holding the primary's
device lock while operating on its auxiliary device.

Patch 4 fixes missing cleanup on ETH probe/resume errors.

Regards,
Tariq

V3:
- Link to V2:
  https://lore.kernel.org/all/20260413105323.186411-1-tariqt@nvidia.com/
- Added "net/mlx5e: SD, Fix missing cleanup on probe/resume error"
  patch to solve missing cleanup bug. (Sashiko)
- remove MLX5_SD_STATE_DESTROYING and move
  mlx5_devcom_comp_set_ready(false) to mlx5_sd_cleanup(), simplify the
  locking around SD state. (Sashiko)

Shay Drory (4):
  net/mlx5: SD: Serialize init/cleanup
  net/mlx5: SD, Keep multi-pf debugfs entries on primary
  net/mlx5e: SD, Fix missing cleanup on probe/resume error
  net/mlx5e: SD, Fix race condition in secondary device probe/remove

 .../net/ethernet/mellanox/mlx5/core/en_main.c | 32 +++++++--
 .../net/ethernet/mellanox/mlx5/core/lib/sd.c  | 68 +++++++++++++++----
 .../net/ethernet/mellanox/mlx5/core/lib/sd.h  |  2 +
 3 files changed, 86 insertions(+), 16 deletions(-)


base-commit: d40831b016b4986e70d20d0ad14e6a0c62318986
-- 
2.44.0


^ permalink raw reply

* [PATCH net V3 2/4] net/mlx5: SD, Keep multi-pf debugfs entries on primary
From: Tariq Toukan @ 2026-04-23 12:31 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Shay Drory, Simon Horman, Kees Cook, Patrisious Haddad,
	Parav Pandit, Gal Pressman, netdev, linux-rdma, linux-kernel,
	Dragos Tatulea
In-Reply-To: <20260423123104.201552-1-tariqt@nvidia.com>

From: Shay Drory <shayd@nvidia.com>

mlx5_sd_init() creates the "multi-pf" debugfs directory under the
primary device debugfs root, but stored the dentry in the calling
device's sd struct. When sd_cleanup() run on a different PF,
this leads to using the wrong sd->dfs for removing entries, which
results in memory leak and an error in when re-creating the SD.[1]

Fix it by explicitly storing the debugfs dentry in the primary
device sd struct and use it for all per-group files.

[1]
debugfs: 'multi-pf' already exists in '0000:08:00.1'

Fixes: 4375130bf527 ("net/mlx5: SD, Add debugfs")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../net/ethernet/mellanox/mlx5/core/lib/sd.c  | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
index 96b4316f570e..897b0d81b27d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
@@ -461,9 +461,13 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
 	if (err)
 		goto err_sd_unregister;
 
-	sd->dfs = debugfs_create_dir("multi-pf", mlx5_debugfs_get_dev_root(primary));
-	debugfs_create_x32("group_id", 0400, sd->dfs, &sd->group_id);
-	debugfs_create_file("primary", 0400, sd->dfs, primary, &dev_fops);
+	primary_sd->dfs =
+		debugfs_create_dir("multi-pf",
+				   mlx5_debugfs_get_dev_root(primary));
+	debugfs_create_x32("group_id", 0400, primary_sd->dfs,
+			   &primary_sd->group_id);
+	debugfs_create_file("primary", 0400, primary_sd->dfs, primary,
+			    &dev_fops);
 
 	mlx5_sd_for_each_secondary(i, primary, pos) {
 		char name[32];
@@ -473,7 +477,8 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
 			goto err_unset_secondaries;
 
 		snprintf(name, sizeof(name), "secondary_%d", i - 1);
-		debugfs_create_file(name, 0400, sd->dfs, pos, &dev_fops);
+		debugfs_create_file(name, 0400, primary_sd->dfs, pos,
+				    &dev_fops);
 
 	}
 
@@ -491,7 +496,8 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
 	mlx5_sd_for_each_secondary_to(i, primary, to, pos)
 		sd_cmd_unset_secondary(pos);
 	sd_cmd_unset_primary(primary);
-	debugfs_remove_recursive(sd->dfs);
+	debugfs_remove_recursive(primary_sd->dfs);
+	primary_sd->dfs = NULL;
 err_sd_unregister:
 	mlx5_devcom_comp_set_ready(sd->devcom, false);
 	mlx5_devcom_comp_unlock(sd->devcom);
@@ -520,7 +526,8 @@ void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
 	mlx5_sd_for_each_secondary(i, primary, pos)
 		sd_cmd_unset_secondary(pos);
 	sd_cmd_unset_primary(primary);
-	debugfs_remove_recursive(sd->dfs);
+	debugfs_remove_recursive(primary_sd->dfs);
+	primary_sd->dfs = NULL;
 
 	sd_info(primary, "group id %#x, uncombined\n", sd->group_id);
 	primary_sd->state = MLX5_SD_STATE_DOWN;
-- 
2.44.0


^ permalink raw reply related

* [PATCH net V3 1/4] net/mlx5: SD: Serialize init/cleanup
From: Tariq Toukan @ 2026-04-23 12:31 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Shay Drory, Simon Horman, Kees Cook, Patrisious Haddad,
	Parav Pandit, Gal Pressman, netdev, linux-rdma, linux-kernel,
	Dragos Tatulea
In-Reply-To: <20260423123104.201552-1-tariqt@nvidia.com>

From: Shay Drory <shayd@nvidia.com>

mlx5_sd_init() / mlx5_sd_cleanup() may run from multiple PFs in the same
Socket-Direct group. This can cause the SD bring-up/tear-down sequence
to be executed more than once or interleaved across PFs.

Protect SD init/cleanup with mlx5_devcom_comp_lock() and track the SD
group state on the primary device. Skip init if the primary is already
UP, and skip cleanup unless the primary is UP.

In addition, move mlx5_devcom_comp_set_ready(false) from sd_unregister()
into the cleanup's locked section. A concurrent init acquiring the
devcom lock will now observe devcom is no longer ready and bail out
immediately.

Fixes: 381978d28317 ("net/mlx5e: Create single netdev per SD group")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../net/ethernet/mellanox/mlx5/core/lib/sd.c  | 32 +++++++++++++++----
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
index 762c783156b4..96b4316f570e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
@@ -18,6 +18,7 @@ struct mlx5_sd {
 	u8 host_buses;
 	struct mlx5_devcom_comp_dev *devcom;
 	struct dentry *dfs;
+	u8 state;
 	bool primary;
 	union {
 		struct { /* primary */
@@ -31,6 +32,11 @@ struct mlx5_sd {
 	};
 };
 
+enum mlx5_sd_state {
+	MLX5_SD_STATE_DOWN = 0,
+	MLX5_SD_STATE_UP,
+};
+
 static int mlx5_sd_get_host_buses(struct mlx5_core_dev *dev)
 {
 	struct mlx5_sd *sd = mlx5_get_sd(dev);
@@ -270,9 +276,6 @@ static void sd_unregister(struct mlx5_core_dev *dev)
 {
 	struct mlx5_sd *sd = mlx5_get_sd(dev);
 
-	mlx5_devcom_comp_lock(sd->devcom);
-	mlx5_devcom_comp_set_ready(sd->devcom, false);
-	mlx5_devcom_comp_unlock(sd->devcom);
 	mlx5_devcom_unregister_component(sd->devcom);
 }
 
@@ -426,6 +429,7 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
 	struct mlx5_core_dev *primary, *pos, *to;
 	struct mlx5_sd *sd = mlx5_get_sd(dev);
 	u8 alias_key[ACCESS_KEY_LEN];
+	struct mlx5_sd *primary_sd;
 	int err, i;
 
 	err = sd_init(dev);
@@ -440,10 +444,15 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
 	if (err)
 		goto err_sd_cleanup;
 
+	mlx5_devcom_comp_lock(sd->devcom);
 	if (!mlx5_devcom_comp_is_ready(sd->devcom))
-		return 0;
+		goto out;
 
 	primary = mlx5_sd_get_primary(dev);
+	primary_sd = mlx5_get_sd(primary);
+
+	if (primary_sd->state != MLX5_SD_STATE_DOWN)
+		goto out;
 
 	for (i = 0; i < ACCESS_KEY_LEN; i++)
 		alias_key[i] = get_random_u8();
@@ -472,6 +481,9 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
 		sd->group_id, mlx5_devcom_comp_get_size(sd->devcom));
 	sd_print_group(primary);
 
+	primary_sd->state = MLX5_SD_STATE_UP;
+out:
+	mlx5_devcom_comp_unlock(sd->devcom);
 	return 0;
 
 err_unset_secondaries:
@@ -481,6 +493,8 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
 	sd_cmd_unset_primary(primary);
 	debugfs_remove_recursive(sd->dfs);
 err_sd_unregister:
+	mlx5_devcom_comp_set_ready(sd->devcom, false);
+	mlx5_devcom_comp_unlock(sd->devcom);
 	sd_unregister(dev);
 err_sd_cleanup:
 	sd_cleanup(dev);
@@ -491,22 +505,28 @@ void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
 {
 	struct mlx5_sd *sd = mlx5_get_sd(dev);
 	struct mlx5_core_dev *primary, *pos;
+	struct mlx5_sd *primary_sd;
 	int i;
 
 	if (!sd)
 		return;
 
+	mlx5_devcom_comp_lock(sd->devcom);
 	if (!mlx5_devcom_comp_is_ready(sd->devcom))
-		goto out;
+		goto out_unlock;
 
 	primary = mlx5_sd_get_primary(dev);
+	primary_sd = mlx5_get_sd(primary);
 	mlx5_sd_for_each_secondary(i, primary, pos)
 		sd_cmd_unset_secondary(pos);
 	sd_cmd_unset_primary(primary);
 	debugfs_remove_recursive(sd->dfs);
 
 	sd_info(primary, "group id %#x, uncombined\n", sd->group_id);
-out:
+	primary_sd->state = MLX5_SD_STATE_DOWN;
+	mlx5_devcom_comp_set_ready(sd->devcom, false);
+out_unlock:
+	mlx5_devcom_comp_unlock(sd->devcom);
 	sd_unregister(dev);
 	sd_cleanup(dev);
 }
-- 
2.44.0


^ permalink raw reply related

* [PATCH net V3 4/4] net/mlx5e: SD, Fix race condition in secondary device probe/remove
From: Tariq Toukan @ 2026-04-23 12:31 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Shay Drory, Simon Horman, Kees Cook, Patrisious Haddad,
	Parav Pandit, Gal Pressman, netdev, linux-rdma, linux-kernel,
	Dragos Tatulea
In-Reply-To: <20260423123104.201552-1-tariqt@nvidia.com>

From: Shay Drory <shayd@nvidia.com>

When utilizing Socket-Direct single netdev functionality the driver
resolves the actual auxiliary device using mlx5_sd_get_adev(). However,
the current implementation returns the primary ETH auxiliary device
without holding the device lock, leading to a potential race condition
where the ETH device could be unbound or removed concurrently during
probe, suspend, resume, or remove operations.[1]

Fix this by introducing mlx5_sd_put_adev() and updating
mlx5_sd_get_adev() so that secondaries devices would acquire the device
lock of the returned auxiliary device. After the lock is acquired, a
second devcom check is needed[2].
In addition, update The callers to pair the get operation with the new
put operation, ensuring the lock is held while the auxiliary device is
being operated on and released afterwards.

The "primary" designation is determined once in sd_register(). It's set
before devcom is marked ready, and it never changes after that.
In Addition, The primary path never locks a secondary: When the primary
device invoke mlx5_sd_get_adev(), it sees dev == primary and returns.
no additional lock is taken.
Therefore lock ordering is always: secondary_lock -> primary_lock. The
reverse never happens, so ABBA deadlock is impossible.

[1]
for example:
BUG: kernel NULL pointer dereference, address: 0000000000000370
PGD 0 P4D 0
Oops: Oops: 0000 [#1] SMP
CPU: 4 UID: 0 PID: 3945 Comm: bash Not tainted 6.19.0-rc3+ #1 NONE
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:mlx5e_dcbnl_dscp_app+0x23/0x100 [mlx5_core]
Call Trace:
 <TASK>
 mlx5e_remove+0x82/0x12a [mlx5_core]
 device_release_driver_internal+0x194/0x1f0
 bus_remove_device+0xc6/0x140
 device_del+0x159/0x3c0
 ? devl_param_driverinit_value_get+0x29/0x80
 mlx5_rescan_drivers_locked+0x92/0x160 [mlx5_core]
 mlx5_unregister_device+0x34/0x50 [mlx5_core]
 mlx5_uninit_one+0x43/0xb0 [mlx5_core]
 remove_one+0x4e/0xc0 [mlx5_core]
 pci_device_remove+0x39/0xa0
 device_release_driver_internal+0x194/0x1f0
 unbind_store+0x99/0xa0
 kernfs_fop_write_iter+0x12e/0x1e0
 vfs_write+0x215/0x3d0
 ksys_write+0x5f/0xd0
 do_syscall_64+0x55/0xe90
 entry_SYSCALL_64_after_hwframe+0x4b/0x53

[2]
    CPU0 (primary)                     CPU1 (secondary)
==========================================================================
mlx5e_remove() (device_lock held)
                                     mlx5e_remove() (2nd device_lock held)
                                      mlx5_sd_get_adev()
                                       mlx5_devcom_comp_is_ready() => true
                                       device_lock(primary)
 mlx5_sd_get_adev() ==> ret adev
 _mlx5e_remove()
 mlx5_sd_cleanup()
 // mlx5e_remove finished
 // releasing device_lock
                                       //need another check here...
                                       mlx5_devcom_comp_is_ready() => false

Fixes: 381978d28317 ("net/mlx5e: Create single netdev per SD group")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../net/ethernet/mellanox/mlx5/core/en_main.c   | 10 ++++++++++
 .../net/ethernet/mellanox/mlx5/core/lib/sd.c    | 17 +++++++++++++++++
 .../net/ethernet/mellanox/mlx5/core/lib/sd.h    |  2 ++
 3 files changed, 29 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 9c340ad2fe09..c4cb5369f0a0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -6778,11 +6778,14 @@ static int mlx5e_resume(struct auxiliary_device *adev)
 		err = _mlx5e_resume(actual_adev);
 		if (err)
 			goto sd_cleanup;
+		mlx5_sd_put_adev(actual_adev, adev);
 	}
 	return 0;
 
 sd_cleanup:
 	mlx5_sd_cleanup(mdev);
+	if (actual_adev)
+		mlx5_sd_put_adev(actual_adev, adev);
 	return err;
 }
 
@@ -6822,6 +6825,8 @@ static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
 		err = _mlx5e_suspend(actual_adev, false);
 
 	mlx5_sd_cleanup(mdev);
+	if (actual_adev)
+		mlx5_sd_put_adev(actual_adev, adev);
 	return err;
 }
 
@@ -6923,11 +6928,14 @@ static int mlx5e_probe(struct auxiliary_device *adev,
 		err = _mlx5e_probe(actual_adev);
 		if (err)
 			goto sd_cleanup;
+		mlx5_sd_put_adev(actual_adev, adev);
 	}
 	return 0;
 
 sd_cleanup:
 	mlx5_sd_cleanup(mdev);
+	if (actual_adev)
+		mlx5_sd_put_adev(actual_adev, adev);
 	return err;
 }
 
@@ -6980,6 +6988,8 @@ static void mlx5e_remove(struct auxiliary_device *adev)
 		_mlx5e_remove(actual_adev);
 
 	mlx5_sd_cleanup(mdev);
+	if (actual_adev)
+		mlx5_sd_put_adev(actual_adev, adev);
 }
 
 static const struct auxiliary_device_id mlx5e_id_table[] = {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
index 897b0d81b27d..f7b226823ab4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
@@ -538,6 +538,10 @@ void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
 	sd_cleanup(dev);
 }
 
+/* Cannot take devcom lock as a gate for device lock. ABBA deadlock:
+ * primary:  actual_adev_lock -> SD devcom comp lock
+ * secondary: SD devcom comp lock -> actual_adev_lock
+ */
 struct auxiliary_device *mlx5_sd_get_adev(struct mlx5_core_dev *dev,
 					  struct auxiliary_device *adev,
 					  int idx)
@@ -555,5 +559,18 @@ struct auxiliary_device *mlx5_sd_get_adev(struct mlx5_core_dev *dev,
 	if (dev == primary)
 		return adev;
 
+	device_lock(&primary->priv.adev[idx]->adev.dev);
+	/* In case primary finish removing its adev */
+	if (!mlx5_devcom_comp_is_ready(sd->devcom)) {
+		device_unlock(&primary->priv.adev[idx]->adev.dev);
+		return NULL;
+	}
 	return &primary->priv.adev[idx]->adev;
 }
+
+void mlx5_sd_put_adev(struct auxiliary_device *actual_adev,
+		      struct auxiliary_device *adev)
+{
+	if (actual_adev != adev)
+		device_unlock(&actual_adev->dev);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
index 137efaf9aabc..9bfd5b9756b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
@@ -15,6 +15,8 @@ struct mlx5_core_dev *mlx5_sd_ch_ix_get_dev(struct mlx5_core_dev *primary, int c
 struct auxiliary_device *mlx5_sd_get_adev(struct mlx5_core_dev *dev,
 					  struct auxiliary_device *adev,
 					  int idx);
+void mlx5_sd_put_adev(struct auxiliary_device *actual_adev,
+		      struct auxiliary_device *adev);
 
 int mlx5_sd_init(struct mlx5_core_dev *dev);
 void mlx5_sd_cleanup(struct mlx5_core_dev *dev);
-- 
2.44.0


^ permalink raw reply related

* [PATCH net V3 3/4] net/mlx5e: SD, Fix missing cleanup on probe/resume error
From: Tariq Toukan @ 2026-04-23 12:31 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Shay Drory, Simon Horman, Kees Cook, Patrisious Haddad,
	Parav Pandit, Gal Pressman, netdev, linux-rdma, linux-kernel,
	Dragos Tatulea
In-Reply-To: <20260423123104.201552-1-tariqt@nvidia.com>

From: Shay Drory <shayd@nvidia.com>

When _mlx5e_probe() or _mlx5e_resume() fails, the preceding
successful mlx5_sd_init() is not undone, leaving the SD group in an
UP state without a matching cleanup.

Call mlx5_sd_cleanup() on the error path so the SD state is reset.

Fixes: 381978d28317 ("net/mlx5e: Create single netdev per SD group")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../net/ethernet/mellanox/mlx5/core/en_main.c | 22 +++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 5a46870c4b74..9c340ad2fe09 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -6774,9 +6774,16 @@ static int mlx5e_resume(struct auxiliary_device *adev)
 		return err;
 
 	actual_adev = mlx5_sd_get_adev(mdev, adev, edev->idx);
-	if (actual_adev)
-		return _mlx5e_resume(actual_adev);
+	if (actual_adev) {
+		err = _mlx5e_resume(actual_adev);
+		if (err)
+			goto sd_cleanup;
+	}
 	return 0;
+
+sd_cleanup:
+	mlx5_sd_cleanup(mdev);
+	return err;
 }
 
 static int _mlx5e_suspend(struct auxiliary_device *adev, bool pre_netdev_reg)
@@ -6912,9 +6919,16 @@ static int mlx5e_probe(struct auxiliary_device *adev,
 		return err;
 
 	actual_adev = mlx5_sd_get_adev(mdev, adev, edev->idx);
-	if (actual_adev)
-		return _mlx5e_probe(actual_adev);
+	if (actual_adev) {
+		err = _mlx5e_probe(actual_adev);
+		if (err)
+			goto sd_cleanup;
+	}
 	return 0;
+
+sd_cleanup:
+	mlx5_sd_cleanup(mdev);
+	return err;
 }
 
 static void _mlx5e_remove(struct auxiliary_device *adev)
-- 
2.44.0


^ permalink raw reply related

* Re: [PATCH v2] mptcp: do not drop partial packets
From: Shardul Bankar @ 2026-04-23 12:39 UTC (permalink / raw)
  To: Matthieu Baerts, pabeni, martineau
  Cc: geliang, davem, edumazet, kuba, horms, netdev, mptcp,
	linux-kernel, janak, kalpan.jani
In-Reply-To: <88096a1b-0c16-40ae-a03a-0d0d7f1702a4@kernel.org>

On Wed, 2026-04-22 at 19:03 +0200, Matthieu Baerts wrote:
> Hi Shardul,
> 
> On 22/04/2026 16:39, Shardul Bankar wrote:
> > 
> 
> Thank you for the v2.
> 
> I didn't review it (yet), but just to let you know that there are
> some
> rules on Netdev [1] (that usually also applied on MPTCP side), and an
> important one is:
> 
>  - don't repost your patches within one 24h period
> 
> Each version generates a lot of emails that are sent and need to be
> triaged. With the high volume, it is then harder for us to follow,
> plus
> a lot of shared resources are used, etc.
> 
> One last thing, because this patch is not an urgent fix, do you mind
> sending new versions only the to MPTCP ML: to a restricted number of
> people for the first versions, there is enough traffic on Netdev.
> 
> [1] https://docs.kernel.org/process/maintainer-netdev.html
> 
> > A previous attempt at this fix (commit 1d2ce718811a ("mptcp: do not
> > drop partial packets"), reverted in commit bf39160c4218 ("Revert
> 
> Note: these two commits should not be mentioned here, they have only
> been applied to the MPTCP tree, but not upstreamed. Instead, please
> use
> lore links, e.g.
> 
> https://lore.kernel.org/c9b426a4e163aa3c4fe8b80c79f1a610f47ae7d8.1763075056.git.pabeni@redhat.com
> 
> > "mptcp: do not drop partial packets"")) also added a zero-window
> > check and changed rcv_wnd_sent initialization, which caused test
> > regressions.  This version addresses only the partial packet
> > handling
> > without modifying receive window accounting.
> > 
> > Fixes: ab174ad8ef76 ("mptcp: move ooo skbs into msk out of order
> > queue.")
> > Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/600
> > Signed-off-by: Shardul Bankar <shardul.b@mpiricsoftware.com>
> 
> Checkpatch is complaining that the author of the patch is not the
> same
> as the one who sent the patch; You probably need to run this command
> to
> fix it:
> 
>   git commit --amend --reset-author
> 
> (when the patch is sent, `git format-patch` will add a second From:
> tag)
> 
> Cheers,
> Matt

Hi Matthieu,

Thanks for the pointers. I'll wait for your code review and address the
process feedback (recipient list, commit message, email mismatch) along
with any code comments together in v3.

Regards,
Shardul

^ permalink raw reply

* Re: [RFC PATCH] net: skb: on zero-copy formatted output to skb
From: Andrew Lunn @ 2026-04-23 12:40 UTC (permalink / raw)
  To: Dmitry Antipov
  Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	netdev, linux-bluetooth
In-Reply-To: <20260423073638.778334-1-dmantipov@yandex.ru>

> +int skb_printf(struct sk_buff *skb, const char *fmt, ...)
> +{
> +	int len, size = skb_availroom(skb);
> +	va_list args;
> +
> +	va_start(args, fmt);
> +	len = vsnprintf(skb_tail_pointer(skb), size, fmt, args);
> +	va_end(args);
> +
> +	if (unlikely(len >= size))
> +		return -ENOSPC;

A quick look in drivers/bluetooth suggests that none of them care
about truncation, at least they don't check the return code. Maybe it
would be better to truncate than return an error?

I would also try to make the behaviour consistent with the normal
sprintf(), or snprintf(). You want to give users some idea what it is
doing based on its name. It is well known that snprintf() will
truncate, and does not return an error code. sprintf() will just
overwrite the end of the buffer and not return an error code etc.

However calling this skb_snprintf() would be odd, since you don't
actually pass size. But it hints at what it does.

So please add some kerneldoc describing what it actually does.

Please also annotate the const char *fmt, so the compiler can do
format string checks, parameter counting etc.

	Andrew

^ permalink raw reply

* Re: [PATCH v2 net 04/11] octeontx2-af: npc: cn20k: Make default entries as x4.
From: Simon Horman @ 2026-04-23 12:42 UTC (permalink / raw)
  To: Ratheesh Kannoth
  Cc: netdev, linux-kernel, sgoutham, davem, edumazet, kuba, pabeni,
	andrew+netdev, dan.carpenter
In-Reply-To: <20260420023442.3295891-5-rkannoth@marvell.com>

On Mon, Apr 20, 2026 at 08:04:35AM +0530, Ratheesh Kannoth wrote:
> X4 profile users won't alloc x2 entries. Allocating x2 entries
> would cause under utilized subbanks(X2). Avoid this in X4 kex
> profile, all allocations will be from x4 subbank.
> 
> Fixes: 09d3b7a1403f ("octeontx2-af: npc: cn20k: Allocate default MCAM indexes")
> Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
> ---
>  .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 26 ++++++++--
>  .../marvell/octeontx2/nic/otx2_flows.c        | 48 +++++++++++++------
>  2 files changed, 56 insertions(+), 18 deletions(-)

Hi Ratheesh,

This patch seems to involve a non-trivial amount of refactoring
in order to facilitate implementing the change described in the
changelog. This makes review a bit challenging (for me).

I am wondering if the patch could be split into two: a refactor
followed by the functional change.

Also, this feels more like an improvement to be targeted at net-next
than a fix for net. If it is a bug fix, I think that warrants a being
explained more clearly in the commit message.

Lastly, Sashiko generated a review of this patch. However, I do
not believe the concerns it raises are bugs or need to block
progress of this patchset.

...

^ permalink raw reply

* Re: [PATCH net-next v6 0/2] net: mana: add ethtool private flag for full-page RX buffers
From: Dipayaan Roy @ 2026-04-23 12:48 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	pabeni, leon, longli, kotaranov, horms, shradhagupta, ssengar,
	ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
	linux-rdma, stephen, jacob.e.keller, leitao, kees, john.fastabend,
	hawk, bpf, daniel, ast, sdf, dipayanroy
In-Reply-To: <20260416083146.0bb94d2b@kernel.org>

On Thu, Apr 16, 2026 at 08:31:46AM -0700, Jakub Kicinski wrote:
> On Tue, 14 Apr 2026 09:00:56 -0700 Dipayaan Roy wrote:
> > I still see roughly a 5% overhead from the atomic refcount operation
> > itself, but on that platform there is no throughput drop when using
> > page fragments versus full-page mode.
> 
> That seems to contradict your claim that it's a problem with a specific
> platform.. Since we're in the merge window I asked David Wei to try to
> experiment with disabling page fragmentation on the ARM64 platforms we
> have at Meta. If it repros we should use the generic rx-buf-len
> ringparam because more NICs may want to implement this strategy.

Hi Jakub,

Thanks. I think I was not precise enough in my previous reply.

What I meant is that the atomic refcount cost itself does not appear to
be unique to the affected platform. I see a similar ~5% overhead on
another ARM64 platformi (different vendor) as well. However, on that platform
there is no throughput delta between fragment mode and full-page mode; both reach
line rate.

On the affected platform, fragment mode shows an additional ~15%
throughput drop versus full-page mode. So the current data suggests that
the atomic overhead is common, but the throughput regression is not
explained by that overhead alone and likely depends on an additional
platform-specific factor.

Separately, the hardware team collected PCIe traces on the affected
platform and reported stalls in the fragment-mode case that are not seen
in full-page mode. They are still investigating the root cause, but
their current hypothesis is that this is related to that platform’s
PCIe/root-port microarchitecture rather than to page_pool refcounting
alone.

That said, I agree the right direction depends on whether this
reproduces on other ARM64 platforms. If David is able to reproduce the
same behavior, then using the generic rx-buf-len ringparam sounds like
the better direction.

Please let me know what David finds, and I can rework the patch
accordingly.


Regards
Dipayaan Roy

^ permalink raw reply

* Re: [PATCH net v3 8/8] xsk: don't support AF_XDP on 32-bit architectures
From: Jason Xing @ 2026-04-23 13:03 UTC (permalink / raw)
  To: Alexander Lobakin
  Cc: Maciej Fijalkowski, davem, edumazet, kuba, pabeni, bjorn,
	magnus.karlsson, jonathan.lemon, sdf, ast, daniel, hawk,
	john.fastabend, bpf, netdev, Jason Xing
In-Reply-To: <f78a505b-6be1-4b4b-86f4-005d709e0253@intel.com>

On Thu, Apr 23, 2026 at 8:15 PM Alexander Lobakin
<aleksander.lobakin@intel.com> wrote:
>
> From: Jason Xing <kerneljasonxing@gmail.com>
> Date: Thu, 23 Apr 2026 07:49:58 +0800
>
> > On Thu, Apr 23, 2026 at 12:58 AM Maciej Fijalkowski
> > <maciej.fijalkowski@intel.com> wrote:
> >>
> >> On Thu, Apr 23, 2026 at 12:37:07AM +0800, Jason Xing wrote:
> >>> On Thu, Apr 23, 2026 at 12:10 AM Alexander Lobakin
> >>> <aleksander.lobakin@intel.com> wrote:
> >>>>
> >>>> From: Jason Xing <kerneljasonxing@gmail.com>
> >>>> Date: Wed, 22 Apr 2026 11:36:50 +0800
> >>>>
> >>>>> From: Jason Xing <kernelxing@tencent.com>
> >>>>>
> >>>>> In copy mode TX, xsk_skb_destructor_set_addr() stores the 64-bit
> >>>>> descriptor address into skb_shinfo(skb)->destructor_arg (void *) via a
> >>>>> uintptr_t cast:
> >>>>>
> >>>>>     skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t)addr | 0x1UL);
> >>>>>
> >>>>> On 32-bit architectures uintptr_t is 32 bits, so the upper 32 bits of
> >>>>> the descriptor address are silently dropped. In XDP_ZEROCOPY unaligned
> >>>>> mode the chunk offset is encoded in bits 48-63 of the descriptor
> >>>>> address (XSK_UNALIGNED_BUF_OFFSET_SHIFT = 48), meaning the offset is
> >>>>> lost entirely. The completion queue then returns a truncated address to
> >>>>> userspace, making buffer recycling impossible.
> >>>>
> >>>> What if we relax the restriction a bit? For example, refuse to configure
> >>>
> >>> As to the bug itself, yes, It only affects the unaligned mode.
> >>>
> >>> I wonder if we can support this after someone requires us to support
> >>> 32-bit arch and use it in the real world, then we can use the previous
> >>> patch to complete the full support (which doesn't harm the path on
> >>> 64-bit arch).
> >>>
> >>> The code looks like this based on your suggestion. Just for the record.
> >>> diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
> >>> index 58da2f4f4397..03417b04592f 100644
> >>> --- a/net/xdp/xdp_umem.c
> >>> +++ b/net/xdp/xdp_umem.c
> >>> @@ -177,6 +177,9 @@ static int xdp_umem_reg(struct xdp_umem *umem,
> >>> struct xdp_umem_reg *mr)
> >>> if (mr->flags & ~XDP_UMEM_FLAGS_VALID)
> >>> return -EINVAL;
> >>> + if (!IS_ENABLED(CONFIG_64BIT) && unaligned_chunks)
> >>> + return -EOPNOTSUPP;
> >>> +
> >>> if (!unaligned_chunks && !is_power_of_2(chunk_size))
> >>> return -EINVAL;
> >>>
> >>> Actually I'm fine with either of them. Right now I'm not so sure which
> >>> direction this patch should take :)
> >>
> >> Abstracting from discussion, that is not a patch we would want against
> >> -net. We should not forbid 32bit on stable kernels, maybe there is someone
> >> in the 'basement' using 32bit xsk on stable kernel. Plus the fixes tag vs
> >> patch's content looks weird ;)
> >
> > Sorry, I don't follow this. Any specific suggestions on how to move forward?
>
> Maciej just says that if we go the first route (forbid 32-bit arches),
> then this commit should not go to the stable/LTS kernels.
> But
>
> >
> > Now we have three approaches w/o the fixes tag:
> > 1. completely forbid 32-bit arch
> > 2. only forbid unaligned mode on 32-bit arch
> > 3. completely fix/modify the allocation logic of the first frag on
> > 32-bit (see the v2-0008 patch)
> >
> > I'm wondering how to proceed with that?
>
> I've just reread the v2 thread (I realized I missed it earlier) and to
> me, the v2-0008 (route 3) solution looks good. It introduces a bit of
> overhead, but only for 32-bit arches, where the XSk performance will
> never be push-it-to-the-limit anyway (esp. given that this is skb mode).
>
> So I'd personally vote for number 3. 47 insertions(+), 7 deletions(-) is
> not a big deal. And for 64-bit arches, there won't be any object code
> changes at all (unconditional `return 0` and checking the return value
> of xsk_skb_init_misc() will be optimized out by the compiler).
>
> Number 2 is also okay-ish, if we're sure that addr is always 32-bit on
> 32-bit arches in the aligned mode. But given that you already has a
> proper fix (n. 3) which allows to not forbid anything at all, I believe
> it's more preferred to fix rather than disable.
>
> + as mentioned above, if you go route number 3, the series could be sent
> to -net and the fix would eventually hit the stable/LTS trees, but I
> don't think we can disable/forbid something in the stable kernels.

Thanks for the explanation!

I will submit solution #3 to fix this issue. And the v4-0008 should be
simpler. We'll see :)

Thanks,
Jason

^ permalink raw reply

* [PATCH net v4 0/4] Fix i40e/ice/iavf VF bonding after netdev lock changes
From: Jose Ignacio Tornos Martinez @ 2026-04-23 13:04 UTC (permalink / raw)
  To: netdev
  Cc: intel-wired-lan, przemyslaw.kitszel, aleksandr.loktionov,
	jacob.e.keller, horms, jesse.brandeburg, anthony.l.nguyen, davem,
	edumazet, kuba, pabeni, Jose Ignacio Tornos Martinez

This series fixes VF bonding failures introduced by commit ad7c7b2172c3
("net: hold netdev instance lock during sysfs operations").

When adding VFs to a bond immediately after setting trust mode, MAC
address changes fail with -EAGAIN, preventing bonding setup. This
affects both i40e (700-series) and ice (800-series) Intel NICs.

The core issue is lock contention: iavf_set_mac() is now called with the
netdev lock held and waits for MAC change completion while holding it.
However, both the watchdog task that sends the request and the adminq_task
that processes PF responses also need this lock, creating a deadlock where
neither can run, causing timeouts.

Additionally, setting VF trust triggers an unnecessary ~10 second VF reset
in i40e driver that delays bonding setup, even though filter
synchronization happens naturally during normal VF operation. For ice
driver, the delay is not so big, but in the same way the operation is not
necessary.

This series:
1. Adds safety guard to prevent MAC changes during reset or early
   initialization (before VF is ready)
2. Eliminates unnecessary VF reset when setting trust in i40e, resetting
   only when ADQ cloud filters need cleanup
3. Fixes lock contention by polling admin queue synchronously
4. Eliminates unnecessary VF reset when setting trust in ice, resetting
   only when MAC LLDP filters need cleanup

The key fix (patch 3/4) implements a synchronous MAC change operation
similar to the approach used for ndo_change_mtu deadlock fix:
https://lore.kernel.org/intel-wired-lan/20260211191855.1532226-1-poros@redhat.com/ 
Instead of scheduling work and waiting, it:

- Sends the virtchnl message directly (not via watchdog)
- Polls the admin queue hardware directly for responses
- Processes all messages inline (including non-MAC messages)
- Returns when complete or times out

This allows the operation to complete synchronously while holding
netdev_lock, without relying on watchdog or adminq_task.

The function can sleep for up to 2.5 seconds polling hardware, but this
is acceptable since netdev_lock is per-device and only serializes
operations on the same interface.

Testing shows VF bonding now works reliably in ~5 seconds vs 15+ seconds
before (i40e), without timeouts or errors (i40e and ice).

Tested on Intel 700-series (i40e) and 800-series (ice) dual-port NICs
with iavf driver.

Thanks to Jan Tluka <jtluka@redhat.com> and Yuying Ma <yuma@redhat.com> for
reporting the issues.

Note: The refactoring suggested in v2 review to unify polling functions
and call iavf_virtchnl_completion() for all messages will be submitted
separately to net-next after this fix merges.

Jose Ignacio Tornos Martinez (4):
  iavf: return EBUSY if reset in progress or not ready during MAC change
  i40e: skip unnecessary VF reset when setting trust
  iavf: send MAC change request synchronously
  ice: skip unnecessary VF reset when setting trust
---
v4:
  - No changes to patch 1 from v3
  - Complete patch 2 with AI review (sashiko.dev) from Simon Horman.
  - Complete patch 3 with the comments from Przemek Kitszel and AI review
    from Simon Horman.
  - Complete patch 4 with AI review (sashiko.dev) from Simon Horman and
    issues addressed when comparing with i40e.
  - Drop patch 5 from v3 (refactoring is postponed)
v3: https://lore.kernel.org/netdev/20260414110006.124286-1-jtornosm@redhat.com/

 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 42 ++++++++++++++++++++++++++++++++----------
 drivers/net/ethernet/intel/iavf/iavf.h             | 10 ++++++++--
 drivers/net/ethernet/intel/iavf/iavf_main.c        | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
 drivers/net/ethernet/intel/iavf/iavf_virtchnl.c    | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 drivers/net/ethernet/intel/ice/ice_sriov.c         | 41 +++++++++++++++++++++++++++++++++++++----
 drivers/net/ethernet/intel/ice/ice_vf_lib.c        |  2 +-
 drivers/net/ethernet/intel/ice/ice_vf_lib.h        |  1 +
 7 files changed, 225 insertions(+), 43 deletions(-)
--
2.43.0


^ permalink raw reply

* [PATCH net v4 1/4] iavf: return EBUSY if reset in progress or not ready during MAC change
From: Jose Ignacio Tornos Martinez @ 2026-04-23 13:04 UTC (permalink / raw)
  To: netdev
  Cc: intel-wired-lan, przemyslaw.kitszel, aleksandr.loktionov,
	jacob.e.keller, horms, jesse.brandeburg, anthony.l.nguyen, davem,
	edumazet, kuba, pabeni, Jose Ignacio Tornos Martinez
In-Reply-To: <20260423130405.139568-1-jtornosm@redhat.com>

When a MAC address change is requested while the VF is resetting or still
initializing, return -EBUSY immediately instead of attempting the
operation.

Additionally, during early initialization states (before __IAVF_DOWN),
the PF may be slow to respond to MAC change requests, causing long
delays. Only allow MAC changes once the VF reaches __IAVF_DOWN state or
later, when the watchdog is running and the VF is ready for operations.

After commit ad7c7b2172c3 ("net: hold netdev instance lock
during sysfs operations"), MAC changes are called with the netdev lock
held, so we should not wait with the lock held during reset or
initialization. This allows the caller to retry or handle the busy state
appropriately without blocking other operations.

Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
---

 drivers/net/ethernet/intel/iavf/iavf_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
index dad001abc908..67aa14350b1b 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -1060,6 +1060,9 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
 	struct sockaddr *addr = p;
 	int ret;
 
+	if (iavf_is_reset_in_progress(adapter) || adapter->state < __IAVF_DOWN)
+		return -EBUSY;
+
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH net v4 2/4] i40e: skip unnecessary VF reset when setting trust
From: Jose Ignacio Tornos Martinez @ 2026-04-23 13:04 UTC (permalink / raw)
  To: netdev
  Cc: intel-wired-lan, przemyslaw.kitszel, aleksandr.loktionov,
	jacob.e.keller, horms, jesse.brandeburg, anthony.l.nguyen, davem,
	edumazet, kuba, pabeni, Jose Ignacio Tornos Martinez
In-Reply-To: <20260423130405.139568-1-jtornosm@redhat.com>

The current implementation triggers a VF reset when changing the trust
setting, causing a ~10 second delay during bonding setup.

In all the cases, the reset causes a ~10 second delay during which:
- VF must reinitialize completely
- Any in-progress operations (like bonding enslave) fail with timeouts
- VF is unavailable

When granting trust, no reset is needed - we can just set the capability
flag to allow privileged operations.

When revoking trust, we need to:
1. Clear the capability flag to block privileged operations
2. Disable promiscuous mode if it was enabled (trusted VFs can enable it)
3. Only reset if ADQ is enabled (to clean up cloud filters)

When we do reset (ADQ case), we reset first to clear VF_STATE_ACTIVE
(which blocks new cloud filter additions), then delete existing cloud
filters safely. This avoids the race condition where VF could add filters
during deletion.

When we don't reset, we manually handle capability flag and promiscuous
mode via helper function, eliminating the delay.

Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v4: Address AI review (sashiko.dev) from Simon Horman:
    - Manually set/clear capability flag when not resetting
    - Explicitly disable promiscuous mode when revoking trust                                        
    - Fix cloud filter race: reset FIRST (clears VF_STATE_ACTIVE),
      delete filters AFTER (no race window)
    - Add helper function i40e_setup_vf_trust() for non-reset path
v3: https://lore.kernel.org/all/20260414110006.124286-3-jtornosm@redhat.com/

 .../ethernet/intel/i40e/i40e_virtchnl_pf.c    | 42 ++++++++++++++-----
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index a26c3d47ec15..69f68fec6809 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -4943,6 +4943,30 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable)
 	return ret;
 }
 
+/**
+ * i40e_setup_vf_trust - Enable/disable VF trust mode without reset
+ * @vf: VF to configure
+ * @setting: trust setting
+ *
+ * Manually handle capability flag and promiscuous mode when changing trust
+ * without performing a VF reset.
+ * When reset is performed, this is not necessary as the reset procedure
+ * already handles this.
+ **/
+static void i40e_setup_vf_trust(struct i40e_vf *vf, bool setting)
+{
+	if (setting) {
+		set_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
+	} else {
+		clear_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
+
+		if (test_bit(I40E_VF_STATE_UC_PROMISC, &vf->vf_states) ||
+		    test_bit(I40E_VF_STATE_MC_PROMISC, &vf->vf_states))
+			i40e_config_vf_promiscuous_mode(vf, vf->lan_vsi_idx,
+							false, false);
+	}
+}
+
 /**
  * i40e_ndo_set_vf_trust
  * @netdev: network interface device structure of the pf
@@ -4987,19 +5011,17 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting)
 	set_bit(__I40E_MACVLAN_SYNC_PENDING, pf->state);
 	pf->vsi[vf->lan_vsi_idx]->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
 
-	i40e_vc_reset_vf(vf, true);
+	/* Reset only if revoking trust with ADQ (for cloud filter cleanup) */
+	if (vf->adq_enabled && !setting) {
+		i40e_vc_reset_vf(vf, true);
+		i40e_del_all_cloud_filters(vf);
+	} else {
+		i40e_setup_vf_trust(vf, setting);
+	}
+
 	dev_info(&pf->pdev->dev, "VF %u is now %strusted\n",
 		 vf_id, setting ? "" : "un");
 
-	if (vf->adq_enabled) {
-		if (!vf->trusted) {
-			dev_info(&pf->pdev->dev,
-				 "VF %u no longer Trusted, deleting all cloud filters\n",
-				 vf_id);
-			i40e_del_all_cloud_filters(vf);
-		}
-	}
-
 out:
 	clear_bit(__I40E_VIRTCHNL_OP_PENDING, pf->state);
 	return ret;
-- 
2.53.0


^ permalink raw reply related

* [PATCH net v4 3/4] iavf: send MAC change request synchronously
From: Jose Ignacio Tornos Martinez @ 2026-04-23 13:04 UTC (permalink / raw)
  To: netdev
  Cc: intel-wired-lan, przemyslaw.kitszel, aleksandr.loktionov,
	jacob.e.keller, horms, jesse.brandeburg, anthony.l.nguyen, davem,
	edumazet, kuba, pabeni, Jose Ignacio Tornos Martinez, stable
In-Reply-To: <20260423130405.139568-1-jtornosm@redhat.com>

After commit ad7c7b2172c3 ("net: hold netdev instance lock during sysfs
operations"), iavf_set_mac() is called with the netdev instance lock
already held.

The function queues a MAC address change request via
iavf_replace_primary_mac() and then waits for completion. However, in
the current flow, the actual virtchnl message is sent by the watchdog
task, which also needs to acquire the netdev lock to run. Additionally,
the adminq_task which processes virtchnl responses also needs the netdev
lock.

This creates a deadlock scenario:
1. iavf_set_mac() holds netdev lock and waits for MAC change
2. Watchdog needs netdev lock to send the request -> blocked
3. Even if request is sent, adminq_task needs netdev lock to process
   PF response -> blocked
4. MAC change times out after 2.5 seconds
5. iavf_set_mac() returns -EAGAIN

This particularly affects VFs during bonding setup when multiple VFs are
enslaved in quick succession.

Fix by implementing a synchronous MAC change operation similar to the
approach used in commit fdadbf6e84c4 ("iavf: fix incorrect reset handling
in callbacks").

The solution:
1. Send the virtchnl ADD_ETH_ADDR message directly (not via watchdog)
2. Poll the admin queue hardware directly for responses
3. Process all received messages (including non-MAC messages)
4. Return when MAC change completes or times out

A new generic function iavf_poll_virtchnl_response() is introduced that
can be reused for any future synchronous virtchnl operations. It takes a
callback to check completion, allowing flexible condition checking.

This allows the operation to complete synchronously while holding
netdev_lock, without relying on watchdog or adminq_task. The function
can sleep for up to 2.5 seconds polling hardware, but this is acceptable
since netdev_lock is per-device and only serializes operations on the
same interface.

To support this, change iavf_add_ether_addrs() to return an error code
instead of void, allowing callers to detect failures. Additionally,
export iavf_mac_add_reject() to enable proper rollback on local failures
(timeouts, send errors) - PF rejections are already handled automatically
by iavf_virtchnl_completion().

Fixes: ad7c7b2172c3 ("net: hold netdev instance lock during sysfs operations")
cc: stable@vger.kernel.org
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v4: Complete with Przemek Kitszel comments:
    - Remove vc_waitqueue entirely (not needed any more)
    - Add named parameters to callback function pointer declaration for
      clarity
    - Simplify callback signature: add v_op parameter so callback
      receives the opcode from the processed message to identify which
      response was received
    - Optimize polling loop to single condition check per iteration
      instead of checking both before and after message processing
    Address AI review (sashiko.dev) from Simon Horman:
    - Complete iavf_add_ether_addrs() error handling
    - Skip non-virtchnl hardware events (received_op=VIRTCHNL_OP_UNKNOWN),
      these can cause false completion detection
    - Complete rollback for local failures (not PF rejection) reusing
      iavf_mac_add_reject() to restore the old primary filter
v3: https://lore.kernel.org/netdev/20260414110006.124286-4-jtornosm@redhat.com/

 drivers/net/ethernet/intel/iavf/iavf.h        | 10 +-
 drivers/net/ethernet/intel/iavf/iavf_main.c   | 70 +++++++++----
 .../net/ethernet/intel/iavf/iavf_virtchnl.c   | 99 +++++++++++++++++--
 3 files changed, 151 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
index e9fb0a0919e3..78fa3df06e11 100644
--- a/drivers/net/ethernet/intel/iavf/iavf.h
+++ b/drivers/net/ethernet/intel/iavf/iavf.h
@@ -260,7 +260,6 @@ struct iavf_adapter {
 	struct work_struct adminq_task;
 	struct work_struct finish_config;
 	wait_queue_head_t down_waitqueue;
-	wait_queue_head_t vc_waitqueue;
 	struct iavf_q_vector *q_vectors;
 	struct list_head vlan_filter_list;
 	int num_vlan_filters;
@@ -589,8 +588,9 @@ void iavf_configure_queues(struct iavf_adapter *adapter);
 void iavf_enable_queues(struct iavf_adapter *adapter);
 void iavf_disable_queues(struct iavf_adapter *adapter);
 void iavf_map_queues(struct iavf_adapter *adapter);
-void iavf_add_ether_addrs(struct iavf_adapter *adapter);
+int iavf_add_ether_addrs(struct iavf_adapter *adapter);
 void iavf_del_ether_addrs(struct iavf_adapter *adapter);
+void iavf_mac_add_reject(struct iavf_adapter *adapter);
 void iavf_add_vlans(struct iavf_adapter *adapter);
 void iavf_del_vlans(struct iavf_adapter *adapter);
 void iavf_set_promiscuous(struct iavf_adapter *adapter);
@@ -607,6 +607,12 @@ void iavf_disable_vlan_stripping(struct iavf_adapter *adapter);
 void iavf_virtchnl_completion(struct iavf_adapter *adapter,
 			      enum virtchnl_ops v_opcode,
 			      enum iavf_status v_retval, u8 *msg, u16 msglen);
+int iavf_poll_virtchnl_response(struct iavf_adapter *adapter,
+				bool (*condition)(struct iavf_adapter *adapter,
+						  const void *data,
+						  enum virtchnl_ops v_op),
+				const void *cond_data,
+				unsigned int timeout_ms);
 int iavf_config_rss(struct iavf_adapter *adapter);
 void iavf_cfg_queues_bw(struct iavf_adapter *adapter);
 void iavf_cfg_queues_quanta_size(struct iavf_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
index 67aa14350b1b..bc5994bf2cd9 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -1047,6 +1047,48 @@ static bool iavf_is_mac_set_handled(struct net_device *netdev,
 	return ret;
 }
 
+/**
+ * iavf_mac_change_done - Check if MAC change completed
+ * @adapter: board private structure
+ * @data: MAC address being checked (as const void *)
+ * @v_op: virtchnl opcode from processed message
+ *
+ * Callback for iavf_poll_virtchnl_response() to check if MAC change completed.
+ *
+ * Returns true if MAC change completed, false otherwise
+ */
+static bool iavf_mac_change_done(struct iavf_adapter *adapter,
+				 const void *data, enum virtchnl_ops v_op)
+{
+	const u8 *addr = data;
+
+	return iavf_is_mac_set_handled(adapter->netdev, addr);
+}
+
+/**
+ * iavf_set_mac_sync - Synchronously change MAC address
+ * @adapter: board private structure
+ * @addr: MAC address to set
+ *
+ * Sends MAC change request to PF and polls admin queue for response.
+ * Caller must hold netdev_lock. This can sleep for up to 2.5 seconds.
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int iavf_set_mac_sync(struct iavf_adapter *adapter, const u8 *addr)
+{
+	int ret;
+
+	netdev_assert_locked(adapter->netdev);
+
+	ret = iavf_add_ether_addrs(adapter);
+	if (ret)
+		return ret;
+
+	return iavf_poll_virtchnl_response(adapter, iavf_mac_change_done,
+					   addr, 2500);
+}
+
 /**
  * iavf_set_mac - NDO callback to set port MAC address
  * @netdev: network interface device structure
@@ -1067,25 +1109,20 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
 		return -EADDRNOTAVAIL;
 
 	ret = iavf_replace_primary_mac(adapter, addr->sa_data);
-
 	if (ret)
 		return ret;
 
-	ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
-					       iavf_is_mac_set_handled(netdev, addr->sa_data),
-					       msecs_to_jiffies(2500));
-
-	/* If ret < 0 then it means wait was interrupted.
-	 * If ret == 0 then it means we got a timeout.
-	 * else it means we got response for set MAC from PF,
-	 * check if netdev MAC was updated to requested MAC,
-	 * if yes then set MAC succeeded otherwise it failed return -EACCES
-	 */
-	if (ret < 0)
+	ret = iavf_set_mac_sync(adapter, addr->sa_data);
+	if (ret) {
+		/* Rollback for local failures (timeout, send error, -EBUSY).
+		 * Note: If PF rejects the request (sends error response),
+		 * iavf_virtchnl_completion() automatically calls
+		 * iavf_mac_add_reject(), ret=0, and this is not executed.
+		 * Only local failures (no PF response received) need manual rollback.
+		 */
+		iavf_mac_add_reject(adapter);
 		return ret;
-
-	if (!ret)
-		return -EAGAIN;
+	}
 
 	if (!ether_addr_equal(netdev->dev_addr, addr->sa_data))
 		return -EACCES;
@@ -5415,9 +5452,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/* Setup the wait queue for indicating transition to down status */
 	init_waitqueue_head(&adapter->down_waitqueue);
 
-	/* Setup the wait queue for indicating virtchannel events */
-	init_waitqueue_head(&adapter->vc_waitqueue);
-
 	INIT_LIST_HEAD(&adapter->ptp.aq_cmds);
 	init_waitqueue_head(&adapter->ptp.phc_time_waitqueue);
 	mutex_init(&adapter->ptp.aq_cmd_lock);
diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
index a52c100dcbc5..d1afb8261c24 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
@@ -2,6 +2,7 @@
 /* Copyright(c) 2013 - 2018 Intel Corporation. */
 
 #include <linux/net/intel/libie/rx.h>
+#include <net/netdev_lock.h>
 
 #include "iavf.h"
 #include "iavf_ptp.h"
@@ -555,20 +556,23 @@ iavf_set_mac_addr_type(struct virtchnl_ether_addr *virtchnl_ether_addr,
  * @adapter: adapter structure
  *
  * Request that the PF add one or more addresses to our filters.
+ *
+ * Return: 0 on success, negative on failure
  **/
-void iavf_add_ether_addrs(struct iavf_adapter *adapter)
+int iavf_add_ether_addrs(struct iavf_adapter *adapter)
 {
 	struct virtchnl_ether_addr_list *veal;
 	struct iavf_mac_filter *f;
 	int i = 0, count = 0;
 	bool more = false;
 	size_t len;
+	int ret;
 
 	if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
 		/* bail because we already have a command pending */
 		dev_err(&adapter->pdev->dev, "Cannot add filters, command %d pending\n",
 			adapter->current_op);
-		return;
+		return -EBUSY;
 	}
 
 	spin_lock_bh(&adapter->mac_vlan_list_lock);
@@ -580,7 +584,7 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter)
 	if (!count) {
 		adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_MAC_FILTER;
 		spin_unlock_bh(&adapter->mac_vlan_list_lock);
-		return;
+		return 0;
 	}
 	adapter->current_op = VIRTCHNL_OP_ADD_ETH_ADDR;
 
@@ -594,8 +598,9 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter)
 
 	veal = kzalloc(len, GFP_ATOMIC);
 	if (!veal) {
+		adapter->current_op = VIRTCHNL_OP_UNKNOWN;
 		spin_unlock_bh(&adapter->mac_vlan_list_lock);
-		return;
+		return -ENOMEM;
 	}
 
 	veal->vsi_id = adapter->vsi_res->vsi_id;
@@ -615,8 +620,15 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter)
 
 	spin_unlock_bh(&adapter->mac_vlan_list_lock);
 
-	iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR, (u8 *)veal, len);
+	ret = iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR, (u8 *)veal, len);
 	kfree(veal);
+	if (ret) {
+		dev_err(&adapter->pdev->dev,
+			"Unable to send ADD_ETH_ADDR message to PF, error %d\n", ret);
+		adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+	}
+
+	return ret;
 }
 
 /**
@@ -713,7 +725,7 @@ static void iavf_mac_add_ok(struct iavf_adapter *adapter)
  *
  * Remove filters from list based on PF response.
  **/
-static void iavf_mac_add_reject(struct iavf_adapter *adapter)
+void iavf_mac_add_reject(struct iavf_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
 	struct iavf_mac_filter *f, *ftmp;
@@ -2389,7 +2401,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
 			iavf_mac_add_reject(adapter);
 			/* restore administratively set MAC address */
 			ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
-			wake_up(&adapter->vc_waitqueue);
 			break;
 		case VIRTCHNL_OP_DEL_VLAN:
 			dev_err(&adapter->pdev->dev, "Failed to delete VLAN filter, error %s\n",
@@ -2586,7 +2597,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
 				eth_hw_addr_set(netdev, adapter->hw.mac.addr);
 				netif_addr_unlock_bh(netdev);
 			}
-		wake_up(&adapter->vc_waitqueue);
 		break;
 	case VIRTCHNL_OP_GET_STATS: {
 		struct iavf_eth_stats *stats =
@@ -2956,3 +2966,76 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
 	} /* switch v_opcode */
 	adapter->current_op = VIRTCHNL_OP_UNKNOWN;
 }
+
+/**
+ * iavf_poll_virtchnl_response - Poll admin queue for virtchnl response
+ * @adapter: adapter structure
+ * @condition: callback to check if desired response received
+ * @cond_data: context data passed to condition callback
+ * @timeout_ms: maximum time to wait in milliseconds
+ *
+ * Polls the admin queue and processes all incoming virtchnl messages.
+ * After processing each valid message, calls the condition callback to check
+ * if the expected response has been received. The callback receives the opcode
+ * of the processed message to identify which response was received. Continues
+ * polling until the callback returns true or timeout expires.
+ * Clear current_op on timeout to prevent permanent -EBUSY state.
+ * Caller must hold netdev_lock. This can sleep for up to timeout_ms while
+ * polling hardware.
+ *
+ * Return: 0 on success (condition met), -EAGAIN on timeout, or error code
+ **/
+int iavf_poll_virtchnl_response(struct iavf_adapter *adapter,
+				bool (*condition)(struct iavf_adapter *adapter,
+						  const void *data,
+						  enum virtchnl_ops v_op),
+				const void *cond_data,
+				unsigned int timeout_ms)
+{
+	struct iavf_hw *hw = &adapter->hw;
+	struct iavf_arq_event_info event;
+	enum virtchnl_ops received_op;
+	unsigned long timeout;
+	u32 v_retval;
+	u16 pending;
+	int ret = -EAGAIN;
+
+	netdev_assert_locked(adapter->netdev);
+
+	event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
+	event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
+	if (!event.msg_buf)
+		return -ENOMEM;
+
+	timeout = jiffies + msecs_to_jiffies(timeout_ms);
+	do {
+		if (iavf_clean_arq_element(hw, &event, &pending) == IAVF_SUCCESS) {
+			received_op = (enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
+			if (received_op != VIRTCHNL_OP_UNKNOWN) {
+				v_retval = le32_to_cpu(event.desc.cookie_low);
+
+				iavf_virtchnl_completion(adapter, received_op,
+							 (enum iavf_status)v_retval,
+							 event.msg_buf, event.msg_len);
+
+				if (condition(adapter, cond_data, received_op)) {
+					ret = 0;
+					break;
+				}
+			}
+
+			memset(event.msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE);
+
+			if (pending)
+				continue;
+		}
+
+		usleep_range(50, 75);
+	} while (time_before(jiffies, timeout));
+
+	if (ret == -EAGAIN && adapter->current_op != VIRTCHNL_OP_UNKNOWN)
+		adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+
+	kfree(event.msg_buf);
+	return ret;
+}
-- 
2.53.0


^ permalink raw reply related

* [PATCH net v4 4/4] ice: skip unnecessary VF reset when setting trust
From: Jose Ignacio Tornos Martinez @ 2026-04-23 13:04 UTC (permalink / raw)
  To: netdev
  Cc: intel-wired-lan, przemyslaw.kitszel, aleksandr.loktionov,
	jacob.e.keller, horms, jesse.brandeburg, anthony.l.nguyen, davem,
	edumazet, kuba, pabeni, Jose Ignacio Tornos Martinez
In-Reply-To: <20260423130405.139568-1-jtornosm@redhat.com>

Similar to the i40e fix, ice_set_vf_trust() unconditionally calls
ice_reset_vf() when the trust setting changes. While the delay is smaller
than i40e this reset is still unnecessary in most cases.

Additionally, the original code has a race condition: it deletes MAC LLDP
filters BEFORE resetting the VF. During this deletion, the VF is still
ACTIVE and can add new MAC LLDP filters concurrently, potentially
corrupting the filter list.

When granting trust, no reset is needed - we can just set the capability
flag to allow privileged operations.

When revoking trust, we need to:
1. Clear the capability flag to block privileged operations
2. Disable promiscuous mode if it was enabled (trusted VFs can enable it)
3. Only reset if MAC LLDP filters exist (to clean them up)

When we do reset (MAC LLDP case), we fix the race condition by resetting
first to clear VF state (which blocks new MAC LLDP filter additions), then
delete existing filters safely. During cleanup, vf->trusted remains true so
ice_vf_is_lldp_ena() works properly. Only after cleanup do we set
vf->trusted = false.

When we don't reset, we manually handle capability flag and promiscuous
mode via helper function.

The ice driver already has logic to clean up MAC LLDP filters when
removing trust. After this cleanup, the VF reset is only necessary if
there were actually filters to remove (num_mac_lldp was non-zero).

This saves time and eliminates unnecessary service disruption when
changing VF trust settings in most cases, while properly handling filter
cleanup.

Fixes: 2296345416b0 ("ice: receive LLDP on trusted VFs")
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v4:
    - Address AI review (sashiko.dev) from Simon Horman:
      vf->trusted ordering bug
    - Fix upstream race condition when comparing with i40e code
    - Apply capability flag and promiscuous mode fixes from i40e AI review
    - Add helper function ice_setup_vf_trust() for non-reset path
    - Export ice_vf_clear_all_promisc_modes() for code reuse 
v3: https://lore.kernel.org/all/20260414110006.124286-5-jtornosm@redhat.com/

 drivers/net/ethernet/intel/ice/ice_sriov.c  | 41 +++++++++++++++++++--
 drivers/net/ethernet/intel/ice/ice_vf_lib.c |  2 +-
 drivers/net/ethernet/intel/ice/ice_vf_lib.h |  1 +
 3 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c
index 7e00e091756d..d0da7f6adc23 100644
--- a/drivers/net/ethernet/intel/ice/ice_sriov.c
+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
@@ -1364,6 +1364,34 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
 	return __ice_set_vf_mac(ice_netdev_to_pf(netdev), vf_id, mac);
 }
 
+/**
+ * ice_setup_vf_trust - Enable/disable VF trust mode without reset
+ * @vf: VF to configure
+ * @setting: trust setting
+ *
+ * Manually handle capability flag and promiscuous mode when changing trust
+ * without performing a VF reset.
+ * When reset is performed, this is not necessary as the reset procedure
+ * already handles this.
+ **/
+static void ice_setup_vf_trust(struct ice_vf *vf, bool setting)
+{
+	struct ice_vsi *vsi;
+
+	if (setting) {
+		set_bit(ICE_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
+	} else {
+		clear_bit(ICE_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
+
+		if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states) ||
+		    test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) {
+			vsi = ice_get_vf_vsi(vf);
+			if (vsi)
+				ice_vf_clear_all_promisc_modes(vf, vsi);
+		}
+	}
+}
+
 /**
  * ice_set_vf_trust
  * @netdev: network interface device structure
@@ -1399,11 +1427,16 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted)
 
 	mutex_lock(&vf->cfg_lock);
 
-	while (!trusted && vf->num_mac_lldp)
-		ice_vf_update_mac_lldp_num(vf, ice_get_vf_vsi(vf), false);
-
+	/* Reset only if revoking trust with MAC LLDP filters */
+	if (!trusted && vf->num_mac_lldp) {
+		ice_reset_vf(vf, ICE_VF_RESET_NOTIFY);
+		while (vf->num_mac_lldp)
+			ice_vf_update_mac_lldp_num(vf, ice_get_vf_vsi(vf), false);
+	} else {
+		ice_setup_vf_trust(vf, trusted);
+	}
 	vf->trusted = trusted;
-	ice_reset_vf(vf, ICE_VF_RESET_NOTIFY);
+
 	dev_info(ice_pf_to_dev(pf), "VF %u is now %strusted\n",
 		 vf_id, trusted ? "" : "un");
 
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
index c8bc952f05cd..81bbf30e5c29 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
@@ -623,7 +623,7 @@ ice_vf_get_promisc_masks(struct ice_vf *vf, struct ice_vsi *vsi,
  *
  * Clear all promiscuous/allmulticast filters for a VF
  */
-static int
+int
 ice_vf_clear_all_promisc_modes(struct ice_vf *vf, struct ice_vsi *vsi)
 {
 	struct ice_pf *pf = vf->pf;
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
index 7a9c75d1d07c..a3501bd92311 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
@@ -310,6 +310,7 @@ bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf);
 void
 ice_vf_get_promisc_masks(struct ice_vf *vf, struct ice_vsi *vsi,
 			 u8 *ucast_m, u8 *mcast_m);
+int ice_vf_clear_all_promisc_modes(struct ice_vf *vf, struct ice_vsi *vsi);
 int
 ice_vf_set_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m);
 int
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH v11 08/12] kvm: Define EXPORT_STATIC_CALL_FOR_KVM()
From: Sean Christopherson @ 2026-04-23 13:12 UTC (permalink / raw)
  To: Pawan Gupta
  Cc: x86, Jon Kohler, Nikolay Borisov, H. Peter Anvin, Josh Poimboeuf,
	David Kaplan, Borislav Petkov, Dave Hansen, Peter Zijlstra,
	Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, KP Singh,
	Jiri Olsa, David S. Miller, David Laight, Andy Lutomirski,
	Thomas Gleixner, Ingo Molnar, David Ahern, Martin KaFai Lau,
	Eduard Zingerman, Song Liu, Yonghong Song, John Fastabend,
	Stanislav Fomichev, Hao Luo, Paolo Bonzini, Jonathan Corbet,
	Jason Baron, Alice Ryhl, Steven Rostedt, Ard Biesheuvel,
	Shuah Khan, linux-kernel, kvm, Asit Mallick, Tao Zhang, bpf,
	netdev, linux-doc
In-Reply-To: <20260422-vmscape-bhb-v11-8-b18e0cf32af4@linux.intel.com>

Uber nit (don't bother with a new version), please capitalize KVM:

On Wed, Apr 22, 2026, Pawan Gupta wrote:
> EXPORT_SYMBOL_FOR_KVM() exists to export symbols to KVM modules. Static
> calls need the same treatment when the core kernel defines a static_call
> that KVM needs access to (e.g. from a VM-exit path).
> 
> Define EXPORT_STATIC_CALL_FOR_KVM() as the static_call analogue of
> EXPORT_SYMBOL_FOR_KVM(). The same three-way logic applies:
> 
>   - KVM_SUB_MODULES defined: export to "kvm," plus all sub-modules
>   - KVM=m, no sub-modules: export to "kvm" only
>   - KVM built-in: no export needed (noop)
> 
>   As with EXPORT_SYMBOL_FOR_KVM(), allow architectures to override both
>   macros (e.g. to suppress the export when kvm.ko itself will not be
>   built despite CONFIG_KVM=m). Add the x86 no-op overrides in
>   arch/x86/include/asm/kvm_types.h for that case. To keep the pair in
>   sync, EXPORT_STATIC_CALL_FOR_KVM() is defined inside the
>   EXPORT_SYMBOL_FOR_KVM #ifndef block; an arch that defines
>   EXPORT_SYMBOL_FOR_KVM must also define EXPORT_STATIC_CALL_FOR_KVM or the
>   build will fail with a compile-time error.
> 
> As with EXPORT_SYMBOL_FOR_KVM(), allow architectures to override
> EXPORT_STATIC_CALL_FOR_KVM definition (e.g. to suppress the export when
> kvm.ko itself will not be built despite CONFIG_KVM=m). Add the x86 no-op
> override in arch/x86/include/asm/kvm_types.h for that case.
> 
> Architectures must also define EXPORT_STATIC_CALL_FOR_KVM when they define
> EXPORT_SYMBOL_FOR_KVM.
> 
> Suggested-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> ---

Acked-by: Sean Christopherson <seanjc@google.com>

^ permalink raw reply

* RE: [PATCH net v4 1/4] iavf: return EBUSY if reset in progress or not ready during MAC change
From: Loktionov, Aleksandr @ 2026-04-23 13:14 UTC (permalink / raw)
  To: Jose Ignacio Tornos Martinez, netdev@vger.kernel.org
  Cc: intel-wired-lan@lists.osuosl.org, Kitszel, Przemyslaw,
	Keller, Jacob E, horms@kernel.org, jesse.brandeburg@intel.com,
	Nguyen, Anthony L, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com
In-Reply-To: <20260423130405.139568-2-jtornosm@redhat.com>



> -----Original Message-----
> From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
> Sent: Thursday, April 23, 2026 3:04 PM
> To: netdev@vger.kernel.org
> Cc: intel-wired-lan@lists.osuosl.org; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Loktionov, Aleksandr
> <aleksandr.loktionov@intel.com>; Keller, Jacob E
> <jacob.e.keller@intel.com>; horms@kernel.org;
> jesse.brandeburg@intel.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; davem@davemloft.net;
> edumazet@google.com; kuba@kernel.org; pabeni@redhat.com; Jose Ignacio
> Tornos Martinez <jtornosm@redhat.com>
> Subject: [PATCH net v4 1/4] iavf: return EBUSY if reset in progress or
> not ready during MAC change
> 
> When a MAC address change is requested while the VF is resetting or
> still initializing, return -EBUSY immediately instead of attempting
> the operation.
> 
> Additionally, during early initialization states (before __IAVF_DOWN),
> the PF may be slow to respond to MAC change requests, causing long
> delays. Only allow MAC changes once the VF reaches __IAVF_DOWN state
> or later, when the watchdog is running and the VF is ready for
> operations.
> 
> After commit ad7c7b2172c3 ("net: hold netdev instance lock during
> sysfs operations"), MAC changes are called with the netdev lock held,
> so we should not wait with the lock held during reset or
> initialization. This allows the caller to retry or handle the busy
> state appropriately without blocking other operations.
> 
> Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> ---
> 
>  drivers/net/ethernet/intel/iavf/iavf_main.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c
> b/drivers/net/ethernet/intel/iavf/iavf_main.c
> index dad001abc908..67aa14350b1b 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_main.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
> @@ -1060,6 +1060,9 @@ static int iavf_set_mac(struct net_device
> *netdev, void *p)
>  	struct sockaddr *addr = p;
>  	int ret;
> 
> +	if (iavf_is_reset_in_progress(adapter) || adapter->state <
> __IAVF_DOWN)
> +		return -EBUSY;
> +
>  	if (!is_valid_ether_addr(addr->sa_data))
>  		return -EADDRNOTAVAIL;
> 
> --
> 2.53.0

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

^ 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