Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH iwl-next v3 2/2] i40e: add devlink parameter for Flow Director ATR sample rate
From: Simon Horman @ 2026-07-08 14:36 UTC (permalink / raw)
  To: mheib
  Cc: Simon Horman, intel-wired-lan, netdev, jiri, davem, edumazet,
	kuba, pabeni, corbet, anthony.l.nguyen, przemyslaw.kitszel,
	andrew+netdev
In-Reply-To: <20260701093830.948756-2-mheib@redhat.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
i40e: add devlink parameter for Flow Director ATR sample rate

This commit introduces a runtime devlink parameter to tune the Flow Director
ATR sample rate. This allows dynamic adjustments to the sampling interval
without rebuilding the driver, which can help reduce TCP packet reordering
on systems with high-rate workloads.

> diff --git a/drivers/net/ethernet/intel/i40e/i40e_devlink.c b/drivers/net/ethernet/intel/i40e/i40e_devlink.c
> index 229179ccc1319..cf487efdd803d 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_devlink.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_devlink.c
[ ... ]
> @@ -33,12 +33,48 @@ static int i40e_max_mac_per_vf_get(struct devlink *devlink,
>  	return 0;
>  }
>  
> +static int i40e_atr_sample_rate_set(struct devlink *devlink,
> +				    u32 id,
> +				    struct devlink_param_gset_ctx *ctx,
> +				    struct netlink_ext_ack *extack)
> +{
> +	struct i40e_pf *pf = devlink_priv(devlink);
> +	u32 sample_rate = ctx->val.vu32;
> +
> +	pf->atr_sample_rate = sample_rate;

[Severity: Low]
Does modifying pf->atr_sample_rate concurrently with the Tx fast path
introduce a data race?

In the Tx fast path, i40e_atr() reads this value locklessly. If the devlink
callback sets this to 0 between the two reads in i40e_atr():

drivers/net/ethernet/intel/i40e/i40e_txrx.c:i40e_atr() {
        if (!pf->atr_sample_rate)
                return;
        ...
        if (tx_ring->atr_count < pf->atr_sample_rate)
        ...
}

Could this race lead to a situation where the second check evaluates
tx_ring->atr_count against 0, unintentionally programming an extra Flow
Director filter?

While the functional impact might just be a single extra sampled packet,
should we use READ_ONCE() in the fast path and WRITE_ONCE() here to avoid
KCSAN data race warnings and ensure a consistent value is used throughout
the function?

> +	return 0;
> +}

[ ... ]

^ permalink raw reply

* Re: [RFC] VEGA: a syzbot-like workflow for LLM-found kernel bugs
From: Greg KH @ 2026-07-08 14:55 UTC (permalink / raw)
  To: Yuan Tan
  Cc: linux-kernel, workflows, jhs, sven, netdev, netfilter-devel,
	linux-crypto
In-Reply-To: <20260708092247.4188498-1-yuantan098@gmail.com>

On Wed, Jul 08, 2026 at 02:22:47AM -0700, Yuan Tan wrote:
> Hi all,
> 
> We would like to ask for feedback on a proposed workflow for reporting Linux
> kernel bugs found by an LLM-assisted code auditing tool that we have
> been developing since earlier this year.
> 
> Since February, we have been developing an LLM-driven kernel code auditing
> tool called VEGA. It started as a side project, but the results became much
> substantial than we expected: VEGA has found hundreds of valid bugs in Linux
> kernel.
> 
> That immediately created a practical problem: we do not want to dump a large
> pile of bug reports onto mail lists and annoy the maintainers.

True, which is why we all end up with long lists of issues/patches at
the moment.  The initial reaction is "we need a dashboard for everyone
to collab around!" like you did here, but I'd like to say this is not
the best thing to do at all.

syzbot can get away with a dashboard because someone is tending to it,
triaging the "serious" bugs before they become public, and only letting
the "would be nice to fix one day" type issues remain.  That's a huge
resource commitment that Google has made here, and that's great, but I
doubt that anyone else will have those resources to do this type of
thing.

Instead, let's just work to get these things fixed.  We all have
hundreds of patches/reports in our internal systems right now,
attempting to triage/rank/coordinate would just waste time.  In other
words, just grind through them, send patches out, and get these fixed.

I'm doing this now, and I know many others are as well.  We are all
running "different" tools, and so we find different issues, so we can
all just keep sending patches as we get them done.  It's going to take a
lot of effort (I've somehow convinced 8 interns to help me out with this
this summer), but once we get it done, we'll be much better off.

> The first thing we tried was to fix as many as we could ourselves. We
> started working with a group of student volunteers. Most of them are
> college students, so we have been training them, reviewing their patches,
> and trying to build an internal review process before anything is sent to
> the mailing list. The goal is to turn these findings into useful fixes, and
> also to help new contributors grow into people who can reduce maintainer
> workload instead of adding to it.
> 
> The process was not perfect. Some patches were not good enough, and we also
> made some mistakes early on when deciding what should be called a security
> issue.  Our internal review process has been improving with the help of the
> community.

That's great, keep it up!

> But the remaining queue is still too large for us to handle.
> 
> Recently Jamal pointed out problems around our tags. That made me realize
> that we should probably stop treating this as an ad-hoc patch effort and
> build something closer to syzbot: public, reproducible, trackable,
> deduplicated, and useful to maintainers.

Again, I think that effort is going to be larger than just getting the
patches fixed and pushed out.  It also turns into a central
point-of-failure, which is what we do not want to have at all for the
kernel.

But hey, I could be totally wrong.  Maybe some generous company that is
involved in unleashing this hell on us would be so kind as to pony up to
do the work to create this and help fix the issues that their tools are
finding.  Just like Google did in the past, there is precedent, but for
some reason people don't like learning from history...

It's going to be a long 18 months...

greg k-h

^ permalink raw reply

* Re: (subset) [PATCH v5 0/4] clk: qcom: Add RPMCC and GCC support for the Qualcomm Shikra SoC
From: Bjorn Andersson @ 2026-07-08 14:56 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Richard Cochran, Brian Masney, Imran Shaik
  Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, Krzysztof Kozlowski,
	linux-arm-msm, linux-clk, devicetree, linux-kernel, netdev,
	Krzysztof Kozlowski, Dmitry Baryshkov
In-Reply-To: <20260608-shikra-gcc-rpmcc-clks-v5-0-94cefe092ee3@oss.qualcomm.com>


On Mon, 08 Jun 2026 17:51:48 +0530, Imran Shaik wrote:
> This series adds support for the Global Clock Controller (GCC) and
> RPM-managed clocks on Qualcomm Shikra SoC.
> 
> Qualcomm Shikra SoC details:
>  - https://lore.kernel.org/all/20260428-shikra-socid-v1-0-6ff16bad5ea2@oss.qualcomm.com/
> 
> 
> [...]

Applied, thanks!

[4/4] clk: qcom: Add Global clock controller support on Qualcomm Shikra SoC
      commit: 01cf3e27824d1cf2dcb815e59087c6556819b039

Best regards,
-- 
Bjorn Andersson <andersson@kernel.org>

^ permalink raw reply

* Re: [PATCH v5 net 2/7] i40e: avoid null ptr dereference in i40e_ptp_stop()
From: Simon Horman @ 2026-07-08 15:04 UTC (permalink / raw)
  To: maciej.fijalkowski
  Cc: Simon Horman, intel-wired-lan, netdev, magnus.karlsson, kuba,
	pabeni, przemyslaw.kitszel, jacob.e.keller
In-Reply-To: <20260701124524.13644-3-maciej.fijalkowski@intel.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
i40e: avoid null ptr dereference in i40e_ptp_stop()
    
Check if main_vsi is not null before calling dev_info() to avoid a null
pointer dereference when i40e_vsi_clear() frees the main VSI during rebuild.

> diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
> index ff62b5f2c8150..ca93df4d67859 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
> @@ -1556,8 +1556,9 @@ void i40e_ptp_stop(struct i40e_pf *pf)
>  	if (pf->ptp_clock) {
>  		ptp_clock_unregister(pf->ptp_clock);
>  		pf->ptp_clock = NULL;
> -		dev_info(&pf->pdev->dev, "%s: removed PHC on %s\n", __func__,
> -			 main_vsi->netdev->name);
> +		if (main_vsi)
> +			dev_info(&pf->pdev->dev, "%s: removed PHC on %s\n", __func__,
> +				 main_vsi->netdev->name);

[Severity: High]
This isn't a bug introduced by this patch, but this lockless check appears
to introduce a time-of-check to time-of-use race condition.

When i40e_remove() calls i40e_ptp_stop(pf), it does so unsynchronized from
the background i40e_rebuild() task. If i40e_rebuild() fails during setup, it
calls i40e_vsi_clear(main_vsi), which frees the VSI and its netdev.

If i40e_ptp_stop() caches main_vsi right before it is cleared, couldn't the
if (main_vsi) check pass, but the subsequent main_vsi->netdev->name access
dereference freed memory, causing a use-after-free?

[Severity: High]
This is another pre-existing issue, but I noticed that i40e_ptp_stop() doesn't
seem to cancel the background workqueue task ptp_extts0_work.

During device removal, i40e_remove() calls i40e_ptp_stop() and then
subsequently frees the i40e_pf structure. If the work executes after the PF
is freed, will it access the deallocated i40e_pf structure and trigger a
use-after-free?

[Severity: High]
This is also a pre-existing issue, but I am looking at how pf->ptp_tx_skb is
cleared earlier in i40e_ptp_stop(). The teardown uses I40E_FLAG_PTP_ENA as a 
gate guard:

i40e_ptp_stop() clears I40E_FLAG_PTP_ENA, then locklessly checks and frees
pf->ptp_tx_skb using dev_kfree_skb_any().

The interrupt handler i40e_ptp_tx_hwtstamp() uses the same bit as a guard:

    if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags))
            return;

If the interrupt handler passes the test_bit check just before i40e_ptp_stop()
executes clear_bit(), both contexts could concurrently read the same
pf->ptp_tx_skb pointer into local variables before it is NULLed out. Could
this result in a double free of the SKB?

[Severity: High]
There is a similar pre-existing issue related to the teardown of the
timestamping state in i40e_ptp_stop() racing with the TX datapath.

The TX datapath i40e_tstamp() protects the state using a bit lock:

    if (pf->ptp_tx &&
        !test_and_set_bit_lock(__I40E_PTP_TX_IN_PROGRESS, pf->state)) {
            ...
            pf->ptp_tx_skb = skb_get(skb);
    }

However, i40e_ptp_stop() checks pf->ptp_tx_skb locklessly and only clears
the bit lock if the SKB was present. If the TX datapath acquires the lock
and is preempted right before assigning pf->ptp_tx_skb, i40e_ptp_stop()
might execute, see a NULL ptp_tx_skb, and skip the cleanup block.

When the TX datapath resumes, it assigns the SKB pointer. Since the device
is subsequently destroyed, does this cause the SKB to be permanently leaked?

>  	}
>  
>  	if (i40e_is_ptp_pin_dev(&pf->hw)) {

[Severity: High]
This isn't a bug introduced by this patch, but while reviewing the driver's
cleanup paths, I noticed a potential leak in the i40e_probe() error handling:

drivers/net/ethernet/intel/i40e/i40e_main.c:i40e_probe() {
...
err_vsis:
        set_bit(__I40E_DOWN, pf->state);
        i40e_ptp_stop(pf);
        i40e_clear_interrupt_scheme(pf);
        kfree(pf->vsi);
...
}

If initialization fails after VSIs are successfully created, this cleanup
path calls kfree(pf->vsi) which frees the pointer array, but does not appear
to unregister the netdev or free the actual VSI structs and hardware rings.

Could this leave an active, registered netdev with dangling pointers to the
subsequently freed PF, potentially triggering a use-after-free upon network
traffic or userspace access?

[Severity: High]
This is a pre-existing issue, but I noticed an ad-hoc locking pattern in
i40e_remove():

drivers/net/ethernet/intel/i40e/i40e_main.c:i40e_remove() {
...
        while (test_and_set_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
                usleep_range(1000, 2000);
...
}

This attempts to synchronize with the background reset path by spinning on
a bit flag, which acts as a sleepable lock without the standard fairness or
deadlock detection guarantees. 

Since this ad-hoc locking scheme fails to provide proper mutual exclusion
earlier in the function, could this be the direct cause of why i40e_ptp_stop()
executes unsynchronized from i40e_rebuild()? Should a proper mutex be used
here instead?

^ permalink raw reply

* Re: [PATCH net] nfc: nci: fix out-of-bounds read in activation parameter parsing
From: Muhammad Bilal @ 2026-07-08 15:10 UTC (permalink / raw)
  To: Simon Horman
  Cc: David Heidelberg, netdev, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, oe-linux-nfc, linux-kernel
In-Reply-To: <20260708130534.GA1481798@horms.kernel.org>

Hi Simon,

Thanks for the review and the Reviewed-by.

One of the issues raised by the AI review (the NFC-DEP general bytes
handling in nci_store_general_bytes_nfc_dep()) is already addressed by
a separate follow-up patch:

Link: https://lore.kernel.org/all/20260628214929.135152-1-meatuni001@gmail.com/

The remaining AI-raised points are independent of this fix and can be
investigated separately if they prove to be valid.

On Wed, Jul 8, 2026 at 6:07 PM Simon Horman <horms@kernel.org> wrote:
>
> On Mon, Jun 29, 2026 at 02:00:26AM +0500, Muhammad Bilal wrote:
> > nci_extract_activation_params_iso_dep() and
> > nci_extract_activation_params_nfc_dep() receive a pointer into the
> > RF_INTF_ACTIVATED_NTF notification but are not told how many bytes
> > remain.  Each reads a one-byte length field (rats_res_len,
> > attrib_res_len, atr_res_len or atr_req_len) and then memcpy()s that many
> > bytes from the packet.  The length is clamped to the destination size,
> > but it is never checked against the remaining activation-parameter data,
> > so a notification whose length field is larger than the data present
> > reads past the end of the buffer.
> >
> > The sibling nci_extract_rf_params_*() helpers were recently given a
> > data_len argument and matching remaining-length checks, but the
> > activation-parameter helpers were not updated.
> >
> > Pass the remaining length down and validate each field against it before
> > copying, as the rf_params helpers do.
> >
> > Fixes: ac2068384034 ("NFC: Parse NCI NFC-DEP activation params")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
>
> Reviewed-by: Simon Horman <horms@kernel.org>
>
> FTR, there is an AI-=generated review of this patch on sashiko.dev.
> However, I think that the issues raised there can be treated
> as possible follow-up rather than impeding the progress of this patch.

^ permalink raw reply

* Re: [PATCH bpf-next 0/1] selftests: drv-net: XDP RX checksum metadata test
From: Lorenzo Bianconi @ 2026-07-08 15:12 UTC (permalink / raw)
  To: Vladimir Vdovin
  Cc: sdf, kuba, andrii, ast, daniel, hawk, john.fastabend, martin.lau,
	sdf.kernel, bpf, netdev
In-Reply-To: <cover.1783514455.git.deliran@verdict.gg>

[-- Attachment #1: Type: text/plain, Size: 1814 bytes --]

> Hi Lorenzo,

Hi Vladimir,

> 
> Here is the driver selftest for your XDP RX checksum series, as
> discussed. It is written against your b4/bpf-xdp-meta-rxcksum branch
> (the bitmask ip_summed + cksum/cksum_level API) and applies on top of
> it rebased onto net-next, since the drv-net xdp_metadata.py test it
> extends only exists there. Feel free to pick it straight into v4.
> 
> It adds an xdp_rx_csum program to xdp_metadata.bpf.o and two cases
> gated on the "checksum" xdp-rx-metadata feature (SKIP on devices
> without it, e.g. netdevsim):
> 
>  - xdp_rx_csum_valid (tcp/udp variants): traffic with a correct
>    checksum from the remote endpoint must be reported with a usable
>    verdict (CHECKSUM_UNNECESSARY and/or CHECKSUM_COMPLETE);
> 
>  - xdp_rx_csum_invalid: UDP with a corrupted L4 checksum (net/lib
>    csum -E) must not be reported as CHECKSUM_UNNECESSARY.

thx for working on it. Unfortunately I do not have the time to look into it a
the moment. I rebased my b4/bpf-xdp-meta-rxcksum branch on top of net-next one.
Feel free to repost it adding your patch on top of it.

Regards,
Lorenzo

> 
> 
> One question on the invalid case: I assert only that UNNECESSARY is not
> set for a corrupted checksum (COMPLETE may still legitimately be
> reported, since it carries the raw sum for wrong packets too). Is that
> the documented expectation you and Jakub want the test to encode, or
> should it be stricter?
> 
> Thanks,
> Vladimir
> 
> Vladimir Vdovin (1):
>   selftests: drv-net: add XDP RX checksum metadata tests
> 
>  .../selftests/drivers/net/hw/xdp_metadata.py  | 103 ++++++++++++++++
>  .../selftests/net/lib/xdp_metadata.bpf.c      | 112 ++++++++++++++++--
>  2 files changed, 202 insertions(+), 13 deletions(-)
> 
> -- 
> 2.47.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* [PATCH iwl-next] idpf: add flow-based XDP fallback for FWs without Tx FIFO support
From: Alexander Lobakin @ 2026-07-08 15:13 UTC (permalink / raw)
  To: intel-wired-lan
  Cc: Alexander Lobakin, Tony Nguyen, Przemek Kitszel, Andrew Lunn,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, nxne.cnse.osdt.itp.upstreaming, netdev,
	linux-kernel

From the first days of XDP implementation in idpf, it relied and
worked solely on top of the queue-based scheduling Tx mode, which
basically means simple FIFO. However, turned out not every firmware
supports this mode and XDP doesn't work there at all.

Since the flow-based scheduling Tx mode is mandatory and supported
by every FW, introduce a simple fallback guarded by a static key
to not hurt the more performant mode. The FB mode generates a
completion for each Tx descriptor and never guarantees that there
won't be any out-of-order completions. Serialize that using a
bitmap of completed descriptors and report contiguous blocks of
free bits to match XDP and XSk expectations and avoid further
code complication.

The usage of a bitmap on hotpath might sound scary, but this
fallback is able to reach around 70% of the QB mode's performance,
which is comparable to what ice gives us. The main bottlenecks are
unlikely()s and one completion per each descriptor, while in the QB
mode we have one completion per batch (which might contain 64 or
even 128 frames), plus the size of the completion descriptor is
8 bytes in this mode (4 bytes in the QB mode), which means a lot
of additional PCI traffic.

bloat-o-meter shows .text increase in about 2 Kb without adding new
functions or uninlining any of the existing ones. I played a bunch
with inlining and uninlining certain pieces or the whole fallback,
but the compiler collapses and optimizes libeth templates so hardly
so that each additional external call only makes things worse.

Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
---
 drivers/net/ethernet/intel/idpf/idpf.h      |   1 +
 drivers/net/ethernet/intel/idpf/idpf_txrx.h |  11 +-
 drivers/net/ethernet/intel/idpf/xdp.h       |  60 +++++++++-
 include/net/libeth/xdp.h                    |  13 +++
 drivers/net/ethernet/intel/idpf/idpf_txrx.c |  10 +-
 drivers/net/ethernet/intel/idpf/xdp.c       | 115 +++++++++++++++++++-
 6 files changed, 201 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf.h b/drivers/net/ethernet/intel/idpf/idpf.h
index ec1b75f039bb..5414bbbee07a 100644
--- a/drivers/net/ethernet/intel/idpf/idpf.h
+++ b/drivers/net/ethernet/intel/idpf/idpf.h
@@ -384,6 +384,7 @@ struct idpf_vport {
 	struct idpf_tx_queue **txqs;
 	u16 num_txq;
 	u16 num_xdp_txq;
+	bool xdpsq_fb;
 	bool xdpsq_share;
 	struct bpf_prog *xdp_prog;
 
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
index a0d92adf11c4..ba6193f01552 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
@@ -625,11 +625,12 @@ libeth_cacheline_set_assert(struct idpf_rx_queue,
  * @clean_budget: singleq only, queue cleaning budget
  * @cleaned_pkts: Number of packets cleaned for the above said case
  * @refillq: Pointer to refill queue
+ * @cached_tstamp_caps: Tx timestamp capabilities negotiated with the CP
  * @pending: number of pending descriptors to send in QB
  * @xdp_tx: number of pending &xdp_buff or &xdp_frame buffers
  * @timer: timer for XDP Tx queue cleanup
  * @xdp_lock: lock for XDP Tx queues sharing
- * @cached_tstamp_caps: Tx timestamp capabilities negotiated with the CP
+ * @pending_mask: mask of buffers waiting for completion in the FB XDP mode
  * @tstamp_task: Work that handles Tx timestamp read
  * @stats_sync: See struct u64_stats_sync
  * @q_stats: See union idpf_tx_queue_stats
@@ -689,6 +690,8 @@ struct idpf_tx_queue {
 			u16 cleaned_pkts;
 
 			struct idpf_sw_queue *refillq;
+
+			struct idpf_ptp_vport_tx_tstamp_caps *cached_tstamp_caps;
 		};
 		struct {
 			u32 pending;
@@ -696,10 +699,11 @@ struct idpf_tx_queue {
 
 			struct libeth_xdpsq_timer *timer;
 			struct libeth_xdpsq_lock xdp_lock;
+
+			unsigned long *pending_mask;
 		};
 	};
 
-	struct idpf_ptp_vport_tx_tstamp_caps *cached_tstamp_caps;
 	struct work_struct *tstamp_task;
 
 	struct u64_stats_sync stats_sync;
@@ -718,8 +722,7 @@ struct idpf_tx_queue {
 	__cacheline_group_end_aligned(cold);
 };
 libeth_cacheline_set_assert(struct idpf_tx_queue, 64,
-			    104 +
-			    offsetof(struct idpf_tx_queue, cached_tstamp_caps) -
+			    96 + offsetof(struct idpf_tx_queue, tstamp_task) -
 			    offsetofend(struct idpf_tx_queue, timer) +
 			    offsetof(struct idpf_tx_queue, q_stats) -
 			    offsetofend(struct idpf_tx_queue, tstamp_task),
diff --git a/drivers/net/ethernet/intel/idpf/xdp.h b/drivers/net/ethernet/intel/idpf/xdp.h
index 63e56f7d43e0..3d01c535bd4c 100644
--- a/drivers/net/ethernet/intel/idpf/xdp.h
+++ b/drivers/net/ethernet/intel/idpf/xdp.h
@@ -8,6 +8,10 @@
 
 #include "idpf_txrx.h"
 
+struct idpf_q_vec_rsrc;
+
+DECLARE_STATIC_KEY_FALSE(idpf_xdp_fb);
+
 int idpf_xdp_rxq_info_init(struct idpf_rx_queue *rxq);
 int idpf_xdp_rxq_info_init_all(const struct idpf_q_vec_rsrc *rsrc);
 void idpf_xdp_rxq_info_deinit(struct idpf_rx_queue *rxq, u32 model);
@@ -21,6 +25,34 @@ void idpf_xdpsqs_put(const struct idpf_vport *vport);
 u32 idpf_xdpsq_poll(struct idpf_tx_queue *xdpsq, u32 budget);
 bool idpf_xdp_tx_flush_bulk(struct libeth_xdp_tx_bulk *bq, u32 flags);
 
+static inline void idpf_xdp_tx_xmit_fb(struct libeth_xdp_tx_desc desc, u32 i,
+				       const struct libeth_xdpsq *sq, u64 priv)
+{
+	struct idpf_flex_tx_sched_desc *tx_desc = sq->descs;
+	u32 cmd;
+
+	cmd = FIELD_PREP(IDPF_TXD_FLEX_FLOW_DTYPE_M,
+			 IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE);
+	if (desc.flags & LIBETH_XDP_TX_LAST)
+		cmd |= IDPF_TXD_FLEX_FLOW_CMD_EOP;
+	if (priv && (desc.flags & LIBETH_XDP_TX_CSUM))
+		cmd |= IDPF_TXD_FLEX_FLOW_CMD_CS_EN;
+
+	tx_desc = &tx_desc[i];
+	tx_desc->buf_addr = cpu_to_le64(desc.addr);
+
+#ifdef __LIBETH_WORD_ACCESS
+	*(u64 *)&tx_desc->qw1 = ((u64)desc.len << 48) | ((u64)i << 32) | cmd;
+#else
+	tx_desc->qw1.rxr_bufsize = cpu_to_le16(desc.len);
+	tx_desc->qw1.compl_tag = cpu_to_le16(i);
+	tx_desc->qw1.ts[0] = 0;
+	tx_desc->qw1.ts[1] = 0;
+	tx_desc->qw1.ts[2] = 0;
+	tx_desc->qw1.cmd_dtype = cmd;
+#endif
+}
+
 /**
  * idpf_xdp_tx_xmit - produce a single HW Tx descriptor out of XDP desc
  * @desc: XDP descriptor to pull the DMA address and length from
@@ -34,6 +66,14 @@ static inline void idpf_xdp_tx_xmit(struct libeth_xdp_tx_desc desc, u32 i,
 	struct idpf_flex_tx_desc *tx_desc = sq->descs;
 	u32 cmd;
 
+	if (static_branch_unlikely(&idpf_xdp_fb) &&
+	    idpf_queue_has(FLOW_SCH_EN,
+			   libeth_xdpsq_to_sq(sq, struct idpf_tx_queue,
+					      next_to_use))) {
+		idpf_xdp_tx_xmit_fb(desc, i, sq, priv);
+		return;
+	}
+
 	cmd = FIELD_PREP(IDPF_FLEX_TXD_QW1_DTYPE_M,
 			 IDPF_TX_DESC_DTYPE_FLEX_L2TAG1_L2TAG2);
 	if (desc.flags & LIBETH_XDP_TX_LAST)
@@ -53,10 +93,27 @@ static inline void idpf_xdp_tx_xmit(struct libeth_xdp_tx_desc desc, u32 i,
 #endif
 }
 
+static inline void idpf_xdpsq_set_rs_fb(const struct idpf_tx_queue *xdpsq)
+{
+	u32 n = min(xdpsq->pending, xdpsq->desc_count - xdpsq->next_to_clean);
+
+	bitmap_set(xdpsq->pending_mask, xdpsq->next_to_clean, n);
+
+	n = xdpsq->pending - n;
+	if (n)
+		bitmap_set(xdpsq->pending_mask, 0, n);
+}
+
 static inline void idpf_xdpsq_set_rs(const struct idpf_tx_queue *xdpsq)
 {
 	u32 ntu, cmd;
 
+	if (static_branch_unlikely(&idpf_xdp_fb) &&
+	    idpf_queue_has(FLOW_SCH_EN, xdpsq)) {
+		idpf_xdpsq_set_rs_fb(xdpsq);
+		return;
+	}
+
 	ntu = xdpsq->next_to_use;
 	if (unlikely(!ntu))
 		ntu = xdpsq->desc_count;
@@ -84,7 +141,8 @@ static inline void idpf_xdpsq_update_tail(const struct idpf_tx_queue *xdpsq)
  * Set the RS bit ("end of batch"), bump the tail, and queue the cleanup timer.
  * To be called after a NAPI polling loop, at the end of .ndo_xdp_xmit() etc.
  */
-static inline void idpf_xdp_tx_finalize(void *_xdpsq, bool sent, bool flush)
+static __always_inline void idpf_xdp_tx_finalize(void *_xdpsq, bool sent,
+						 bool flush)
 {
 	struct idpf_tx_queue *xdpsq = _xdpsq;
 
diff --git a/include/net/libeth/xdp.h b/include/net/libeth/xdp.h
index 898723ab62e8..ed61d83bda2d 100644
--- a/include/net/libeth/xdp.h
+++ b/include/net/libeth/xdp.h
@@ -430,6 +430,19 @@ struct libeth_xdpsq {
 	struct libeth_xdpsq_lock	*lock;
 };
 
+/**
+ * libeth_xdpsq_to_sq - get SQ pointer from an XDPSQ pointer
+ * @xdpsq: &libeth_xdpsq corresponding to the queue
+ * @type: typeof() of the driver Tx queue structure
+ * @member: name of the NTU field inside @type
+ *
+ * Some of the sending callbacks take only &libeth_xdpsq pointer and no pointer
+ * to the actual driver Tx queue structure. Use this helper to quickly jump to
+ * the latter when needed.
+ */
+#define libeth_xdpsq_to_sq(xdpsq, type, member)				      \
+	container_of_const((xdpsq)->ntu, type, member)
+
 /**
  * struct libeth_xdp_tx_desc - abstraction for an XDP Tx descriptor
  * @addr: DMA address of the frame
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index 4b94e554d7fa..81e21a564da6 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -227,7 +227,7 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
 
 	idpf_xsk_setup_queue(vport, tx_q, VIRTCHNL2_QUEUE_TYPE_TX);
 
-	if (!idpf_queue_has(FLOW_SCH_EN, tx_q))
+	if (!idpf_queue_has(FLOW_SCH_EN, tx_q) || idpf_queue_has(XDP, tx_q))
 		return 0;
 
 	refillq = tx_q->refillq;
@@ -1058,6 +1058,11 @@ static void idpf_clean_queue_set(const struct idpf_queue_set *qs)
 			if (idpf_queue_has(XDP, q->txq)) {
 				q->txq->pending = 0;
 				q->txq->xdp_tx = 0;
+
+				if (static_branch_unlikely(&idpf_xdp_fb) &&
+				    idpf_queue_has(FLOW_SCH_EN, q->txq))
+					bitmap_zero(q->txq->pending_mask,
+						    q->txq->desc_count);
 			} else {
 				q->txq->txq_grp->num_completions_pending = 0;
 			}
@@ -1320,7 +1325,8 @@ static void idpf_txq_group_rel(struct idpf_q_vec_rsrc *rsrc)
 			if (!txq_grp->txqs[j])
 				continue;
 
-			if (idpf_queue_has(FLOW_SCH_EN, txq_grp->txqs[j])) {
+			if (idpf_queue_has(FLOW_SCH_EN, txq_grp->txqs[j]) &&
+			    !idpf_queue_has(XDP, txq_grp->txqs[j])) {
 				kfree(txq_grp->txqs[j]->refillq);
 				txq_grp->txqs[j]->refillq = NULL;
 			}
diff --git a/drivers/net/ethernet/intel/idpf/xdp.c b/drivers/net/ethernet/intel/idpf/xdp.c
index cbccd4546768..8a4e0a13364d 100644
--- a/drivers/net/ethernet/intel/idpf/xdp.c
+++ b/drivers/net/ethernet/intel/idpf/xdp.c
@@ -7,6 +7,8 @@
 #include "xdp.h"
 #include "xsk.h"
 
+DEFINE_STATIC_KEY_FALSE(idpf_xdp_fb);
+
 static int idpf_rxq_for_each(const struct idpf_q_vec_rsrc *rsrc,
 			     int (*fn)(struct idpf_rx_queue *rxq, void *arg),
 			     void *arg)
@@ -183,8 +185,8 @@ int idpf_xdpsqs_get(const struct idpf_vport *vport)
 		kfree(xdpsq->refillq);
 		xdpsq->refillq = NULL;
 
-		idpf_queue_clear(FLOW_SCH_EN, xdpsq);
-		idpf_queue_clear(FLOW_SCH_EN, xdpsq->complq);
+		idpf_queue_assign(FLOW_SCH_EN, xdpsq, vport->xdpsq_fb);
+		idpf_queue_assign(FLOW_SCH_EN, xdpsq->complq, vport->xdpsq_fb);
 		idpf_queue_set(NOIRQ, xdpsq);
 		idpf_queue_set(XDP, xdpsq);
 		idpf_queue_set(XDP, xdpsq->complq);
@@ -197,6 +199,28 @@ int idpf_xdpsqs_get(const struct idpf_vport *vport)
 		xdpsq->pending = 0;
 		xdpsq->xdp_tx = 0;
 		xdpsq->thresh = libeth_xdp_queue_threshold(xdpsq->desc_count);
+
+		if (static_branch_unlikely(&idpf_xdp_fb) &&
+		    idpf_queue_has(FLOW_SCH_EN, xdpsq)) {
+			xdpsq->pending_mask =
+				bitmap_zalloc_node(xdpsq->desc_count,
+						   GFP_KERNEL,
+						   cpu_to_mem(i - sqs));
+			if (xdpsq->pending_mask)
+				continue;
+
+			for (int j = i - 1; j >= sqs; j--) {
+				xdpsq = vport->txqs[j];
+
+				if (idpf_queue_has(FLOW_SCH_EN, xdpsq))
+					bitmap_free(xdpsq->pending_mask);
+			}
+
+			for (u32 j = 0; j < vport->num_xdp_txq; j++)
+				kfree(timers[j]);
+
+			return -ENOMEM;
+		}
 	}
 
 	return 0;
@@ -222,6 +246,12 @@ void idpf_xdpsqs_put(const struct idpf_vport *vport)
 		libeth_xdpsq_deinit_timer(xdpsq->timer);
 		libeth_xdpsq_put(&xdpsq->xdp_lock, dev);
 
+		if (static_branch_unlikely(&idpf_xdp_fb) &&
+		    idpf_queue_has(FLOW_SCH_EN, xdpsq)) {
+			bitmap_free(xdpsq->pending_mask);
+			xdpsq->pending_mask = NULL;
+		}
+
 		kfree(xdpsq->timer);
 		xdpsq->refillq = NULL;
 		idpf_queue_clear(NOIRQ, xdpsq);
@@ -250,6 +280,65 @@ static int idpf_xdp_parse_cqe(const struct idpf_splitq_4b_tx_compl_desc *desc,
 	return upper_16_bits(val);
 }
 
+static u32 idpf_xdpsq_poll_fb(struct idpf_tx_queue *xdpsq, u32 budget)
+{
+	struct idpf_compl_queue *cq = xdpsq->complq;
+	unsigned long *mask = xdpsq->pending_mask;
+	u32 done_frames, tx_cnt, new_ntc;
+	u32 ntc = cq->next_to_clean;
+	u32 cnt = cq->desc_count;
+	bool gen;
+
+	gen = idpf_queue_has(GEN_CHK, cq);
+
+	for (done_frames = 0; done_frames < budget; ) {
+		int ret;
+
+		ret = idpf_xdp_parse_cqe(&cq->comp[ntc].common, gen);
+		if (ret >= 0) {
+			__clear_bit(ret, mask);
+			done_frames++;
+
+			goto next;
+		}
+
+		switch (ret) {
+		case -ENODATA:
+			goto out;
+		case -EINVAL:
+			break;
+		}
+
+next:
+		if (unlikely(++ntc == cnt)) {
+			ntc = 0;
+			gen = !gen;
+			idpf_queue_change(GEN_CHK, cq);
+		}
+	}
+
+out:
+	cq->next_to_clean = ntc;
+
+	if (unlikely(!done_frames))
+		return 0;
+
+	tx_cnt = xdpsq->desc_count;
+
+	/* Don't go past next_to_use */
+	__set_bit(xdpsq->next_to_use, mask);
+
+	new_ntc = find_next_bit(mask, tx_cnt, xdpsq->next_to_clean);
+	done_frames = new_ntc - xdpsq->next_to_clean;
+
+	if (new_ntc == tx_cnt)
+		done_frames += find_first_bit(mask, tx_cnt);
+
+	__clear_bit(xdpsq->next_to_use, mask);
+
+	return done_frames;
+}
+
 u32 idpf_xdpsq_poll(struct idpf_tx_queue *xdpsq, u32 budget)
 {
 	struct idpf_compl_queue *cq = xdpsq->complq;
@@ -260,6 +349,10 @@ u32 idpf_xdpsq_poll(struct idpf_tx_queue *xdpsq, u32 budget)
 	u32 done_frames;
 	bool gen;
 
+	if (static_branch_unlikely(&idpf_xdp_fb) &&
+	    idpf_queue_has(FLOW_SCH_EN, xdpsq))
+		return idpf_xdpsq_poll_fb(xdpsq, budget);
+
 	gen = idpf_queue_has(GEN_CHK, cq);
 
 	for (done_frames = 0; done_frames < budget; ) {
@@ -479,6 +572,24 @@ static int idpf_xdp_setup_prog(struct idpf_vport *vport,
 		return -ENOSPC;
 	}
 
+	vport->xdpsq_fb = !idpf_is_cap_ena(vport->adapter, IDPF_OTHER_CAPS,
+					   VIRTCHNL2_CAP_SPLITQ_QSCHED);
+	if (!vport->xdpsq_fb)
+		goto reset;
+
+	if (prog) {
+		bool warn = !static_key_enabled(&idpf_xdp_fb);
+
+		static_branch_inc(&idpf_xdp_fb);
+
+		if (warn && net_ratelimit())
+			netdev_warn(vport->netdev,
+				    "The FW doesn't support Tx in FIFO mode, XDP Tx performance might be suboptimal\n");
+	} else {
+		static_branch_dec(&idpf_xdp_fb);
+	}
+
+reset:
 	old = cfg->user_config.xdp_prog;
 	cfg->user_config.xdp_prog = prog;
 
-- 
2.55.0


^ permalink raw reply related

* Re: [PATCH net v2] tun/tap & vhost-net: make qdisc backpressure opt-in via IFF_BACKPRESSURE
From: Simon Schippers @ 2026-07-08 15:12 UTC (permalink / raw)
  To: Brett A C Sheffield, Michael S. Tsirkin
  Cc: Willem de Bruijn, Jason Wang, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, netdev, Simon Horman,
	Jonathan Corbet, Shuah Khan, Andrew Lunn, Tim Gebauer, linux-doc,
	linux-kernel
In-Reply-To: <ak1cIAwQzKS35x0m@karahi.librecast.net>

On 7/7/26 22:05, Brett A C Sheffield wrote:
> On 2026-07-07 08:52, Simon Schippers wrote:
>> Brett, can you try the two attached patches here with iperf3?
>> I think testing with 8 and 16 threads is enough, so where there is a
>> regression.
>>
>> The two patches are about time when to wake:
>> Currently we wake after consuming half the internal ring buffer.
>> One of the attached patches wakes after 2 cachelines (128 of 1000
>> packets) and the other one just wakes once the ring buffer is empty.
>>
>> This would really help :)
> 
> Sure...
> 
> 

The reverted results for reference:
7.2.0-rc1 reverted:

threads 1
[  5]   0.00-10.00  sec  15.3 GBytes  13.1 Gbits/sec  368            sender
[  5]   0.00-10.00  sec  2.00 GBytes  1.72 Gbits/sec                  receiver

threads 2
[SUM]   0.00-10.00  sec  15.9 GBytes  13.7 Gbits/sec  1567             sender
[SUM]   0.00-10.00  sec  4.00 GBytes  3.43 Gbits/sec                  receiver

threads 4
[SUM]   0.00-10.00  sec  16.5 GBytes  14.1 Gbits/sec  6701             sender
[SUM]   0.00-10.00  sec  8.00 GBytes  6.87 Gbits/sec                  receiver

threads 8
[SUM]   0.00-10.00  sec  16.2 GBytes  14.0 Gbits/sec  19319             sender
[SUM]   0.00-10.00  sec  15.7 GBytes  13.5 Gbits/sec                  receiver

threads 16
[SUM]   0.00-10.00  sec  14.4 GBytes  12.4 Gbits/sec  43593             sender
[SUM]   0.00-10.00  sec  14.4 GBytes  12.4 Gbits/sec                  receiver


> 7.2.0-rc2 (unpatched)
> 
> threads 1
> [  5]   0.00-10.00  sec  20.4 GBytes  17.5 Gbits/sec    0            sender
> [  5]   0.00-10.00  sec  2.00 GBytes  1.72 Gbits/sec                  receiver
> 
> threads 2
> [SUM]   0.00-10.00  sec  12.7 GBytes  10.9 Gbits/sec    0             sender
> [SUM]   0.00-10.00  sec  4.00 GBytes  3.43 Gbits/sec                  receiver
> 
> threads 8
> [SUM]   0.00-10.00  sec  11.5 GBytes  9.85 Gbits/sec    0             sender
> [SUM]   0.00-10.01  sec  11.4 GBytes  9.83 Gbits/sec                  receiver
> 
> threads 16
> [SUM]   0.00-10.00  sec  11.6 GBytes  9.95 Gbits/sec    0             sender
> [SUM]   0.00-10.01  sec  11.5 GBytes  9.91 Gbits/sec                  receiver
> 
> 
> 7.2.0-rc2 with 0001-tun-set-waking-threshold-to-ptr_ring_empty.patch
> 
> threads 1
> [  5]   0.00-10.00  sec  19.6 GBytes  16.8 Gbits/sec    0            sender
> [  5]   0.00-10.00  sec  2.00 GBytes  1.72 Gbits/sec                  receiver
> 
> threads 2
> [SUM]   0.00-10.00  sec  11.1 GBytes  9.50 Gbits/sec    0             sender
> [SUM]   0.00-10.00  sec  4.00 GBytes  3.43 Gbits/sec                  receiver
> 
> threads 8
> [SUM]   0.00-10.00  sec  10.8 GBytes  9.25 Gbits/sec    0             sender
> [SUM]   0.00-10.01  sec  10.7 GBytes  9.23 Gbits/sec                  receiver
> 
> threads 16
> [SUM]   0.00-10.00  sec  10.9 GBytes  9.34 Gbits/sec    0             sender
> [SUM]   0.00-10.01  sec  10.8 GBytes  9.30 Gbits/sec                  receiver
> 
> 
> 7.2.0-rc2 with 0001-tun-set-waking-threshold-to-tx_ring.batch.patch
> 
> threads 1
> [  5]   0.00-10.00  sec  19.6 GBytes  16.9 Gbits/sec    2            sender
> [  5]   0.00-10.00  sec  2.00 GBytes  1.72 Gbits/sec                  receiver
> 
> threads 2
> [SUM]   0.00-10.00  sec  13.9 GBytes  11.9 Gbits/sec    0             sender
> [SUM]   0.00-10.00  sec  4.00 GBytes  3.43 Gbits/sec                  receiver
> 
> threads 8
> [SUM]   0.00-10.00  sec  12.7 GBytes  10.9 Gbits/sec    0             sender
> [SUM]   0.00-10.01  sec  12.3 GBytes  10.6 Gbits/sec                  receiver
> 
> threads 16
> [SUM]   0.00-10.00  sec  12.5 GBytes  10.7 Gbits/sec    0             sender
> [SUM]   0.00-10.00  sec  12.4 GBytes  10.7 Gbits/sec                  receiver
> 
> 
> 
> HTH,
> 
> 
> Brett

Thank you again!

These results show that waking earlier performs better in this case:
For 8 threads we get 10.6 Gbit/s instead of 9.83 Gbit/s when waking early
but we are still *far* from the 13.5 Gbit/s when we revert everything
(see above I pasted the reverted results there).

So I come to the conclusion:

1. Waking earlier/later will not fix the performance issues. It may
   improve the performance slightly.
   Apart from that we introduce smp_mb__after_atomic() for the re-check
   on producer side (noop on x86) and a full smp_mb() for the re-check on
   consumer side.
   Nothing else stands out to me apart from the overheads of
   netif_tx_stop_queue() and netif_tx_wake_queue(). But we must use
   those 2 functions one way or another.

2. Users may depend on the dropping. Without backpressure tun/tap acts
   like a pfifo qdisc which tail-drops. Some users may require this.

--> I would merge this opt-in patchset, it should be fine (it is not
    flagged by Sashiko anymore btw). I would not be mad if it would not
    get merged but I am out of ideas on how to improve.

Thanks,
Simon


^ permalink raw reply

* Re: [PATCH iproute2-next v4 2/2] devlink: support u64-array values in devlink param show/set
From: David Ahern @ 2026-07-08 15:18 UTC (permalink / raw)
  To: Ratheesh Kannoth, stephen, kuba, linux-kernel, netdev
  Cc: andrew+netdev, edumazet, pabeni, jiri
In-Reply-To: <20260702031359.2392868-3-rkannoth@marvell.com>

On 7/1/26 9:13 PM, Ratheesh Kannoth wrote:
> diff --git a/devlink/devlink.c b/devlink/devlink.c
> index 803ea5d7..5d092d92 100644
> --- a/devlink/devlink.c
> +++ b/devlink/devlink.c
> @@ -3516,12 +3516,143 @@ static const struct param_val_conv param_val_conv[] = {
>  
>  #define PARAM_VAL_CONV_LEN ARRAY_SIZE(param_val_conv)
>  
> +struct devlink_param_u64_array {
> +	uint64_t size;

use of uint64_t here causes claude to comment:

Style 2: int i loop counter vs uint64_t size field in
param_value_u64_array_put_from_str() — signed/unsigned comparison.


> +	uint64_t *val;
> +};
> +
> +static void param_value_u64_array_free(struct devlink_param_u64_array *arr)
> +{
> +	free(arr->val);
> +	arr->val = NULL;
> +	arr->size = 0;
> +}
> +
> +static int param_value_nested_u64_attr_cb(const struct nlattr *attr, void *data)
> +{
> +	struct devlink_param_u64_array *arr = data;
> +	unsigned int len;
> +	uint64_t val;
> +	uint64_t *new_val;

iproute2 follows netdev coding style - reverse xmas tree.

other comments from claude:

Bug 1 (both cmd_dev_param_set and cmd_port_param_set): When the new and
current U64_ARRAY values are equal, param_value_u64_array_put_from_str()
returns 1 as a sentinel. The code jumps to out: but err is still 1, so
the function returns a non-zero error code to its caller even though
nothing went wrong. All other types reach goto out with err = 0 because
a prior mnlu_gen_socket_sndrcv() call succeeded. Fix: explicitly set err
= 0 before the goto.

Bug 2 (JSON output for U64_ARRAY in pr_out_param_value_print): The loop
calls print_u64(PRINT_ANY, label, ...) with the same key on every
iteration. In JSON mode this produces duplicate keys ("value": 0,
"value": 1, ...), which is invalid JSON. Needs
open_json_array()/close_json_array() wrapping the loop.

Style 1: flag_as_u8 is repurposed to select which netlink attribute to
parse for U64_ARRAY — its name is completely unrelated to this use,
making the code fragile.


Please show json output in the commit message as well.


^ permalink raw reply

* Re: [PATCH net] netfilter: nf_nat_masquerade: recalculate TCP TS offset when port is randomized
From: Florian Westphal @ 2026-07-08 15:23 UTC (permalink / raw)
  To: xietangxin
  Cc: Pablo Neira Ayuso, Phil Sutter, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, gaoxingwang, huyizhen,
	netfilter-devel, coreteam, netdev, linux-kernel, stable
In-Reply-To: <3620a5a9-9ced-4825-9bc4-6950be205749@h-partners.com>

xietangxin <xietangxin@h-partners.com> wrote:
> Thanks for your guidance. I’ve successfully fix the helper location
> as you suggested, and it works fine for local traffic.
> 
> However, I realized that I had completely overlooked the forwarding scenario
> (where SNAT acts as a middlebox gateway, e.g. Host A -> Gateway B -> Server C).
> In this gateway scenario, when random-fully is enabled, the test results show
> a massive performance degradation: the QPS drops from ~19000 down to ~10000.

I don't think the forwarding case is fixable.

Host S could be another NAT gateway, so it could be possible that
the connections originate from different physical machines and
timestamps differ due to different clocks, not per-connection
randomisation.

> Since skb->sk is NULL on the forwarding gateway, my current approach of
> updating tp->tsoffset in struct tcp_sock cannot be applied here.

Yes. I think the tp->tsoffset recalc is fine to handle local case.

For local case we do know that we're the end host and ts recalc is fine.

> To be honest, I am currently stuck on how to handle this forwarding scenario
> within the netfilter architecture without adding redundant overhead to the fast path.
> 
> Could you please give some advice on how the community would prefer to resolve this?
> For instance, should we look into extending the Conntrack NAT extension to
> track and adjust the TCP timestamps?

If we have some guarantee that internal network isn't doing any
snat at all, then yes, one could implement some TS adjustment
scheme similar to seqadj extension we already have to deal with
tcp sequence number adjustments.

We'd have to keep state and subtract the offset to get back the
right tsecr again on reverse direction.

I'm not keen to have something like this, it would breaks PAWS
as soon as the originating host is itself a nat gateway.

Is this really a problem to begin with?

^ permalink raw reply

* [PATCH net] vhost-net: fix TX stall when vhost owns virtio-net header
From: enrico.zanda @ 2026-07-08 15:22 UTC (permalink / raw)
  To: jasowangio, virtualization, mst, netdev, kuba
  Cc: kvm, linux-kernel, eperezma, nd, Enrico Zanda

From: Enrico Zanda <enrico.zanda@arm.com>

When vhost owns the virtio-net header, i.e. when
VHOST_NET_F_VIRTIO_NET_HDR is negotiated, sock_hlen is 0,
meaning that no header will be forwarded to the TAP device.

In the current vhost_net_build_xdp() implementation,
when sock_hlen == 0, the gso pointer can point at the start of the
Ethernet frame instead of a virtio-net header.
This results in a wrong interpretation of the destination MAC address
bytes as struct virtio_net_hdr fields.

This can, for some MAC addresses, trigger -EINVAL and return early
before the TX descriptor is completed, which can stall vhost-net TX.

Before 97b2409f28e0, the gso pointer was set to the zeroed padding area,
using it as a synthetic virtio-net header. Restore that behavior.

Fixes: 97b2409f28e0 ("vhost-net: reduce one userspace copy when building XDP buff")
Signed-off-by: Enrico Zanda <enrico.zanda@arm.com>
---
 drivers/vhost/net.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 77b59f49bddb..3e72b9c6af0c 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -731,10 +731,12 @@ static int vhost_net_build_xdp(struct vhost_net_virtqueue *nvq,
 		goto err;
 	}
 
-	gso = buf + pad - sock_hlen;
-
-	if (!sock_hlen)
+	if (!sock_hlen) {
 		memset(buf, 0, pad);
+		gso = buf;
+	} else {
+		gso = buf + pad - sock_hlen;
+	}
 
 	if ((gso->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
 	    vhost16_to_cpu(vq, gso->csum_start) +
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH] net: use sync wakeups for socket error reports
From: Breno Leitao @ 2026-07-08 15:25 UTC (permalink / raw)
  To: Usama Arif
  Cc: davem, edumazet, horms, kuba, kuniyu, linux-kernel, netdev,
	pabeni, willemb, shakeel.butt, hannes, riel, kernel-team
In-Reply-To: <20260708133815.3419465-1-usama.arif@linux.dev>

On Wed, Jul 08, 2026 at 06:38:15AM -0700, Usama Arif wrote:
> Measured on a 176-core EPYC 9D64 host running a Meta production
> workload, bpftrace on tracepoint:ipi:ipi_send_cpu with a kstack filter
> attributed the sock_def_error_report -> ep_poll_callback ->
> try_to_wake_up -> ttwu_queue_wakelist -> __smp_call_single_queue
> chain to 16,326 IPIs/min.

I am interested in why so many sock_def_error_report().

That's seems a lot for genuine socket errors (RST/ICMP) on a healthy
host, so I suspect these aren't errors at all?

Can you share the full stack above sock_def_error_report()?

^ permalink raw reply

* [PATCH net-next] selftests/net: Skip srv6_end_dt46_l3vpn_test::host_vpn_tests if iproute2 too old
From: Alessio Faina @ 2026-07-08 15:27 UTC (permalink / raw)
  To: netdev, linux-kselftest
  Cc: Alessio Faina, Po-Hsu Lin, Andrea Mayer, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Shuah Khan

In case iproute2 is older than version 5.14.0, released ~Sept 1, 2021,
the End.DT46 support is not available and the host_vpn_tests test contained
in the srv6_end_dt46_l3vpn_test.sh file is failing in some kernel backports.
This is the result of those tests:

################################################################################
TEST SECTION: SRv6 VPN connectivity test among hosts in the same tenant
################################################################################

    TEST: IPv6 Hosts connectivity: hs-t100-1 -> hs-t100-2 (tenant 100)  [ FAIL ]

    TEST: IPv4 Hosts connectivity: hs-t100-1 -> hs-t100-2 (tenant 100)  [ FAIL ]

    TEST: IPv6 Hosts connectivity: hs-t100-2 -> hs-t100-1 (tenant 100)  [ FAIL ]

    TEST: IPv4 Hosts connectivity: hs-t100-2 -> hs-t100-1 (tenant 100)  [ FAIL ]

    TEST: IPv6 Hosts connectivity: hs-t200-3 -> hs-t200-4 (tenant 200)  [ FAIL ]

    TEST: IPv4 Hosts connectivity: hs-t200-3 -> hs-t200-4 (tenant 200)  [ FAIL ]

    TEST: IPv6 Hosts connectivity: hs-t200-4 -> hs-t200-3 (tenant 200)  [ FAIL ]

    TEST: IPv4 Hosts connectivity: hs-t200-4 -> hs-t200-3 (tenant 200)  [ FAIL ]

To amend this, check the current running iproute2 supports the required
feature and, if not, just skip the test to avoid a failure.


Signed-off-by: Alessio Faina <alessio.faina@canonical.com>
---
 .../selftests/net/srv6_end_dt46_l3vpn_test.sh       | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh b/tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh
index a5e959a080bb..406c6a3d253e 100755
--- a/tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh
+++ b/tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh
@@ -510,12 +510,15 @@ host2gateway_tests()
 host_vpn_tests()
 {
 	log_section "SRv6 VPN connectivity test among hosts in the same tenant"
+	if ip route add help 2>&1 | grep -q -i End.DT46; then
+		check_and_log_hs_connectivity 1 2 100
+		check_and_log_hs_connectivity 2 1 100
 
-	check_and_log_hs_connectivity 1 2 100
-	check_and_log_hs_connectivity 2 1 100
-
-	check_and_log_hs_connectivity 3 4 200
-	check_and_log_hs_connectivity 4 3 200
+		check_and_log_hs_connectivity 3 4 200
+		check_and_log_hs_connectivity 4 3 200
+	else
+		echo "SKIP: SRv6 End.DT46 is unsupported by the installed iproute2 version"
+	fi
 }
 
 host_vpn_isolation_tests()
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v21 net-next 01/12] net/nebula-matrix: add minimum nbl build framework
From: Breno Leitao @ 2026-07-08 15:28 UTC (permalink / raw)
  To: illusion.wang
  Cc: dimon.zhao, alvin.wang, sam.chen, netdev, andrew+netdev, corbet,
	kuba, horms, linux-doc, pabeni, vadim.fedorenko, lukas.bulwahn,
	edumazet, enelsonmoore, skhan, hkallweit1, open list
In-Reply-To: <20260708064742.35391-2-illusion.wang@nebula-matrix.com>

On Wed, Jul 08, 2026 at 02:47:27PM +0800, illusion.wang wrote:
> From: illusion wang <illusion.wang@nebula-matrix.com>
> +Support
> +=======
> +
> +For more information about m18110-NIC/m18000-NIC, please visit the following URL:
> +https://www.nebula-matrix.com/

Do you have a link for the site in english?

Thanks

^ permalink raw reply

* Re: [PATCH V3 1/4] dmaengine: xilinx_dma: Fix MCDMA descriptor fields based on DMA direction
From: Pandey, Radhey Shyam @ 2026-07-08 15:32 UTC (permalink / raw)
  To: Srinivas Neeli, Vinod Koul, Radhey Shyam Pandey
  Cc: Frank Li, Michal Simek, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Suraj Gupta,
	Marek Vasut, Tomi Valkeinen, Alex Bereza, Folker Schwesinger,
	dmaengine, netdev, linux-arm-kernel, linux-kernel, git
In-Reply-To: <20260708100652.603074-2-srinivas.neeli@amd.com>

> The MCDMA BD format differs between memory-to-device (MM2S) and
> device-to-memory (S2MM) directions, but the driver was using generic
> 'status' and 'sideband_status' fields for both. This led to incorrect
> residue calculations when the hardware updates direction-specific fields.
> 
> Refactor the descriptor structure to use unions with direction-specific
> field mappings, and update the residue calculation logic to select the
> correct status field based on DMA direction.
> 
> This matches the hardware descriptor layout and fixes incorrect
> residue reporting.
> 
> Fixes: 6ccd692bfb7f ("dmaengine: xilinx_dma: Add Xilinx AXI MCDMA Engine driver support")
> Signed-off-by: Srinivas Neeli <srinivas.neeli@amd.com>

Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Thanks!
> ---
> Changes in V3:
>   - Renamed subject from "for MM2S vs S2MM" to "based on DMA direction".
>   - Reworded commit message for clarity.
>   - Added XILINX_MCDMA_BD_HW_SIZE macro and static_assert to verify
>     descriptor size at compile time.
>   - Refactored residue calculation to separate addition and subtraction
>     operations for better readability.
> 
> Changes in V2:
>   - No change.
> ---
>   drivers/dma/xilinx/xilinx_dma.c | 26 +++++++++++++++++++-------
>   1 file changed, 19 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index 98b41b8f8915..ff5b29a808e9 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -223,6 +223,7 @@
>   #define XILINX_MCDMA_IRQ_ERR_MASK		BIT(7)
>   #define XILINX_MCDMA_BD_EOP			BIT(30)
>   #define XILINX_MCDMA_BD_SOP			BIT(31)
> +#define XILINX_MCDMA_BD_HW_SIZE			64
>   
>   /**
>    * struct xilinx_vdma_desc_hw - Hardware Descriptor
> @@ -277,8 +278,10 @@ struct xilinx_axidma_desc_hw {
>    * @buf_addr_msb: MSB of Buffer address @0x0C
>    * @rsvd: Reserved field @0x10
>    * @control: Control Information field @0x14
> - * @status: Status field @0x18
> - * @sideband_status: Status of sideband signals @0x1C
> + * @mm2s_ctrl_sideband: Sideband control info for mm2s @0x18
> + * @s2mm_status: Status field for s2mm @0x18
> + * @mm2s_status: Status field for mm2s @0x1C
> + * @s2mm_sideband_status: Sideband status for s2mm @0x1C
>    * @app: APP Fields @0x20 - 0x30
>    */
>   struct xilinx_aximcdma_desc_hw {
> @@ -288,10 +291,17 @@ struct xilinx_aximcdma_desc_hw {
>   	u32 buf_addr_msb;
>   	u32 rsvd;
>   	u32 control;
> -	u32 status;
> -	u32 sideband_status;
> +	union {
> +		u32 mm2s_ctrl_sideband;
> +		u32 s2mm_status;
> +	};
> +	union {
> +		u32 mm2s_status;
> +		u32 s2mm_sideband_status;
> +	};
>   	u32 app[XILINX_DMA_NUM_APP_WORDS];
>   } __aligned(64);
> +static_assert(sizeof(struct xilinx_aximcdma_desc_hw) == XILINX_MCDMA_BD_HW_SIZE);
>   
>   /**
>    * struct xilinx_cdma_desc_hw - Hardware Descriptor
> @@ -1015,9 +1025,11 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan,
>   					   struct xilinx_aximcdma_tx_segment,
>   					   node);
>   			aximcdma_hw = &aximcdma_seg->hw;
> -			residue +=
> -				(aximcdma_hw->control & chan->xdev->max_buffer_len) -
> -				(aximcdma_hw->status & chan->xdev->max_buffer_len);
> +			residue += aximcdma_hw->control & chan->xdev->max_buffer_len;
> +			if (chan->direction == DMA_DEV_TO_MEM)
> +				residue -= aximcdma_hw->s2mm_status & chan->xdev->max_buffer_len;
> +			else
> +				residue -= aximcdma_hw->mm2s_status & chan->xdev->max_buffer_len;
>   		}
>   	}
>   


^ permalink raw reply

* Re: [PATCH iproute2-next] ip: add OVPN device mode support
From: David Ahern @ 2026-07-08 15:33 UTC (permalink / raw)
  To: Marco Baffo, netdev; +Cc: Stephen Hemminger, Antonio Quartulli
In-Reply-To: <20260703111419.842059-1-marco@mandelbit.com>

On 7/3/26 5:14 AM, Marco Baffo wrote:
> Allow selecting point-to-point or multi-peer mode when creating an
> OVPN device.

iproute2 does not currently support ovpn, so this patch is doing more
than just selecting a mode. It adds support to create ovpn netdevices
via iproute2. Enhance the commit message.

> 
> Signed-off-by: Marco Baffo <marco@mandelbit.com>
> ---
>  ip/Makefile           |  2 +-
>  ip/iplink.c           |  2 +-
>  ip/iplink_ovpn.c      | 87 +++++++++++++++++++++++++++++++++++++++++++
>  man/man8/ip-link.8.in | 24 ++++++++++++
>  4 files changed, 113 insertions(+), 2 deletions(-)
>  create mode 100644 ip/iplink_ovpn.c
> 
> diff --git a/ip/Makefile b/ip/Makefile
> index 3535ba78..978f6841 100644
> --- a/ip/Makefile
> +++ b/ip/Makefile
> @@ -13,7 +13,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
>      ipvrf.o iplink_xstats.o ipseg6.o iplink_netdevsim.o iplink_rmnet.o \
>      ipnexthop.o ipmptcp.o iplink_bareudp.o iplink_wwan.o ipioam6.o \
>      iplink_amt.o iplink_batadv.o iplink_gtp.o iplink_virt_wifi.o \
> -    iplink_netkit.o ipstats.o
> +    iplink_netkit.o ipstats.o iplink_ovpn.o
>  
>  RTMONOBJ=rtmon.o
>  
> diff --git a/ip/iplink.c b/ip/iplink.c
> index 3f0b46c9..c6aee8b6 100644
> --- a/ip/iplink.c
> +++ b/ip/iplink.c
> @@ -42,7 +42,7 @@ void iplink_types_usage(void)
>  		"          ifb | ip6erspan | ip6gre | ip6gretap | ip6tnl |\n"
>  		"          ipip | ipoib | ipvlan | ipvtap |\n"
>  		"          macsec | macvlan | macvtap | netdevsim |\n"
> -		"          netkit | nlmon | pfcp | rmnet | sit | team | team_slave |\n"
> +		"          netkit | nlmon | ovpn | pfcp | rmnet | sit | team | team_slave |\n"
>  		"          vcan | veth | vlan | vrf | vti | vxcan | vxlan | wwan |\n"
>  		"          xfrm | virt_wifi }\n");
>  }
> diff --git a/ip/iplink_ovpn.c b/ip/iplink_ovpn.c
> new file mode 100644
> index 00000000..08e59526
> --- /dev/null
> +++ b/ip/iplink_ovpn.c
> @@ -0,0 +1,87 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * iplink_ovpn.c	OpenVPN DCO device support
> + *
> + * Author: Marco Baffo <marco@mandelbit.com>
> + *
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <linux/if_link.h>
> +
> +#include "utils.h"
> +#include "ip_common.h"
> +
> +static void print_explain(FILE *f)
> +{
> +	fprintf(f,
> +		"Usage: ... ovpn [ mode { p2p | mp } ]\n"
> +		"\n"
> +		"MODE := p2p | mp\n"
> +		"(p2p is the default if mode is not specified)\n");
> +}
> +
> +static int ovpn_parse_opt(struct link_util *lu, int argc, char **argv,
> +			  struct nlmsghdr *n)
> +{
> +	while (argc > 0) {
> +		if (matches(*argv, "mode") == 0) {
> +			__u8 mode;
> +
> +			NEXT_ARG();
> +			if (strcmp(*argv, "p2p") == 0)
> +				mode = OVPN_MODE_P2P;
> +			else if (strcmp(*argv, "mp") == 0)
> +				mode = OVPN_MODE_MP;

the options need to be a table used for both setting and displaying value.


^ permalink raw reply

* Re: [PATCH net-next] net: ipip: use tunnel parameters for fill_forward_path route lookup
From: David Ahern @ 2026-07-08 15:34 UTC (permalink / raw)
  To: Lorenzo Bianconi, Ido Schimmel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Pablo Neira Ayuso,
	Florian Westphal
  Cc: netdev, netfilter-devel
In-Reply-To: <20260708-ipip-route-lookup-fill_forward_path-v1-1-b77df74822ed@kernel.org>

On 7/8/26 5:25 AM, Lorenzo Bianconi wrote:
> Pass source address, DSCP and output interface from the tunnel
> configuration to ip_route_output() in ipip_fill_forward_path(), aligning
> the route lookup with the slow path in ipip_tunnel_xmit().
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  net/ipv4/ipip.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
> index b643194f57d2..d1aa048a6099 100644
> --- a/net/ipv4/ipip.c
> +++ b/net/ipv4/ipip.c
> @@ -360,8 +360,9 @@ static int ipip_fill_forward_path(struct net_device_path_ctx *ctx,
>  	const struct iphdr *tiph = &tunnel->parms.iph;
>  	struct rtable *rt;
>  
> -	rt = ip_route_output(dev_net(ctx->dev), tiph->daddr, 0, 0, 0,
> -			     RT_SCOPE_UNIVERSE);
> +	rt = ip_route_output(dev_net(ctx->dev), tiph->daddr, tiph->saddr,
> +			     inet_dsfield_to_dscp(tiph->tos),
> +			     tunnel->parms.link, RT_SCOPE_UNIVERSE);
>  	if (IS_ERR(rt))
>  		return PTR_ERR(rt);
>  
> 
> ---
> base-commit: 155c68aef2397f8c5d72ef10acf48ae159bf1869
> change-id: 20260708-ipip-route-lookup-fill_forward_path-6a8a1f45084c
> 
> Best regards,

This and the ipv6 version seem correct to me. Please add test cases for
both.

^ permalink raw reply

* Re: [PATCH net-next] net: ipip: use tunnel parameters for fill_forward_path route lookup
From: Lorenzo Bianconi @ 2026-07-08 15:39 UTC (permalink / raw)
  To: David Ahern
  Cc: Ido Schimmel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Pablo Neira Ayuso, Florian Westphal,
	netdev, netfilter-devel
In-Reply-To: <9badfd3b-f9f7-49b8-9c34-980b17c22794@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 1558 bytes --]

On Jul 08, David Ahern wrote:
> On 7/8/26 5:25 AM, Lorenzo Bianconi wrote:
> > Pass source address, DSCP and output interface from the tunnel
> > configuration to ip_route_output() in ipip_fill_forward_path(), aligning
> > the route lookup with the slow path in ipip_tunnel_xmit().
> > 
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> >  net/ipv4/ipip.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
> > index b643194f57d2..d1aa048a6099 100644
> > --- a/net/ipv4/ipip.c
> > +++ b/net/ipv4/ipip.c
> > @@ -360,8 +360,9 @@ static int ipip_fill_forward_path(struct net_device_path_ctx *ctx,
> >  	const struct iphdr *tiph = &tunnel->parms.iph;
> >  	struct rtable *rt;
> >  
> > -	rt = ip_route_output(dev_net(ctx->dev), tiph->daddr, 0, 0, 0,
> > -			     RT_SCOPE_UNIVERSE);
> > +	rt = ip_route_output(dev_net(ctx->dev), tiph->daddr, tiph->saddr,
> > +			     inet_dsfield_to_dscp(tiph->tos),
> > +			     tunnel->parms.link, RT_SCOPE_UNIVERSE);
> >  	if (IS_ERR(rt))
> >  		return PTR_ERR(rt);
> >  
> > 
> > ---
> > base-commit: 155c68aef2397f8c5d72ef10acf48ae159bf1869
> > change-id: 20260708-ipip-route-lookup-fill_forward_path-6a8a1f45084c
> > 
> > Best regards,
> 
> This and the ipv6 version seem correct to me. Please add test cases for
> both.

I guess we already have selftests for them in:
https://github.com/torvalds/linux/blob/master/tools/testing/selftests/net/netfilter/nft_flowtable.sh#L584

Regards,
Lorenzo


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH net-next] net: ip6_tunnel: use tunnel parameters for fill_forward_path route lookup
From: David Ahern @ 2026-07-08 15:42 UTC (permalink / raw)
  To: Lorenzo Bianconi, Ido Schimmel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Pablo Neira Ayuso,
	Florian Westphal
  Cc: netdev, netfilter-devel
In-Reply-To: <20260708-ip6ip6-route-lookup-fill_forward_path-v1-1-863b9647102e@kernel.org>

On 7/8/26 6:48 AM, Lorenzo Bianconi wrote:
> Pass source address, output interface and flowlabel (carrying TClass
> and flow label) from the tunnel configuration to the flowi6 struct in
> ip6_tnl_fill_forward_path(), aligning the route lookup with the slow
> path in ipxip6_tnl_xmit().
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  net/ipv6/ip6_tunnel.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
> index bf8e40af60b0..557d8637ac57 100644
> --- a/net/ipv6/ip6_tunnel.c
> +++ b/net/ipv6/ip6_tunnel.c
> @@ -1847,6 +1847,10 @@ static int ip6_tnl_fill_forward_path(struct net_device_path_ctx *ctx,
>  	struct ip6_tnl *t = netdev_priv(ctx->dev);
>  	struct flowi6 fl6 = {
>  		.daddr = t->parms.raddr,
> +		.saddr = t->parms.laddr,
> +		.flowi6_oif = t->parms.link,
> +		.flowlabel = t->parms.flowinfo &
> +			     (IPV6_TCLASS_MASK | IPV6_FLOWLABEL_MASK),
>  	};
>  	struct dst_entry *dst;
>  	int err;
> 
> ---
> base-commit: 08030ddb87b4c6c6a2c03c82731b5e188f02f5b9
> change-id: 20260708-ip6ip6-route-lookup-fill_forward_path-9fc45a9118e9
> 
> Best regards,

Reviewed-by: David Ahern <dsahern@kernel.org>


^ permalink raw reply

* Re: [PATCH net-next] net: ipip: use tunnel parameters for fill_forward_path route lookup
From: David Ahern @ 2026-07-08 15:42 UTC (permalink / raw)
  To: Lorenzo Bianconi, Ido Schimmel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Pablo Neira Ayuso,
	Florian Westphal
  Cc: netdev, netfilter-devel
In-Reply-To: <20260708-ipip-route-lookup-fill_forward_path-v1-1-b77df74822ed@kernel.org>

On 7/8/26 5:25 AM, Lorenzo Bianconi wrote:
> Pass source address, DSCP and output interface from the tunnel
> configuration to ip_route_output() in ipip_fill_forward_path(), aligning
> the route lookup with the slow path in ipip_tunnel_xmit().
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  net/ipv4/ipip.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
> index b643194f57d2..d1aa048a6099 100644
> --- a/net/ipv4/ipip.c
> +++ b/net/ipv4/ipip.c
> @@ -360,8 +360,9 @@ static int ipip_fill_forward_path(struct net_device_path_ctx *ctx,
>  	const struct iphdr *tiph = &tunnel->parms.iph;
>  	struct rtable *rt;
>  
> -	rt = ip_route_output(dev_net(ctx->dev), tiph->daddr, 0, 0, 0,
> -			     RT_SCOPE_UNIVERSE);
> +	rt = ip_route_output(dev_net(ctx->dev), tiph->daddr, tiph->saddr,
> +			     inet_dsfield_to_dscp(tiph->tos),
> +			     tunnel->parms.link, RT_SCOPE_UNIVERSE);
>  	if (IS_ERR(rt))
>  		return PTR_ERR(rt);
>  
> 
> ---
> base-commit: 155c68aef2397f8c5d72ef10acf48ae159bf1869
> change-id: 20260708-ipip-route-lookup-fill_forward_path-6a8a1f45084c
> 
> Best regards,

Reviewed-by: David Ahern <dsahern@kernel.org>


^ permalink raw reply

* [PATCH 0/2] Bring includes in linux/kmod.h up to date
From: Petr Pavlu @ 2026-07-08 15:44 UTC (permalink / raw)
  To: Tony Luck, Borislav Petkov, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, x86, H. Peter Anvin, Philipp Reisner, Lars Ellenberg,
	Christoph Böhmwalder, Jens Axboe, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Rafael J. Wysocki, Michal Januszewski,
	Helge Deller, Alexander Viro, Christian Brauner, Jan Kara,
	Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
	NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey, Mark Fasheh,
	Joel Becker, Joseph Qi, Tejun Heo, Johannes Weiner,
	Michal Koutný, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Pavel Machek, Len Brown,
	Andrew Morton, Danilo Krummrich, Nikolay Aleksandrov,
	Ido Schimmel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, David Howells, Jarkko Sakkinen,
	Paul Moore, James Morris, Serge E. Hallyn, Kentaro Takeda,
	Tetsuo Handa
  Cc: linux-edac, linux-kernel, drbd-dev, linux-block, greybus-dev,
	linuxppc-dev, linux-acpi, linux-fbdev, dri-devel, linux-fsdevel,
	linux-nfs, ocfs2-devel, cgroups, linux-modules, linux-pm,
	driver-core, bridge, netdev, keyrings, linux-security-module

The usermode helper declarations were previously provided by linux/kmod.h
but commit c1f3fa2a4fde ("kmod: split off umh headers into its own file")
moved them to linux/umh.h in 2017. Add explicit includes of linux/umh.h to
files that use usermode helpers and remove linux/kmod.h where it is no
longer needed.

Then clean up linux/kmod.h so that it includes only the headers that it
actually requires, importantly removing the compat linux/umh.h include.

Apologies for the wide distribution.

This cleanup is motivated by trying to reduce the preprocessed size of
linux/module.h, which includes linux/kmod.h. The linux/module.h header is
included by every *.mod.c file to provide `struct module` and other related
definitions, so it should avoid pulling in unnecessary dependencies. Note
that this series doesn't immediately improve the situation, since most of
the files included by linux/kmod.h are, for now, also included by
linux/module.h through other paths.

Petr Pavlu (2):
  umh, treewide: Explicitly include linux/umh.h where needed
  module: Bring includes in linux/kmod.h up to date

 arch/x86/kernel/cpu/mce/dev-mcelog.c |  2 +-
 drivers/block/drbd/drbd_nl.c         |  1 +
 drivers/greybus/svc_watchdog.c       |  1 +
 drivers/macintosh/windfarm_core.c    |  1 +
 drivers/pnp/pnpbios/core.c           |  2 +-
 drivers/video/fbdev/uvesafb.c        |  1 +
 fs/coredump.c                        |  2 +-
 fs/nfs/cache_lib.c                   |  2 +-
 fs/nfsd/nfs4layouts.c                |  2 +-
 fs/nfsd/nfs4recover.c                |  1 +
 fs/ocfs2/stackglue.c                 |  1 +
 include/linux/kmod.h                 | 12 ++----------
 kernel/cgroup/cgroup-v1.c            |  1 +
 kernel/module/kmod.c                 |  1 +
 kernel/power/process.c               |  2 +-
 kernel/reboot.c                      |  2 +-
 kernel/umh.c                         |  2 +-
 lib/kobject_uevent.c                 |  2 +-
 net/bridge/br_stp_if.c               |  2 +-
 security/keys/request_key.c          |  2 +-
 security/tomoyo/common.h             |  2 +-
 21 files changed, 22 insertions(+), 22 deletions(-)


base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
-- 
2.54.0


^ permalink raw reply

* [PATCH 1/2] umh, treewide: Explicitly include linux/umh.h where needed
From: Petr Pavlu @ 2026-07-08 15:44 UTC (permalink / raw)
  To: Tony Luck, Borislav Petkov, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, x86, H. Peter Anvin, Philipp Reisner, Lars Ellenberg,
	Christoph Böhmwalder, Jens Axboe, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Rafael J. Wysocki, Michal Januszewski,
	Helge Deller, Alexander Viro, Christian Brauner, Jan Kara,
	Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
	NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey, Mark Fasheh,
	Joel Becker, Joseph Qi, Tejun Heo, Johannes Weiner,
	Michal Koutný, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Pavel Machek, Len Brown,
	Andrew Morton, Danilo Krummrich, Nikolay Aleksandrov,
	Ido Schimmel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, David Howells, Jarkko Sakkinen,
	Paul Moore, James Morris, Serge E. Hallyn, Kentaro Takeda,
	Tetsuo Handa
  Cc: linux-edac, linux-kernel, drbd-dev, linux-block, greybus-dev,
	linuxppc-dev, linux-acpi, linux-fbdev, dri-devel, linux-fsdevel,
	linux-nfs, ocfs2-devel, cgroups, linux-modules, linux-pm,
	driver-core, bridge, netdev, keyrings, linux-security-module
In-Reply-To: <20260708154510.6794-1-petr.pavlu@suse.com>

The usermode helper declarations were previously provided by linux/kmod.h
but commit c1f3fa2a4fde ("kmod: split off umh headers into its own file")
moved them to linux/umh.h in 2017. Add explicit includes of linux/umh.h to
files that use usermode helpers and remove linux/kmod.h where it is no
longer needed.

Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
 arch/x86/kernel/cpu/mce/dev-mcelog.c | 2 +-
 drivers/block/drbd/drbd_nl.c         | 1 +
 drivers/greybus/svc_watchdog.c       | 1 +
 drivers/macintosh/windfarm_core.c    | 1 +
 drivers/pnp/pnpbios/core.c           | 2 +-
 drivers/video/fbdev/uvesafb.c        | 1 +
 fs/coredump.c                        | 2 +-
 fs/nfs/cache_lib.c                   | 2 +-
 fs/nfsd/nfs4layouts.c                | 2 +-
 fs/nfsd/nfs4recover.c                | 1 +
 fs/ocfs2/stackglue.c                 | 1 +
 kernel/cgroup/cgroup-v1.c            | 1 +
 kernel/module/kmod.c                 | 1 +
 kernel/power/process.c               | 2 +-
 kernel/reboot.c                      | 2 +-
 kernel/umh.c                         | 2 +-
 lib/kobject_uevent.c                 | 2 +-
 net/bridge/br_stp_if.c               | 2 +-
 security/keys/request_key.c          | 2 +-
 security/tomoyo/common.h             | 2 +-
 20 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kernel/cpu/mce/dev-mcelog.c b/arch/x86/kernel/cpu/mce/dev-mcelog.c
index 053555206d81..af4e76babe7a 100644
--- a/arch/x86/kernel/cpu/mce/dev-mcelog.c
+++ b/arch/x86/kernel/cpu/mce/dev-mcelog.c
@@ -11,7 +11,7 @@
 
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/poll.h>
 
 #include "internal.h"
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index f9ffcd67607b..de90cf4a0789 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
 
 #include <linux/module.h>
+#include <linux/umh.h>
 #include <linux/drbd.h>
 #include <linux/in.h>
 #include <linux/fs.h>
diff --git a/drivers/greybus/svc_watchdog.c b/drivers/greybus/svc_watchdog.c
index 16e6de5e9eff..b318eb34bcca 100644
--- a/drivers/greybus/svc_watchdog.c
+++ b/drivers/greybus/svc_watchdog.c
@@ -7,6 +7,7 @@
 
 #include <linux/delay.h>
 #include <linux/suspend.h>
+#include <linux/umh.h>
 #include <linux/workqueue.h>
 #include <linux/greybus.h>
 
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 5307b1e34261..e66de11c69a3 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -34,6 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
+#include <linux/umh.h>
 
 #include "windfarm.h"
 
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index f7e86ae9f72f..46af1f549337 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -47,7 +47,7 @@
 #include <linux/delay.h>
 #include <linux/acpi.h>
 #include <linux/freezer.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/kthread.h>
 
 #include <asm/page.h>
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 9d82326c744f..6c503e6914d6 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/umh.h>
 #include <video/edid.h>
 #include <video/uvesafb.h>
 #ifdef CONFIG_X86
diff --git a/fs/coredump.c b/fs/coredump.c
index e68a76ff92a3..4908b44f6fdc 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -32,7 +32,7 @@
 #include <linux/tsacct_kern.h>
 #include <linux/cn_proc.h>
 #include <linux/audit.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/fsnotify.h>
 #include <linux/fs_struct.h>
 #include <linux/pipe_fs_i.h>
diff --git a/fs/nfs/cache_lib.c b/fs/nfs/cache_lib.c
index 9738a1ae92ca..ca4e81d4e315 100644
--- a/fs/nfs/cache_lib.c
+++ b/fs/nfs/cache_lib.c
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 2009 Trond Myklebust <Trond.Myklebust@netapp.com>
  */
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/mount.h>
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index f34320e4c2f4..008f0f088c3a 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2014 Christoph Hellwig.
  */
 #include <linux/exportfs_block.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/file.h>
 #include <linux/jhash.h>
 #include <linux/sched.h>
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 6ea25a52d2f4..20b98e43f668 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -41,6 +41,7 @@
 #include <linux/fs.h>
 #include <linux/hex.h>
 #include <linux/module.h>
+#include <linux/umh.h>
 #include <net/net_namespace.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/sunrpc/clnt.h>
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
index 741d6191d871..0ccaab29426d 100644
--- a/fs/ocfs2/stackglue.c
+++ b/fs/ocfs2/stackglue.c
@@ -18,6 +18,7 @@
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
 #include <linux/sysctl.h>
+#include <linux/umh.h>
 
 #include "ocfs2_fs.h"
 
diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c
index a4337c9b5287..60eb994c32ae 100644
--- a/kernel/cgroup/cgroup-v1.c
+++ b/kernel/cgroup/cgroup-v1.c
@@ -16,6 +16,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/cgroupstats.h>
 #include <linux/fs_parser.h>
+#include <linux/umh.h>
 
 #include <trace/events/cgroup.h>
 
diff --git a/kernel/module/kmod.c b/kernel/module/kmod.c
index a25dccdf7aa7..dcaad5d65275 100644
--- a/kernel/module/kmod.c
+++ b/kernel/module/kmod.c
@@ -28,6 +28,7 @@
 #include <linux/ptrace.h>
 #include <linux/async.h>
 #include <linux/uaccess.h>
+#include <linux/umh.h>
 
 #include <trace/events/module.h>
 #include "internal.h"
diff --git a/kernel/power/process.c b/kernel/power/process.c
index dc0dfc349f22..295904ec9a82 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -16,7 +16,7 @@
 #include <linux/freezer.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <trace/events/power.h>
 #include <linux/cpuset.h>
 
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 695c33e75efd..3d4a262973e7 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -11,13 +11,13 @@
 #include <linux/ctype.h>
 #include <linux/export.h>
 #include <linux/kexec.h>
-#include <linux/kmod.h>
 #include <linux/kmsg_dump.h>
 #include <linux/reboot.h>
 #include <linux/suspend.h>
 #include <linux/syscalls.h>
 #include <linux/syscore_ops.h>
 #include <linux/uaccess.h>
+#include <linux/umh.h>
 
 /*
  * this indicates whether you can reboot with ctrl-alt-del: the default is yes
diff --git a/kernel/umh.c b/kernel/umh.c
index 48117c569e1a..72b2d9a878aa 100644
--- a/kernel/umh.c
+++ b/kernel/umh.c
@@ -8,7 +8,7 @@
 #include <linux/binfmts.h>
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/cred.h>
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index ddbc4d7482d2..a67129e452a3 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -17,7 +17,7 @@
 #include <linux/string.h>
 #include <linux/kobject.h>
 #include <linux/export.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/slab.h>
 #include <linux/socket.h>
 #include <linux/skbuff.h>
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index a7e5422eb5d1..89bc161a4b47 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -8,7 +8,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <net/switchdev.h>
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index fa2bb9f2f538..e6ba2d054399 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -9,7 +9,7 @@
 
 #include <linux/export.h>
 #include <linux/sched.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/err.h>
 #include <linux/keyctl.h>
 #include <linux/slab.h>
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index d098cf8aae61..d26034000913 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -16,7 +16,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/file.h>
-#include <linux/kmod.h>
+#include <linux/umh.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/namei.h>
-- 
2.54.0


^ permalink raw reply related

* [PATCH 2/2] module: Bring includes in linux/kmod.h up to date
From: Petr Pavlu @ 2026-07-08 15:44 UTC (permalink / raw)
  To: Tony Luck, Borislav Petkov, Thomas Gleixner, Ingo Molnar,
	Dave Hansen, x86, H. Peter Anvin, Philipp Reisner, Lars Ellenberg,
	Christoph Böhmwalder, Jens Axboe, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Rafael J. Wysocki, Michal Januszewski,
	Helge Deller, Alexander Viro, Christian Brauner, Jan Kara,
	Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
	NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey, Mark Fasheh,
	Joel Becker, Joseph Qi, Tejun Heo, Johannes Weiner,
	Michal Koutný, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
	Sami Tolvanen, Aaron Tomlin, Pavel Machek, Len Brown,
	Andrew Morton, Danilo Krummrich, Nikolay Aleksandrov,
	Ido Schimmel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, David Howells, Jarkko Sakkinen,
	Paul Moore, James Morris, Serge E. Hallyn, Kentaro Takeda,
	Tetsuo Handa
  Cc: linux-edac, linux-kernel, drbd-dev, linux-block, greybus-dev,
	linuxppc-dev, linux-acpi, linux-fbdev, dri-devel, linux-fsdevel,
	linux-nfs, ocfs2-devel, cgroups, linux-modules, linux-pm,
	driver-core, bridge, netdev, keyrings, linux-security-module
In-Reply-To: <20260708154510.6794-1-petr.pavlu@suse.com>

Including linux/kmod.h alone results in 1.5 MB of preprocessed output, even
though it provides only a few functions and macros.

The header currently depends on:

* __printf() -> linux/compiler_attributes.h,
* ENOSYS -> linux/errno.h,
* bool -> linux/types.h.

Include only these files, reducing the preprocessed output to 10 kB.

Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
 include/linux/kmod.h | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 9a07c3215389..b9474a62a568 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -2,17 +2,9 @@
 #ifndef __LINUX_KMOD_H__
 #define __LINUX_KMOD_H__
 
-/*
- *	include/linux/kmod.h
- */
-
-#include <linux/umh.h>
-#include <linux/gfp.h>
-#include <linux/stddef.h>
+#include <linux/compiler_attributes.h>
 #include <linux/errno.h>
-#include <linux/compiler.h>
-#include <linux/workqueue.h>
-#include <linux/sysctl.h>
+#include <linux/types.h>
 
 #ifdef CONFIG_MODULES
 /* modprobe exit status on success, -ve on error.  Return value
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH net-next v11 7/7] selftests: netconsole: validate target resume
From: Matthieu Baerts @ 2026-07-08 15:50 UTC (permalink / raw)
  To: Andre Carvalho, Breno Leitao
  Cc: netdev, linux-kernel, linux-kselftest, Andrew Lunn,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Shuah Khan, Simon Horman
In-Reply-To: <20260118-netcons-retrigger-v11-7-4de36aebcf48@gmail.com>

Hi Andre, Breno,

On 18/01/2026 12:00, Andre Carvalho wrote:
> Introduce a new netconsole selftest to validate that netconsole is able
> to resume a deactivated target when the low level interface comes back.
> 
> The test setups the network using netdevsim, creates a netconsole target
> and then remove/add netdevsim in order to bring the same interfaces
> back. Afterwards, the test validates that the target works as expected.
> 
> Targets are created via cmdline parameters to the module to ensure that
> we are able to resume targets that were bound by mac and interface name.

I'm sorry to react on this "old" patch, but I have some troubles running
this netcons_resume.sh test in a new environment with containers.

> diff --git a/tools/testing/selftests/drivers/net/netcons_resume.sh b/tools/testing/selftests/drivers/net/netcons_resume.sh
> new file mode 100755
> index 000000000000..fc5e5e3ad3d4
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/net/netcons_resume.sh

(...)

> +function trigger_reactivation() {
> +	# Add back low level module
> +	modprobe netdevsim
> +	# Recreate namespace and two interfaces
> +	set_network
> +	# Restore MACs
> +	ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" \
> +		address "${SAVED_DSTMAC}"
> +	if [ "${BINDMODE}" == "mac" ]; then
> +		ip link set dev "${SRCIF}" down
> +		ip link set dev "${SRCIF}" address "${SAVED_SRCMAC}"
> +		# Rename device in order to trigger target resume, as initial
> +		# when device was recreated it didn't have correct mac address.
> +		ip link set dev "${SRCIF}" name "${TARGET}"

When I execute the test, the "ifname" bind mode works without issues,
but the "mac" one not. From what I see, the socat process doesn't get
any UDP packet when expected. I wonder if the problem might not come
from here: the interface is disabled before changing the MAC address and
renaming the interface, but not re-enabled at the end. Is it normal?

If I add 'up' at the end of this last line here, or if I remove the
whole if-statement block, the test passes.

In the console, I can see these messages, with or without re-enabling
the interface:

  netdevsim netdevsim642 eni642np1: renamed from eth0
  netdevsim netdevsim387 eni387np1: renamed from eth1
  netconsole: netconsole: local port 1514
  netconsole: netconsole: local IPv4 address 192.0.2.1
  netconsole: netconsole: interface name ''
  netconsole: netconsole: local ethernet address '1e:95:b7:ae:ab:dc'
  netconsole: netconsole: remote port 6666
  netconsole: netconsole: remote IPv4 address 192.0.2.2
  netconsole: netconsole: remote ethernet address e6:12:42:f8:4c:b2
  printk: console [netcon_ext0] enabled
  netconsole: network logging started
  netconsole: network logging stopped on interface eni387np1 as it
unregistered
  netdevsim netdevsim642 eni642np1: renamed from eth0
  netdevsim netdevsim387 eni387np1: renamed from eth1
  netconsole: Process resuming  (mac: 1e:95:b7:ae:ab:dc), s:2, r:-1
  netpoll: netconsole: device 1e:95:b7:ae:ab:dc not up yet, forcing it
  netconsole: network logging resumed on interface eni387np1
  netdevsim netdevsim387 netcons_LFLQP: renamed from eni387np1
  netconsole selftest: netcons_LFLQP

The "network logging resumed on interface" seems to suggest that the
previous patch of this series here, commit 220dbe3c76ed ("netconsole:
resume previously deactivated target"), managed to resume the previously
activated target, but not in my case.

What I don't understand is why is it working on the Netdev CI, and not
on my side. The main difference is that I might be missing some
userspace packages -- but I don't see what can be missing here, all
other netconsole tests pass -- a specific kernel config, or not applied
patch. Or something different on the host -- in a container on my side
-- but there shouldn't be any interactions with the host here,
everything is happening in the VM. Any ideas? :)

> +	fi
> +}
> +
> +function trigger_deactivation() {
> +	# Start by storing mac addresses so we can be restored in reactivate
> +	SAVED_DSTMAC=$(ip netns exec "${NAMESPACE}" \
> +		cat /sys/class/net/"$DSTIF"/address)
> +	SAVED_SRCMAC=$(mac_get "${SRCIF}")
> +	# Remove low level module
> +	rmmod netdevsim
> +}
> +
> +trap cleanup EXIT
> +
> +# Run the test twice, with different cmdline parameters
> +for BINDMODE in "ifname" "mac"
> +do
> +	echo "Running with bind mode: ${BINDMODE}" >&2
> +	# Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5)
> +	echo "6 5" > /proc/sys/kernel/printk

Can we remove this? Without that, it is hard to understand what went
wrong in case of issues.

> +
> +	# Create one namespace and two interfaces
> +	set_network
> +
> +	# Create the command line for netconsole, with the configuration from
> +	# the function above
> +	CMDLINE=$(create_cmdline_str "${BINDMODE}")
> +
> +	# The content of kmsg will be save to the following file
> +	OUTPUT_FILE="/tmp/${TARGET}-${BINDMODE}"
> +
> +	# Load the module, with the cmdline set
> +	modprobe netconsole "${CMDLINE}"
> +	# Expose cmdline target in configfs
> +	mkdir "${NETCONS_CONFIGFS}/cmdline0"
> +
> +	# Target should be enabled
> +	wait_target_state "cmdline0" "enabled"
> +
> +	# Trigger deactivation by unloading netdevsim module. Target should be
> +	# disabled.
> +	trigger_deactivation
> +	wait_target_state "cmdline0" "disabled"
> +
> +	# Trigger reactivation by loading netdevsim, recreating the network and
> +	# restoring mac addresses. Target should be re-enabled.
> +	trigger_reactivation
> +	wait_target_state "cmdline0" "enabled"
> +
> +	# Listen for netconsole port inside the namespace and destination
> +	# interface
> +	listen_port_and_save_to "${OUTPUT_FILE}" &
> +	# Wait for socat to start and listen to the port.
> +	wait_local_port_listen "${NAMESPACE}" "${PORT}" udp
> +	# Send the message
> +	echo "${MSG}: ${TARGET}" > /dev/kmsg
> +	# Wait until socat saves the file to disk
> +	busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}"

In my case, the script was stopping here, without any message. I can
send a patch adding "|| true" to go to the next instruction, and display
"FAIL: File was not generated.".

> +	# Make sure the message was received in the dst part
> +	# and exit
> +	validate_msg "${OUTPUT_FILE}"
> +
> +	# kill socat in case it is still running
> +	pkill_socat
> +	# Cleanup & unload the module
> +	cleanup
> +
> +	echo "${BINDMODE} : Test passed" >&2
> +done
> +
> +trap - EXIT
> +exit "${EXIT_STATUS}"
> 

Cheers,
Matt

^ permalink raw reply

* Re: [PATCH nf] ipvs: make destination flags atomic
From: Julian Anastasov @ 2026-07-08 15:53 UTC (permalink / raw)
  To: Yizhou Zhao
  Cc: Simon Horman, David Ahern, Ido Schimmel, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Pablo Neira Ayuso,
	Florian Westphal, Phil Sutter, Alexander Frolkin, netdev,
	lvs-devel, linux-kernel, netfilter-devel, coreteam, stable,
	Yuxiang Yang, Ao Wang, Xuewei Feng, Qi Li, Ke Xu
In-Reply-To: <91509A0C-9E4A-4F0E-A45C-ABD29396067E@mails.tsinghua.edu.cn>


	Hello,

On Wed, 8 Jul 2026, Yizhou Zhao wrote:

> > On Jul 8, 2026, at 03:18, Julian Anastasov <ja@ssi.bg> wrote:
> > 
> > On Tue, 7 Jul 2026, Yizhou Zhao wrote:
> > 
> 
> We have posted a v2 patch at:
> https://lore.kernel.org/netfilter-devel/20260708060454.20534-1-zhaoyz24@mails.tsinghua.edu.cn/
> 
> The v2 patch updates the commit message with more conservative
> wording, and fixes the checkpatch logical-continuation warnings.

	After looking again at the code, I think we can
do it in different way:

- IP_VS_DEST_F_AVAILABLE and IP_VS_DEST_F_OVERLOAD are defined
in include/uapi/linux/ip_vs.h but we never export them to user
space. So, we are free to change them. We can move them to 
include/net/ip_vs.h, see below...

- IP_VS_DEST_F_AVAILABLE is changed only under service_mutex,
so we can keep its usage

- IP_VS_DEST_F_OVERLOAD needs different access methods.
We can add 'unsigned long flags2;', may be after l_threshold.
And to switch to such usage (F_OVERLOAD -> FL_OVERLOAD):

	- test_bit(IP_VS_DEST_FL_OVERLOAD, &dest->flags2)
	- set_bit(IP_VS_DEST_FL_OVERLOAD, &dest->flags2)

		Sometimes if (test_bit()) clear_bit() can avoid
		full memory barrier in ip_vs_dest_update_overload()

	- clear_bit(IP_VS_DEST_FL_OVERLOAD, &dest->flags2)
		test_bit() guard can help here too

	As there are other races involved, something like
this can be a starting point for such change. It tries harder
to update the overload flag on dest edit/add but it does not
include the proposed bitops:

diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 49297fec448a..b34631270e24 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -1906,6 +1906,8 @@ static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest)
 		kfree(dest);
 }
 
+void ip_vs_dest_update_overload(struct ip_vs_dest *dest);
+
 /* IPVS sync daemon data and function prototypes
  * (from ip_vs_sync.c)
  */
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index d19caf66afeb..3fd221996e6e 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1087,6 +1087,26 @@ static inline int ip_vs_dest_totalconns(struct ip_vs_dest *dest)
 		+ atomic_read(&dest->inactconns);
 }
 
+__always_inline void ip_vs_dest_update_overload(struct ip_vs_dest *dest)
+{
+	int conns, l, u;
+
+	u = READ_ONCE(dest->u_threshold);
+	if (!u)
+		goto unset;
+	conns = ip_vs_dest_totalconns(dest);
+	if (conns >= u) {
+		dest->flags |= IP_VS_DEST_F_OVERLOAD;
+		return;
+	}
+	l = READ_ONCE(dest->l_threshold) ? : (u * 3 / 4);
+	if (conns >= l && l)
+		return;
+
+unset:
+	dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
+}
+
 /*
  *	Bind a connection entry with a virtual service destination
  *	Called just after a new connection entry is created.
@@ -1161,9 +1181,7 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
 		atomic_inc(&dest->persistconns);
 	}
 
-	if (dest->u_threshold != 0 &&
-	    ip_vs_dest_totalconns(dest) >= dest->u_threshold)
-		dest->flags |= IP_VS_DEST_F_OVERLOAD;
+	ip_vs_dest_update_overload(dest);
 }
 
 
@@ -1257,16 +1275,8 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
 		atomic_dec(&dest->persistconns);
 	}
 
-	if (dest->l_threshold != 0) {
-		if (ip_vs_dest_totalconns(dest) < dest->l_threshold)
-			dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
-	} else if (dest->u_threshold != 0) {
-		if (ip_vs_dest_totalconns(dest) * 4 < dest->u_threshold * 3)
-			dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
-	} else {
-		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
-			dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
-	}
+	if (dest->flags & IP_VS_DEST_F_OVERLOAD)
+		ip_vs_dest_update_overload(dest);
 
 	ip_vs_dest_put(dest);
 }
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index bcf40b8c41cf..2871116e46ec 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1315,6 +1315,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
 	struct ip_vs_service *old_svc;
 	struct ip_vs_scheduler *sched;
 	int conn_flags;
+	bool upd_thresh;
 
 	/* We cannot modify an address and change the address family */
 	BUG_ON(!add && udest->af != dest->af);
@@ -1370,10 +1371,12 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
 	/* set the dest status flags */
 	dest->flags |= IP_VS_DEST_F_AVAILABLE;
 
-	if (udest->u_threshold == 0 || udest->u_threshold > dest->u_threshold)
-		dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
-	dest->u_threshold = udest->u_threshold;
-	dest->l_threshold = udest->l_threshold;
+	upd_thresh = READ_ONCE(dest->u_threshold) != udest->u_threshold ||
+		     READ_ONCE(dest->l_threshold) != udest->l_threshold;
+	WRITE_ONCE(dest->u_threshold, udest->u_threshold);
+	WRITE_ONCE(dest->l_threshold, udest->l_threshold);
+	if (upd_thresh)
+		ip_vs_dest_update_overload(dest);
 
 	dest->af = udest->af;
 
@@ -3667,8 +3670,8 @@ __ip_vs_get_dest_entries(struct netns_ipvs *ipvs, const struct ip_vs_get_dests *
 			entry.port = dest->port;
 			entry.conn_flags = atomic_read(&dest->conn_flags);
 			entry.weight = atomic_read(&dest->weight);
-			entry.u_threshold = dest->u_threshold;
-			entry.l_threshold = dest->l_threshold;
+			entry.u_threshold = READ_ONCE(dest->u_threshold);
+			entry.l_threshold = READ_ONCE(dest->l_threshold);
 			entry.activeconns = atomic_read(&dest->activeconns);
 			entry.inactconns = atomic_read(&dest->inactconns);
 			entry.persistconns = atomic_read(&dest->persistconns);
@@ -4277,8 +4280,10 @@ static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest)
 			 dest->tun_port) ||
 	    nla_put_u16(skb, IPVS_DEST_ATTR_TUN_FLAGS,
 			dest->tun_flags) ||
-	    nla_put_u32(skb, IPVS_DEST_ATTR_U_THRESH, dest->u_threshold) ||
-	    nla_put_u32(skb, IPVS_DEST_ATTR_L_THRESH, dest->l_threshold) ||
+	    nla_put_u32(skb, IPVS_DEST_ATTR_U_THRESH,
+			READ_ONCE(dest->u_threshold)) ||
+	    nla_put_u32(skb, IPVS_DEST_ATTR_L_THRESH,
+			READ_ONCE(dest->l_threshold)) ||
 	    nla_put_u32(skb, IPVS_DEST_ATTR_ACTIVE_CONNS,
 			atomic_read(&dest->activeconns)) ||
 	    nla_put_u32(skb, IPVS_DEST_ATTR_INACT_CONNS,

Regards

--
Julian Anastasov <ja@ssi.bg>


^ permalink raw reply related


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