* [PATCH net 02/13] i40e: Cleanup PTP pins on probe failure
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Matt Vollrath, Kohei Enju,
Paul Menzel, Sunitha Mekala
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Matt Vollrath <tactii@gmail.com>
PTP pin structs are allocated early in probe, but never cleaned up.
Fix this by calling i40e_ptp_free_pins in the error path.
To support this, i40e_ptp_free_pins is added to the header and
pin_config is correctly nullified after being freed.
This has been an issue since i40e_ptp_alloc_pins was introduced.
Fixes: 1050713026a08 ("i40e: add support for PTP external synchronization clock")
Reported-by: Kohei Enju <kohei@enjuk.jp>
Cc: stable@vger.kernel.org
Signed-off-by: Matt Vollrath <tactii@gmail.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Kohei Enju <kohei@enjuk.jp>
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e.h | 1 +
drivers/net/ethernet/intel/i40e/i40e_main.c | 1 +
drivers/net/ethernet/intel/i40e/i40e_ptp.c | 3 ++-
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index dcb50c2e1aa2..83e780919ac9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -1318,6 +1318,7 @@ void i40e_ptp_restore_hw_time(struct i40e_pf *pf);
void i40e_ptp_init(struct i40e_pf *pf);
void i40e_ptp_stop(struct i40e_pf *pf);
int i40e_ptp_alloc_pins(struct i40e_pf *pf);
+void i40e_ptp_free_pins(struct i40e_pf *pf);
int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset);
int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi);
int i40e_get_partition_bw_setting(struct i40e_pf *pf);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index f06fcef644e5..6d4f9218dc68 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -16112,6 +16112,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
i40e_clear_interrupt_scheme(pf);
kfree(pf->vsi);
err_switch_setup:
+ i40e_ptp_free_pins(pf);
i40e_reset_interrupt_capability(pf);
timer_shutdown_sync(&pf->service_timer);
err_mac_addr:
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
index 404a716db8da..7d07c389bb23 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
@@ -940,12 +940,13 @@ int i40e_ptp_hwtstamp_get(struct net_device *netdev,
*
* Release memory allocated for PTP pins.
**/
-static void i40e_ptp_free_pins(struct i40e_pf *pf)
+void i40e_ptp_free_pins(struct i40e_pf *pf)
{
if (i40e_is_ptp_pin_dev(&pf->hw)) {
kfree(pf->ptp_pins);
kfree(pf->ptp_caps.pin_config);
pf->ptp_pins = NULL;
+ pf->ptp_caps.pin_config = NULL;
}
}
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 04/13] idpf: fix read_dev_clk_lock spinlock init in idpf_ptp_init()
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Emil Tantilov, Simon Horman,
Samuel Salin
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
In idpf_ptp_init(), read_dev_clk_lock is initialized after
ptp_schedule_worker() had already been called (and after
idpf_ptp_settime64() could reach the lock). The PTP aux worker
fires immediately upon scheduling and can call into
idpf_ptp_read_src_clk_reg_direct(), which takes
spin_lock(&ptp->read_dev_clk_lock) on an uninitialized lock, triggering
the lockdep "non-static key" warning:
[12973.796587] idpf 0000:83:00.0: Device HW Reset initiated
[12974.094507] INFO: trying to register non-static key.
...
[12974.097208] Call Trace:
[12974.097213] <TASK>
[12974.097218] dump_stack_lvl+0x93/0xe0
[12974.097234] register_lock_class+0x4c4/0x4e0
[12974.097249] ? __lock_acquire+0x427/0x2290
[12974.097259] __lock_acquire+0x98/0x2290
[12974.097272] lock_acquire+0xc6/0x310
[12974.097281] ? idpf_ptp_read_src_clk_reg+0xb7/0x150 [idpf]
[12974.097311] ? lockdep_hardirqs_on_prepare+0xde/0x190
[12974.097318] ? finish_task_switch.isra.0+0xd2/0x350
[12974.097330] ? __pfx_ptp_aux_kworker+0x10/0x10 [ptp]
[12974.097343] _raw_spin_lock+0x30/0x40
[12974.097353] ? idpf_ptp_read_src_clk_reg+0xb7/0x150 [idpf]
[12974.097373] idpf_ptp_read_src_clk_reg+0xb7/0x150 [idpf]
[12974.097391] ? kthread_worker_fn+0x88/0x3d0
[12974.097404] ? kthread_worker_fn+0x4e/0x3d0
[12974.097411] idpf_ptp_update_cached_phctime+0x26/0x120 [idpf]
[12974.097428] ? _raw_spin_unlock_irq+0x28/0x50
[12974.097436] idpf_ptp_do_aux_work+0x15/0x20 [idpf]
[12974.097454] ptp_aux_kworker+0x20/0x40 [ptp]
[12974.097464] kthread_worker_fn+0xd5/0x3d0
[12974.097474] ? __pfx_kthread_worker_fn+0x10/0x10
[12974.097482] kthread+0xf4/0x130
[12974.097489] ? __pfx_kthread+0x10/0x10
[12974.097498] ret_from_fork+0x32c/0x410
[12974.097512] ? __pfx_kthread+0x10/0x10
[12974.097519] ret_from_fork_asm+0x1a/0x30
[12974.097540] </TASK>
Move the call to spin_lock_init() up a bit to make sure read_dev_clk_lock
is not touched before it's been initialized.
Fixes: 5cb8805d2366 ("idpf: negotiate PTP capabilities and get PTP clock")
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/idpf/idpf_ptp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
index eec91c4f0a75..4a51d2727547 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
@@ -952,6 +952,8 @@ int idpf_ptp_init(struct idpf_adapter *adapter)
goto free_ptp;
}
+ spin_lock_init(&adapter->ptp->read_dev_clk_lock);
+
err = idpf_ptp_create_clock(adapter);
if (err)
goto free_ptp;
@@ -977,8 +979,6 @@ int idpf_ptp_init(struct idpf_adapter *adapter)
goto remove_clock;
}
- spin_lock_init(&adapter->ptp->read_dev_clk_lock);
-
pci_dbg(adapter->pdev, "PTP init successful\n");
return 0;
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 03/13] i40e: keep q_vectors array in sync with channel count changes
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Simon Horman, Sunitha Mekala
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
For the main VSI, i40e_set_num_rings_in_vsi() always derives
num_q_vectors from pf->num_lan_msix. At the same time, ethtool -L stores
the user requested channel count in vsi->req_queue_pairs and the queue
setup path uses that value for the effective number of queue pairs.
This leaves queue and vector counts out of sync after shrinking channel
count via ethtool -L. The active queue configuration is reduced, but the
VSI still keeps the full PF-sized q_vector topology.
That mismatch breaks reconfiguration flows which rely on vector/NAPI
state matching the effective channel configuration. In particular,
toggling /sys/class/net/<dev>/threaded after reducing the channel count
can hang, and later channel-count changes can fail because VSI reinit
does not rebuild q_vectors to match the new vector count.
Fix this by making the main VSI num_q_vectors follow the effective
requested channel count, capped by the available MSI-X vectors. Update
i40e_vsi_reinit_setup() to rebuild q_vectors during VSI reinit so the
vector topology is refreshed together with the ring arrays when channel
count changes.
Keep alloc_queue_pairs unchanged and based on pf->num_lan_qps so the VSI
retains its full queue capacity.
Selftest napi_threaded.py was originally used when Jakub reported hang
on /sys/class/net/<dev>/threaded toggle. In order to make it pass on
i40e, use persistent NAPI configuration for q_vector NAPIs so NAPI
identity and threaded settings survive q_vector reallocation across
channel-count changes. This is achieved by using netif_napi_add_config()
when configuring q_vectors.
$ export NETIF=ens259f1np1
$ sudo -E env PATH="$PATH" ./tools/testing/selftests/drivers/net/napi_threaded.py
TAP version 13
1..3
ok 1 napi_threaded.napi_init
ok 2 napi_threaded.change_num_queues
ok 3 napi_threaded.enable_dev_threaded_disable_napi_threaded
Totals: pass:3 fail:0 xfail:0 xpass:0 skip:0 error:0
[Jake: use min() and clamp() as suggested by Simon on Intel Wired LAN]
Reported-by: Jakub Kicinski <kuba@kernel.org>
Closes: https://lore.kernel.org/intel-wired-lan/20260316133100.6054a11f@kernel.org/
Fixes: d2a69fefd756 ("i40e: Fix changing previously set num_queue_pairs for PFs")
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 34 ++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 6d4f9218dc68..23156015ed86 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -11403,10 +11403,14 @@ static void i40e_service_timer(struct timer_list *t)
static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
{
struct i40e_pf *pf = vsi->back;
+ u16 qps;
switch (vsi->type) {
case I40E_VSI_MAIN:
vsi->alloc_queue_pairs = pf->num_lan_qps;
+ qps = vsi->req_queue_pairs ?
+ min(vsi->req_queue_pairs, pf->num_lan_qps) :
+ pf->num_lan_qps;
if (!vsi->num_tx_desc)
vsi->num_tx_desc = ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
I40E_REQ_DESCRIPTOR_MULTIPLE);
@@ -11414,7 +11418,7 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
vsi->num_rx_desc = ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
I40E_REQ_DESCRIPTOR_MULTIPLE);
if (test_bit(I40E_FLAG_MSIX_ENA, pf->flags))
- vsi->num_q_vectors = pf->num_lan_msix;
+ vsi->num_q_vectors = clamp(qps, 1, pf->num_lan_msix);
else
vsi->num_q_vectors = 1;
@@ -11503,6 +11507,7 @@ static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi, bool alloc_qvectors)
err_vectors:
kfree(vsi->tx_rings);
+ vsi->tx_rings = NULL;
return ret;
}
@@ -12043,7 +12048,8 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx)
cpumask_copy(&q_vector->affinity_mask, cpu_possible_mask);
if (vsi->netdev)
- netif_napi_add(vsi->netdev, &q_vector->napi, i40e_napi_poll);
+ netif_napi_add_config(vsi->netdev, &q_vector->napi,
+ i40e_napi_poll, v_idx);
/* tie q_vector and vsi together */
vsi->q_vectors[v_idx] = q_vector;
@@ -14264,12 +14270,27 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
pf = vsi->back;
+ if (test_bit(I40E_FLAG_MSIX_ENA, pf->flags)) {
+ i40e_put_lump(pf->irq_pile, vsi->base_vector, vsi->idx);
+ vsi->base_vector = 0;
+ }
+
i40e_put_lump(pf->qp_pile, vsi->base_queue, vsi->idx);
i40e_vsi_clear_rings(vsi);
- i40e_vsi_free_arrays(vsi, false);
+ i40e_vsi_free_q_vectors(vsi);
+ i40e_vsi_free_arrays(vsi, true);
i40e_set_num_rings_in_vsi(vsi);
- ret = i40e_vsi_alloc_arrays(vsi, false);
+
+ ret = i40e_vsi_alloc_arrays(vsi, true);
+ if (ret)
+ goto err_vsi;
+
+ /* Rebuild q_vectors during VSI reinit because the effective channel
+ * count may change num_q_vectors. Keep vector topology aligned with the
+ * queue configuration after ethtool's .set_channels() callback.
+ */
+ ret = i40e_vsi_setup_vectors(vsi);
if (ret)
goto err_vsi;
@@ -14281,7 +14302,7 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
dev_info(&pf->pdev->dev,
"failed to get tracking for %d queues for VSI %d err %d\n",
alloc_queue_pairs, vsi->seid, ret);
- goto err_vsi;
+ goto err_lump;
}
vsi->base_queue = ret;
@@ -14305,7 +14326,6 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
return vsi;
err_rings:
- i40e_vsi_free_q_vectors(vsi);
if (vsi->netdev_registered) {
vsi->netdev_registered = false;
unregister_netdev(vsi->netdev);
@@ -14315,6 +14335,8 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
if (vsi->type == I40E_VSI_MAIN)
i40e_devlink_destroy_port(pf);
i40e_aq_delete_element(&pf->hw, vsi->seid, NULL);
+err_lump:
+ i40e_vsi_free_q_vectors(vsi);
err_vsi:
i40e_vsi_clear(vsi);
return NULL;
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 05/13] idpf: do not enable XDP if queue based scheduling is not supported
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Patryk Holda
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Joshua Hay <joshua.a.hay@intel.com>
The current XDP implementation uses queue based scheduling for its TxQs.
If the FW does not advertise support for queue based scheduling, do not
enable XDP. Add the missing capability check at the start of the XDP
configuration. This will temporarily break XDP while a flow based
implementation is worked on, as well as while FWs with queue based by
default are rolled out.
Fixes: 705457e7211f ("idpf: implement XDP_SETUP_PROG in ndo_bpf for splitq")
Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
Tested-by: Patryk Holda <patryk.holda@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/idpf/xdp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/intel/idpf/xdp.c b/drivers/net/ethernet/intel/idpf/xdp.c
index cbccd4546768..dcd867517a5f 100644
--- a/drivers/net/ethernet/intel/idpf/xdp.c
+++ b/drivers/net/ethernet/intel/idpf/xdp.c
@@ -510,6 +510,13 @@ int idpf_xdp(struct net_device *dev, struct netdev_bpf *xdp)
if (!idpf_is_queue_model_split(vport->dflt_qv_rsrc.txq_model))
goto notsupp;
+ if (!idpf_is_cap_ena(vport->adapter, IDPF_OTHER_CAPS,
+ VIRTCHNL2_CAP_SPLITQ_QSCHED)) {
+ NL_SET_ERR_MSG_MOD(xdp->extack,
+ "Device does not support requested XDP Tx scheduling mode");
+ goto notsupp;
+ }
+
switch (xdp->command) {
case XDP_SETUP_PROG:
ret = idpf_xdp_setup_prog(vport, xdp);
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 06/13] idpf: fix skb datapath queue based scheduling crashes and timeouts
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Samuel Salin
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Joshua Hay <joshua.a.hay@intel.com>
The splitq Tx resource checks were assuming that the queues were using
flow based scheduling and checking the refillqs for free buffers.
However, the Tx refillqs are not allocated when using queue based
scheduling resulting in a NULL ptr dereference. Adjust the Tx resource
checks to only check available descriptor resources when using queue
based scheduling. Because queue based scheduling does not have any
notion of descriptor only completions, there cannot be any packets in
flight, meaning there is no need to check for pending completions.
The driver also only supported 8 byte completion descriptors in the skb
datapath previously. However, currently the FW only supports 4 byte
completion descriptors when using queue based scheduling. This meant we
were skipping over completions, resulting in Tx timeouts. Add support
to process both 4 and 8 byte completion descriptors, depending on the
scheduling mode. Cache the next_to_clean completion descriptor in the
completion queue struct, and fetch this descriptor before the start of
each cleaning loop. Access the next descriptor in the loop by
calculating the index based on raw byte count.
Fixes: 0c3f135e840d ("idpf: stop Tx if there are insufficient buffer resources")
Fixes: 1c325aac10a8 ("idpf: configure resources for TX queues")
Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/idpf/idpf_txrx.h | 6 +++-
drivers/net/ethernet/intel/idpf/idpf_txrx.c | 49 ++++++++++++++++++-----------
2 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
index 4be5b3b6d3ed..b6836e38f449 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
@@ -807,11 +807,13 @@ libeth_cacheline_set_assert(struct idpf_buf_queue, 64, 24, 32);
* @txq_grp: See struct idpf_txq_group
* @flags: See enum idpf_queue_flags_t
* @desc_count: Number of descriptors
+ * @desc_sz: Descriptor size in bytes
* @clean_budget: queue cleaning budget
* @netdev: &net_device corresponding to this queue
* @next_to_use: Next descriptor to use. Relevant in both split & single txq
* and bufq.
* @next_to_clean: Next descriptor to clean
+ * @ntc_desc: Pointer to next_to_clean descriptor for next NAPI poll
* @num_completions: Only relevant for TX completion queue. It tracks the
* number of completions received to compare against the
* number of completions pending, as accumulated by the
@@ -833,6 +835,7 @@ struct idpf_compl_queue {
DECLARE_BITMAP(flags, __IDPF_Q_FLAGS_NBITS);
u32 desc_count;
+ u32 desc_sz;
u32 clean_budget;
struct net_device *netdev;
@@ -841,6 +844,7 @@ struct idpf_compl_queue {
__cacheline_group_begin_aligned(read_write);
u32 next_to_use;
u32 next_to_clean;
+ struct idpf_splitq_tx_compl_desc *ntc_desc;
aligned_u64 num_completions;
__cacheline_group_end_aligned(read_write);
@@ -853,7 +857,7 @@ struct idpf_compl_queue {
struct idpf_q_vector *q_vector;
__cacheline_group_end_aligned(cold);
};
-libeth_cacheline_set_assert(struct idpf_compl_queue, 40, 16, 24);
+libeth_cacheline_set_assert(struct idpf_compl_queue, 48, 24, 24);
/**
* struct idpf_sw_queue
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index f6b3b15364ff..4fc0bb14c5b1 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -270,11 +270,9 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
static int idpf_compl_desc_alloc(const struct idpf_vport *vport,
struct idpf_compl_queue *complq)
{
- u32 desc_size;
-
- desc_size = idpf_queue_has(FLOW_SCH_EN, complq) ?
- sizeof(*complq->comp) : sizeof(*complq->comp_4b);
- complq->size = array_size(complq->desc_count, desc_size);
+ complq->desc_sz = idpf_queue_has(FLOW_SCH_EN, complq) ?
+ sizeof(*complq->comp) : sizeof(*complq->comp_4b);
+ complq->size = array_size(complq->desc_count, complq->desc_sz);
complq->desc_ring = dma_alloc_coherent(complq->netdev->dev.parent,
complq->size, &complq->dma,
@@ -284,6 +282,7 @@ static int idpf_compl_desc_alloc(const struct idpf_vport *vport,
complq->next_to_use = 0;
complq->next_to_clean = 0;
+ complq->ntc_desc = complq->comp;
idpf_queue_set(GEN_CHK, complq);
idpf_xsk_setup_queue(vport, complq,
@@ -2193,7 +2192,7 @@ static void idpf_tx_handle_rs_completion(struct idpf_tx_queue *txq,
static bool idpf_tx_clean_complq(struct idpf_compl_queue *complq, int budget,
int *cleaned)
{
- struct idpf_splitq_tx_compl_desc *tx_desc;
+ struct idpf_splitq_tx_compl_desc *tx_desc = complq->ntc_desc;
s16 ntc = complq->next_to_clean;
struct idpf_netdev_priv *np;
unsigned int complq_budget;
@@ -2201,7 +2200,6 @@ static bool idpf_tx_clean_complq(struct idpf_compl_queue *complq, int budget,
int i;
complq_budget = complq->clean_budget;
- tx_desc = &complq->comp[ntc];
ntc -= complq->desc_count;
do {
@@ -2257,11 +2255,12 @@ static bool idpf_tx_clean_complq(struct idpf_compl_queue *complq, int budget,
u64_stats_update_end(&tx_q->stats_sync);
fetch_next_desc:
- tx_desc++;
+ tx_desc = (struct idpf_splitq_tx_compl_desc *)
+ ((u8 *)tx_desc + complq->desc_sz);
ntc++;
if (unlikely(!ntc)) {
ntc -= complq->desc_count;
- tx_desc = &complq->comp[0];
+ tx_desc = complq->comp;
idpf_queue_change(GEN_CHK, complq);
}
@@ -2271,6 +2270,8 @@ static bool idpf_tx_clean_complq(struct idpf_compl_queue *complq, int budget,
complq_budget--;
} while (likely(complq_budget));
+ complq->ntc_desc = tx_desc;
+
/* Store the state of the complq to be used later in deciding if a
* TXQ can be started again
*/
@@ -2437,21 +2438,32 @@ static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 descs_needed,
* @tx_q: the queue to be checked
* @descs_needed: number of descriptors required for this packet
* @bufs_needed: number of buffers needed for this packet
+ * @flow: true if queue uses flow based scheduling, false if queue based scheduling
*
* Return: 0 if stop is not needed
*/
static int idpf_tx_maybe_stop_splitq(struct idpf_tx_queue *tx_q,
- u32 descs_needed,
- u32 bufs_needed)
+ u32 descs_needed, u32 bufs_needed,
+ bool flow)
{
- /* Since we have multiple resources to check for splitq, our
+ /* Since we have multiple resources to check for flow based splitq, our
* start,stop_thrs becomes a boolean check instead of a count
* threshold.
*/
- if (netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
- idpf_txq_has_room(tx_q, descs_needed,
- bufs_needed),
- 1, 1))
+ if (flow && netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
+ idpf_txq_has_room(tx_q,
+ descs_needed,
+ bufs_needed),
+ 1, 1))
+ return 0;
+
+ /* For queue based splitq, there is no need to check the number of
+ * pending completions since we cannot reuse descriptors until we get
+ * completions, so we only need to check for descriptor resources.
+ */
+ if (!flow && netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
+ IDPF_DESC_UNUSED(tx_q),
+ descs_needed, descs_needed))
return 0;
u64_stats_update_begin(&tx_q->stats_sync);
@@ -3021,6 +3033,7 @@ static bool idpf_tx_splitq_need_re(struct idpf_tx_queue *tx_q)
static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
struct idpf_tx_queue *tx_q)
{
+ bool flow = idpf_queue_has(FLOW_SCH_EN, tx_q);
struct idpf_tx_splitq_params tx_params = {
.prev_ntu = tx_q->next_to_use,
};
@@ -3040,7 +3053,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
/* Check for splitq specific TX resources */
count += (IDPF_TX_DESCS_PER_CACHE_LINE + tso);
- if (idpf_tx_maybe_stop_splitq(tx_q, count, buf_count)) {
+ if (idpf_tx_maybe_stop_splitq(tx_q, count, buf_count, flow)) {
idpf_tx_buf_hw_update(tx_q, tx_q->next_to_use, false);
return NETDEV_TX_BUSY;
@@ -3072,7 +3085,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
idpf_tx_set_tstamp_desc(ctx_desc, idx);
}
- if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
+ if (flow) {
struct idpf_sw_queue *refillq = tx_q->refillq;
/* Save refillq state in case of a packet rollback. Otherwise,
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 07/13] idpf: fix xdp crash in soft reset error path
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Emil Tantilov
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
NULL pointer dereference is reported in cases where idpf_vport_open()
fails during soft reset:
./xdpsock -i <inf> -q -r -N
[ 3179.186687] idpf 0000:83:00.0: Failed to initialize queue ids for vport 0: -12
[ 3179.276739] BUG: kernel NULL pointer dereference, address: 0000000000000010
[ 3179.277636] #PF: supervisor read access in kernel mode
[ 3179.278470] #PF: error_code(0x0000) - not-present page
[ 3179.279285] PGD 0
[ 3179.280083] Oops: Oops: 0000 [#1] SMP NOPTI
...
[ 3179.283997] Workqueue: events xp_release_deferred
[ 3179.284770] RIP: 0010:idpf_find_rxq_vec+0x17/0x30 [idpf]
...
[ 3179.291937] Call Trace:
[ 3179.292392] <TASK>
[ 3179.292843] idpf_qp_switch+0x25/0x820 [idpf]
[ 3179.293325] idpf_xsk_pool_setup+0x7c/0x520 [idpf]
[ 3179.293803] idpf_xdp+0x59/0x240 [idpf]
[ 3179.294275] xp_disable_drv_zc+0x62/0xb0
[ 3179.294743] xp_clear_dev+0x40/0xb0
[ 3179.295198] xp_release_deferred+0x1f/0xa0
[ 3179.295648] process_one_work+0x226/0x730
[ 3179.296106] worker_thread+0x19e/0x340
[ 3179.296557] ? __pfx_worker_thread+0x10/0x10
[ 3179.297009] kthread+0xf4/0x130
[ 3179.297459] ? __pfx_kthread+0x10/0x10
[ 3179.297910] ret_from_fork+0x32c/0x410
[ 3179.298361] ? __pfx_kthread+0x10/0x10
[ 3179.298702] ret_from_fork_asm+0x1a/0x30
Fix the error handling of the soft reset in idpf_xdp_setup_prog() by
restoring the vport->xdp_prog to the old value. This avoids referencing
the orphaned prog that was copied to vport->xdp_prog in the soft reset
and prevents subsequent false positive by idpf_xdp_enabled(). Roll back
the number of queues as well. Also only call put on the program if the
soft reset was successful. Returning an error will trigger the core XDP
stack to handle the put otherwise.
Update the restart check in idpf_xsk_pool_setup() to use IDPF_VPORT_UP bit
instead of netif_running(). The idpf_vport_stop/start() calls will not
update the __LINK_STATE_START bit, making this test a false positive
should the soft reset fail.
Fixes: 3d57b2c00f09 ("idpf: add XSk pool initialization")
Cc: stable@vger.kernel.org
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/idpf/idpf_txrx.h | 6 +++---
drivers/net/ethernet/intel/idpf/idpf_virtchnl.h | 4 ++--
drivers/net/ethernet/intel/idpf/idpf_lib.c | 4 +---
drivers/net/ethernet/intel/idpf/idpf_txrx.c | 12 ++++--------
drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 19 ++++---------------
drivers/net/ethernet/intel/idpf/xdp.c | 8 +++++---
drivers/net/ethernet/intel/idpf/xsk.c | 4 +++-
7 files changed, 22 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
index b6836e38f449..22c647d6dd5c 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
@@ -1084,9 +1084,9 @@ void idpf_vport_init_num_qs(struct idpf_vport *vport,
struct idpf_q_vec_rsrc *rsrc);
void idpf_vport_calc_num_q_desc(struct idpf_vport *vport,
struct idpf_q_vec_rsrc *rsrc);
-int idpf_vport_calc_total_qs(struct idpf_adapter *adapter, u16 vport_index,
- struct virtchnl2_create_vport *vport_msg,
- struct idpf_vport_max_q *max_q);
+void idpf_vport_calc_total_qs(struct idpf_adapter *adapter, u16 vport_index,
+ struct virtchnl2_create_vport *vport_msg,
+ struct idpf_vport_max_q *max_q);
void idpf_vport_calc_num_q_groups(struct idpf_q_vec_rsrc *rsrc);
int idpf_vport_queues_alloc(struct idpf_vport *vport,
struct idpf_q_vec_rsrc *rsrc);
diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
index 6876e3ed9d1b..76d238fc660c 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
@@ -169,8 +169,8 @@ int idpf_send_destroy_vport_msg(struct idpf_adapter *adapter, u32 vport_id);
int idpf_send_enable_vport_msg(struct idpf_adapter *adapter, u32 vport_id);
int idpf_send_disable_vport_msg(struct idpf_adapter *adapter, u32 vport_id);
-int idpf_vport_adjust_qs(struct idpf_vport *vport,
- struct idpf_q_vec_rsrc *rsrc);
+void idpf_vport_adjust_qs(struct idpf_vport *vport,
+ struct idpf_q_vec_rsrc *rsrc);
int idpf_vport_alloc_max_qs(struct idpf_adapter *adapter,
struct idpf_vport_max_q *max_q);
void idpf_vport_dealloc_max_qs(struct idpf_adapter *adapter,
diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c
index cf966fe6c759..56198b417c97 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
@@ -2042,9 +2042,7 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
/* Adjust resource parameters prior to reallocating resources */
switch (reset_cause) {
case IDPF_SR_Q_CHANGE:
- err = idpf_vport_adjust_qs(new_vport, new_rsrc);
- if (err)
- goto free_vport;
+ idpf_vport_adjust_qs(new_vport, new_rsrc);
break;
case IDPF_SR_Q_DESC_CHANGE:
/* Update queue parameters before allocating resources */
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index 4fc0bb14c5b1..4e0d31023123 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -1568,12 +1568,10 @@ void idpf_vport_calc_num_q_desc(struct idpf_vport *vport,
* @vport_idx: vport idx to retrieve vport pointer
* @vport_msg: message to fill with data
* @max_q: vport max queue info
- *
- * Return: 0 on success, error value on failure.
*/
-int idpf_vport_calc_total_qs(struct idpf_adapter *adapter, u16 vport_idx,
- struct virtchnl2_create_vport *vport_msg,
- struct idpf_vport_max_q *max_q)
+void idpf_vport_calc_total_qs(struct idpf_adapter *adapter, u16 vport_idx,
+ struct virtchnl2_create_vport *vport_msg,
+ struct idpf_vport_max_q *max_q)
{
int dflt_splitq_txq_grps = 0, dflt_singleq_txqs = 0;
int dflt_splitq_rxq_grps = 0, dflt_singleq_rxqs = 0;
@@ -1624,7 +1622,7 @@ int idpf_vport_calc_total_qs(struct idpf_adapter *adapter, u16 vport_idx,
}
if (!vport_config)
- return 0;
+ return;
user = &vport_config->user_config;
user->num_req_rx_qs = le16_to_cpu(vport_msg->num_rx_q);
@@ -1640,8 +1638,6 @@ int idpf_vport_calc_total_qs(struct idpf_adapter *adapter, u16 vport_idx,
vport_msg->num_tx_q = cpu_to_le16(user->num_req_tx_qs + num_xdpsq);
if (idpf_is_queue_model_split(le16_to_cpu(vport_msg->txq_model)))
vport_msg->num_tx_complq = vport_msg->num_tx_q;
-
- return 0;
}
/**
diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
index be66f9b2e101..91af4f298475 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -1578,12 +1578,7 @@ int idpf_send_create_vport_msg(struct idpf_adapter *adapter,
else
vport_msg->rxq_model = cpu_to_le16(VIRTCHNL2_QUEUE_MODEL_SINGLE);
- err = idpf_vport_calc_total_qs(adapter, idx, vport_msg, max_q);
- if (err) {
- dev_err(&adapter->pdev->dev, "Enough queues are not available");
-
- return err;
- }
+ idpf_vport_calc_total_qs(adapter, idx, vport_msg, max_q);
if (!adapter->vport_params_recvd[idx]) {
adapter->vport_params_recvd[idx] = kzalloc(IDPF_CTLQ_MAX_BUF_LEN,
@@ -4065,24 +4060,18 @@ int idpf_vport_queue_ids_init(struct idpf_vport *vport,
* @vport: virtual port data struct
* @rsrc: pointer to queue and vector resources
*
- * Renegotiate queues. Returns 0 on success, negative on failure.
+ * Renegotiate queues.
*/
-int idpf_vport_adjust_qs(struct idpf_vport *vport, struct idpf_q_vec_rsrc *rsrc)
+void idpf_vport_adjust_qs(struct idpf_vport *vport, struct idpf_q_vec_rsrc *rsrc)
{
struct virtchnl2_create_vport vport_msg;
- int err;
vport_msg.txq_model = cpu_to_le16(rsrc->txq_model);
vport_msg.rxq_model = cpu_to_le16(rsrc->rxq_model);
- err = idpf_vport_calc_total_qs(vport->adapter, vport->idx, &vport_msg,
- NULL);
- if (err)
- return err;
+ idpf_vport_calc_total_qs(vport->adapter, vport->idx, &vport_msg, NULL);
idpf_vport_init_num_qs(vport, &vport_msg, rsrc);
idpf_vport_calc_num_q_groups(rsrc);
-
- return 0;
}
/**
diff --git a/drivers/net/ethernet/intel/idpf/xdp.c b/drivers/net/ethernet/intel/idpf/xdp.c
index dcd867517a5f..f6e6b72169fd 100644
--- a/drivers/net/ethernet/intel/idpf/xdp.c
+++ b/drivers/net/ethernet/intel/idpf/xdp.c
@@ -488,11 +488,13 @@ static int idpf_xdp_setup_prog(struct idpf_vport *vport,
"Could not reopen the vport after XDP setup");
cfg->user_config.xdp_prog = old;
- old = prog;
- }
+ vport->xdp_prog = old;
- if (old)
+ /* Restore previous queue config */
+ idpf_vport_adjust_qs(vport, &vport->dflt_qv_rsrc);
+ } else if (old) {
bpf_prog_put(old);
+ }
libeth_xdp_set_redirect(vport->netdev, vport->xdp_prog);
diff --git a/drivers/net/ethernet/intel/idpf/xsk.c b/drivers/net/ethernet/intel/idpf/xsk.c
index d95d3efdfd36..3d8c430efd2b 100644
--- a/drivers/net/ethernet/intel/idpf/xsk.c
+++ b/drivers/net/ethernet/intel/idpf/xsk.c
@@ -553,6 +553,7 @@ int idpf_xskrq_poll(struct idpf_rx_queue *rxq, u32 budget)
int idpf_xsk_pool_setup(struct idpf_vport *vport, struct netdev_bpf *bpf)
{
+ const struct idpf_netdev_priv *np = netdev_priv(vport->netdev);
struct xsk_buff_pool *pool = bpf->xsk.pool;
u32 qid = bpf->xsk.queue_id;
bool restart;
@@ -568,7 +569,8 @@ int idpf_xsk_pool_setup(struct idpf_vport *vport, struct netdev_bpf *bpf)
return -EINVAL;
}
- restart = idpf_xdp_enabled(vport) && netif_running(vport->netdev);
+ restart = idpf_xdp_enabled(vport) &&
+ test_bit(IDPF_VPORT_UP, np->state);
if (!restart)
goto pool;
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 08/13] idpf: fix double free and use-after-free in aux device error paths
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Greg Kroah-Hartman, Tony Nguyen,
stable, Paul Menzel
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
When auxiliary_device_add() fails in idpf_plug_vport_aux_dev() or
idpf_plug_core_aux_dev(), the err_aux_dev_add label calls
auxiliary_device_uninit() and falls through to err_aux_dev_init. The
uninit call will trigger put_device(), which invokes the release
callback (idpf_vport_adev_release / idpf_core_adev_release) that frees
iadev. The fall-through then reads adev->id from the freed iadev for
ida_free() and double-frees iadev with kfree().
Free the IDA slot and clear the back-pointer before uninit, while adev
is still valid, then return immediately.
Commit 65637c3a1811 ("idpf: fix UAF in RDMA core aux dev deinitialization")
fixed the same use-after-free in the matching unplug path in this file but
missed both probe error paths.
Cc: Tony Nguyen <anthony.l.nguyen@intel.com>
Cc: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: stable@kernel.org
Fixes: be91128c579c ("idpf: implement RDMA vport auxiliary dev create, init, and destroy")
Fixes: f4312e6bfa2a ("idpf: implement core RDMA auxiliary dev create, init, and destroy")
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/idpf/idpf_idc.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_idc.c b/drivers/net/ethernet/intel/idpf/idpf_idc.c
index 7e4f4ac92653..b7d6b08fc89e 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_idc.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_idc.c
@@ -90,7 +90,10 @@ static int idpf_plug_vport_aux_dev(struct iidc_rdma_core_dev_info *cdev_info,
return 0;
err_aux_dev_add:
+ ida_free(&idpf_idc_ida, adev->id);
+ vdev_info->adev = NULL;
auxiliary_device_uninit(adev);
+ return ret;
err_aux_dev_init:
ida_free(&idpf_idc_ida, adev->id);
err_ida_alloc:
@@ -228,7 +231,10 @@ static int idpf_plug_core_aux_dev(struct iidc_rdma_core_dev_info *cdev_info)
return 0;
err_aux_dev_add:
+ ida_free(&idpf_idc_ida, adev->id);
+ cdev_info->adev = NULL;
auxiliary_device_uninit(adev);
+ return ret;
err_aux_dev_init:
ida_free(&idpf_idc_ida, adev->id);
err_ida_alloc:
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 09/13] ice: fix setting RSS VSI hash for E830
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Marcin Szycik
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Marcin Szycik <marcin.szycik@linux.intel.com>
ice_set_rss_hfunc() performs a VSI update, in which it sets hashing
function, leaving other VSI options unchanged. However, ::q_opt_flags is
mistakenly set to the value of another field, instead of its original
value, probably due to a typo. What happens next is hardware-dependent:
On E810, only the first bit is meaningful (see
ICE_AQ_VSI_Q_OPT_PE_FLTR_EN) and can potentially end up in a different
state than before VSI update.
On E830, some of the remaining bits are not reserved. Setting them
to some unrelated values can cause the firmware to reject the update
because of invalid settings, or worse - succeed.
Reproducer:
sudo ethtool -X $PF1 equal 8
Output in dmesg:
Failed to configure RSS hash for VSI 6, error -5
Fixes: 352e9bf23813 ("ice: enable symmetric-xor RSS for Toeplitz hash function")
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 1d1947a7fe11..c52c465280f7 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -8046,7 +8046,7 @@ int ice_set_rss_hfunc(struct ice_vsi *vsi, u8 hfunc)
ctx->info.q_opt_rss |=
FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hfunc);
ctx->info.q_opt_tc = vsi->info.q_opt_tc;
- ctx->info.q_opt_flags = vsi->info.q_opt_rss;
+ ctx->info.q_opt_flags = vsi->info.q_opt_flags;
err = ice_update_vsi(hw, vsi->idx, ctx, NULL);
if (err) {
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 10/13] ice: fix locking in ice_dcb_rebuild()
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Bart Van Assche, intel-wired-lan,
Arpana Arland
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Bart Van Assche <bvanassche@acm.org>
Move the mutex_lock() call up to prevent that DCB settings change after
the first ice_query_port_ets() call. The second ice_query_port_ets()
call in ice_dcb_rebuild() is already protected by pf->tc_mutex.
This also fixes a bug in an error path, as before taking the first
"goto dcb_error" in the function jumped over mutex_lock() to
mutex_unlock().
This bug has been detected by the clang thread-safety analyzer.
Cc: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Cc: intel-wired-lan@lists.osuosl.org
Fixes: 242b5e068b25 ("ice: Fix DCB rebuild after reset")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Tested-by: Arpana Arland <arpanax.arland@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
index 16aa25535152..0bc6dd375687 100644
--- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
@@ -537,14 +537,14 @@ void ice_dcb_rebuild(struct ice_pf *pf)
struct ice_dcbx_cfg *err_cfg;
int ret;
+ mutex_lock(&pf->tc_mutex);
+
ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
if (ret) {
dev_err(dev, "Query Port ETS failed\n");
goto dcb_error;
}
- mutex_lock(&pf->tc_mutex);
-
if (!pf->hw.port_info->qos_cfg.is_sw_lldp)
ice_cfg_etsrec_defaults(pf->hw.port_info);
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 12/13] ice: dpll: fix rclk pin state get for E810
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Ivan Vecera <ivecera@redhat.com>
The refactoring of ice_dpll_rclk_state_on_pin_get() to use
ice_dpll_pin_get_parent_idx() omitted the base_rclk_idx adjustment that was
correctly added in the ice_dpll_rclk_state_on_pin_set() path. This breaks
E810 devices where base_rclk_idx is non-zero, causing the wrong hardware
index to be used for pin state lookup and incorrect recovered clock state
to be reported via the DPLL subsystem. E825C is unaffected as its
base_rclk_idx is 0.
While at it, add bounds check against ICE_DPLL_RCLK_NUM_MAX on hw_idx after
the base_rclk_idx subtraction in both ice_dpll_rclk_state_on_pin_{get,set}()
to prevent out-of-bounds access on the pin state array.
Fixes: ad1df4f2d591 ("ice: dpll: Support E825-C SyncE and dynamic pin discovery")
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/ice/ice_dpll.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 27b460926bac..892bc7c2e28b 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -2523,6 +2523,8 @@ ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv,
if (hw_idx < 0)
goto unlock;
hw_idx -= pf->dplls.base_rclk_idx;
+ if (hw_idx >= ICE_DPLL_RCLK_NUM_MAX)
+ goto unlock;
if ((enable && p->state[hw_idx] == DPLL_PIN_STATE_CONNECTED) ||
(!enable && p->state[hw_idx] == DPLL_PIN_STATE_DISCONNECTED)) {
@@ -2586,6 +2588,9 @@ ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv,
hw_idx = ice_dpll_pin_get_parent_idx(p, parent_pin);
if (hw_idx < 0)
goto unlock;
+ hw_idx -= pf->dplls.base_rclk_idx;
+ if (hw_idx >= ICE_DPLL_RCLK_NUM_MAX)
+ goto unlock;
ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_RCLK_INPUT,
extack);
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 11/13] ice: fix PTP hang for E825C devices
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller, Simon Horman, Rinitha S
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Grzegorz Nitka <grzegorz.nitka@intel.com>
Change the order of PTP reconfiguration when port goes down or up
(ice_down and ice_up calls) to be more graceful and consistent from
timestamp interrupts processing perspective.
For both calls (ice_up and ice_down), accompanying ice_ptp_link_change
is called which starts/stops PTP timer. This patch changes the order:
- while link goes down: disable net device Tx first (netif_carrier_off,
netif_tx_disable), then call ice_ptp_link_change
- while link goes up: ice_ptp_link_change called first, then re-enable
net device Tx (netif_tx_start_all_queues)
Otherwise, there is a narrow window in which PTP timestamp request has
been triggered and timestamp processing occurs when PTP timer is not
enabled yet (up case) or already disabled (down case). This may lead to
undefined behavior and receiving invalid timestamps. This case was
observed on E825C devices only.
Fixes: 6b1ff5d39228 ("ice: always call ice_ptp_link_change and make it void")
Cc: stable@vger.kernel.org
Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Rinitha S <sx.rinitha@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/ice/ice_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index c52c465280f7..8cc9d0521988 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -6732,10 +6732,10 @@ static int ice_up_complete(struct ice_vsi *vsi)
(vsi->port_info->phy.link_info.link_info & ICE_AQ_LINK_UP) &&
((vsi->netdev && (vsi->type == ICE_VSI_PF ||
vsi->type == ICE_VSI_SF)))) {
+ ice_ptp_link_change(pf, true);
ice_print_link_msg(vsi, true);
netif_tx_start_all_queues(vsi->netdev);
netif_carrier_on(vsi->netdev);
- ice_ptp_link_change(pf, true);
}
/* Perform an initial read of the statistics registers now to
@@ -7263,9 +7263,9 @@ int ice_down(struct ice_vsi *vsi)
if (vsi->netdev) {
vlan_err = ice_vsi_del_vlan_zero(vsi);
- ice_ptp_link_change(vsi->back, false);
netif_carrier_off(vsi->netdev);
netif_tx_disable(vsi->netdev);
+ ice_ptp_link_change(vsi->back, false);
}
ice_vsi_dis_irq(vsi);
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* [PATCH net 13/13] ice: dpll: fix misplaced header macros
From: Jacob Keller @ 2026-05-05 5:14 UTC (permalink / raw)
To: Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Michal Kubiak, Joshua Hay, Madhu Chittim, Willem de Bruijn,
Dave Ertman, Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable, Jacob Keller
In-Reply-To: <20260504-jk-iwl-net-2026-05-04-v1-0-a222a88bd962@intel.com>
From: Ivan Vecera <ivecera@redhat.com>
The CGU register definitions (ICE_CGU_R10, ICE_CGU_R11 and related field
masks) were placed after the #endif of the _ICE_DPLL_H_ include guard,
leaving them unprotected. Move them inside the guard.
Fixes: ad1df4f2d591 ("ice: dpll: Support E825-C SyncE and dynamic pin discovery")
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
drivers/net/ethernet/intel/ice/ice_dpll.h | 32 +++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
index ae42cdea0ee1..8678575359b9 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
@@ -8,6 +8,22 @@
#define ICE_DPLL_RCLK_NUM_MAX 4
+#define ICE_CGU_R10 0x28
+#define ICE_CGU_R10_SYNCE_CLKO_SEL GENMASK(8, 5)
+#define ICE_CGU_R10_SYNCE_CLKODIV_M1 GENMASK(13, 9)
+#define ICE_CGU_R10_SYNCE_CLKODIV_LOAD BIT(14)
+#define ICE_CGU_R10_SYNCE_DCK_RST BIT(15)
+#define ICE_CGU_R10_SYNCE_ETHCLKO_SEL GENMASK(18, 16)
+#define ICE_CGU_R10_SYNCE_ETHDIV_M1 GENMASK(23, 19)
+#define ICE_CGU_R10_SYNCE_ETHDIV_LOAD BIT(24)
+#define ICE_CGU_R10_SYNCE_DCK2_RST BIT(25)
+#define ICE_CGU_R10_SYNCE_S_REF_CLK GENMASK(31, 27)
+
+#define ICE_CGU_R11 0x2C
+#define ICE_CGU_R11_SYNCE_S_BYP_CLK GENMASK(6, 1)
+
+#define ICE_CGU_BYPASS_MUX_OFFSET_E825C 3
+
/**
* enum ice_dpll_pin_sw - enumerate ice software pin indices:
* @ICE_DPLL_PIN_SW_1_IDX: index of first SW pin
@@ -157,19 +173,3 @@ static inline void ice_dpll_deinit(struct ice_pf *pf) { }
#endif
#endif
-
-#define ICE_CGU_R10 0x28
-#define ICE_CGU_R10_SYNCE_CLKO_SEL GENMASK(8, 5)
-#define ICE_CGU_R10_SYNCE_CLKODIV_M1 GENMASK(13, 9)
-#define ICE_CGU_R10_SYNCE_CLKODIV_LOAD BIT(14)
-#define ICE_CGU_R10_SYNCE_DCK_RST BIT(15)
-#define ICE_CGU_R10_SYNCE_ETHCLKO_SEL GENMASK(18, 16)
-#define ICE_CGU_R10_SYNCE_ETHDIV_M1 GENMASK(23, 19)
-#define ICE_CGU_R10_SYNCE_ETHDIV_LOAD BIT(24)
-#define ICE_CGU_R10_SYNCE_DCK2_RST BIT(25)
-#define ICE_CGU_R10_SYNCE_S_REF_CLK GENMASK(31, 27)
-
-#define ICE_CGU_R11 0x2C
-#define ICE_CGU_R11_SYNCE_S_BYP_CLK GENMASK(6, 1)
-
-#define ICE_CGU_BYPASS_MUX_OFFSET_E825C 3
--
2.54.0.rc2.531.gaf818d63126a
^ permalink raw reply related
* Re: [Intel-wired-lan] [PATCH iwl-net v1 2/2] ice: use NETIF_F_HW_CSUM instead of IP/IPV6
From: Jacob Keller @ 2026-05-05 5:16 UTC (permalink / raw)
To: Michal Swiatkowski
Cc: intel-wired-lan, netdev, jramaseu, anthony.l.nguyen,
przemyslaw.kitszel, aleksandr.loktionov
In-Reply-To: <aflzeKTaOUBy2Xsn@mev-dev.igk.intel.com>
On 5/4/2026 9:35 PM, Michal Swiatkowski wrote:
> On Mon, May 04, 2026 at 04:53:12PM -0700, Jacob Keller wrote:
>> On 4/28/2026 12:06 AM, Michal Swiatkowski wrote:
>>> The hardware is capable of calculating checksum for IPV6 packets with
>>> extension header. To not drop such packets switch from IP/IPV6 checksum
>>> to HW_CSUM.
>>>
>>> HW_CSUM is also used in previous generation (i40e).
>>>
>>> Previously HW_CSUM was used to indicate that hardware supports general
>>> checksum. Drop it assuming that if the hardware supports it, it is used.
>>>
>>> Disabling offload for E830 in case of TSO isn't needed anymore as the
>>> check for TSO is done in Tx path just before preparation of the special
>>> GCS descriptor.
>>>
>>> The commit from Fixes didn't introduce a bug, it just shown that the
>>> driver is doing sth wrong with the checksum features.
>>>
>>> Suggested-by: Jakub Ramaseuski <jramaseu@redhat.com>
>>> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
>>> Fixes: 04c20a9356f2 ("net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension")
>>> Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
>>> ---
>> Am I correct in thinking that this supersedes (really, properly fixes)
>> the patch "ice: enable NETIF_F_HW_CSUM for GSO packets" at
>> https://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260310150557.1138437-1-jramaseu@redhat.com/
>> ?
>>
>> Thanks,
>> Jake
>
> Yes, exactly. I think I linked it in cover letter, but maybe I should do
> it also here.
>
> Thanks
I think its fine, I just wanted to make sure I was correct in marking
that patch as rejected in patchwork.
Thanks,
Jake
^ permalink raw reply
* Re: [PATCH batadv 0/8] batman-adv: follow up fixes
From: Matthieu Baerts @ 2026-05-05 5:21 UTC (permalink / raw)
To: Sven Eckelmann
Cc: Jakub Kicinski, Konstantin Ryabitsev, Marek Lindner,
Simon Wunderlich, Antonio Quartulli, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, b.a.t.m.a.n, netdev,
linux-kernel, Ao Zhou, Haoze Xie, Jiexun Wang, Juefei Pu,
Luxing Yin, Ruide Cao, Xin Liu, Yifan Wu, Yuan Tan, stable,
Kernel.org Tools
In-Reply-To: <2262783.irdbgypaU6@sven-l14>
Hi Sven,
05 May 2026 07:00:27 Sven Eckelmann <sven@narfation.org>:
> On Tuesday, 5 May 2026 06:46:11 CEST Sven Eckelmann wrote:
>> On Tuesday, 5 May 2026 02:10:51 CEST Jakub Kicinski wrote:
>>> On Sun, 03 May 2026 14:22:33 +0200 Sven Eckelmann wrote:
>>>> While reviewing the fixes submitted to batman-adv in the recent weeks,
>>>> further problems in similar or adjecent code was identified. This was either
>>>> noticed in the manual review or reported by sashiko.dev.
>>>
>>> Are you CCing netdev to get this reviewed by Sashiko?
>>> Please don't..
>>> We delegate code to sub-sub-systems to lower the patch volume :(
>>>
>>
>> Because of `b4 prep --auto-to-cc`. Will now manually remove you.
>
> To speed up the discussion: @Konstantin, is there a way in b4 to say "stop at
> the sub-sub-systems" when doing `b4 prep --auto-to-cc`? I am just trying to get the
> `b4` workflow somehow working with the netdev requirements.
Maybe a new option could be added, but that seems difficult to guess
where to stop, and to which subsystems to apply this.
Can you not simply omit using `b4 prep --auto-to-cc` when working
with "internal" patches?
On my side, that's what I'm doing. I added a .b4-config file with this
content, not to have to specify --set-prefix nor --to:
[b4]
send-series-to = MPTCP Linux <mptcp@lists.linux.dev>
prep-pre-flight-checks = disable-needs-auto-to-cc
send-prefixes = mptcp-next
Cheers,
Matt
^ permalink raw reply
* Re: [PATCH net] net: wan: fsl_uhdlc_hdlc: fix dma_rmb usage in hdlc_rx_done
From: Christophe Leroy (CS GROUP) @ 2026-05-05 5:29 UTC (permalink / raw)
To: Holger Brunck, netdev; +Cc: linuxppc-dev, andrew+netdev, qiang.zhao, horms
In-Reply-To: <20260504155642.2216040-1-holger.brunck@hitachienergy.com>
Hi,
Le 04/05/2026 à 17:56, Holger Brunck a écrit :
> If dma_rmb is used it has to be done after reading bd_status and checking
> if R_E_S is zero. Therefore we need to move it into the while loop.
Can you give more details ? Why does dma_rmb() has to be done after
reading bd_status and checking if R_E_S is zero ?
>
> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
> Signed-off-by: Holger Brunck <holger.brunck@hitachienergy.com>
> ---
> drivers/net/wan/fsl_ucc_hdlc.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> index 15bfb78381d4..09081f128a98 100644
> --- a/drivers/net/wan/fsl_ucc_hdlc.c
> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> @@ -523,12 +523,12 @@ static int hdlc_rx_done(struct ucc_hdlc_private *priv, int rx_work_limit)
> u16 length, howmany = 0;
> u8 *bdbuffer;
>
> - dma_rmb();
> bd = priv->currx_bd;
> bd_status = be16_to_cpu(bd->status);
>
> /* while there are received buffers and BD is full (~R_E) */
> while (!((bd_status & (R_E_S)) || (--rx_work_limit < 0))) {
> + dma_rmb();
> if (bd_status & (RX_BD_ERRORS)) {
> dev->stats.rx_errors++;
>
> @@ -610,7 +610,6 @@ static int hdlc_rx_done(struct ucc_hdlc_private *priv, int rx_work_limit)
>
> bd_status = be16_to_cpu(bd->status);
> }
> - dma_rmb();
>
> priv->currx_bd = bd;
> return howmany;
^ permalink raw reply
* Re: [PATCH net] net: wan: fsl_ucc_hdlc: fix indentation error
From: Christophe Leroy (CS GROUP) @ 2026-05-05 5:31 UTC (permalink / raw)
To: Holger Brunck, netdev; +Cc: linuxppc-dev, andrew+netdev, qiang.zhao, horms
In-Reply-To: <20260504160734.2217382-1-holger.brunck@hitachienergy.com>
Hi,
Le 04/05/2026 à 18:07, Holger Brunck a écrit :
> Remove the whitespace to fix the indentation.
Do we really need a patch for that ? What's the added value of doing
this change compared to the cost of doing it ?
>
> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
> Signed-off-by: Holger Brunck <holger.brunck@hitachienergy.com>
> ---
> drivers/net/wan/fsl_ucc_hdlc.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> index 09081f128a98..adf3863463f5 100644
> --- a/drivers/net/wan/fsl_ucc_hdlc.c
> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> @@ -764,7 +764,7 @@ static void uhdlc_memclean(struct ucc_hdlc_private *priv)
> qe_muram_free(priv->ucc_pram_offset);
> priv->ucc_pram = NULL;
> priv->ucc_pram_offset = 0;
> - }
> + }
>
> kfree(priv->rx_skbuff);
> priv->rx_skbuff = NULL;
^ permalink raw reply
* Re: [PATCH 0/6] SUNRPC: Address remaining cache_check_rcu() UAF in cache content files
From: Jeff Layton @ 2026-05-05 5:32 UTC (permalink / raw)
To: Chuck Lever, Misbah Anjum N, NeilBrown, Olga Kornievskaia,
Dai Ngo, Tom Talpey, Trond Myklebust, Anna Schumaker,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Yang Erkun
Cc: linux-nfs, linux-kernel, netdev, Chuck Lever
In-Reply-To: <20260501-cache-uaf-fix-v1-0-a49928bf4817@oracle.com>
On Fri, 2026-05-01 at 10:51 -0400, Chuck Lever wrote:
> Misbah Anjum reported a use-after-free in cache_check_rcu()
> reached through e_show() while sosreport was reading
> /proc/fs/nfsd/exports on ppc64le. Two fixes for that report
> landed in v7.0:
>
> 48db892356d6 ("NFSD: Defer sub-object cleanup in export put callbacks")
> e7fcf179b82d ("NFSD: Hold net reference for the lifetime of /proc/fs/nfs/exports fd")
>
> The original e_show() repro is now fixed. However, the same
> sosreport workload still reproduces a closely related fault on
> post-v7.0 mainline (Misbah, ppc64le) and on master.20260424
> (internal report, aarch64). In both cases the fault is in
> cache_check_rcu() reached through c_show() rather than e_show(),
> and the cache_head pointer is plain garbage:
>
> pc : cache_check_rcu+0x40 [sunrpc]
> lr : c_show+0x60 [sunrpc]
> ...faulting on h->flags off h = 0x0000000200000000
>
> c_show() is the generic show callback used by
> /proc/net/rpc/<cd>/content for every per-net cache_detail
> (auth.unix.ip, auth.unix.gid, nfsd.fh, nfsd.export). Two
> bugs combine in that path:
>
> 1. cache_unregister_net() / cache_destroy_net() free cd and
> cd->hash_table synchronously when the namespace exits. The
> /proc/net/rpc/.../content open path takes only a module
> reference, so a fd kept open across a netns exit walks a
> freed hash_table and returns garbage cache_head pointers.
> This is the same hazard that e7fcf179b82d closed for the
> /proc/fs/nfs/exports file alone.
>
> 2. ip_map_put() drops auth_domain_put() before kfree_rcu(), so
> sub-objects can be freed before the RCU grace period -- the
> same hazard that 48db892356d6 fixed for svc_export_put() and
> expkey_put(). unix_gid_put() does not have this bug
> structurally (its put_group_info() runs inside the call_rcu()
> callback) but it uses a separate idiom from the other three
> caches.
>
> This series replaces the v1 narrow fixes with shared
> infrastructure that covers all four cache_detail .put paths
> and all three per-cache file types:
>
> Patch 1 hoists nfsd_export_wq up to the sunrpc layer as
> sunrpc_cache_wq, exposed through sunrpc_cache_queue_release()
> and sunrpc_cache_drain() so all four put callbacks share one
> workqueue and one drain primitive.
>
> Patch 2 converts ip_map_put() to the queue_rcu_work() pattern,
> moving auth_domain_put() into a deferred ip_map_release() that
> runs after the RCU grace period.
>
> Patch 3 unifies unix_gid_put() onto the same pattern for
> consistency (not a bug fix on its own).
>
> Patch 4 takes a get_net(cd->net) in content_open(), cache_open(),
> and open_flush() and drops it in the matching release helpers,
> so cache_destroy_net() cannot run while a sunrpc cache fd is
> open.
>
> Series has been compile-tested only.
>
> ---
> Chuck Lever (6):
> SUNRPC: Move cache_initialize() declaration to sunrpc-private header
> SUNRPC: Provide a shared workqueue for cache release callbacks
> SUNRPC: Defer ip_map sub-object cleanup past RCU grace period
> SUNRPC: Use shared release pattern for the unix_gid cache
> SUNRPC: Hold cd->net for the lifetime of cache files
> NFSD: Convert nfsd_export_shutdown() to sunrpc_cache_destroy_net()
>
> fs/nfsd/export.c | 45 ++--------------------
> fs/nfsd/export.h | 2 -
> fs/nfsd/nfsctl.c | 8 +---
> include/linux/sunrpc/cache.h | 3 +-
> net/sunrpc/cache.c | 90 ++++++++++++++++++++++++++++++++++++++++++--
> net/sunrpc/sunrpc.h | 2 +
> net/sunrpc/sunrpc_syms.c | 23 ++++++-----
> net/sunrpc/svcauth_unix.c | 46 ++++++++++++----------
> 8 files changed, 135 insertions(+), 84 deletions(-)
> ---
> base-commit: f3a313ecd1fdab1f5da119db355363b13af6fcac
> change-id: 20260430-cache-uaf-fix-a13000f67c37
>
> Best regards,
> --
> Chuck Lever
The series looks sane.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH net] net: wan: fsl_ucc_hdlc: free tx_skbuff in uhdlc_memclean
From: Christophe Leroy (CS GROUP) @ 2026-05-05 5:37 UTC (permalink / raw)
To: Holger Brunck, netdev; +Cc: linuxppc-dev, andrew+netdev, qiang.zhao, horms
In-Reply-To: <20260504161145.2217950-1-holger.brunck@hitachienergy.com>
Le 04/05/2026 à 18:11, Holger Brunck a écrit :
> When cleaning up the resources we need to iterate over the
> tx_skbuf array to free pending TX messages.
>
> Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
> Signed-off-by: Holger Brunck <holger.brunck@hitachienergy.com>
> ---
> drivers/net/wan/fsl_ucc_hdlc.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
> index adf3863463f5..68f78aeabdc3 100644
> --- a/drivers/net/wan/fsl_ucc_hdlc.c
> +++ b/drivers/net/wan/fsl_ucc_hdlc.c
> @@ -739,6 +739,8 @@ static int uhdlc_open(struct net_device *dev)
>
> static void uhdlc_memclean(struct ucc_hdlc_private *priv)
> {
> + int i;
> +
> qe_muram_free(ioread16be(&priv->ucc_pram->riptr));
> qe_muram_free(ioread16be(&priv->ucc_pram->tiptr));
>
> @@ -769,6 +771,11 @@ static void uhdlc_memclean(struct ucc_hdlc_private *priv)
> kfree(priv->rx_skbuff);
> priv->rx_skbuff = NULL;
>
> + for (i = 0; i < TX_BD_RING_LEN) {
> + kfree(priv->tx_skbuff[i]);
I don't think you can just kfree() an skb like this.
I think you have to call dev_kfree_skb_any() instead.
Christophe
> + priv->tx_skbuff[i] = NULL;
> + }
> +
> kfree(priv->tx_skbuff);
> priv->tx_skbuff = NULL;
>
^ permalink raw reply
* Re: [PATCH net v2] xfrm: esp: avoid in-place decrypt on shared skb frags
From: Steffen Klassert @ 2026-05-05 5:42 UTC (permalink / raw)
To: Hex Rabbit
Cc: Hyunwoo Kim, netdev, Greg Kroah-Hartman, Herbert Xu, Simon Horman,
David S . Miller, David Ahern, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Ido Schimmel, linux-kernel
In-Reply-To: <CAF3ZFefQM5Ud8iWDoKV9FPdZ=8V0KD56Bvkdcku1fmm6aaD_Cg@mail.gmail.com>
On Tue, May 05, 2026 at 10:49:42AM +0800, Hex Rabbit wrote:
> Hi Hyunwoo, Steffen,
>
> > The report and patch for this issue were already posted on
> > the public netdev ML 6 days ago, i.e., the bug was already
> > publicly reported:
> >
> > https://lore.kernel.org/all/afLDKSvAvMwGh7Fy@v4bel/
> >
> > Credit for patch authorship is adequately covered by
> > Signed-off-by alone. Setting aside that your work proceeded
> > independently rather than as a review of my earlier
> > submission, the trailer should conform to convention to
> > avoid future misunderstanding.
>
> For clarity, I also found and reported the issue independently to
> security@kernel.org on the same day, with my own reproducer and
> root-cause analysis. At that time I was not aware of your report or
> patch; otherwise I would have referenced it earlier.
>
> I am still not fully familiar with the exact kernel trailer convention
> here, so I added both Reported-by tags because the reports were
> independent.
>
> Steffen, either trailer form is fine with me. If you decide to drop my
> Reported-by because the patch already has my Signed-off-by, I have no
> objection.
You reported it, so you can have the tag.
This is now applied to the ipsec tree, thanks a lot everybody!
^ permalink raw reply
* Re: [PATCH net v6] ipv6: flowlabel: enforce per-netns limit for unprivileged callers
From: Maoyi Xie @ 2026-05-05 5:55 UTC (permalink / raw)
To: Willem de Bruijn
Cc: davem, kuba, pabeni, edumazet, dsahern, kuznet, willemb, netdev,
linux-kernel, stable
In-Reply-To: <willemdebruijn.kernel.3269daabfa48e@gmail.com>
Thanks for the review.
I will take the prep patch. The series becomes 2 patches.
1/2 ipv6: flowlabel: take ip6_fl_lock across mem_check and
fl_intern, convert fl_size to int
2/2 ipv6: flowlabel: enforce per-netns limit for unprivileged
callers (this v6, rebased on 1/2)
For 1/2 I plan to:
- Move spin_lock_bh(&ip6_fl_lock) and the matching unlock from
fl_intern() into its only caller ipv6_flowlabel_get(), so the
mem_check() call runs under the same lock.
- Convert fl_size from atomic_t to int. The remaining readers
are ip6_flowlabel_seq_show() and ip6_flowlabel_proc_init().
Both already run under ip6_fl_lock or read only at init.
- The atomic_inc and atomic_dec on fl_size in fl_intern,
ip6_fl_gc and ip6_fl_purge become plain ++ and --. All three
sites already run under ip6_fl_lock.
For 2/2 I will also:
- Move fl_free() in ip6_fl_gc() back below the fl_size and
flowlabel_count decrements. You noted only the ip6_fl_purge()
reorder was unnecessary. With 1/2 in place, both decrements
become plain --, so the concern goes away.
- Fix the spaces around the / operator that checkpatch flagged.
I will send v7 shortly.
Maoyi
Nanyang Technological University
https://maoyixie.com/
^ permalink raw reply
* RE: [PATCH net-next 07/15] ixgbe: E610: add ACI dynamic debug
From: Kwapulinski, Piotr @ 2026-05-05 6:11 UTC (permalink / raw)
To: Keller, Jacob E
Cc: Kitszel, Przemyslaw, andrew+netdev@lunn.ch, davem@davemloft.net,
edumazet@google.com, pabeni@redhat.com, Lobakin, Aleksander,
horms@kernel.org, michal.swiatkowski@linux.intel.com,
Jagielski, Jedrzej, Loktionov, Aleksandr, Nitka, Grzegorz,
Vecera, Ivan, Kubalewski, Arkadiusz, Nguyen, Anthony L,
Wegrzyn, Stefan, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, pmenzel@molgen.mpg.de,
Mekala, SunithaX D
In-Reply-To: <7505d7e3-4686-457e-a79e-776c634e9edb@intel.com>
>-----Original Message-----
>From: Keller, Jacob E <jacob.e.keller@intel.com>
>Sent: Tuesday, May 5, 2026 12:33 AM
>To: Kwapulinski, Piotr <piotr.kwapulinski@intel.com>
>Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; andrew+netdev@lunn.ch; davem@davemloft.net; edumazet@google.com; pabeni@redhat.com; Lobakin, Aleksander <aleksander.lobakin@intel.com>; horms@kernel.org; michal.swiatkowski@linux.intel.com; Jagielski, Jedrzej <jedrzej.jagielski@intel.com>; Loktionov, Aleksandr <aleksandr.loktionov@intel.com>; Nitka, Grzegorz <grzegorz.nitka@intel.com>; Vecera, Ivan <ivecera@redhat.com>; Kubalewski, Arkadiusz <arkadiusz.kubalewski@intel.com>; Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Wegrzyn, Stefan <stefan.wegrzyn@intel.com>; Kwapulinski, Piotr <piotr.kwapulinski@intel.com>; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; pmenzel@molgen.mpg.de; Mekala, SunithaX D <sunithax.d.mekala@intel.com>
>Subject: Re: [PATCH net-next 07/15] ixgbe: E610: add ACI dynamic debug
>
>On 5/2/2026 7:06 PM, Jakub Kicinski wrote:
>> This is an AI-generated review of your patch. The human sending this
>> email has considered the AI review valid, or at least plausible.
>> ---
>> ixgbe: E610: add ACI dynamic debug
>>
>> This commit enables dynamic debugging of the Admin Command Interface
>> (ACI) for the e610 adapter, allowing ACI commands and descriptor
>> details to be printed into the kernel log.
>>
>>> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
>>> b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
>>> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
>>> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
>>
>> [ ... ]
>>
>>> @@ -106,8 +185,12 @@ static int ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw,
>>> if (desc->flags & cpu_to_le16(LIBIE_AQ_FLAG_RD)) {
>>> for (i = 0; i < buf_size / 4; i++)
>>> IXGBE_WRITE_REG(hw, IXGBE_PF_HIBA(i), ((u32 *)buf)[i]);
>>> - if (buf_tail_size)
>>> + ixgbe_aci_debug(hw, desc, buf, buf_size);
>>> + if (buf_tail_size) {
>>> IXGBE_WRITE_REG(hw, IXGBE_PF_HIBA(i), buf_tail);
>>> + ixgbe_aci_debug(hw, desc, &buf_tail,
>>> + buf_tail_size);
>>> + }
>>> }
>>> }
>>
>> Does this result in redundant output being printed to the kernel log?
>>
>> When buf_tail_size is non-zero, ixgbe_aci_debug() is called twice:
>> once for the full buffer, and a second time for just the tail. Since
>> ixgbe_aci_debug() prints the full CQ CMD descriptor details each time,
>> this appears to print the descriptor headers twice and fragment the buffer output.
>>
>> [ ... ]
>>
>>> @@ -183,10 +278,13 @@ static int ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw,
>>> if (valid_buf) {
>>> for (i = 0; i < buf_size / 4; i++)
>>> ((u32 *)buf)[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIBA(i));
>>> + ixgbe_aci_debug(hw, raw_desc, buf, buf_size);
>>> if (buf_tail_size) {
>>> buf_tail = IXGBE_READ_REG(hw, IXGBE_PF_HIBA(i));
>>> memcpy(buf + buf_size - buf_tail_size, &buf_tail,
>>> buf_tail_size);
>>> + ixgbe_aci_debug(hw, raw_desc, &buf_tail,
>>> + buf_tail_size);
>>> }
>>> }
>>
>> Can this read uninitialized memory from the buffer?
>>
>> At the point ixgbe_aci_debug(..., buf, buf_size) is called, the loop
>> has only populated the 4-byte aligned chunks of the buffer. The
>> trailing bytes at the end of the buffer are not populated until the
>> memcpy() occurs later in the block. Because ixgbe_aci_debug() consumes
>> buf_size bytes, it looks like it will read and log uninitialized
>> trailing memory (potentially from the kernel stack).
>>
>> Also, similar to the transmit path, this calls ixgbe_aci_debug() a
>> second time on &buf_tail, which will print the descriptor headers again.
>>
>> Could we move a single ixgbe_aci_debug(..., buf, buf_size) call to the
>> end of the block, after the entire buffer including the tail has been fully written?
>
>Piotr,
>
>Please review this report and submit a new version of this patch to Intel Wired LAN.
>
>While you are at it, please review the following report from a run of sashiko I did myself using claude:
Will update. Thank you.
Piotr
>
>> commit 198ec0389c757125d9079647a6c8aba34ba29048
>> Author: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
>> ixgbe: E610: add ACI dynamic debug
>> This patch enables dynamic debug of the Admin Command Interface (ACI)
>> for the E610 adapter, adding descriptor and buffer hex dumps via the
>> standard dyndbg infrastructure, plus hw_dbg() calls on error paths.
>>> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
>>> b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
>>> index 665a9813e251..b686636beb93 100644
>>> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
>>> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
>> [ ... ]
>>> @@ -147,6 +230,7 @@ static int ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw,
>>> raw_desc[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIDA(i));
>>> raw_desc[i] = raw_desc[i];
>>> }
>>>+ ixgbe_aci_debug(hw, raw_desc, NULL, 0);
>>> }
>> [ ... ]
>>> /* Handle timeout and invalid state of HICR register */
>>>- if (hicr & IXGBE_PF_HICR_C)
>>>+ if (hicr & IXGBE_PF_HICR_C) {
>>>+ hw_dbg(hw, "error: Admin Command 0x%X command timeout\n",
>>>+ le16_to_cpu(desc->opcode));
>>> return -ETIME;
>>>+ }
>> Since raw_desc is declared as a cast of desc:
>> u32 *raw_desc = (u32 *)desc;
>> and the sync response read loop overwrites raw_desc[] (and thus desc)
>> with firmware response data, could le16_to_cpu(desc->opcode) here
>> print the response opcode rather than the original command opcode?
>> The local variable opcode already holds the original value saved
>> earlier via:
>> opcode = le16_to_cpu(desc->opcode); Would it be more correct to
>> use opcode directly in this hw_dbg() call (and the one in the
>> invalid-state check below)?
>>> @@ -183,10 +278,13 @@ static int ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw,
>>> if (valid_buf) {
>>> for (i = 0; i < buf_size / 4; i++)
>>> ((u32 *)buf)[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIBA(i));
>>>+ ixgbe_aci_debug(hw, raw_desc, buf, buf_size);
>>> if (buf_tail_size) {
>>> buf_tail = IXGBE_READ_REG(hw, IXGBE_PF_HIBA(i));
>>> memcpy(buf + buf_size - buf_tail_size, &buf_tail,
>>> buf_tail_size);
>>>+ ixgbe_aci_debug(hw, raw_desc, &buf_tail,
>>>+ buf_tail_size);
>>> }
>>> }
>> When buf_size is not 4-byte aligned, ixgbe_aci_debug() is called with
>> the full buf_size before the tail bytes have been read from hardware
>> and memcpy'd into buf. The hex dump will show stale content for the
>> last 1-3 bytes of the buffer.
>> Should the ixgbe_aci_debug() call be moved after the tail memcpy so
>> that it dumps the complete response?
^ permalink raw reply
* Re: [PATCH net] i2c: sun6i-p2wi: fix of_node reference leak in probe
From: Shitalkumar Gandhi @ 2026-05-05 6:12 UTC (permalink / raw)
To: Jakub Kicinski
Cc: MD Danish Anwar, Parvathi Pudi, Roger Quadros,
Mohan Reddy Putluru, David S . Miller, Eric Dumazet, Paolo Abeni,
Andrew Lunn, Simon Horman, Dan Carpenter, netdev,
linux-arm-kernel, linux-kernel, Shitalkumar Gandhi
In-Reply-To: <20260504164750.5eb6c55a@kernel.org>
On Mon, 4 May 2026 16:47:50 -0700 Jakub Kicinski wrote:
> This is obviously not something that should go via the networking tree
Yeah, sorry - mis-routed this. Wrong recipient list on my end,
please ignore. The i2c patch is already on linux-i2c.
Shitalkumar
^ permalink raw reply
* Re: [PATCH net v2] net: mana: Optimize irq affinity for low vcpu configs
From: Shradha Gupta @ 2026-05-05 6:15 UTC (permalink / raw)
To: Yury Norov
Cc: Dexuan Cui, Wei Liu, Haiyang Zhang, K. Y. Srinivasan, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Konstantin Taranov, Simon Horman, Erni Sri Satya Vennela,
Dipayaan Roy, Shiraz Saleem, Michael Kelley, Long Li, Yury Norov,
linux-hyperv, linux-kernel, netdev, Paul Rosswurm, Shradha Gupta,
Saurabh Singh Sengar, stable
In-Reply-To: <afYxOPL4DNjXM7tL@yury>
On Sat, May 02, 2026 at 01:15:36PM -0400, Yury Norov wrote:
> On Sat, May 02, 2026 at 07:37:43AM -0700, Shradha Gupta wrote:
> > On Fri, May 01, 2026 at 12:22:20PM -0400, Yury Norov wrote:
> > > On Wed, Apr 29, 2026 at 02:06:37AM -0700, Shradha Gupta wrote:
> > > > In mana driver, the number of IRQs allocated is capped by the
> > > > min(num_cpu + 1, queue count). In cases, where the IRQ count is greater
> > > > than the vcpu count, we want to utilize all the vCPUs, irrespective of
> > > > their NUMA/core bindings.
> > > >
> > > > This is important, especially in the envs where number of vCPUs are so
> > > > few that the softIRQ handling overhead on two IRQs on the same vCPU is
> > > > much more than their overheads if they were spread across sibling vCPUs.
> > > >
> > > > This behaviour is more evident with dynamic IRQ allocation. Since MANA
> > > > IRQs are assigned at a later stage compared to static allocation, other
> > > > device IRQs may already be affinitized to the vCPUs. As a result, IRQ
> > > > weights become imbalanced, causing multiple MANA IRQs to land on the
> > > > same vCPU, while some vCPUs have none.
> > > >
> > > > In such cases when many parallel TCP connections are tested, the
> > > > throughput drops significantly.
> > > >
> > > > Test envs:
> > > > =======================================================
> > > > Case 1: without this patch
> > > > =======================================================
> > > > 4 vcpu(2 cores), 5 MANA IRQs (1 HWC + 4 Queue)
> > > >
> > > > TYPE effective vCPU aff
> > > > =======================================================
> > > > IRQ0: HWC 0
> > > > IRQ1: mana_q1 0
> > > > IRQ2: mana_q2 2
> > > > IRQ3: mana_q3 0
> > > > IRQ4: mana_q4 3
> > > >
> > > > %soft on each vCPU(mpstat -P ALL 1) on receiver
> > > > vCPU 0 1 2 3
> > > > =======================================================
> > > > pass 1: 38.85 0.03 24.89 24.65
> > > > pass 2: 39.15 0.03 24.57 25.28
> > > > pass 3: 40.36 0.03 23.20 23.17
> > > >
> > > > =======================================================
> > > > Case 2: with this patch
> > > > =======================================================
> > > > 4 vcpu(2 cores), 5 MANA IRQs (1 HWC + 4 Queue)
> > > >
> > > > TYPE effective vCPU aff
> > > > =======================================================
> > > > IRQ0: HWC 0
> > > > IRQ1: mana_q1 0
> > > > IRQ2: mana_q2 1
> > > > IRQ3: mana_q3 2
> > > > IRQ4: mana_q4 3
> > > >
> > > > %soft on each vCPU(mpstat -P ALL 1) on receiver
> > > > vCPU 0 1 2 3
> > > > =======================================================
> > > > pass 1: 15.42 15.85 14.99 14.51
> > > > pass 2: 15.53 15.94 15.81 15.93
> > > > pass 3: 16.41 16.35 16.40 16.36
> > > >
> > > > =======================================================
> > > > Throughput Impact(in Gbps, same env)
> > > > =======================================================
> > > > TCP conn with patch w/o patch
> > > > 20480 15.65 7.73
> > > > 10240 15.63 8.93
> > > > 8192 15.64 9.69
> > > > 6144 15.64 13.16
> > > > 4096 15.69 15.75
> > > > 2048 15.69 15.83
> > > > 1024 15.71 15.28
> > > >
> > > > Fixes: 755391121038 ("net: mana: Allocate MSI-X vectors dynamically")
> > > > Cc: stable@vger.kernel.org
> > > > Co-developed-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
> > > > Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
> > > > Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> > > > Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> > > > ---
> > > > Changes in v2
> > > > * Removed the unused skip_first_cpu variable
> > > > * fixed exit condition in irq_setup_linear() with len == 0
> > > > * changed return type of irq_setup_linear() as it will always be 0
> > > > * removed the unnecessary rcu_read_lock() in irq_setup_linear()
> > > > * added appropriate comments to indicate expected behaviour when
> > > > IRQs are more than or equal to num_online_cpus()
> > > > ---
> > > > .../net/ethernet/microsoft/mana/gdma_main.c | 47 ++++++++++++++++---
> > > > 1 file changed, 40 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> > > > index 098fbda0d128..d740d1dc43da 100644
> > > > --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
> > > > +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> > > > @@ -167,6 +167,8 @@ static int mana_gd_query_max_resources(struct pci_dev *pdev)
> > > > } else {
> > > > /* If dynamic allocation is enabled we have already allocated
> > > > * hwc msi
> > > > + * Also, we make sure in this case the following is always true
> > > > + * (num_msix_usable - 1 HWC) <= num_online_cpus()
> > > > */
> > > > gc->num_msix_usable = min(resp.max_msix, num_online_cpus() + 1);
> > > > }
> > > > @@ -1672,11 +1674,24 @@ static int irq_setup(unsigned int *irqs, unsigned int len, int node,
> > > > return 0;
> > > > }
> > > >
> > > > +/* should be called with cpus_read_lock() held */
> > > > +static void irq_setup_linear(unsigned int *irqs, unsigned int len)
> > > > +{
> > > > + int cpu;
> > > > +
> > > > + for_each_online_cpu(cpu) {
> > > > + if (len == 0)
> > > > + break;
> > > > +
> > > > + irq_set_affinity_and_hint(*irqs++, cpumask_of(cpu));
> > > > + len--;
> > > > + }
> > > > +}
> > > > +
> > > > static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec)
> > > > {
> > > > struct gdma_context *gc = pci_get_drvdata(pdev);
> > > > struct gdma_irq_context *gic;
> > > > - bool skip_first_cpu = false;
> > > > int *irqs, irq, err, i;
> > > >
> > > > irqs = kmalloc_objs(int, nvec);
> > >
> > > So what about WARN_ON() and nvec adjustment before kmalloc?
> > Hey Yury,
> >
> > I am still a bit unsure about the WARN_ON() before kmalloc, as after
> > that also, in the same function till we take the cpus_read_lock() the
> > num_online_cpus() can change(or reduce). That's why I introduced the
> > dev_dbg() to capture hot-remove edge case.
>
> OK.
>
> > Do you still think it adds more value?
>
> It's your driver, so you know better. I just wonder because you said
> it's good to add WARN_ON(), and then didn't do that.
>
> > >
> > > > @@ -1722,13 +1737,31 @@ static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec)
> > > > * first CPU sibling group since they are already affinitized to HWC IRQ
> > > > */
> > > > cpus_read_lock();
> > > > - if (gc->num_msix_usable <= num_online_cpus())
> > > > - skip_first_cpu = true;
> > > > + if (gc->num_msix_usable <= num_online_cpus()) {
> > > > + err = irq_setup(irqs, nvec, gc->numa_node, true);
> > > > + if (err) {
> > > > + cpus_read_unlock();
> > > > + goto free_irq;
> > >
> > > One thing puzzles me: if you skip first CPU with this 'true', and the
> > > gc->num_msix_usable == num_online_cpus(), it's one more than you can
> > > distribute. What do I miss?
> > >
> >
> > Let me explain this case a bit better then,
> >
> > - num_msix_usable = HWC IRQ + Queue IRQ
> > - nvec in this functions is only Queue IRQ (HWC already setup)
> >
> > When num_online_cpus == num_msix_usable:
> > - nvec = num_online_cpus - 1
> > - first CPU is already assigned to HWC IRQ, so skip it
> > - Queue IRQs fit in the remaining CPUs
> >
> > please let me know if I did not get your question right
>
> Can you put that in a comment?
Sure I will. thanks
>
> > > > + }
> > > > + } else {
> > > > + /*
> > > > + * When num_msix_usable are more than num_online_cpus, we try to
> > > > + * make sure we are using all vcpus. In such a case NUMA or
> > > > + * CPU core affinity does not matter.
> > >
> > > If it doesn't matter, why don't you assign each IRQ to all CPUs then?
> > > In theory, the system would have most of flexibility to balance them.
> > >
> >
> > Okay, let me fix the comment and elaborate on this. It doesn't matter
> > because in such a case we want to anyway exhaust and distribute the
> > Queue IRQs to all vCPUs.
> > We don't want to rely on the system's balancer in this case as it could
> > be skewed by other devices' IRQ weights
>
> I don't understand this. If I want to reserve some CPUs to solely
> handle IRQs from my high-priority hardware, then I configure my system
> accordingly. For example, assign all non-networking IRQs on CPU0, and
> all networking IRQs to all CPUs.
>
> In your case, you distribute IRQs evenly, which means you've no
> preferred CPUs. So, assuming the system is only running your IRQ
> driver, it's at max is as good as all-CPU distribution. In case of
> heavy loading some particular CPU, your scheme could cause
> corresponding IRQs to starve.
>
> I recall, when we was working on irq_setup(), the original idea was to
> distribute IRQs one-to-one, but than I suggested the
>
> irq_set_affinity_and_hint(*irqs++, topology_sibling_cpumask(cpu));
>
> and after experiments, you agreed on that.
>
> Can you please run your throughput test for my suggested distribution
> too? Would be also nice to see how each distribution works when some
> CPUs are under stress.
>
> Thanks,
> Yury
The design of irq_setup() works exactly how we want it for our IRQs for
almost all of our usecases, so we want to keep that as is. The only
scenarios where this is an issue in terms of significant throughput drop
is when we are working with low vCPU VMs (vCPU <= 4 with high TCP
connection counts) and where there are additional NVMe devices attached
to the VM.
The current patch about utilizing all the vCPUs helps in that case and
doesn't cause any regression for other cases.
This linear path is only taken when num_msix_usable > num_online_cpus(),
which is limited to low-vCPU VMs. Larger VMs continue using irq_setup()
as before.
We can definately get our throughput run results on other suggestions
you have. And about that, I just needed a bit more clarity on what to
test against. Are you suggesting, with irq_setup() intact and in use, we
configure the non-mana IRQs to say CPU0 and capture the numbers?
Thanks,
Shradha.
^ permalink raw reply
* Re: [PATCH net-next] net/mlx5: Add MLX5_VXLAN config option
From: Gal Pressman @ 2026-05-05 6:21 UTC (permalink / raw)
To: Jakub Kicinski, Marc Harvey
Cc: Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Mark Bloch,
Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni, netdev,
linux-rdma, linux-kernel, Kuniyuki Iwashima
In-Reply-To: <20260504181022.60ee2a1a@kernel.org>
Hi Marc,
On 05/05/2026 4:10, Jakub Kicinski wrote:
> On Mon, 4 May 2026 15:44:26 -0700 Marc Harvey wrote:
>>> Are you aware of NETIF_F_RX_UDP_TUNNEL_PORT ?
>>> I haven't checked it does exactly what we need, but I recall there was
>>> a ethtool feature for this..
>>
>> Thanks, I didn't know about that feature and mlx5 uses it. However,
>> mlx5 unconditionally sets the `UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN`
>> flag, which excludes port 4789 from the entire UDP tunnel core offload
>> management (see `__udp_tunnel_nic_add_port()`).
>>
>> So using ethtool to disable `NETIF_F_RX_UDP_TUNNEL_PORT` will not
>> disable vxlan offload for port 4789.
>>
>> I think a better approach would be to just remove this static
>> automatic offloading for port 4789, mlx5 is the only driver using
>> `UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN` anyway. However, there might
>> be a reason for this, such as some supported hardware offloading vxlan
>> on port 4789 by default even without commands from the driver.
>>
>> If mlx5 continues to use the `UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN`
>> flag, then some change is required to fully disable vxlan offloading.
>
> Sorry, I don't know mlx5 very well. Sounds like you have to talk
> to nVidia or/and run some experiments. The current patch is a no-go.
>
The hardware offloads 4789 by default, hence the
UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN, you cannot simply remove it.
Have you tried disabling tx-udp_tnl-segmentation through ethtool?
^ permalink raw reply
* Re: [PATCH] net: bridge: replace simple_strtoul with kstrtoul
From: Nikolay Aleksandrov @ 2026-05-05 6:22 UTC (permalink / raw)
To: Aadarsh Chandra, idosch; +Cc: davem, kuba, netdev, bridge, linux-kernel
In-Reply-To: <20260504150146.457562-1-aadarsh.official.xz@gmail.com>
On 04/05/2026 18:01, Aadarsh Chandra wrote:
> The simple_strtoul() function is deprecated. It does not handle
> errors or overflows correctly. Replace it with kstrtoul() in
> brport_store() to ensure that invalid user input is caught and
> returned as an error.
>
> Signed-off-by: Aadarsh Chandra <aadarsh.official.xz@gmail.com>
> ---
> net/bridge/br_sysfs_if.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
This patch should be targeted at net-next (PATCH net-next in subject).
> diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
> index 1f57c36a7fc0..3e948d781970 100644
> --- a/net/bridge/br_sysfs_if.c
> +++ b/net/bridge/br_sysfs_if.c
> @@ -318,7 +318,7 @@ static ssize_t brport_store(struct kobject *kobj,
> struct net_bridge_port *p = kobj_to_brport(kobj);
> ssize_t ret = -EINVAL;
> unsigned long val;
> - char *endp;
> + int err;
>
> if (!ns_capable(dev_net(p->dev)->user_ns, CAP_NET_ADMIN))
> return -EPERM;
> @@ -339,9 +339,11 @@ static ssize_t brport_store(struct kobject *kobj,
> spin_unlock_bh(&p->br->lock);
> kfree(buf_copy);
> } else if (brport_attr->store) {
> - val = simple_strtoul(buf, &endp, 0);
> - if (endp == buf)
> + err = kstrtoul(buf, 0, &val);
You can just use ret = kstrtoul() here and make this simpler, ssize_t is an
int on 32 bit archs and a long on 64 bit ones, so it can hold the return val.
> + if (err) {
> + ret = err;
> goto out_unlock;
> + }
> spin_lock_bh(&p->br->lock);
> ret = brport_attr->store(p, val);
> spin_unlock_bh(&p->br->lock);
Cheers,
Nik
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox