Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v2 2/2] pinctrl: qcom: add the TLMM driver for the Nord platforms
From: Konrad Dybcio @ 2026-04-27 14:33 UTC (permalink / raw)
  To: Bartosz Golaszewski, Bjorn Andersson, Linus Walleij, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
	Bartosz Golaszewski, Shawn Guo, Arnd Bergmann, Dmitry Baryshkov
  Cc: linux-arm-msm, linux-gpio, devicetree, linux-kernel, netdev
In-Reply-To: <20260427-nord-tlmm-v2-2-ade8e0f3d803@oss.qualcomm.com>

On 4/27/26 4:00 PM, Bartosz Golaszewski wrote:
> Add support for the TLMM controller on the Qualcomm Nord platform.
> 
> Co-developed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
> Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> ---

[...]

> +	[177] = PINGROUP(177, ccu_async_in1, atest_char0, _, _, _, _, _, _, _, _, _),
> +	[178] = PINGROUP(178, ccu_async_in2, atest_char1, _, _, _, _, _, _, _, _, _),
> +	[179] = PINGROUP(179, ccu_async_in3, atest_char2, _, _, _, _, _, _, _, _, _),
> +	[180] = PINGROUP(180, ccu_async_in4, atest_char3, _, _, _, _, _, _, _, _, _),
> +	[181] = UFS_RESET(ufs_reset, 0xBD004),

lowercase hex, please

You'll also need to alter the macro definition - the CTL reg is where
you suggest, but the IO reg is at +0xbe000

Konrad

^ permalink raw reply

* RE: [PATCH iwl-net v7 3/3] ice: add dpll peer notification for paired SMA and U.FL pins
From: Loktionov, Aleksandr @ 2026-04-27 14:33 UTC (permalink / raw)
  To: Oros, Petr, netdev@vger.kernel.org
  Cc: Oros, Petr, Nguyen, Anthony L, Kitszel, Przemyslaw, Andrew Lunn,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Kubalewski, Arkadiusz, Jiri Pirko, Vadim Fedorenko,
	Vecera, Ivan, Schmidt, Michal, Keller, Jacob E, Rinitha, SX,
	intel-wired-lan@lists.osuosl.org, linux-kernel@vger.kernel.org
In-Reply-To: <20260417145907.696307-4-poros@redhat.com>



> -----Original Message-----
> From: Petr Oros <poros@redhat.com>
> Sent: Friday, April 17, 2026 4:59 PM
> To: netdev@vger.kernel.org
> Cc: Oros, Petr <poros@redhat.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>;
> David S. Miller <davem@davemloft.net>; Eric Dumazet
> <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo Abeni
> <pabeni@redhat.com>; Simon Horman <horms@kernel.org>; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; Jiri Pirko
> <jiri@resnulli.us>; Vadim Fedorenko <vadim.fedorenko@linux.dev>;
> Vecera, Ivan <ivecera@redhat.com>; Schmidt, Michal
> <mschmidt@redhat.com>; Keller, Jacob E <jacob.e.keller@intel.com>;
> Loktionov, Aleksandr <aleksandr.loktionov@intel.com>; Rinitha, SX
> <sx.rinitha@intel.com>; intel-wired-lan@lists.osuosl.org; linux-
> kernel@vger.kernel.org
> Subject: [PATCH iwl-net v7 3/3] ice: add dpll peer notification for
> paired SMA and U.FL pins
> 
> SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
> SMA2/U.FL2).  When one pin's state changes via a PCA9575 GPIO write,
> the paired pin's state also changes, but no notification is sent for
> the peer pin.  Userspace consumers monitoring the peer via dpll
> netlink subscribe never learn about the update.
> 
> Add ice_dpll_sw_pin_notify_peer() which sends a change notification
> for the paired SW pin.  Call it from ice_dpll_pin_sma_direction_set(),
> ice_dpll_sma_pin_state_set(), and ice_dpll_ufl_pin_state_set() after
> pf->dplls.lock is released.  Use __dpll_pin_change_ntf() because
> dpll_lock is still held by the dpll netlink layer (dpll_pin_pre_doit).
> 
> Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")
> Signed-off-by: Petr Oros <poros@redhat.com>
> ---
>  drivers/net/ethernet/intel/ice/ice_dpll.c | 32
> +++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
> b/drivers/net/ethernet/intel/ice/ice_dpll.c
> index 11b942b83500fb..be72a076f7a15c 100644
> --- a/drivers/net/ethernet/intel/ice/ice_dpll.c
> +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
> @@ -1154,6 +1154,32 @@ ice_dpll_input_state_get(const struct dpll_pin
> *pin, void *pin_priv,
>  				      extack, ICE_DPLL_PIN_TYPE_INPUT);  }
> 
> +/**
> + * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a
> state
> +change
> + * @d: pointer to dplls struct
> + * @changed: the SW pin that was explicitly changed (already notified
> +by dpll core)
> + *
> + * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1
> +and
> + * SMA2/U.FL2).  When one pin's routing changes via the PCA9575 GPIO
> + * expander, the paired pin's state may also change.  Send a change
> + * notification for the peer pin so userspace consumers monitoring
> the
> + * peer via dpll netlink learn about the update.
> + *
> + * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock
> is
> + *          released.  Uses __dpll_pin_change_ntf() because dpll_lock
> is
> + *          still held by the dpll netlink layer.
> + */
> +static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d,
> +					struct ice_dpll_pin *changed)
> +{
> +	struct ice_dpll_pin *peer;
> +
> +	peer = (changed >= d->sma && changed < d->sma +
> ICE_DPLL_PIN_SW_NUM) ?
> +		&d->ufl[changed->idx] : &d->sma[changed->idx];
> +	if (peer->pin)
> +		__dpll_pin_change_ntf(peer->pin);
> +}
> +
>  /**
>   * ice_dpll_sma_direction_set - set direction of SMA pin
>   * @p: pointer to a pin
> @@ -1344,6 +1370,8 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin
> *pin, void *pin_priv,
> 
>  unlock:
>  	mutex_unlock(&pf->dplls.lock);
> +	if (!ret)
> +		ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
> 
>  	return ret;
>  }
> @@ -1462,6 +1490,8 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin
> *pin, void *pin_priv,
> 
>  unlock:
>  	mutex_unlock(&pf->dplls.lock);
> +	if (!ret)
> +		ice_dpll_sw_pin_notify_peer(&pf->dplls, sma);
> 
>  	return ret;
>  }
> @@ -1657,6 +1687,8 @@ ice_dpll_pin_sma_direction_set(const struct
> dpll_pin *pin, void *pin_priv,
>  	mutex_lock(&pf->dplls.lock);
>  	ret = ice_dpll_sma_direction_set(p, direction, extack);
>  	mutex_unlock(&pf->dplls.lock);
> +	if (!ret)
> +		ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
> 
>  	return ret;
>  }
> --
> 2.52.0

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


^ permalink raw reply

* Re: [RFC Patch net-next v1 1/9] r8169: add some register definitions
From: Andrew Lunn @ 2026-04-27 14:34 UTC (permalink / raw)
  To: Javen
  Cc: Heiner Kallweit, nic_swsd@realtek.com, andrew+netdev@lunn.ch,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <bff9db3261a54995aee448e6115f5e29@realsil.com.cn>

> >> +#define RTL8127_RSS_KEY_SIZE 40
> The name here is directly ported from vendor driver, which may carry some confusing.

Part of the task of taking vendor code is re-writing it to make it
understandable. That often means using better names, names which fit
with the Mainline driver. It also means making use of Mainline helpers
like BIT(). So it really is often a case of re-write vendor code, not
drop in vendor code. Use it as documentation, not code.

> V4 actually refers to the type of rx descriptor, not the version of
> RSS IP block. Since RTL8127 exclusively uses this V4 descriptor
> format (and not the older v2/v3 formats), V4 is indeed
> unnecessary. 8125B is from older chips that share the same
> descriptor format, which is also unnecessary.

Maybe also consider taking a step back and looking at the overall
structure of the driver. Would it make sense to have functions which
handle only v1 descriptors, only v2 descriptors, only v3 descriptors
and only v4 descriptors? Would that make the overall code easier to
understand? So you might need to start with refactoring the existing
code, and then add in your new code.

	Andrew

^ permalink raw reply

* Re: MAINTAINERS: Add self for the 3c509 network driver
From: Andrew Lunn @ 2026-04-27 14:36 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Jakub Kicinski, netdev, linux-kernel
In-Reply-To: <alpine.DEB.2.21.2604271056460.28583@angie.orcam.me.uk>

On Mon, Apr 27, 2026 at 11:23:17AM +0100, Maciej W. Rozycki wrote:
> It appears there's a need for a maintainer for the 3Com EtherLink III 
> family of Ethernet network adapters.  There is documentation available 
> and the driver is very mature so the task ought to be of little hassle, 
> so I think I should be able to squeeze in any issues to be addressed.
> 
> Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* RE: [PATCH iwl-net v7 2/3] ice: fix missing dpll notifications for SW pins
From: Kubalewski, Arkadiusz @ 2026-04-27 14:37 UTC (permalink / raw)
  To: Oros, Petr, netdev@vger.kernel.org
  Cc: Oros, Petr, Nguyen, Anthony L, Kitszel, Przemyslaw, Andrew Lunn,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Jiri Pirko, Vadim Fedorenko, Vecera, Ivan,
	Schmidt, Michal, Keller, Jacob E, Loktionov, Aleksandr,
	Rinitha, SX, intel-wired-lan@lists.osuosl.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20260417145907.696307-3-poros@redhat.com>

>From: Petr Oros <poros@redhat.com>
>Sent: Friday, April 17, 2026 4:59 PM
>
>The SMA/U.FL pin redesign (commit 2dd5d03c77e2 ("ice: redesign dpll
>sma/u.fl pins control")) introduced software-controlled pins that wrap
>backing CGU input/output pins, but never updated the notification and
>data paths to propagate pin events to these SW wrappers.
>
>The periodic work sends dpll_pin_change_ntf() only for direct CGU input
>pins.  SW pins that wrap these inputs never receive change or phase
>offset notifications, so userspace consumers such as synce4l monitoring
>SMA pins via dpll netlink never learn about state transitions or phase
>offset updates.  Similarly, ice_dpll_phase_offset_get() reads the SW
>pin's own phase_offset field which is never updated; the PPS monitor
>writes to the backing CGU input's field instead.
>
>Fix by introducing ice_dpll_pin_ntf(), a wrapper around
>dpll_pin_change_ntf() that also notifies any registered SMA/U.FL pin
>whose backing CGU input matches.  Replace all direct
>dpll_pin_change_ntf() calls in the periodic notification paths with
>this wrapper.  Fix ice_dpll_phase_offset_get() to return the backing
>CGU input's phase_offset for input-direction SW pins.
>
>Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")

LGTM,
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> 

>Signed-off-by: Petr Oros <poros@redhat.com>
>---
> drivers/net/ethernet/intel/ice/ice_dpll.c | 47 +++++++++++++++++------
> 1 file changed, 36 insertions(+), 11 deletions(-)
>
>diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
>b/drivers/net/ethernet/intel/ice/ice_dpll.c
>index 3a90a2940fdc6e..11b942b83500fb 100644
>--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
>+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
>@@ -1963,7 +1963,10 @@ ice_dpll_phase_offset_get(const struct dpll_pin
>*pin, void *pin_priv,
> 				       d->active_input == p->input->pin))
> 		*phase_offset = d->phase_offset *
>ICE_DPLL_PHASE_OFFSET_FACTOR;
> 	else if (d->phase_offset_monitor_period)
>-		*phase_offset = p->phase_offset *
>ICE_DPLL_PHASE_OFFSET_FACTOR;
>+		*phase_offset = (p->input &&
>+				 p->direction == DPLL_PIN_DIRECTION_INPUT ?
>+				 p->input->phase_offset :
>+				 p->phase_offset) * ICE_DPLL_PHASE_OFFSET_FACTOR;
> 	else
> 		*phase_offset = 0;
> 	mutex_unlock(&pf->dplls.lock);
>@@ -2659,6 +2662,27 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
> 	return pci_get_dsn(pf->pdev);
> }
>
>+/**
>+ * ice_dpll_pin_ntf - notify pin change including any SW pin wrappers
>+ * @dplls: pointer to dplls struct
>+ * @pin: the dpll_pin that changed
>+ *
>+ * Send a change notification for @pin and for any registered SMA/U.FL
>pin
>+ * whose backing CGU input matches @pin.
>+ */
>+static void ice_dpll_pin_ntf(struct ice_dplls *dplls, struct dpll_pin
>*pin)
>+{
>+	dpll_pin_change_ntf(pin);
>+	for (int i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
>+		if (dplls->sma[i].pin && dplls->sma[i].input &&
>+		    dplls->sma[i].input->pin == pin)
>+			dpll_pin_change_ntf(dplls->sma[i].pin);
>+		if (dplls->ufl[i].pin && dplls->ufl[i].input &&
>+		    dplls->ufl[i].input->pin == pin)
>+			dpll_pin_change_ntf(dplls->ufl[i].pin);
>+	}
>+}
>+
> /**
>  * ice_dpll_notify_changes - notify dpll subsystem about changes
>  * @d: pointer do dpll
>@@ -2667,6 +2691,7 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
>  */
> static void ice_dpll_notify_changes(struct ice_dpll *d)
> {
>+	struct ice_dplls *dplls = &d->pf->dplls;
> 	bool pin_notified = false;
>
> 	if (d->prev_dpll_state != d->dpll_state) {
>@@ -2675,17 +2700,17 @@ static void ice_dpll_notify_changes(struct
>ice_dpll *d)
> 	}
> 	if (d->prev_input != d->active_input) {
> 		if (d->prev_input)
>-			dpll_pin_change_ntf(d->prev_input);
>+			ice_dpll_pin_ntf(dplls, d->prev_input);
> 		d->prev_input = d->active_input;
> 		if (d->active_input) {
>-			dpll_pin_change_ntf(d->active_input);
>+			ice_dpll_pin_ntf(dplls, d->active_input);
> 			pin_notified = true;
> 		}
> 	}
> 	if (d->prev_phase_offset != d->phase_offset) {
> 		d->prev_phase_offset = d->phase_offset;
> 		if (!pin_notified && d->active_input)
>-			dpll_pin_change_ntf(d->active_input);
>+			ice_dpll_pin_ntf(dplls, d->active_input);
> 	}
> }
>
>@@ -2714,6 +2739,7 @@ static bool ice_dpll_is_pps_phase_monitor(struct
>ice_pf *pf)
>
> /**
>  * ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin
>changes
>+ * @dplls: pointer to dplls struct
>  * @pins: array of ice_dpll_pin pointers registered within dpll subsystem
>  * @pin_num: number of pins
>  * @phase_offset_ntf_mask: bitmask of pin indexes to notify
>@@ -2723,15 +2749,14 @@ static bool ice_dpll_is_pps_phase_monitor(struct
>ice_pf *pf)
>  *
>  * Context: Must be called while pf->dplls.lock is released.
>  */
>-static void ice_dpll_pins_notify_mask(struct ice_dpll_pin *pins,
>+static void ice_dpll_pins_notify_mask(struct ice_dplls *dplls,
>+				      struct ice_dpll_pin *pins,
> 				      u8 pin_num,
> 				      u32 phase_offset_ntf_mask)
> {
>-	int i = 0;
>-
>-	for (i = 0; i < pin_num; i++)
>-		if (phase_offset_ntf_mask & (1 << i))
>-			dpll_pin_change_ntf(pins[i].pin);
>+	for (int i = 0; i < pin_num; i++)
>+		if (phase_offset_ntf_mask & BIT(i))
>+			ice_dpll_pin_ntf(dplls, pins[i].pin);
> }
>
> /**
>@@ -2907,7 +2932,7 @@ static void ice_dpll_periodic_work(struct
>kthread_work *work)
> 	ice_dpll_notify_changes(de);
> 	ice_dpll_notify_changes(dp);
> 	if (phase_offset_ntf)
>-		ice_dpll_pins_notify_mask(d->inputs, d->num_inputs,
>+		ice_dpll_pins_notify_mask(d, d->inputs, d->num_inputs,
> 					  phase_offset_ntf);
>
> resched:
>--
>2.52.0


^ permalink raw reply

* Re: MAINTAINERS: Add self for the DEC LANCE network driver
From: Andrew Lunn @ 2026-04-27 14:37 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Jakub Kicinski, netdev, linux-kernel
In-Reply-To: <alpine.DEB.2.21.2604271113520.28583@angie.orcam.me.uk>

On Mon, Apr 27, 2026 at 11:23:35AM +0100, Maciej W. Rozycki wrote:
> Like with the rest of DECstation and TURBOchannel hardware I have been 
> handling the DEC LANCE network driver for some 25 years now anyway.
> 
> Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>

Thanks for taking over these two drivers.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* [RFC PATCH net-next] net: mana: Force single RX buffer per page under SWIOTLB bounce modes
From: Dipayaan Roy @ 2026-04-27 14:41 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, leon, longli, kotaranov, horms, shradhagupta,
	ssengar, ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
	linux-rdma, stephen, jacob.e.keller, dipayanroy, leitao, kees,
	john.fastabend, hawk, bpf, daniel, ast, sdf, yury.norov

The MANA driver has two distinct DMA paths for RX buffers:

1. Without PP_FLAG_DMA_MAP: The driver maps full pages manually,
   creating page-aligned mappings where the DMA offset is always zero.

2. With PP_FLAG_DMA_MAP: page_pool uses sub-page fragments, where
   multiple RX buffers share a single page. The pool maps the whole
   page once, and subsequent allocations use offsets into that region.

Path 2 is problematic in two scenarios where DMA must go through
SWIOTLB bounce buffers:

- Confidential VMs (AMD SEV-SNP, Intel TDX): guest memory is encrypted
  and the NIC cannot access it directly due to lack of TDISP support.
  All DMA must use SWIOTLB bounce buffers.

- Force-bounce mode (swiotlb=force): all DMA is routed through bounce
  buffers regardless of whether the system is a CVM.

In both cases, sub-page RX buffer fragments allocated via page_pool may
not be compatible with bounce buffering in this mode, leading to failures
in the RX path.

Add a check using is_swiotlb_force_bounce() in
mana_use_single_rxbuf_per_page() to detect when force-bounce is active
for the device and force single RX buffer per page allocation.

Note: This issue likely affects any NIC driver using page_pool with
sub-page fragment allocation under SWIOTLB. A more general fix at
the page_pool level may be desirable. Seeking feedback on the
preferred approach.

Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
---
 drivers/net/ethernet/microsoft/mana/mana_en.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 2d44eaf932a8..841421baf0de 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 #include <linux/export.h>
 #include <linux/skbuff.h>
+#include <linux/swiotlb.h>
 #include <linux/cc_platform.h>
 
 #include <net/checksum.h>
@@ -748,10 +749,15 @@ static void *mana_get_rxbuf_pre(struct mana_rxq *rxq, dma_addr_t *da)
 static bool
 mana_use_single_rxbuf_per_page(struct mana_port_context *apc, u32 mtu)
 {
+	struct gdma_context *gc = apc->ac->gdma_dev->gdma_context;
+
 	/* On confidential VMs with guest memory encryption, all DMA goes
 	 * through SWIOTLB bounce buffers. Sub-page RX fragments may not
 	 * be properly bounce-buffered, so use fullpage buffers.
 	 */
+	if (is_swiotlb_force_bounce(gc->dev))
+		return true;
+
 	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
 		return true;
 
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH] [v4] wiznet: convert to GPIO descriptors
From: Andrew Lunn @ 2026-04-27 14:48 UTC (permalink / raw)
  To: Arnd Bergmann, Nicolas Saenz Julienne
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Linus Walleij, Bartosz Golaszewski, Arnd Bergmann,
	Marco Crivellari, netdev, devicetree, linux-kernel, linux-gpio
In-Reply-To: <20260427142924.2702598-1-arnd@kernel.org>

On Mon, Apr 27, 2026 at 04:28:29PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
> 
> The w5100/w5300 drivers only support probing with old platform data in
> MMIO mode, or probing with DT in SPI mode. There are no users of this
> platform data in tree, and from the git history it appears that the only
> users of MMIO mode were on the (since removed) blackfin architecture.

A quick grep does not find any .dts files referencing the compatible.

> It would probably be possible to just remove the MMIO mode driver
> completely, but it seems fine otherwise, and fixing it to use the modern
> interface seems easy enough.

Last real development work on this driver was:

Author: Nicolas Saenz Julienne <nsaenz@kernel.org>
Date:   Wed Jun 12 14:25:25 2019 +0200

    net: ethernet: wiznet: w5X00 add device tree support
    
    The w5X00 chip provides an SPI to Ethernet inteface. This patch allows
    platform devices to be defined through the device tree.

Nicolas, are you still using it?

	Andrew

^ permalink raw reply

* Re: [PATCH] [v4] wiznet: convert to GPIO descriptors
From: Rob Herring @ 2026-04-27 14:50 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Krzysztof Kozlowski, Conor Dooley, Linus Walleij,
	Bartosz Golaszewski, Arnd Bergmann, Marco Crivellari, netdev,
	devicetree, linux-kernel, linux-gpio
In-Reply-To: <20260427142924.2702598-1-arnd@kernel.org>

On Mon, Apr 27, 2026 at 04:28:29PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
> 
> The w5100/w5300 drivers only support probing with old platform data in
> MMIO mode, or probing with DT in SPI mode. There are no users of this
> platform data in tree, and from the git history it appears that the only
> users of MMIO mode were on the (since removed) blackfin architecture.
> 
> Remove the platform data option, as it's unlikely to still be needed, and
> change the internal operation to GPIO descriptors, making the behavior
> the same for SPI and MMIO mode. The other data in the platform_data
> structure is the MAC address, so make that also handled the same for both.
> 
> It would probably be possible to just remove the MMIO mode driver
> completely, but it seems fine otherwise, and fixing it to use the modern
> interface seems easy enough.
> 
> The CONFIG_WIZNET_BUS_SHIFT value was apparently meant to be set
> at compile time to a machine specific value. This was always broken
> for multiplatform configurations with conflicting requirements, and
> in the mainline kernel it was set to 0 anyway. Leave it defined
> locally as 0 but rename it to something without the CONFIG_ prefix.
> 
> Acked-by: Rob Herring <robh@kernel.org>

Well, 3 years later and I'm a bit grumpier seeing .txt binding 
additions. A new compatible plus new property we generally require 
converting the binding first. But I'm not going to revoke my ack here.

Is there even a known user for this new compatible?

Rob

^ permalink raw reply

* Re: [BUG] some temporary IPv6 address don't get regenerated
From: Fernando Fernandez Mancera @ 2026-04-27 14:55 UTC (permalink / raw)
  To: Łukasz Stelmach, netdev
In-Reply-To: <87340td30q.fsf%steelman@post.pl>

On 4/17/26 5:23 PM, Łukasz Stelmach wrote:
> Hi,
> 
> Apparently, something in addrconf.c can go wrong and a temporary
> addresses may not get regenerated leaving users who wish to use them
> with only the stable ones. Below, 2a01:110f:4321:1002:abcc:78d7:2055:94ec
> while still valid is not preferred anymore. Even if it's not the only
> global temporary address it is the only usable to contact hosts on the
> Internet because the other temporary addresses are ULA.
> 

Hi,

I managed to reproduce this, it took me quite some time. It looks like a 
race condition somewhere. I am working on a fix and I will add a 
selftest covering this too.

Ideally, I will send a fix this week. I am now checking if this was 
introduced recently or was always broken.

> Neither received RAs nor adding and removing an address manually (one
> with a different prefix unrelated to these below) which as far as I
> understand, should trigger address maintenance code.
> 

Yup, same situation here.

Thanks,
Fernando.

> I noticed this phenomenon once or twice before. It seems to be very
> rare, yet quite undesirable I'd say. What might have triggered it today
> is a reboot of my router and (possible?) change in lifetime values it
> announced.
> 
> Even stranger is that there is a preferred fd89:: (ULA), but not 2a01::.
> 
> accept_ra as well as use_tempaddr are set to 2.
> 
> Of course, this ma be get fixed by a suspend/resume (no, it may not) or
> manual ifdown/ifup (of course it helped), but nevertheless I thought it
> was worth reporting.
> 
> --8<---------------cut here---------------start------------->8---
> 107: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
>      link/ether b8:ca:3a:d4:1e:97 brd ff:ff:ff:ff:ff:ff
>      inet 192.168.2.122/24 brd 192.168.2.255 scope global dynamic bond0
>         valid_lft 165585sec preferred_lft 165585sec
> 
>      inet6 fd89:82bb:420:2:cab3:d2d6:aeeb:e250/64 scope global temporary dynamic
>         valid_lft 597079sec preferred_lft 78177sec
> 
>      inet6 2a01:110f:4321:1002:abcc:78d7:2055:94ec/64 scope global temporary deprecated dynamic
>         valid_lft 60815sec preferred_lft 0sec
> 
>      inet6 2a01:110f:4321:1002:abac:3aff:fed4:beef/64 scope global dynamic mngtmpaddr proto kernel_ra
>         valid_lft 60815sec preferred_lft 60815sec
> 
>      inet6 fd89:82bb:420:2:24bf:fe8f:5c9c:c753/64 scope global temporary deprecated dynamic
>         valid_lft 511186sec preferred_lft 0sec
> 
>      inet6 fd89:82bb:420:2:abac:3aff:fed4:beef/64 scope global dynamic mngtmpaddr proto kernel_ra
>         valid_lft 2591805sec preferred_lft 604605sec
> 
>      inet6 fe80::abac:3aff:fed4:beef/64 scope link proto kernel_ll
>         valid_lft forever preferred_lft forever
> --8<---------------cut here---------------end--------------->8---
> 


^ permalink raw reply

* Re: [PATCH] [v4] wiznet: convert to GPIO descriptors
From: Arnd Bergmann @ 2026-04-27 15:17 UTC (permalink / raw)
  To: Rob Herring, Arnd Bergmann
  Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Krzysztof Kozlowski, Conor Dooley, Linus Walleij,
	Bartosz Golaszewski, Marco Crivellari, Netdev, devicetree,
	linux-kernel, open list:GPIO SUBSYSTEM
In-Reply-To: <20260427145010.GA2502144-robh@kernel.org>

On Mon, Apr 27, 2026, at 16:50, Rob Herring wrote:
> On Mon, Apr 27, 2026 at 04:28:29PM +0200, Arnd Bergmann wrote:
>> 
>> The CONFIG_WIZNET_BUS_SHIFT value was apparently meant to be set
>> at compile time to a machine specific value. This was always broken
>> for multiplatform configurations with conflicting requirements, and
>> in the mainline kernel it was set to 0 anyway. Leave it defined
>> locally as 0 but rename it to something without the CONFIG_ prefix.
>> 
>> Acked-by: Rob Herring <robh@kernel.org>
>
> Well, 3 years later and I'm a bit grumpier seeing .txt binding 
> additions. A new compatible plus new property we generally require 
> converting the binding first. But I'm not going to revoke my ack here.
>
> Is there even a known user for this new compatible?

No, I'm not aware of any users neither the old nor the new
compatible, it only popped up from my backlog of patches
because of its usage of legacy GPIOs. From what I can
tell, the only users of the non-DT MMIO interface were
out of tree arch/blackfin/ boards.

       Arnd

^ permalink raw reply

* [PATCH net] ice: fix stats array overflow when VF requests more queues
From: Michal Schmidt @ 2026-04-27 15:18 UTC (permalink / raw)
  To: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jacob Keller,
	Petr Oros
  Cc: intel-wired-lan, netdev, linux-kernel

When a VF increases its queue count via VIRTCHNL_OP_REQUEST_QUEUES,
ice_vc_request_qs_msg() sets vf->num_req_qs and triggers a VF reset.
The reset calls ice_vf_reconfig_vsi(), which does ice_vsi_decfg()
followed by ice_vsi_cfg(). ice_vsi_decfg() does not free the per-ring
stats arrays. Inside ice_vsi_cfg_def(), ice_vsi_set_num_qs() updates
alloc_txq/alloc_rxq to the new larger value, but
ice_vsi_alloc_stat_arrays() returns early because the stats already
exist. ice_vsi_alloc_ring_stats() then iterates using the new larger
alloc_txq and writes beyond the bounds of the old, smaller
tx_ring_stats/rx_ring_stats pointer arrays, corrupting adjacent SLUB
metadata.

KASAN detects the bug:
 ==================================================================
 BUG: KASAN: slab-out-of-bounds in ice_vsi_alloc_ring_stats+0x385/0x4a0 [ice]
 Read of size 8 at addr ffff88810affea60 by task kworker/u131:7/221

 CPU: 24 UID: 0 PID: 221 Comm: kworker/u131:7 Not tainted 7.1.0-rc1+ #1 PREEMPT(lazy)
 ...
 Workqueue: ice ice_service_task [ice]
 Call Trace:
  <TASK>
  ...
  kasan_report+0xd7/0x120
  ice_vsi_alloc_ring_stats+0x385/0x4a0 [ice]
  ice_vsi_cfg_def+0x12e2/0x2060 [ice]
  ice_vsi_cfg+0xb5/0x3c0 [ice]
  ice_reset_vf+0x858/0xf80 [ice]
  ice_vc_request_qs_msg+0x1da/0x290 [ice]
  ice_vc_process_vf_msg+0xb15/0x1430 [ice]
  __ice_clean_ctrlq+0x70d/0x9d0 [ice]
  ice_service_task+0x840/0xf20 [ice]
  process_one_work+0x690/0xff0
  worker_thread+0x4d9/0xd20
  kthread+0x322/0x410
  ret_from_fork+0x332/0x660
  ret_from_fork_asm+0x1a/0x30
  </TASK>

 Allocated by task 2439:
  kasan_save_stack+0x1c/0x40
  kasan_save_track+0x10/0x30
  __kasan_kmalloc+0x96/0xb0
  __kmalloc_noprof+0x1d8/0x580
  ice_vsi_cfg_def+0x115c/0x2060 [ice]
  ice_vsi_cfg+0xb5/0x3c0 [ice]
  ice_vsi_setup+0x180/0x320 [ice]
  ice_start_vfs+0x1f3/0x590 [ice]
  ice_ena_vfs+0x66d/0x798 [ice]
  ice_sriov_configure.cold+0xe4/0x121 [ice]
  sriov_numvfs_store+0x279/0x480
  kernfs_fop_write_iter+0x331/0x4f0
  vfs_write+0x4c4/0xe40
  ksys_write+0x10c/0x240
  do_syscall_64+0xd9/0x650
  entry_SYSCALL_64_after_hwframe+0x76/0x7e

 The buggy address belongs to the object at ffff88810affea40
                which belongs to the cache kmalloc-32 of size 32
 The buggy address is located 0 bytes to the right of
                allocated 32-byte region [ffff88810affea40, ffff88810affea60)
 ...
 ==================================================================

ice_vsi_rebuild() handles this correctly by calling
ice_vsi_realloc_stat_arrays() before reconfiguration, but
ice_vf_reconfig_vsi() was missing this call.

Fix by calling ice_vsi_realloc_stat_arrays() in ice_vf_reconfig_vsi()
before ice_vsi_decfg(), mirroring the ice_vsi_rebuild() pattern. Set
vsi->req_txq/req_rxq from vf->num_req_qs so the realloc function knows
the target array size.

See the linked RHEL Jira item for a reproducer.

Fixes: 2a2cb4c6c181 ("ice: replace ice_vf_recreate_vsi() with ice_vf_reconfig_vsi()")
Closes: https://redhat.atlassian.net/browse/RHEL-164321
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
Assisted-by: Claude:claude-opus-4-6 semcode
---
 drivers/net/ethernet/intel/ice/ice_lib.c    | 2 +-
 drivers/net/ethernet/intel/ice/ice_lib.h    | 1 +
 drivers/net/ethernet/intel/ice/ice_vf_lib.c | 7 +++++++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 837b71b7b2b7..fc78176a2a8d 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -3015,7 +3015,7 @@ ice_vsi_rebuild_set_coalesce(struct ice_vsi *vsi,
  * ice_vsi_realloc_stat_arrays - Frees unused stat structures or alloc new ones
  * @vsi: VSI pointer
  */
-static int
+int
 ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi)
 {
 	u16 req_txq = vsi->req_txq ? vsi->req_txq : vsi->alloc_txq;
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
index 49454d98dcfe..6f7da84384e5 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
@@ -66,6 +66,7 @@ int ice_ena_vsi(struct ice_vsi *vsi, bool locked);
 void ice_vsi_decfg(struct ice_vsi *vsi);
 void ice_dis_vsi(struct ice_vsi *vsi, bool locked);
 
+int ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi);
 int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags);
 int ice_vsi_cfg(struct ice_vsi *vsi);
 struct ice_vsi *ice_vsi_alloc(struct ice_pf *pf);
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
index 772f6b07340d..9edb2c14f553 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
@@ -268,6 +268,13 @@ static int ice_vf_reconfig_vsi(struct ice_vf *vf)
 
 	vsi->flags = ICE_VSI_FLAG_NO_INIT;
 
+	vsi->req_txq = vf->num_req_qs;
+	vsi->req_rxq = vf->num_req_qs;
+
+	err = ice_vsi_realloc_stat_arrays(vsi);
+	if (err)
+		return err;
+
 	ice_vsi_decfg(vsi);
 	ice_fltr_remove_all(vsi);
 
-- 
2.54.0


^ permalink raw reply related

* Re: [syzbot] [hams?] KASAN: slab-use-after-free Read in ax25_send_frame (3)
From: Arjan van de Ven @ 2026-04-27 15:25 UTC (permalink / raw)
  To: netdev
  Cc: davem, edumazet, horms, jreuter, kuba, linux-hams, linux-kernel,
	pabeni, syzkaller-bugs, syzbot+9c8999af06ca7df15fc6
In-Reply-To: <69ef2847.170a0220.11de9.001a.GAE@google.com>

This email is created by automation to help kernel developers
deal with a large volume of AI generated bug reports by decoding
oopses into more actionable information.

Decoded Backtrace

net/ax25/ax25_out.c (crash site, UAF read)

  32  ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen,
  32      const ax25_address *src, ax25_address *dest,
  32      ax25_digi *digi, struct net_device *dev)
  33  {
  34      ax25_dev *ax25_dev;
  35      ax25_cb *ax25;
       ...
  77      if (digi != NULL) {
->78          ax25->digipeat = kmemdup(digi, sizeof(*digi), GFP_ATOMIC);
              // <- digi = neigh->digipeat; freed ax25_digi; 66-byte UAF read
  79          if (ax25->digipeat == NULL) {
       ...
 115      return ax25;
 116  }

net/rose/rose_link.c (caller, t0timer callback)

  79  static void rose_t0timer_expiry(struct timer_list *t)
  80  {
  81      struct rose_neigh *neigh = timer_container_of(neigh, t, t0timer);
  82
->83      rose_transmit_restart_request(neigh);
         // <- inlined; calls rose_send_frame -> ax25_send_frame
         //    with neigh->digipeat as the digi argument
  84
  85      neigh->dce_mode = 0;
  86
  87      rose_start_t0timer(neigh);
  88  }

rose_send_frame() inlined at rose_link.c:106:

  95  static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh)
  96  {
       ...
 105      ax25s = neigh->ax25;
->106     neigh->ax25 = ax25_send_frame(skb, 260, rose_call,
             &neigh->callsign, neigh->digipeat, neigh->dev);
         // <- neigh->digipeat passed as digi; freed by rose_timer_expiry
 107      if (ax25s)
 108          ax25_cb_put(ax25s);
 109      return neigh->ax25 != NULL;
 110  }

net/rose/rose_timer.c (free site)

 164  static void rose_timer_expiry(struct timer_list *t)
 165  {
 166      struct rose_sock *rose = timer_container_of(rose, t, timer);
 167      struct sock *sk = &rose->sock;
       ...
 174      switch (rose->state) {
       ...
 182      case ROSE_STATE_2:  /* T3 */
->183          rose_neigh_put(rose->neighbour);
              // <- drops refcount to 0; frees neigh->digipeat (ax25_digi)
              //    and neigh itself; t0timer still pending
 184          rose_disconnect(sk, ETIMEDOUT, -1, -1);
 185          break;
       ...
 197  }

include/net/rose.h (rose_neigh_put, inline free function)

 160  static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
 161  {
 162      if (refcount_dec_and_test(&rose_neigh->use)) {
 163          if (rose_neigh->ax25)
 164              ax25_cb_put(rose_neigh->ax25);
->165          kfree(rose_neigh->digipeat);
              // <- frees the ax25_digi (66 bytes); t0timer not cancelled
 166          kfree(rose_neigh);
 167      }
 168  }

net/rose/rose_route.c (allocation site)

  84      if (rose_neigh == NULL) {
  85          rose_neigh = kmalloc_obj(*rose_neigh, GFP_ATOMIC);
       ...
 100          refcount_set(&rose_neigh->use, 1);
       ...
 107          if (rose_route->ndigis != 0) {
 108              rose_neigh->digipeat =
->109                  kmalloc_obj(ax25_digi, GFP_ATOMIC);
                  // <- allocates the 66-byte ax25_digi later freed and read
       ...
 124          }
 125      }


Tentative Analysis

The crash is a KASAN slab-use-after-free: rose_t0timer_expiry() reads
the freed rose_neigh->digipeat (an ax25_digi struct, 66 bytes) via
ax25_send_frame() -> kmemdup().

Commit d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
changed rose_timer_expiry() from merely decrementing the plain 'use'
counter to calling rose_neigh_put(), which now frees rose_neigh (and
its digipeat) when the refcount hits zero. The new rose_neigh_put()
omits timer cancellation, so after it returns the t0timer embedded in
the (now-freed) rose_neigh can still fire in the same TIMER_SOFTIRQ
batch.

The race on a single-CPU machine (the syzbot scenario) is purely
sequential: rose_timer_expiry() fires first, frees the neigh; then
rose_t0timer_expiry() fires next in the same run_timer_base batch with
a dangling neigh pointer, passes neigh->digipeat to ax25_send_frame,
and kmemdup triggers the KASAN report.

Before d860d1faa6b2, rose_timer_expiry() never freed the neigh; the
free was always performed by rose_remove_neigh() which called
timer_delete_sync() on both timers before freeing. The refcount
conversion introduced a new free path that missed this cancellation.


Potential Solution

Add timer_delete() calls for both ftimer and t0timer inside
rose_neigh_put() before the kfree calls, mirroring what
rose_remove_neigh() already does via timer_delete_sync(). The
non-synchronous variant is required because rose_neigh_put() may be
called from softirq context.

   static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
   {
       if (refcount_dec_and_test(&rose_neigh->use)) {
           timer_delete(&rose_neigh->ftimer);
           timer_delete(&rose_neigh->t0timer);
           if (rose_neigh->ax25)
               ax25_cb_put(rose_neigh->ax25);
           kfree(rose_neigh->digipeat);
           kfree(rose_neigh);
       }
   }


More information

Oops-Analysis: http://oops.fenrus.org/reports/lkml/69ef2847.170a0220.11de9.001a.GAE_google.com/
Assisted-by: Copilot:claude-sonnet-4.6 linux-kernel-oops-x86.

^ permalink raw reply

* Re: [PATCH] [v4] wiznet: convert to GPIO descriptors
From: Andrew Lunn @ 2026-04-27 15:25 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rob Herring, Arnd Bergmann, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Krzysztof Kozlowski,
	Conor Dooley, Linus Walleij, Bartosz Golaszewski,
	Marco Crivellari, Netdev, devicetree, linux-kernel,
	open list:GPIO SUBSYSTEM
In-Reply-To: <57297b41-0f08-43eb-a73c-21a5461a4eb4@app.fastmail.com>

On Mon, Apr 27, 2026 at 05:17:24PM +0200, Arnd Bergmann wrote:
> On Mon, Apr 27, 2026, at 16:50, Rob Herring wrote:
> > On Mon, Apr 27, 2026 at 04:28:29PM +0200, Arnd Bergmann wrote:
> >> 
> >> The CONFIG_WIZNET_BUS_SHIFT value was apparently meant to be set
> >> at compile time to a machine specific value. This was always broken
> >> for multiplatform configurations with conflicting requirements, and
> >> in the mainline kernel it was set to 0 anyway. Leave it defined
> >> locally as 0 but rename it to something without the CONFIG_ prefix.
> >> 
> >> Acked-by: Rob Herring <robh@kernel.org>
> >
> > Well, 3 years later and I'm a bit grumpier seeing .txt binding 
> > additions. A new compatible plus new property we generally require 
> > converting the binding first. But I'm not going to revoke my ack here.
> >
> > Is there even a known user for this new compatible?
> 
> No, I'm not aware of any users neither the old nor the new
> compatible, it only popped up from my backlog of patches
> because of its usage of legacy GPIOs. From what I can
> tell, the only users of the non-DT MMIO interface were
> out of tree arch/blackfin/ boards.

I would suggest giving Nicolas Saenz Julienne time to speak up. If
Nicolas does not require it any more, i suggest removing it. That fits
with what we are trying to do at the moment in netdev, remove old
drivers.

	Andrew

^ permalink raw reply

* RE: [Intel-wired-lan] [PATCH net] ice: fix stats array overflow when VF requests more queues
From: Loktionov, Aleksandr @ 2026-04-27 15:30 UTC (permalink / raw)
  To: Schmidt, Michal, Nguyen, Anthony L, Kitszel, Przemyslaw,
	Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Keller, Jacob E, Oros, Petr
  Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20260427151827.43342-1-mschmidt@redhat.com>



> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Michal Schmidt
> Sent: Monday, April 27, 2026 5:18 PM
> To: Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; Andrew Lunn
> <andrew+netdev@lunn.ch>; David S. Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo
> Abeni <pabeni@redhat.com>; Keller, Jacob E <jacob.e.keller@intel.com>;
> Oros, Petr <poros@redhat.com>
> Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH net] ice: fix stats array overflow
> when VF requests more queues
> 
> When a VF increases its queue count via VIRTCHNL_OP_REQUEST_QUEUES,
> ice_vc_request_qs_msg() sets vf->num_req_qs and triggers a VF reset.
> The reset calls ice_vf_reconfig_vsi(), which does ice_vsi_decfg()
> followed by ice_vsi_cfg(). ice_vsi_decfg() does not free the per-ring
> stats arrays. Inside ice_vsi_cfg_def(), ice_vsi_set_num_qs() updates
> alloc_txq/alloc_rxq to the new larger value, but
> ice_vsi_alloc_stat_arrays() returns early because the stats already
> exist. ice_vsi_alloc_ring_stats() then iterates using the new larger
> alloc_txq and writes beyond the bounds of the old, smaller
> tx_ring_stats/rx_ring_stats pointer arrays, corrupting adjacent SLUB
> metadata.
> 
> KASAN detects the bug:
>  ==================================================================
>  BUG: KASAN: slab-out-of-bounds in
> ice_vsi_alloc_ring_stats+0x385/0x4a0 [ice]  Read of size 8 at addr
> ffff88810affea60 by task kworker/u131:7/221
> 
>  CPU: 24 UID: 0 PID: 221 Comm: kworker/u131:7 Not tainted 7.1.0-rc1+
> #1 PREEMPT(lazy)  ...
>  Workqueue: ice ice_service_task [ice]
>  Call Trace:
>   <TASK>
>   ...
>   kasan_report+0xd7/0x120
>   ice_vsi_alloc_ring_stats+0x385/0x4a0 [ice]
>   ice_vsi_cfg_def+0x12e2/0x2060 [ice]
>   ice_vsi_cfg+0xb5/0x3c0 [ice]
>   ice_reset_vf+0x858/0xf80 [ice]
>   ice_vc_request_qs_msg+0x1da/0x290 [ice]
>   ice_vc_process_vf_msg+0xb15/0x1430 [ice]
>   __ice_clean_ctrlq+0x70d/0x9d0 [ice]
>   ice_service_task+0x840/0xf20 [ice]
>   process_one_work+0x690/0xff0
>   worker_thread+0x4d9/0xd20
>   kthread+0x322/0x410
>   ret_from_fork+0x332/0x660
>   ret_from_fork_asm+0x1a/0x30
>   </TASK>
> 
>  Allocated by task 2439:
>   kasan_save_stack+0x1c/0x40
>   kasan_save_track+0x10/0x30
>   __kasan_kmalloc+0x96/0xb0
>   __kmalloc_noprof+0x1d8/0x580
>   ice_vsi_cfg_def+0x115c/0x2060 [ice]
>   ice_vsi_cfg+0xb5/0x3c0 [ice]
>   ice_vsi_setup+0x180/0x320 [ice]
>   ice_start_vfs+0x1f3/0x590 [ice]
>   ice_ena_vfs+0x66d/0x798 [ice]
>   ice_sriov_configure.cold+0xe4/0x121 [ice]
>   sriov_numvfs_store+0x279/0x480
>   kernfs_fop_write_iter+0x331/0x4f0
>   vfs_write+0x4c4/0xe40
>   ksys_write+0x10c/0x240
>   do_syscall_64+0xd9/0x650
>   entry_SYSCALL_64_after_hwframe+0x76/0x7e
> 
>  The buggy address belongs to the object at ffff88810affea40
>                 which belongs to the cache kmalloc-32 of size 32  The
> buggy address is located 0 bytes to the right of
>                 allocated 32-byte region [ffff88810affea40,
> ffff88810affea60)  ...
>  ==================================================================
> 
> ice_vsi_rebuild() handles this correctly by calling
> ice_vsi_realloc_stat_arrays() before reconfiguration, but
> ice_vf_reconfig_vsi() was missing this call.
> 
> Fix by calling ice_vsi_realloc_stat_arrays() in ice_vf_reconfig_vsi()
> before ice_vsi_decfg(), mirroring the ice_vsi_rebuild() pattern. Set
> vsi->req_txq/req_rxq from vf->num_req_qs so the realloc function knows
> the target array size.
> 
> See the linked RHEL Jira item for a reproducer.
> 
> Fixes: 2a2cb4c6c181 ("ice: replace ice_vf_recreate_vsi() with
> ice_vf_reconfig_vsi()")
> Closes: https://redhat.atlassian.net/browse/RHEL-164321
Not sure are links to local JIRAs are acceptable in kernel?

Why no Cc: stable@vger.kernel.org? 

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

> Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
> Assisted-by: Claude:claude-opus-4-6 semcode
> ---
>  drivers/net/ethernet/intel/ice/ice_lib.c    | 2 +-
>  drivers/net/ethernet/intel/ice/ice_lib.h    | 1 +
>  drivers/net/ethernet/intel/ice/ice_vf_lib.c | 7 +++++++
>  3 files changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c
> b/drivers/net/ethernet/intel/ice/ice_lib.c
> index 837b71b7b2b7..fc78176a2a8d 100644
> --- a/drivers/net/ethernet/intel/ice/ice_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_lib.c
> @@ -3015,7 +3015,7 @@ ice_vsi_rebuild_set_coalesce(struct ice_vsi
> *vsi,
>   * ice_vsi_realloc_stat_arrays - Frees unused stat structures or
> alloc new ones
>   * @vsi: VSI pointer
>   */
> -static int
> +int
>  ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi)  {
>  	u16 req_txq = vsi->req_txq ? vsi->req_txq : vsi->alloc_txq;
> diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h
> b/drivers/net/ethernet/intel/ice/ice_lib.h
> index 49454d98dcfe..6f7da84384e5 100644
> --- a/drivers/net/ethernet/intel/ice/ice_lib.h
> +++ b/drivers/net/ethernet/intel/ice/ice_lib.h
> @@ -66,6 +66,7 @@ int ice_ena_vsi(struct ice_vsi *vsi, bool locked);
> void ice_vsi_decfg(struct ice_vsi *vsi);  void ice_dis_vsi(struct
> ice_vsi *vsi, bool locked);
> 
> +int ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi);
>  int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags);  int
> ice_vsi_cfg(struct ice_vsi *vsi);  struct ice_vsi
> *ice_vsi_alloc(struct ice_pf *pf); diff --git
> a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> index 772f6b07340d..9edb2c14f553 100644
> --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> @@ -268,6 +268,13 @@ static int ice_vf_reconfig_vsi(struct ice_vf *vf)
> 
>  	vsi->flags = ICE_VSI_FLAG_NO_INIT;
> 
> +	vsi->req_txq = vf->num_req_qs;
> +	vsi->req_rxq = vf->num_req_qs;
> +
> +	err = ice_vsi_realloc_stat_arrays(vsi);
> +	if (err)
> +		return err;
> +
>  	ice_vsi_decfg(vsi);
>  	ice_fltr_remove_all(vsi);
> 
> --
> 2.54.0


^ permalink raw reply

* [PATCH net] tcp: do not shrink window clamp when SO_RCVBUF is locked
From: Ankit Jain @ 2026-04-27 15:27 UTC (permalink / raw)
  To: netdev, davem, dsahern, edumazet, ncardwell, kuniyu, kuba, pabeni,
	horms, quic_stranche, quic_subashab
  Cc: linux-kernel, karen.badiryan, ajay.kaher, alexey.makhalov,
	vamsi-krishna.brahmajosyula, yin.ding, tapas.kundu, Ankit Jain,
	stable

When an application explicitly sets SO_RCVBUF, the window clamp should
not be dynamically recalculated based on the memory scaling_ratio.

Currently, tcp_measure_rcv_mss() aggressively crushes the window clamp
down when it sees a poor skb->len to skb->truesize ratio. If the
application explicitly locked the buffer via SO_RCVBUF, this
recalculation causes the advertised window to drop severely.

If the window drops below the interface MSS, it triggers Silly Window
Syndrome (SWS) avoidance on the sender. The sender defers transmission
and drops the connection into a perpetual 200ms PROBE0 timer loop,
drastically reducing throughput.

This is highly reproducible on loopback interfaces (MTU 65536) using
Java-based workloads (like Tomcat/GemFire) where the JVM sets SO_RCVBUF
to 32K or 64K. The bloated loopback truesize forces the scaling ratio
to drop, crushing the window clamp to ~26K, instantly triggering SWS
stalls and causing gigabyte transfers to take minutes instead of
milliseconds.

Since the application locked the buffer, the kernel should respect the
clamp boundary and not dynamically crush it based on runtime ratios.

Fixes: a2cbb1603943 ("tcp: Update window clamping condition")
Cc: stable@vger.kernel.org
Reported-by: Karen Badiryan <karen.badiryan@broadcom.com>
Signed-off-by: Ankit Jain <ankit-aj.jain@broadcom.com>
---
Note to reviewers:

Testing Context:
- The SWS deadlock was successfully reproduced on the latest netdev/net 
  tree (v7.1-rc1) using the actual enterprise Java workload.
- Applying this patch completely resolves the 504 Timeouts and restores 
  loopback throughput.
- Baseline iperf3 auto-tuning remains unaffected by this patch.

For context, here is the exact sequence of events that triggers the 
recalculation flaw, illustrated in a packetdrill-style flow. 
Unpatched kernels aggressively crush the window at step 3, triggering SWS.

// 1. Tomcat creates socket and hardcodes the buffer to 32K
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [32768]) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0

// 2. GemFire connects over loopback (simulating Jumbo MSS of 65496)
+0 < S 0:0(0) win 65535 <mss 65496, sackOK, TS val 100 ecr 0, nop, wscale 8>
+0 > S. 0:0(0) ack 1 <...>
+0 < . 1:1(0) ack 1 win 65535 <TS val 200 ecr 1>
+0 accept(3, ..., ...) = 4

// 3. GemFire sends a 20KB packet, dropping the scaling_ratio.
// Without the patch, tcp_measure_rcv_mss() crushes the window_clamp here.
+0.1 < . 1:20001(20000) ack 1 win 65535 <TS val 300 ecr 1>
+0.1 read(4, ..., 20000) = 20000

// 4. Assert window did not crush
// WITH the patch, the kernel respects the SOCK_RCVBUF_LOCK.
+0 > . 1:1(0) ack 20001 win 65535
---
 net/ipv4/tcp_input.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d5c9e65d9..c1cb9d3ed 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -248,7 +248,8 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
 			do_div(val, skb->truesize);
 			tcp_sk(sk)->scaling_ratio = val ? val : 1;
 
-			if (old_ratio != tcp_sk(sk)->scaling_ratio) {
+			if (old_ratio != tcp_sk(sk)->scaling_ratio &&
+			    !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
 				struct tcp_sock *tp = tcp_sk(sk);
 
 				val = tcp_win_from_space(sk, sk->sk_rcvbuf);
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH] [v4] wiznet: convert to GPIO descriptors
From: Arnd Bergmann @ 2026-04-27 15:34 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Arnd Bergmann, Andrew Lunn, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Krzysztof Kozlowski,
	Conor Dooley, Linus Walleij, Bartosz Golaszewski,
	Marco Crivellari, Netdev, devicetree, linux-kernel,
	open list:GPIO SUBSYSTEM
In-Reply-To: <992f111e-febc-436d-b7ca-fa167a858e93@lunn.ch>

On Mon, Apr 27, 2026, at 17:25, Andrew Lunn wrote:
> On Mon, Apr 27, 2026 at 05:17:24PM +0200, Arnd Bergmann wrote:
>> On Mon, Apr 27, 2026, at 16:50, Rob Herring wrote:
> I would suggest giving Nicolas Saenz Julienne time to speak up. If
> Nicolas does not require it any more, i suggest removing it. That fits
> with what we are trying to do at the moment in netdev, remove old
> drivers.

Sounds good. Even if Nicolas thinks there may be users of the
SPI interface with the existing DT binding, we can still decide
to remove the MMIO interface entirely, as I first suggested.

Apparently the chips are still in production and are commonly
used with microcontrollers, but the only reference I found
about using Linux with it is in a blog post that mentions
an "official" driver from the manufacturer, with an
(incompatible) compatible="w5000-wiz0" DT binding:

https://maker.wiznet.io/gavinchang/projects/linux-w5500-driver-and-use-1/

       Arnd

^ permalink raw reply

* Re: [PATCH net] tcp: do not shrink window clamp when SO_RCVBUF is locked
From: Eric Dumazet @ 2026-04-27 15:38 UTC (permalink / raw)
  To: Ankit Jain
  Cc: netdev, davem, dsahern, ncardwell, kuniyu, kuba, pabeni, horms,
	quic_stranche, quic_subashab, linux-kernel, karen.badiryan,
	ajay.kaher, alexey.makhalov, vamsi-krishna.brahmajosyula,
	yin.ding, tapas.kundu, stable
In-Reply-To: <20260427152756.1205-1-ankit-aj.jain@broadcom.com>

On Mon, Apr 27, 2026 at 8:32 AM Ankit Jain <ankit-aj.jain@broadcom.com> wrote:
>
> When an application explicitly sets SO_RCVBUF, the window clamp should
> not be dynamically recalculated based on the memory scaling_ratio.
>
> Currently, tcp_measure_rcv_mss() aggressively crushes the window clamp
> down when it sees a poor skb->len to skb->truesize ratio. If the
> application explicitly locked the buffer via SO_RCVBUF, this
> recalculation causes the advertised window to drop severely.
>
> If the window drops below the interface MSS, it triggers Silly Window
> Syndrome (SWS) avoidance on the sender. The sender defers transmission
> and drops the connection into a perpetual 200ms PROBE0 timer loop,
> drastically reducing throughput.
>
> This is highly reproducible on loopback interfaces (MTU 65536) using
> Java-based workloads (like Tomcat/GemFire) where the JVM sets SO_RCVBUF
> to 32K or 64K. The bloated loopback truesize forces the scaling ratio
> to drop, crushing the window clamp to ~26K, instantly triggering SWS
> stalls and causing gigabyte transfers to take minutes instead of
> milliseconds.
>
> Since the application locked the buffer, the kernel should respect the
> clamp boundary and not dynamically crush it based on runtime ratios.
>
> Fixes: a2cbb1603943 ("tcp: Update window clamping condition")
> Cc: stable@vger.kernel.org
> Reported-by: Karen Badiryan <karen.badiryan@broadcom.com>
> Signed-off-by: Ankit Jain <ankit-aj.jain@broadcom.com>

Make sure to add a selftests (in ./tools/testing/selftests/net/packetdrill/ )

Thanks.

^ permalink raw reply

* Re: [Intel-wired-lan] [PATCH net] iavf: iavf_virtchnl_completion: drop duplicate ether_addr_equal() test
From: Corinna Vinschen @ 2026-04-27 15:58 UTC (permalink / raw)
  To: Jacob Keller
  Cc: Simon Horman, intel-wired-lan, stable,
	Jose Ignacio Tornos Martinez, netdev, Corinna Vinschen
In-Reply-To: <30b2fade-2545-4f2b-98ad-c6449512c04e@intel.com>

On Apr 24 17:37, Jacob Keller wrote:
> On 4/24/2026 1:32 AM, Corinna Vinschen wrote:
> > On Apr 23 19:55, Simon Horman wrote:
> >> On Tue, Apr 21, 2026 at 01:12:36PM +0200, Corinna Vinschen wrote:
> >>> This is just a simple cleanup fix.  Commit 35a2443d0910f ("iavf: Add
> >>> waiting for response from PF in set mac") introduced a duplicate
> >>> ether_addr_equal() check, so the current code tests the new MAC twice
> >>> against the former MAC.
> >>>
> >>> Remove the outer ether_addr_equal() test, remnant of commit c5c922b3e09b
> >>> ("iavf: fix MAC address setting for VFs when filter is rejected")
> >>>
> >>> Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
> >>> Fixes: 35a2443d0910f ("iavf: Add waiting for response from PF in set mac")
> >>> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> >>> ---
> >>> Added CC: stable@vger.kernel.org
> >>
> >> Hi,
> >>
> >> This feels more like a cleanup for net-next (without a Fixes tag)
> >> than a fix for net. I'm missing where the bug is here.
> > 
> > Yeah, it's not a bug, the "Fixes" tag was just supposed to point out the
> > patch introducing the duplicate test.
> > 
> > Shall I create a v3 or is it ok as is and just goes to net-next instead
> > of net?
> > 
> > 
> > Thanks,
> > Corinna
> > 
> 
> I can make a note for later and either myself or Tony can forward it
> net-next as part of an Intel Wired LAN update when the merge window
> re-opens and any testing has completed. (Not that there is much needing
> to be tested in this patches case)

That's nice, thank you!


Corinna


^ permalink raw reply

* Re: [PATCH net-next v6 0/2] net: mana: add ethtool private flag for full-page RX buffers
From: David Wei @ 2026-04-27 16:01 UTC (permalink / raw)
  To: Dipayaan Roy, kuba
  Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	pabeni, leon, longli, kotaranov, horms, shradhagupta, ssengar,
	ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
	linux-rdma, stephen, jacob.e.keller, leitao, kees, john.fastabend,
	hawk, bpf, daniel, ast, sdf, dipayanroy
In-Reply-To: <aex119OtL8CEGXkb@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>

On 2026-04-25 01:05, Dipayaan Roy wrote:
> On Fri, Apr 24, 2026 at 01:05:24PM -0700, David Wei wrote:
>> On 2026-04-23 05:48, Dipayaan Roy wrote:
>>> On Thu, Apr 16, 2026 at 08:31:46AM -0700, Jakub Kicinski wrote:
>>>> On Tue, 14 Apr 2026 09:00:56 -0700 Dipayaan Roy wrote:
>>>>> I still see roughly a 5% overhead from the atomic refcount operation
>>>>> itself, but on that platform there is no throughput drop when using
>>>>> page fragments versus full-page mode.
>>>>
>>>> That seems to contradict your claim that it's a problem with a specific
>>>> platform.. Since we're in the merge window I asked David Wei to try to
>>>> experiment with disabling page fragmentation on the ARM64 platforms we
>>>> have at Meta. If it repros we should use the generic rx-buf-len
>>>> ringparam because more NICs may want to implement this strategy.
>>>
>>> Hi Jakub,
>>>
>>> Thanks. I think I was not precise enough in my previous reply.
>>>
>>> What I meant is that the atomic refcount cost itself does not appear to
>>> be unique to the affected platform. I see a similar ~5% overhead on
>>> another ARM64 platformi (different vendor) as well. However, on that platform
>>> there is no throughput delta between fragment mode and full-page mode; both reach
>>> line rate.
>>>
>>> On the affected platform, fragment mode shows an additional ~15%
>>> throughput drop versus full-page mode. So the current data suggests that
>>> the atomic overhead is common, but the throughput regression is not
>>> explained by that overhead alone and likely depends on an additional
>>> platform-specific factor.
>>>
>>> Separately, the hardware team collected PCIe traces on the affected
>>> platform and reported stalls in the fragment-mode case that are not seen
>>> in full-page mode. They are still investigating the root cause, but
>>> their current hypothesis is that this is related to that platform’s
>>> PCIe/root-port microarchitecture rather than to page_pool refcounting
>>> alone.
>>>
>>> That said, I agree the right direction depends on whether this
>>> reproduces on other ARM64 platforms. If David is able to reproduce the
>>> same behavior, then using the generic rx-buf-len ringparam sounds like
>>> the better direction.
>>>
>>> Please let me know what David finds, and I can rework the patch
>>> accordingly.
>>
>> I ran a test on Grace, 4 KB pages, 72 cores, 1 NUMA node.
>>
>> Broadcom NIC, bnxt driver, 50 Gbps bandwidth. Hacked it up to either
>> give me 1 or 2 frags per page. No agg ring, no HDS, no HW GRO.
>>
>> Use 1 combined queue only for the server. Affinitized its net rx softirq
>> to run on core 4.
>>
>> Ran iperf3 server, taskset onto cpu cores 32-47. The iperf3 client is
>> running on a host w/ same hw in the same region. Using 32 queues, no
>> softirq affinities. The idea is to hammer page->pp_ref_count from
>> different cores.
>>
>> * 1 frag/page  -> 32.3 Gbps
>> * 2 frags/page -> 36.0 Gbps
>>
>> Comparing perf, for 2 frags/page the cost of skb_release_data() hitting
>> pp_ref_count goes up, as expected. Is this what you see? When you say
>> there's a +5% overhead, what function?
>>
>> Overall tput is higher with multiple frags. That's to be expected w/
>> page pool.
> 
> Hi David,
> 
> Thanks for running this. Your results are consistent with mine.
> 
> I have tested this on 2 ARM64 platforms from different vendors,
> running ntttcp and iperf3 using 4k as base page size.
> In my observation I see both platforms show a 5% overhead in
> napi_pp_put_page (~3.9%) and page_pool_alloc_frag_netmem (~1.9%)
> when running in fragment mode, both stalling on the LSE ldaddal
> atomic that maintains pp_ref_count.
> This seems to be same as your observation as well. However in my
> observation one of the platform shows 15% drop in throughput when
> in fragment mode vs page mode. The other platform I ran the test on
> infact performs slighty better in fragment mode than in full page
> mode (simillar observation as yours).

That's not what I observe. I don't see napi_pp_put_page at all, and
page_pool_alloc_frag_netmem is actually lower with 2 frags/page (4.06%)
than 1 frag/page (5.73%).

The main difference is in skb_release_data which goes from
0.85% (1 frag/page) to 3.32% (2 frags/page).

> 
> So the atomic refcount overhead appears to be common across ARM64
> platforms, but it does not cause a throughput regression.
> The throughput regression seems specific to one platform only for which
> we want to have the full page work around, also the HW team has
> identified PCIe stalls in fragment mode that are absent in full-page mode.
> Their investigation points to a suspected microarchitectural
> issue in the PCIe root port. IMO, there seems to be no issue with
> page_pool itself.
> 
> Given that:
>   - Grace shows fragments are faster (your data)
>   - A second ARM64 platform shows no regression (my data)
>   - Only the affected platform shows a throughput drop
>   - The HW team suspects this to a platform-specific PCIe issue,
>     also form our experiment data the drop in throughput seems to
>     be platform specific only.
> 
> I believe this remains a platform-specific workaround rather than
> a generic issue. Would a private flag still be acceptable for this
> case?
> 
> 
>>
>> There are some 200 Gbps NICs but they're mlx5 so I'd have to redo the
>> driver hack. Are you going to re-implement this change with rx-buf-len
>> instead of a private flag? If so, I won't spend more time running this
>> test.
>>
> I can go either way depending on what Jakub prefers.
> Hi Jakub,
> with this new data from David, is it convincing enough for a mana driver
> specific private flag, which can be set from user space by a udev rule
> by detecting the underlying platform? If not then I will send the next
> version with the other rxbuflen approach.
>>>
>>>
>>> Regards
>>> Dipayaan Roy
> 
> 
> Thanks and Regards
> Dipayaan Roy

^ permalink raw reply

* Re: [syzbot] [virt?] [net?] memory leak in __vsock_create (2)
From: Stefano Garzarella @ 2026-04-27 16:18 UTC (permalink / raw)
  To: syzbot
  Cc: davem, edumazet, horms, kuba, linux-kernel, netdev, pabeni,
	syzkaller-bugs, virtualization
In-Reply-To: <69eacf39.a00a0220.17a17.004d.GAE@google.com>

#syz test: https://github.com/stefano-garzarella/linux.git fix-syzbot-memleak-vsock-create


^ permalink raw reply

* [PATCH] net: nixge: fix skb leak and missing bail on DMA mapping error
From: kernelcoredev @ 2026-04-27 16:20 UTC (permalink / raw)
  To: netdev; +Cc: andrew, andrew+netdev, davem, edumazet, kuba, pabeni,
	kernelcoredev

When dma_mapping_error() fires during RX buffer refill in nixge_recv(),
the skb allocated by netdev_alloc_skb_ip_align() is never freed, and
execution continues writing a corrupt physical address into the hardware
descriptor ring.

Fix by freeing the skb with dev_kfree_skb() and returning early.

This was tested via code inspection, as I do not have access to the
hardware. If dma_mapping_error() occurs, the current code continues
execution, which can leak the skb and program an invalid DMA address
into the descriptor ring. This patch ensures proper cleanup and early
return on error.

Fixes: 492caffa8a1a ("net: ethernet: nixge: Add support for National Instruments XGE netdev")

Signed-off-by: Bentley Blacketer <sonionwhat@gmail.com>
---
 drivers/net/ethernet/ni/nixge.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
index 230d5ff99..b64e2f355 100644
--- a/drivers/net/ethernet/ni/nixge.c
+++ b/drivers/net/ethernet/ni/nixge.c
@@ -645,8 +645,9 @@ static int nixge_recv(struct net_device *ndev, int budget)
 					  NIXGE_MAX_JUMBO_FRAME_SIZE,
 					  DMA_FROM_DEVICE);
 		if (dma_mapping_error(ndev->dev.parent, cur_phys)) {
-			/* FIXME: bail out and clean up */
-			netdev_err(ndev, "Failed to map ...\n");
+			netdev_err(ndev, "Failed to map RX buffer\n");
+			dev_kfree_skb(new_skb);
+			return packets;
 		}
 		nixge_hw_dma_bd_set_phys(cur_p, cur_phys);
 		cur_p->cntrl = NIXGE_MAX_JUMBO_FRAME_SIZE;
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH v2 iproute2-next] utils: add fflush_monitor() helper
From: Stephen Hemminger @ 2026-04-27 16:31 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Ahern, David S . Miller, Jakub Kicinski, Paolo Abeni,
	netdev, eric.dumazet
In-Reply-To: <20260427081953.364819-1-edumazet@google.com>

On Mon, 27 Apr 2026 08:19:53 +0000
Eric Dumazet <edumazet@google.com> wrote:

> Some fflush() calls only make sense for monitor programs.
> 
> For other cases, forcing a flush is expensive.
> 
> After this patch, ip, tc and ss are correctly buffering most of their
> output when redirected to a file.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

What about pulling all the fflush from the leaf calls, and move the fflush
to one common place. There are some of these that need to come back
like the addr flush loop, this is just a semi-automated first pass.

From 815ed9eb987fc458987e753b3a2fa1786578b485 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 27 Apr 2026 09:26:58 -0700
Subject: [PATCH] flush stdout only in monitor mode

As Eric pointed out fflush() only makes sense in monitor mode.
In other modes buffering the output helps with large outputs
like route dumps.

Move the fflush() into rtnl_listen() which is the common code
used by all monitoring subcommands.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 bridge/fdb.c      | 2 --
 bridge/link.c     | 2 --
 bridge/mdb.c      | 1 -
 bridge/mst.c      | 1 -
 bridge/vlan.c     | 4 ----
 bridge/vni.c      | 2 --
 genl/ctrl.c       | 2 --
 ip/ipaddress.c    | 8 --------
 ip/ipfou.c        | 1 -
 ip/ipila.c        | 1 -
 ip/ipioam6.c      | 1 -
 ip/ipl2tp.c       | 2 --
 ip/iplink.c       | 2 --
 ip/ipmptcp.c      | 6 ------
 ip/ipmroute.c     | 1 -
 ip/ipneigh.c      | 4 ----
 ip/ipnetconf.c    | 1 -
 ip/ipnetns.c      | 1 -
 ip/ipnexthop.c    | 6 ------
 ip/ipntable.c     | 2 --
 ip/ipprefix.c     | 1 -
 ip/iproute.c      | 4 ----
 ip/iprule.c       | 1 -
 ip/ipseg6.c       | 1 -
 ip/ipstats.c      | 2 --
 ip/iptoken.c      | 2 --
 ip/iptuntap.c     | 1 -
 ip/rtmon.c        | 1 -
 ip/tcp_metrics.c  | 4 ----
 ip/xfrm_monitor.c | 5 -----
 ip/xfrm_policy.c  | 2 --
 ip/xfrm_state.c   | 1 -
 lib/libnetlink.c  | 2 ++
 tc/tc_class.c     | 1 -
 tc/tc_filter.c    | 1 -
 tc/tc_qdisc.c     | 1 -
 36 files changed, 2 insertions(+), 78 deletions(-)

diff --git a/bridge/fdb.c b/bridge/fdb.c
index d57b5750..05f093b5 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -309,7 +309,6 @@ int print_fdb(struct nlmsghdr *n, void *arg)
 	print_string(PRINT_ANY, "state", "%s\n",
 			   state_n2a(r->ndm_state));
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
@@ -417,7 +416,6 @@ static int fdb_show(int argc, char **argv)
 		exit(1);
 	}
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
diff --git a/bridge/link.c b/bridge/link.c
index 1c8faa85..7638797d 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -292,7 +292,6 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "%s", "\n");
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
@@ -669,7 +668,6 @@ static int brlink_show(int argc, char **argv)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 	return 0;
 }
 
diff --git a/bridge/mdb.c b/bridge/mdb.c
index 72490971..112deeb9 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -501,7 +501,6 @@ static int mdb_show(int argc, char **argv)
 
 	close_json_object();
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
diff --git a/bridge/mst.c b/bridge/mst.c
index 37362c45..8e46c762 100644
--- a/bridge/mst.c
+++ b/bridge/mst.c
@@ -158,7 +158,6 @@ static int mst_show(int argc, char **argv)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 	return 0;
 }
 
diff --git a/bridge/vlan.c b/bridge/vlan.c
index 3c240207..27d31ba8 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -756,7 +756,6 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg)
 	struct if_stats_msg *ifsm = NLMSG_DATA(n);
 	struct rtattr *tb[IFLA_STATS_MAX+1];
 	int len = n->nlmsg_len;
-	FILE *fp = arg;
 
 	len -= NLMSG_LENGTH(sizeof(*ifsm));
 	if (len < 0) {
@@ -778,7 +777,6 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg)
 		print_vlan_stats_attr(tb[IFLA_STATS_LINK_XSTATS_SLAVE],
 				      ifsm->ifindex);
 
-	fflush(fp);
 	return 0;
 }
 
@@ -1205,7 +1203,6 @@ static int vlan_show(int argc, char **argv, int subject)
 
 out:
 	delete_json_obj();
-	fflush(stdout);
 	return 0;
 }
 
@@ -1260,7 +1257,6 @@ static int vlan_global_show(int argc, char **argv)
 		close_vlan_port();
 
 	delete_json_obj();
-	fflush(stdout);
 	return 0;
 }
 
diff --git a/bridge/vni.c b/bridge/vni.c
index 57b04c8c..b28647fd 100644
--- a/bridge/vni.c
+++ b/bridge/vni.c
@@ -333,7 +333,6 @@ int print_vnifilter_rtm(struct nlmsghdr *n, void *arg)
 	if (opened)
 		close_vni_port();
 
-	fflush(stdout);
 	return 0;
 }
 
@@ -381,7 +380,6 @@ static int vni_show(int argc, char **argv)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 	return 0;
 }
 
diff --git a/genl/ctrl.c b/genl/ctrl.c
index 9412c2f0..88ff4cb8 100644
--- a/genl/ctrl.c
+++ b/genl/ctrl.c
@@ -275,7 +275,6 @@ static int print_ctrl(struct rtnl_ctrl_data *ctrl,
 	struct genlmsghdr *ghdr = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *attrs;
-	FILE *fp = (FILE *) arg;
 
 	if (n->nlmsg_type !=  GENL_ID_CTRL) {
 		fprintf(stderr, "Not a controller message, nlmsg_len=%d "
@@ -339,7 +338,6 @@ static int print_ctrl(struct rtnl_ctrl_data *ctrl,
 	if (tb[CTRL_ATTR_MCAST_GROUPS])
 		print_ctrl_mcast(tb[CTRL_ATTR_MCAST_GROUPS]);
 
-	fflush(fp);
 	return 0;
 }
 
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 4d93a04a..f538bf88 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -894,7 +894,6 @@ static int print_linkinfo_brief(FILE *fp, const char *name,
 		print_string(PRINT_FP, NULL, "%s", "\n");
 	}
 
-	fflush(fp);
 	return 0;
 }
 
@@ -1346,7 +1345,6 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
 	}
 
 	print_string(PRINT_FP, NULL, "%s", "\n");
-	fflush(fp);
 	/* prettier here if stderr and stdout go to the same place */
 	if (truncated_vfs)
 		fprintf(stderr, "Truncated VF list: %s\n", name);
@@ -1732,7 +1730,6 @@ int print_addrinfo(struct nlmsghdr *n, void *arg)
 	}
 	print_string(PRINT_FP, NULL, "%s", "\n");
 brief_exit:
-	fflush(fp);
 	return 0;
 }
 
@@ -1768,7 +1765,6 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi,
 
 	if (brief) {
 		print_string(PRINT_FP, NULL, "%s", "\n");
-		fflush(fp);
 	}
 	return 0;
 }
@@ -2006,7 +2002,6 @@ static int ipaddr_flush(void)
 				else
 					printf("*** Flush is complete after %d round%s ***\n", round, round > 1?"s":"");
 			}
-			fflush(stdout);
 			return 0;
 		}
 		round++;
@@ -2015,7 +2010,6 @@ static int ipaddr_flush(void)
 
 		if (show_stats) {
 			printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed);
-			fflush(stdout);
 		}
 
 		/* If we are flushing, and specifying primary, then we
@@ -2027,7 +2021,6 @@ static int ipaddr_flush(void)
 			goto flush_done;
 	}
 	fprintf(stderr, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops);
-	fflush(stderr);
 	return 1;
 }
 
@@ -2351,7 +2344,6 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 			print_link_stats(stdout, n);
 		close_json_object();
 	}
-	fflush(stdout);
 
 out:
 	free_nlmsg_chain(ainfo);
diff --git a/ip/ipfou.c b/ip/ipfou.c
index 760cfee2..8c1e061a 100644
--- a/ip/ipfou.c
+++ b/ip/ipfou.c
@@ -322,7 +322,6 @@ static int do_show(int argc, char **argv)
 		return 1;
 	}
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
diff --git a/ip/ipila.c b/ip/ipila.c
index 80f34f29..2590de9a 100644
--- a/ip/ipila.c
+++ b/ip/ipila.c
@@ -159,7 +159,6 @@ static int do_list(int argc, char **argv)
 		return 1;
 	}
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
diff --git a/ip/ipioam6.c b/ip/ipioam6.c
index 18860989..118fcd1c 100644
--- a/ip/ipioam6.c
+++ b/ip/ipioam6.c
@@ -261,7 +261,6 @@ static int ioam6_do_cmd(void)
 			exit(1);
 		}
 		delete_json_obj();
-		fflush(stdout);
 	}
 
 	return 0;
diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c
index 87a4b898..97f7ff08 100644
--- a/ip/ipl2tp.c
+++ b/ip/ipl2tp.c
@@ -467,7 +467,6 @@ static int get_session(struct l2tp_data *p)
 		exit(1);
 	}
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
@@ -502,7 +501,6 @@ static int get_tunnel(struct l2tp_data *p)
 		exit(1);
 	}
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
diff --git a/ip/iplink.c b/ip/iplink.c
index fce6631d..eae51438 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -1296,7 +1296,6 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr)
 	print_nl();
 	print_mpls_link_stats(fp, stats, "        ");
 	print_string(PRINT_FP, NULL, "%s", "\n");
-	fflush(fp);
 }
 
 static void print_af_stats_attr(FILE *fp, int ifindex, struct rtattr *attr)
@@ -1359,7 +1358,6 @@ static int print_af_stats(struct nlmsghdr *n, void *arg)
 	if (tb[IFLA_STATS_AF_SPEC])
 		print_af_stats_attr(fp, ifsm->ifindex, tb[IFLA_STATS_AF_SPEC]);
 
-	fflush(fp);
 	return 0;
 }
 
diff --git a/ip/ipmptcp.c b/ip/ipmptcp.c
index 3df89db5..02cf72ce 100644
--- a/ip/ipmptcp.c
+++ b/ip/ipmptcp.c
@@ -276,7 +276,6 @@ static int print_mptcp_addrinfo(struct rtattr *addrinfo)
 
 	print_nl();
 	close_json_object();
-	fflush(stdout);
 
 	return 0;
 }
@@ -320,12 +319,10 @@ static int mptcp_addr_dump(void)
 	if (rtnl_dump_filter(&genl_rth, print_mptcp_addr, stdout) < 0) {
 		fprintf(stderr, "Dump terminated\n");
 		delete_json_obj();
-		fflush(stdout);
 		return -2;
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 	return 0;
 }
 
@@ -349,7 +346,6 @@ static int mptcp_addr_show(int argc, char **argv)
 	ret = print_mptcp_addr(answer, stdout);
 	delete_json_obj();
 	free(answer);
-	fflush(stdout);
 	return ret;
 }
 
@@ -430,7 +426,6 @@ static int print_mptcp_limit(struct nlmsghdr *n, void *arg)
 
 	print_nl();
 	close_json_object();
-	fflush(stdout);
 
 	return 0;
 }
@@ -592,7 +587,6 @@ static int mptcp_monitor_msg(struct rtnl_ctrl_data *ctrl,
 out:
 	print_nl();
 	close_json_object();
-	fflush(stdout);
 
 	return 0;
 }
diff --git a/ip/ipmroute.c b/ip/ipmroute.c
index c540eab1..164632e6 100644
--- a/ip/ipmroute.c
+++ b/ip/ipmroute.c
@@ -206,7 +206,6 @@ int print_mroute(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "\n", NULL);
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
diff --git a/ip/ipneigh.c b/ip/ipneigh.c
index e678545a..b21fd637 100644
--- a/ip/ipneigh.c
+++ b/ip/ipneigh.c
@@ -298,7 +298,6 @@ static int print_neigh_brief(FILE *fp, struct ndmsg *r, struct rtattr *tb[])
 
 	print_string(PRINT_FP, NULL, "%s", "\n");
 	close_json_object();
-	fflush(fp);
 
 	return 0;
 }
@@ -472,7 +471,6 @@ int print_neigh(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "\n", "");
 	close_json_object();
-	fflush(fp);
 
 	return 0;
 }
@@ -630,7 +628,6 @@ static int do_show_or_flush(int argc, char **argv, int flush)
 					else
 						printf("*** Flush is complete after %d round%s ***\n", round, round > 1?"s":"");
 				}
-				fflush(stdout);
 				return 0;
 			}
 			round++;
@@ -638,7 +635,6 @@ static int do_show_or_flush(int argc, char **argv, int flush)
 				exit(1);
 			if (show_stats) {
 				printf("\n*** Round %d, deleting %d entries ***\n", round, filter.flushed);
-				fflush(stdout);
 			}
 			filter.state &= ~NUD_FAILED;
 		}
diff --git a/ip/ipnetconf.c b/ip/ipnetconf.c
index 020eff78..57bb99d1 100644
--- a/ip/ipnetconf.c
+++ b/ip/ipnetconf.c
@@ -140,7 +140,6 @@ int print_netconf(struct rtnl_ctrl_data *ctrl, struct nlmsghdr *n, void *arg)
 
 	close_json_object();
 	print_string(PRINT_FP, NULL, "\n", NULL);
-	fflush(fp);
 	return 0;
 }
 
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 3a33a3ad..587534ae 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -327,7 +327,6 @@ int print_nsid(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "\n", NULL);
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
diff --git a/ip/ipnexthop.c b/ip/ipnexthop.c
index d5c42936..14b525aa 100644
--- a/ip/ipnexthop.c
+++ b/ip/ipnexthop.c
@@ -826,7 +826,6 @@ int print_cache_nexthop(struct nlmsghdr *n, void *arg, bool process_cache)
 
 	__print_nexthop_entry(fp, NULL, &nhe, n->nlmsg_type == RTM_DELNEXTHOP);
 	print_string(PRINT_FP, NULL, "%s", "\n");
-	fflush(fp);
 
 	if (process_cache)
 		ipnh_cache_process_nlmsg(n, &nhe);
@@ -882,7 +881,6 @@ int print_nexthop_bucket(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "%s", "\n");
 	close_json_object();
-	fflush(fp);
 
 	return 0;
 }
@@ -1178,7 +1176,6 @@ static int ipnh_get_id(__u32 id)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 
 	free(answer);
 
@@ -1266,7 +1263,6 @@ static int ipnh_list_flush(int argc, char **argv, int action)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
@@ -1342,7 +1338,6 @@ static int ipnh_bucket_list(int argc, char **argv)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
@@ -1383,7 +1378,6 @@ static int ipnh_bucket_get_id(__u32 id, __u16 bucket_index)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 
 	free(answer);
 
diff --git a/ip/ipntable.c b/ip/ipntable.c
index 54db9b62..51fa067c 100644
--- a/ip/ipntable.c
+++ b/ip/ipntable.c
@@ -532,7 +532,6 @@ static void print_ndtstats(const struct ndt_stats *ndts)
 
 static int print_ntable(struct nlmsghdr *n, void *arg)
 {
-	FILE *fp = (FILE *)arg;
 	struct ndtmsg *ndtm = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *tb[NDTA_MAX+1];
@@ -633,7 +632,6 @@ static int print_ntable(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "\n", "");
 	close_json_object();
-	fflush(fp);
 
 	return 0;
 }
diff --git a/ip/ipprefix.c b/ip/ipprefix.c
index 4ec30524..5704f2f9 100644
--- a/ip/ipprefix.c
+++ b/ip/ipprefix.c
@@ -81,7 +81,6 @@ int print_prefix(struct nlmsghdr *n, void *arg)
 	}
 
 	fprintf(fp, "\n");
-	fflush(fp);
 
 	return 0;
 }
diff --git a/ip/iproute.c b/ip/iproute.c
index c2538894..820e8701 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -1012,7 +1012,6 @@ int print_route(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "\n", NULL);
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
@@ -1781,7 +1780,6 @@ static int iproute_flush(int family, rtnl_filter_t filter_fn)
 					printf("*** Flush is complete after %d round%s ***\n",
 					       round, round > 1 ? "s" : "");
 			}
-			fflush(stdout);
 			return 0;
 		}
 		round++;
@@ -1798,7 +1796,6 @@ static int iproute_flush(int family, rtnl_filter_t filter_fn)
 		if (show_stats) {
 			printf("\n*** Round %d, deleting %d entries ***\n",
 			       round, filter.flushed);
-			fflush(stdout);
 		}
 	}
 }
@@ -2035,7 +2032,6 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 	return 0;
 }
 
diff --git a/ip/iprule.c b/ip/iprule.c
index 3af02da2..b56b1b18 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -599,7 +599,6 @@ int print_rule(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "\n", "");
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
diff --git a/ip/ipseg6.c b/ip/ipseg6.c
index 305b8961..efd37227 100644
--- a/ip/ipseg6.c
+++ b/ip/ipseg6.c
@@ -197,7 +197,6 @@ static int seg6_do_cmd(void)
 			exit(1);
 		}
 		delete_json_obj();
-		fflush(stdout);
 	}
 
 	return 0;
diff --git a/ip/ipstats.c b/ip/ipstats.c
index f0f8dcdc..8a2ac85e 100644
--- a/ip/ipstats.c
+++ b/ip/ipstats.c
@@ -879,7 +879,6 @@ static int ipstats_dump(struct ipstats_stat_enabled *enabled)
 		rc = -2;
 	}
 
-	fflush(stdout);
 	return rc;
 }
 
@@ -1355,6 +1354,5 @@ int ipstats_print(struct nlmsghdr *n, void *arg)
 	if (rc)
 		return rc;
 
-	fflush(fp);
 	return 0;
 }
diff --git a/ip/iptoken.c b/ip/iptoken.c
index f25a7c8b..8bd9b4dc 100644
--- a/ip/iptoken.c
+++ b/ip/iptoken.c
@@ -41,7 +41,6 @@ static void usage(void)
 static int print_token(struct nlmsghdr *n, void *arg)
 {
 	struct rtnl_dump_args *args = arg;
-	FILE *fp = args->fp;
 	int ifindex = args->ifindex;
 	struct ifinfomsg *ifi = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
@@ -85,7 +84,6 @@ static int print_token(struct nlmsghdr *n, void *arg)
 			   "ifname", "%s\n",
 			   ll_index_to_name(ifi->ifi_index));
 	close_json_object();
-	fflush(fp);
 
 	return 0;
 }
diff --git a/ip/iptuntap.c b/ip/iptuntap.c
index 6718ec6c..0f46fe6a 100644
--- a/ip/iptuntap.c
+++ b/ip/iptuntap.c
@@ -444,7 +444,6 @@ static int do_show(int argc, char **argv)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
 
 	return 0;
 }
diff --git a/ip/rtmon.c b/ip/rtmon.c
index 470f4ba6..507a80da 100644
--- a/ip/rtmon.c
+++ b/ip/rtmon.c
@@ -46,7 +46,6 @@ static int dump_msg(struct rtnl_ctrl_data *ctrl,
 	if (!init_phase)
 		write_stamp(fp);
 	fwrite((void *)n, 1, NLMSG_ALIGN(n->nlmsg_len), fp);
-	fflush(fp);
 	return 0;
 }
 
diff --git a/ip/tcp_metrics.c b/ip/tcp_metrics.c
index 9c8fb072..09943f42 100644
--- a/ip/tcp_metrics.c
+++ b/ip/tcp_metrics.c
@@ -156,7 +156,6 @@ static void print_tcp_metrics(struct rtattr *a)
 
 static int process_msg(struct nlmsghdr *n, void *arg)
 {
-	FILE *fp = (FILE *) arg;
 	struct genlmsghdr *ghdr;
 	struct rtattr *attrs[TCP_METRICS_ATTR_MAX + 1], *a;
 	const char *h;
@@ -334,7 +333,6 @@ static int process_msg(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "\n", "");
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
@@ -477,7 +475,6 @@ static int tcpm_do_cmd(int cmd, int argc, char **argv)
 				} else if (show_stats)
 					printf("*** Flush is complete after %d round%s ***\n",
 					       round, round > 1 ? "s" : "");
-				fflush(stdout);
 				return 0;
 			}
 			round++;
@@ -486,7 +483,6 @@ static int tcpm_do_cmd(int cmd, int argc, char **argv)
 			if (show_stats) {
 				printf("\n*** Round %d, deleting %d entries ***\n",
 				       round, f.flushed);
-				fflush(stdout);
 			}
 		}
 		return 0;
diff --git a/ip/xfrm_monitor.c b/ip/xfrm_monitor.c
index 1f67fe9d..a96358b0 100644
--- a/ip/xfrm_monitor.c
+++ b/ip/xfrm_monitor.c
@@ -85,7 +85,6 @@ static int xfrm_acquire_print(struct nlmsghdr *n, void *arg)
 
 	if (oneline)
 		fprintf(fp, "\n");
-	fflush(fp);
 
 	return 0;
 }
@@ -114,7 +113,6 @@ static int xfrm_state_flush_print(struct nlmsghdr *n, void *arg)
 
 	if (oneline)
 		fprintf(fp, "\n");
-	fflush(fp);
 
 	return 0;
 }
@@ -151,7 +149,6 @@ static int xfrm_policy_flush_print(struct nlmsghdr *n, void *arg)
 
 	if (oneline)
 		fprintf(fp, "\n");
-	fflush(fp);
 
 	return 0;
 }
@@ -232,7 +229,6 @@ static int xfrm_ae_print(struct nlmsghdr *n, void *arg)
 	xfrm_usersa_print(&id->sa_id, id->reqid, fp);
 
 	fprintf(fp, "\n");
-	fflush(fp);
 
 	return 0;
 }
@@ -257,7 +253,6 @@ static int xfrm_mapping_print(struct nlmsghdr *n, void *arg)
 	xfrm_usersa_print(&map->id, map->reqid, fp);
 
 	fprintf(fp, "\n");
-	fflush(fp);
 	return 0;
 }
 
diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c
index 8687ced3..e60acd5b 100644
--- a/ip/xfrm_policy.c
+++ b/ip/xfrm_policy.c
@@ -565,7 +565,6 @@ int xfrm_policy_print(struct nlmsghdr *n, void *arg)
 
 	if (oneline)
 		fprintf(fp, "\n");
-	fflush(fp);
 
 	return 0;
 }
@@ -1232,7 +1231,6 @@ int xfrm_policy_default_print(struct nlmsghdr *n, FILE *fp)
 	fprintf(fp, " in:  %s\n", xfrm_policy_to_str(up->in));
 	fprintf(fp, " fwd: %s\n", xfrm_policy_to_str(up->fwd));
 	fprintf(fp, " out: %s\n", xfrm_policy_to_str(up->out));
-	fflush(fp);
 
 	return 0;
 }
diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index 252a7a53..dcd08d59 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -1051,7 +1051,6 @@ static int __do_xfrm_state_print(struct nlmsghdr *n, void *arg, bool nokeys)
 
 	if (oneline)
 		fprintf(fp, "\n");
-	fflush(fp);
 
 	return 0;
 }
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 6b275a1f..7c74ebd3 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -1275,6 +1275,8 @@ int rtnl_listen(struct rtnl_handle *rtnl,
 			}
 
 			err = handler(&ctrl, h, jarg);
+			fflush(stdout);
+
 			if (err < 0)
 				return err;
 
diff --git a/tc/tc_class.c b/tc/tc_class.c
index 6d707d8c..ea6d986a 100644
--- a/tc/tc_class.c
+++ b/tc/tc_class.c
@@ -380,7 +380,6 @@ int print_class(struct nlmsghdr *n, void *arg)
 		close_json_object();
 	}
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index 7db850bd..b1dcf1ba 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -374,7 +374,6 @@ int print_filter(struct nlmsghdr *n, void *arg)
 
 	print_ext_msg(tb);
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
index 7eb9a31b..634d5f70 100644
--- a/tc/tc_qdisc.c
+++ b/tc/tc_qdisc.c
@@ -344,7 +344,6 @@ int print_qdisc(struct nlmsghdr *n, void *arg)
 
 	print_ext_msg(tb);
 	close_json_object();
-	fflush(fp);
 	return 0;
 }
 
-- 
2.53.0



^ permalink raw reply related

* Re: [PATCH net v4 2/4] i40e: skip unnecessary VF reset when setting trust
From: Simon Horman @ 2026-04-27 16:25 UTC (permalink / raw)
  To: jtornosm
  Cc: 'Simon Horman', netdev, intel-wired-lan,
	przemyslaw.kitszel, aleksandr.loktionov, jacob.e.keller,
	jesse.brandeburg, anthony.l.nguyen, davem, edumazet, kuba, pabeni
In-Reply-To: <20260423130405.139568-3-jtornosm@redhat.com>

From: 'Simon Horman' <horms@kernel.org>

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: skip unnecessary VF reset when setting trust

This commit attempts to reduce the bonding setup delay by skipping the
synchronous VF reset when changing the trust setting, manually handling
the capability flag and promiscuous mode instead.

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

Is this description accurate?

i40e_vc_reset_vf() is synchronous and restores I40E_VF_STATE_ACTIVE before
returning. When i40e_del_all_cloud_filters() traverses
vf->cloud_filter_list locklessly afterwards, the VF is already active again.

Could a concurrent VIRTCHNL_OP_ADD_CLOUD_FILTER message from the guest be
processed asynchronously and corrupt the list?

> diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> index a26c3d47ec1561..26b62650aac9aa 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
[ ... ]
> @@ -4943,6 +4943,30 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable)
>  	return ret;
>  }
>  
> +/**
> + * i40e_setup_vf_trust - Enable/disable VF trust mode without reset
> + * @vf: VF to configure
> + * @setting: trust setting
> + *
> + * Manually handle capability flag and promiscuous mode when changing trust
> + * without performing a VF reset.
> + * When reset is performed, this is not necessary as the reset procedure
> + * already handles this.
> + **/
> +static void i40e_setup_vf_trust(struct i40e_vf *vf, bool setting)
> +{
> +	if (setting) {
> +		set_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
> +	} else {
> +		clear_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps);
> +
> +		if (test_bit(I40E_VF_STATE_UC_PROMISC, &vf->vf_states) ||
> +		    test_bit(I40E_VF_STATE_MC_PROMISC, &vf->vf_states))
> +			i40e_config_vf_promiscuous_mode(vf, vf->lan_vsi_idx,
> +							false, false);

Does this pass the internal software array index (vf->lan_vsi_idx) instead of
the firmware VSI ID (vf->lan_vsi_id)?

i40e_config_vf_promiscuous_mode() uses i40e_find_vsi_from_id() which matches
against the firmware ID. Could this cause the lookup to fail and silently
leave promiscuous mode enabled on the hardware?

Also, should this clear the I40E_VF_STATE_UC_PROMISC and
I40E_VF_STATE_MC_PROMISC flags from vf->vf_states?

If an untrusted VF performs a valid operation like adding a new VLAN, could
i40e_vc_add_vlan_msg() check the uncleared state bit and automatically issue
an AdminQ command to re-enable promiscuous mode, bypassing the revocation?

> +	}
> +}
> +
>  /**
>   * i40e_ndo_set_vf_trust
>   * @netdev: network interface device structure of the pf
> @@ -4987,19 +5011,17 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting)
>  	set_bit(__I40E_MACVLAN_SYNC_PENDING, pf->state);
>  	pf->vsi[vf->lan_vsi_idx]->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
>  
> -	i40e_vc_reset_vf(vf, true);
> +	/* Reset only if revoking trust with ADQ (for cloud filter cleanup) */
> +	if (vf->adq_enabled && !setting) {
> +		i40e_vc_reset_vf(vf, true);
> +		i40e_del_all_cloud_filters(vf);

Could this lead to a memory leak of the cloud filters?

The synchronous reset in i40e_vc_reset_vf() destroys the VF's VSI and
allocates a new one with a new firmware SEID. When
i40e_del_all_cloud_filters() executes afterwards, it looks up the VSI using
the old SEID from the filters, which might fail and cause it to skip the
free operation entirely.

> +	} else {
> +		i40e_setup_vf_trust(vf, setting);
> +	}

By skipping the reset when revoking trust for non-ADQ VFs, do we leave excess
hardware filters intact? Trusted VFs can configure MAC and VLAN filters
beyond standard limits. Without a reset to flush them, does the untrusted
VF retain its configured spoofed MAC addresses and excessive VLANs
indefinitely?

Furthermore, when granting trust, skipping the reset prevents sending the
VIRTCHNL_EVENT_RESET_IMPENDING event to the guest. Since virtchnl VF drivers
negotiate their capabilities and resource requests during initialization,
does this mean the guest driver remains unaware of its newly granted
privileges until the interface is manually restarted?

> +
>  	dev_info(&pf->pdev->dev, "VF %u is now %strusted\n",
>  		 vf_id, setting ? "" : "un");
>

^ permalink raw reply

* Re: [PATCH net v4 3/4] iavf: send MAC change request synchronously
From: Simon Horman @ 2026-04-27 16:43 UTC (permalink / raw)
  To: jtornosm
  Cc: 'Simon Horman', netdev, intel-wired-lan,
	przemyslaw.kitszel, aleksandr.loktionov, jacob.e.keller,
	jesse.brandeburg, anthony.l.nguyen, davem, edumazet, kuba, pabeni
In-Reply-To: <20260423130405.139568-4-jtornosm@redhat.com>

From: 'Simon Horman' <horms@kernel.org>

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
---
iavf: send MAC change request synchronously

This commit updates the MAC address setting in the iavf driver to be
synchronous. It sends the virtchnl message directly and polls the admin
queue for the response, rather than relying on the watchdog task, to avoid
deadlocks when holding the netdev instance lock.

> diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
> index 67aa14350b1b01..bc5994bf2cd99d 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_main.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c

[ ... ]

> @@ -1067,25 +1109,20 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
>  		return -EADDRNOTAVAIL;
>  
>  	ret = iavf_replace_primary_mac(adapter, addr->sa_data);
> -
>  	if (ret)
>  		return ret;
>  
> -	ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
> -					       iavf_is_mac_set_handled(netdev, addr->sa_data),
> -					       msecs_to_jiffies(2500));
> -
> -	/* If ret < 0 then it means wait was interrupted.
> -	 * If ret == 0 then it means we got a timeout.
> -	 * else it means we got response for set MAC from PF,
> -	 * check if netdev MAC was updated to requested MAC,
> -	 * if yes then set MAC succeeded otherwise it failed return -EACCES
> -	 */
> -	if (ret < 0)
> +	ret = iavf_set_mac_sync(adapter, addr->sa_data);
> +	if (ret) {
> +		/* Rollback for local failures (timeout, send error, -EBUSY).
> +		 * Note: If PF rejects the request (sends error response),
> +		 * iavf_virtchnl_completion() automatically calls
> +		 * iavf_mac_add_reject(), ret=0, and this is not executed.
> +		 * Only local failures (no PF response received) need manual rollback.
> +		 */
> +		iavf_mac_add_reject(adapter);
>  		return ret;
> -
> -	if (!ret)
> -		return -EAGAIN;
> +	}

Does the manual rollback in iavf_set_mac() need to restore adapter->hw.mac.addr?

Before calling iavf_set_mac_sync(), iavf_replace_primary_mac() optimistically
updates adapter->hw.mac.addr to the new MAC address and unsets the is_primary
flag on the old MAC filter. If iavf_set_mac_sync() fails locally,
iavf_mac_add_reject() deletes the pending new MAC filter but doesn't restore
adapter->hw.mac.addr back to netdev->dev_addr.

By contrast, the PF-rejection path in iavf_virtchnl_completion() explicitly
restores it:

	iavf_mac_add_reject(adapter);
	/* restore administratively set MAC address */
	ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);

If the local failure was a timeout and a delayed success response arrives from
the PF later, could iavf_virtchnl_completion() blindly copy the corrupted
adapter->hw.mac.addr into netdev->dev_addr? This seems like it would silently
change the interface MAC to an address already deleted from the internal list.

Additionally, on subsequent MAC change attempts, wouldn't
iavf_replace_primary_mac() search for the old filter using the corrupted
adapter->hw.mac.addr, fail to find it, and permanently leak the old filter in
the PF's hardware tables?

[ ... ]

> diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> index a52c100dcbc56d..d1afb8261c2412 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c

[ ... ]

> @@ -2956,3 +2966,76 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
>  	} /* switch v_opcode */
>  	adapter->current_op = VIRTCHNL_OP_UNKNOWN;
>  }
> +
> +/**
> + * iavf_poll_virtchnl_response - Poll admin queue for virtchnl response
> + * @adapter: adapter structure
> + * @condition: callback to check if desired response received
> + * @cond_data: context data passed to condition callback
> + * @timeout_ms: maximum time to wait in milliseconds
> + *
> + * Polls the admin queue and processes all incoming virtchnl messages.
> + * After processing each valid message, calls the condition callback to check
> + * if the expected response has been received. The callback receives the opcode
> + * of the processed message to identify which response was received. Continues
> + * polling until the callback returns true or timeout expires.
> + * Clear current_op on timeout to prevent permanent -EBUSY state.
> + * Caller must hold netdev_lock. This can sleep for up to timeout_ms while
> + * polling hardware.
> + *
> + * Return: 0 on success (condition met), -EAGAIN on timeout, or error code
> + **/
> +int iavf_poll_virtchnl_response(struct iavf_adapter *adapter,
> +				bool (*condition)(struct iavf_adapter *adapter,
> +						  const void *data,
> +						  enum virtchnl_ops v_op),
> +				const void *cond_data,
> +				unsigned int timeout_ms)
> +{

[ ... ]

> +		if (iavf_clean_arq_element(hw, &event, &pending) == IAVF_SUCCESS) {
> +			received_op = (enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
> +			if (received_op != VIRTCHNL_OP_UNKNOWN) {
> +				v_retval = le32_to_cpu(event.desc.cookie_low);
> +
> +				iavf_virtchnl_completion(adapter, received_op,
> +							 (enum iavf_status)v_retval,
> +							 event.msg_buf, event.msg_len);
> +
> +				if (condition(adapter, cond_data, received_op)) {
> +					ret = 0;
> +					break;
> +				}
> +			}
> +
> +			memset(event.msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE);
> +
> +			if (pending)
> +				continue;
> +		}
> +
> +		usleep_range(50, 75);
> +	} while (time_before(jiffies, timeout));
> +
> +	if (ret == -EAGAIN && adapter->current_op != VIRTCHNL_OP_UNKNOWN)
> +		adapter->current_op = VIRTCHNL_OP_UNKNOWN;

Could clearing adapter->current_op on timeout cause overlapping virtchnl
commands and state corruption?

If the timeout expires and adapter->current_op is forced to
VIRTCHNL_OP_UNKNOWN, the VF watchdog might consider the admin queue free
and send a new command while the PF is still actively processing the
timed-out request.

If the PF eventually completes the timed-out request and sends a late response,
iavf_virtchnl_completion() will process it. At the end of
iavf_virtchnl_completion(), the driver unconditionally clears the state:

	adapter->current_op = VIRTCHNL_OP_UNKNOWN;

Would this prematurely clear the tracking state for the newly in-flight
overlapping command, compounding the state machine corruption and allowing
even more commands to be sent concurrently?

> +
> +	kfree(event.msg_buf);
> +	return ret;
> +}

^ permalink raw reply


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