From 9f7007ee9858c99aa43101bc8352c672fee85644 Mon Sep 17 00:00:00 2001 From: Michael Bommarito Date: Wed, 17 Jun 2026 17:57:54 -0400 Subject: [PATCH 01/10] idpf: bound interrupt-vector register fill to the allocated array idpf_get_reg_intr_vecs() fills the caller-allocated reg_vals[] array from the VIRTCHNL2_OP_ALLOC_VECTORS reply in adapter->req_vec_chunks, bounding its inner loop only by the per-chunk num_vectors. The array is sized separately: idpf_intr_reg_init() allocates kzalloc_objs(struct idpf_vec_regs, total_vecs) from caps.num_allocated_vectors and only checks the returned count after the fill. The sum of per-chunk num_vectors is never reconciled against total_vecs, so a reply with a small num_allocated_vectors but chunks summing higher writes past the end of reg_vals[]. Impact: a control plane (a PF or hypervisor device model) that returns a VIRTCHNL2_OP_ALLOC_VECTORS reply whose per-chunk num_vectors sum exceeds num_allocated_vectors writes struct idpf_vec_regs entries past the end of the reg_vals kmalloc allocation (KASAN slab-out-of-bounds write). Bound the fill loop to the array capacity passed in by the callers, mirroring the sibling idpf_vport_get_q_reg(). The existing num_regs < num_vecs check then rejects an undersized reply without the out-of-bounds write happening first. Fixes: d4d558718266 ("idpf: initialize interrupts and enable vport") Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Michael Bommarito Reviewed-by: Aleksandr Loktionov Tested-by: Samuel Salin Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/idpf/idpf_dev.c | 2 +- drivers/net/ethernet/intel/idpf/idpf_vf_dev.c | 2 +- drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 5 +++-- drivers/net/ethernet/intel/idpf/idpf_virtchnl.h | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/idpf/idpf_dev.c b/drivers/net/ethernet/intel/idpf/idpf_dev.c index 1a0c71c95ef1..4079a787657f 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_dev.c +++ b/drivers/net/ethernet/intel/idpf/idpf_dev.c @@ -87,7 +87,7 @@ static int idpf_intr_reg_init(struct idpf_vport *vport, if (!reg_vals) return -ENOMEM; - num_regs = idpf_get_reg_intr_vecs(adapter, reg_vals); + num_regs = idpf_get_reg_intr_vecs(adapter, reg_vals, total_vecs); if (num_regs < num_vecs) { err = -EINVAL; goto free_reg_vals; diff --git a/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c b/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c index a07d7e808ca9..6726084f6cfa 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c +++ b/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c @@ -86,7 +86,7 @@ static int idpf_vf_intr_reg_init(struct idpf_vport *vport, if (!reg_vals) return -ENOMEM; - num_regs = idpf_get_reg_intr_vecs(adapter, reg_vals); + num_regs = idpf_get_reg_intr_vecs(adapter, reg_vals, total_vecs); if (num_regs < num_vecs) { err = -EINVAL; goto free_reg_vals; diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c index dc5ad784f456..8bd6cca64c9b 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c @@ -1318,11 +1318,12 @@ idpf_vport_init_queue_reg_chunks(struct idpf_vport_config *vport_config, * idpf_get_reg_intr_vecs - Get vector queue register offset * @adapter: adapter structure to get the vector chunks * @reg_vals: Register offsets to store in + * @num_vecs: number of entries the @reg_vals array can hold * * Return: number of registers that got populated */ int idpf_get_reg_intr_vecs(struct idpf_adapter *adapter, - struct idpf_vec_regs *reg_vals) + struct idpf_vec_regs *reg_vals, int num_vecs) { struct virtchnl2_vector_chunks *chunks; struct idpf_vec_regs reg_val; @@ -1346,7 +1347,7 @@ int idpf_get_reg_intr_vecs(struct idpf_adapter *adapter, dynctl_reg_spacing = le32_to_cpu(chunk->dynctl_reg_spacing); itrn_reg_spacing = le32_to_cpu(chunk->itrn_reg_spacing); - for (i = 0; i < num_vec; i++) { + for (i = 0; i < num_vec && num_regs < num_vecs; i++) { reg_vals[num_regs].dyn_ctl_reg = reg_val.dyn_ctl_reg; reg_vals[num_regs].itrn_reg = reg_val.itrn_reg; reg_vals[num_regs].itrn_index_spacing = diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h index 6876e3ed9d1b..9b1c9c86f6ea 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h @@ -104,7 +104,7 @@ int idpf_vc_core_init(struct idpf_adapter *adapter); void idpf_vc_core_deinit(struct idpf_adapter *adapter); int idpf_get_reg_intr_vecs(struct idpf_adapter *adapter, - struct idpf_vec_regs *reg_vals); + struct idpf_vec_regs *reg_vals, int num_vecs); int idpf_queue_reg_init(struct idpf_vport *vport, struct idpf_q_vec_rsrc *rsrc, struct idpf_queue_id_reg_info *chunks); From bef152db47debcd14cbacefc5767f6f026c4bc89 Mon Sep 17 00:00:00 2001 From: Joshua Hay Date: Tue, 30 Jun 2026 16:56:19 -0700 Subject: [PATCH 02/10] idpf: adjust TxQ ring count minimum Set the TxQ ring count minimum to 128 descriptors. Any lower than this, and the queue will stall and trigger Tx timeouts in flow based scheduling mode. This is because next_to_clean might never be updated. In flow based scheduling mode, next_to_clean is only updated after a descriptor completion is processed, i.e. after the RE bit is set in the last descriptor of a Tx packet. This will never happen with a ring size of 64 and an IDPF_TX_SPLITQ_RE_MIN_GAP of 64. No matter what the value of last_re is initialized/set to, the calculated gap will be at most 63 and never trigger the RE bit. Even a ring size of 96 does not solve this. Because of how infrequent next_to_clean is updated and how small the ring is, IDPF_DESC_UNUSED will be much smaller on average. This increases the chance the queue will be stopped because a multi-descriptor packet, e.g. a large LSO packet, does not see enough resources on the ring. In this case, the queue will trigger the stop logic. The queue permanently stalls because there is no chance for a descriptor completion to update next_to_clean since it is dependent on a packet being sent. Fixes: 5f417d551324 ("idpf: replace flow scheduling buffer ring with buffer pool") Signed-off-by: Joshua Hay Reviewed-by: Aleksandr Loktionov Tested-by: Samuel Salin Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/idpf/idpf_txrx.c | 5 +---- drivers/net/ethernet/intel/idpf/idpf_txrx.h | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c index 7f9056404f64..c724d429a7aa 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c @@ -3097,10 +3097,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb, tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE; tx_params.eop_cmd = IDPF_TXD_FLEX_FLOW_CMD_EOP; - /* Set the RE bit to periodically "clean" the descriptor ring. - * MIN_GAP is set to MIN_RING size to ensure it will be set at - * least once each time around the ring. - */ + /* Set the RE bit periodically to "clean" the descriptor ring */ if (idpf_tx_splitq_need_re(tx_q)) { tx_params.eop_cmd |= IDPF_TXD_FLEX_FLOW_CMD_RE; tx_q->txq_grp->num_completions_pending++; diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h index 4be5b3b6d3ed..908dfa28674e 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h @@ -21,7 +21,7 @@ /* Mailbox Queue */ #define IDPF_MAX_MBXQ 1 -#define IDPF_MIN_TXQ_DESC 64 +#define IDPF_MIN_TXQ_DESC 128 #define IDPF_MIN_RXQ_DESC 64 #define IDPF_MIN_TXQ_COMPLQ_DESC 256 #define IDPF_MAX_QIDS 256 From 9bff30482c10f70d9e56c0633a6616e07140e217 Mon Sep 17 00:00:00 2001 From: Yuho Choi Date: Fri, 3 Jul 2026 01:03:32 -0400 Subject: [PATCH 03/10] idpf: Fix mailbox IRQ name leak on request failure idpf_mb_intr_req_irq() allocates the mailbox IRQ name before calling request_irq(). On success, the name is released later through kfree(free_irq()), but request_irq() failure returns without freeing it. Free the allocated name on the request_irq() failure path. Fixes: 4930fbf419a7 ("idpf: add core init and interrupt request") Signed-off-by: Yuho Choi Reviewed-by: Aleksandr Loktionov Tested-by: Samuel Salin Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/idpf/idpf_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c index cf966fe6c759..bb81e620c5c8 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_lib.c +++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c @@ -139,7 +139,7 @@ static int idpf_mb_intr_req_irq(struct idpf_adapter *adapter) if (err) { dev_err(&adapter->pdev->dev, "IRQ request for mailbox failed, error: %d\n", err); - + kfree(name); return err; } From c2816d613f388814d27bc9fd6dbd931a88056e19 Mon Sep 17 00:00:00 2001 From: Aaron Ma Date: Wed, 29 Apr 2026 11:48:49 +0800 Subject: [PATCH 04/10] ice: wait for reset completion in ice_resume() ice_resume() schedules an asynchronous PF reset and returns immediately. The reset runs later in ice_service_task(). If userspace tries to bring up the net device before the reset finishes, ice_open() fails with -EBUSY: ice_resume() ice_schedule_reset() # sets ICE_PFR_REQ, returns ... ice_open() ice_is_reset_in_progress() # ICE_PFR_REQ still set, -EBUSY ... ice_service_task() ice_do_reset() ice_rebuild() # clears ICE_PFR_REQ, too late Reproduced on E800 series NICs during suspend/resume with irdma enabled, where the aux device probe widens the race window. ice 0000:81:00.0: can't open net device while reset is in progress Add a best-effort wait (10s timeout, matching ice_devlink_info_get()) for the reset to complete before returning from ice_resume(). In practice the reset completes in ~300ms. Fixes: 769c500dcc1e ("ice: Add advanced power mgmt for WoL") Cc: stable@vger.kernel.org Reviewed-by: Kohei Enju Reviewed-by: Aleksandr Loktionov Reviewed-by: Przemek Kitszel Signed-off-by: Aaron Ma Tested-by: Alexander Nowlin Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index e2fd2dab03e3..d88835482d3a 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -5637,6 +5637,16 @@ static int ice_resume(struct device *dev) /* Restart the service task */ mod_timer(&pf->serv_tmr, round_jiffies(jiffies + pf->serv_tmr_period)); + /* Best-effort wait for the scheduled reset to finish so that the + * device is operational before returning. Without this, userspace + * (e.g. NetworkManager) may try to open the net device while the + * asynchronous reset is still in progress, hitting -EBUSY. + */ + ret = ice_wait_for_reset(pf, secs_to_jiffies(10)); + if (ret) + dev_err(dev, "Wait for reset timed out (10s) during resume: %d\n", + ret); + return 0; } From fb096882095e5a8d6b5159e43793d4a38a0c5b1f Mon Sep 17 00:00:00 2001 From: Dawid Osuchowski Date: Thu, 14 May 2026 18:35:55 +0200 Subject: [PATCH 05/10] ice: fix VF interrupts cleanup When a virtual function sends an IRQ map command, the PF will set up interrupts according to that request. However, because these interrupts are never reset, the next time Virtual Function initializes, the interrupts are still enabled for a given VF, which leads to performance degradation in certain cases due to interrupts being unexpectedly enabled and thus causing interrupt floods. Cc: stable@vger.kernel.org Fixes: 1071a8358a28 ("ice: Implement virtchnl commands for AVF support") Suggested-by: Vladimir Medvedkin Reviewed-by: Aleksandr Loktionov Signed-off-by: Dawid Osuchowski Reviewed-by: Simon Horman Tested-by: Patryk Holda Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_vf_lib.c | 27 +++++++++++++++++++ .../ethernet/intel/ice/ice_vf_lib_private.h | 1 + drivers/net/ethernet/intel/ice/virt/queues.c | 21 +++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c index 9052e71e9c99..a54cb2b8d3c7 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c @@ -848,6 +848,30 @@ static void ice_notify_vf_reset(struct ice_vf *vf) NULL); } +/** + * ice_reset_interrupts - clear all queue interrupt configuration for a VSI + * @vsi: the VSI whose interrupt registers should be cleared + * + * Zero the QINT_RQCTL and QINT_TQCTL registers for all allocated queues + * in the VSI. This clears the entire register including MSIX_INDX, ITR_INDX, + * CAUSE_ENA and NEXTQ fields, unlike ice_vf_dis_rxq_interrupt() which only + * clears the CAUSE_ENA bit. + */ +void ice_reset_interrupts(struct ice_vsi *vsi) +{ + struct ice_pf *pf = vsi->back; + struct ice_hw *hw = &pf->hw; + int i; + + ice_for_each_alloc_rxq(vsi, i) + wr32(hw, QINT_RQCTL(vsi->rxq_map[i]), 0); + + ice_for_each_alloc_txq(vsi, i) + wr32(hw, QINT_TQCTL(vsi->txq_map[i]), 0); + + ice_flush(hw); +} + /** * ice_reset_vf - Reset a particular VF * @vf: pointer to the VF structure @@ -919,6 +943,9 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) ice_dis_vf_qs(vf); + /* cleanup interrupt registers */ + ice_reset_interrupts(vsi); + /* Call Disable LAN Tx queue AQ whether or not queues are * enabled. This is needed for successful completion of VFR. */ diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h b/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h index 5392b0404986..321d29c25b7c 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h @@ -26,6 +26,7 @@ void ice_initialize_vf_entry(struct ice_vf *vf); void ice_deinitialize_vf_entry(struct ice_vf *vf); void ice_dis_vf_qs(struct ice_vf *vf); +void ice_reset_interrupts(struct ice_vsi *vsi); int ice_check_vf_init(struct ice_vf *vf); enum virtchnl_status_code ice_err_to_virt_err(int err); struct ice_port_info *ice_vf_get_port_info(struct ice_vf *vf); diff --git a/drivers/net/ethernet/intel/ice/virt/queues.c b/drivers/net/ethernet/intel/ice/virt/queues.c index 31be2f76181c..431c9c546b04 100644 --- a/drivers/net/ethernet/intel/ice/virt/queues.c +++ b/drivers/net/ethernet/intel/ice/virt/queues.c @@ -224,6 +224,24 @@ void ice_vf_ena_rxq_interrupt(struct ice_vsi *vsi, u32 q_idx) wr32(hw, QINT_RQCTL(pfq), reg | QINT_RQCTL_CAUSE_ENA_M); } +/** + * ice_vf_dis_rxq_interrupt - disable Rx queue interrupt via QINT_RQCTL + * @vsi: VSI of the VF to configure + * @q_idx: VF queue index used to determine the queue in the PF's space + */ +static void ice_vf_dis_rxq_interrupt(struct ice_vsi *vsi, u32 q_idx) +{ + struct ice_hw *hw = &vsi->back->hw; + u32 pfq = vsi->rxq_map[q_idx]; + u32 reg; + + reg = rd32(hw, QINT_RQCTL(pfq)); + reg &= ~QINT_RQCTL_CAUSE_ENA_M; + wr32(hw, QINT_RQCTL(pfq), reg); + + ice_flush(hw); +} + /** * ice_vc_ena_qs_msg * @vf: pointer to the VF info @@ -416,6 +434,8 @@ int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) goto error_param; } + for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) + ice_vf_dis_rxq_interrupt(vsi, vf_q_id); bitmap_zero(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF); } else if (q_map) { for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { @@ -436,6 +456,7 @@ int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) goto error_param; } + ice_vf_dis_rxq_interrupt(vsi, vf_q_id); /* Clear enabled queues flag */ clear_bit(vf_q_id, vf->rxq_ena); } From 3a9de5590da4ffd9e9c541c4c4d492aa2b54cf6e Mon Sep 17 00:00:00 2001 From: Dawei Feng Date: Tue, 16 Jun 2026 23:57:42 +0800 Subject: [PATCH 06/10] ice: fix memory leak in ice_lbtest_prepare_rings() ice_lbtest_prepare_rings() frees Rx rings only when ice_vsi_start_all_rx_rings() fails. If ice_vsi_setup_rx_rings() fails after allocating some descriptors, or if ice_vsi_cfg_lan() fails after the Rx rings were prepared, the function reaches the Tx cleanup path without releasing the initialized Rx resources. Fix this by adding separate unwind paths for Rx setup failure and LAN configuration failure. The Rx setup failure path releases the partially prepared Rx rings before freeing Tx rings, while later failures first undo the LAN Tx configuration and then release the Rx rings in reverse setup order. The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1-rc7. An x86_64 allyesconfig build showed no new warnings. As we do not have an Intel E800 Series adapter available to run the ethtool offline loopback selftest, no runtime testing was able to be performed. Fixes: 0e674aeb0b77 ("ice: Add handler for ethtool selftest") Cc: stable@vger.kernel.org Signed-off-by: Dawei Feng Reviewed-by: Jacob Keller Tested-by: Rinitha S (A Contingent worker at Intel) Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_ethtool.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index 49371b065845..7eb380be7ed2 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -1069,18 +1069,18 @@ static int ice_lbtest_prepare_rings(struct ice_vsi *vsi) status = ice_vsi_cfg_lan(vsi); if (status) - goto err_setup_rx_ring; + goto err_cfg_lan; status = ice_vsi_start_all_rx_rings(vsi); if (status) - goto err_start_rx_ring; + goto err_cfg_lan; return 0; -err_start_rx_ring: - ice_vsi_free_rx_rings(vsi); -err_setup_rx_ring: +err_cfg_lan: ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, 0); +err_setup_rx_ring: + ice_vsi_free_rx_rings(vsi); err_setup_tx_ring: ice_vsi_free_tx_rings(vsi); From b00be7c6b4bd7da3d510753b27ff6cb7ec647d07 Mon Sep 17 00:00:00 2001 From: Przemyslaw Korba Date: Wed, 20 May 2026 13:50:06 +0200 Subject: [PATCH 07/10] ice: suppress DPLL errors during reset recovery During reset recovery, the admin queue returns EBUSY which is expected behavior. However, the DPLL subsystem was logging these as errors and incrementing the error counter, potentially leading to unnecessary warnings and even disabling the DPLL periodic worker if the threshold was reached. Suppress error logging and error counter increments when the admin queue returns EBUSY, as this is expected during reset recovery and not a real failure condition. test case: - ethtool --reset eth3 irq-shared dma-shared filter-shared offload-shared mac-shared phy-shared ram-shared - observe if dmesg EBUSY errors are gone Fixes: d7999f5ea64b ("ice: implement dpll interface to control cgu") Signed-off-by: Przemyslaw Korba Reviewed-by: Simon Horman Tested-by: Rinitha S (A Contingent worker at Intel) Reviewed-by: Aleksandr Loktionov Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ice/ice_dpll.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index 30c3a4db7d61..85a74cd6ea1f 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -793,7 +793,7 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin, ret, libie_aq_str(pf->hw.adminq.sq_last_status), pin_type_name[pin_type], pin->idx); - else + else if (pf->hw.adminq.sq_last_status != LIBIE_AQ_RC_EBUSY) dev_err_ratelimited(ice_pf_to_dev(pf), "err:%d %s failed to update %s pin:%u\n", ret, @@ -3024,7 +3024,8 @@ static int ice_dpll_pps_update_phase_offsets(struct ice_pf *pf, *phase_offset_pins_updated = 0; ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas, ARRAY_SIZE(meas)); - if (ret && pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_EAGAIN) { + if (ret && (pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_EAGAIN || + pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_EBUSY)) { return 0; } else if (ret) { dev_err(ice_pf_to_dev(pf), @@ -3086,10 +3087,12 @@ ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init) d->dpll_idx, d->prev_input_idx, d->input_idx, d->dpll_state, d->prev_dpll_state, d->mode); if (ret) { - dev_err(ice_pf_to_dev(pf), - "update dpll=%d state failed, ret=%d %s\n", - d->dpll_idx, ret, - libie_aq_str(pf->hw.adminq.sq_last_status)); + /* EBUSY is expected during reset recovery, don't log error */ + if (pf->hw.adminq.sq_last_status != LIBIE_AQ_RC_EBUSY) + dev_err(ice_pf_to_dev(pf), + "update dpll=%d state failed, ret=%d %s\n", + d->dpll_idx, ret, + libie_aq_str(pf->hw.adminq.sq_last_status)); return ret; } if (init) { @@ -3158,7 +3161,9 @@ static void ice_dpll_periodic_work(struct kthread_work *work) d->periodic_counter % dp->phase_offset_monitor_period == 0) ret = ice_dpll_pps_update_phase_offsets(pf, &phase_offset_ntf); if (ret) { - d->cgu_state_acq_err_num++; + /* EBUSY is expected during reset recovery */ + if (pf->hw.adminq.sq_last_status != LIBIE_AQ_RC_EBUSY) + d->cgu_state_acq_err_num++; /* stop rescheduling this worker */ if (d->cgu_state_acq_err_num > ICE_CGU_STATE_ACQ_ERR_THRESHOLD) { From 5ffab5b9589c50e4cfc0cf36ffd76c89422d4019 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 12 Jul 2026 14:22:42 +0100 Subject: [PATCH 08/10] igc: remove napi_synchronize() in igc_down() When an AF_XDP zero-copy application is killed abruptly, the XSK pool is torn down but NAPI keeps polling. igc_clean_rx_irq_zc() then returns the full budget on every poll, so napi_complete_done() never clears NAPI_STATE_SCHED. igc_down() calls napi_synchronize() before napi_disable(), so it spins forever waiting for that bit and the interface never goes down. Drop the napi_synchronize() and let napi_disable() do the job -- it sets NAPI_STATE_DISABLE, which forces the stuck poll to complete. Reorder it ahead of igc_set_queue_napi() so the NAPI mapping is cleared only after polling has stopped, matching the recent igb fix b1e067240379. Fixes: fc9df2a0b520 ("igc: Enable RX via AF_XDP zero-copy") Suggested-by: Maciej Fijalkowski Cc: stable@vger.kernel.org Signed-off-by: David Carlier Reviewed-by: Maciej Fijalkowski Reviewed-by: Dima Ruinskiy Tested-by: Moriya Kadosh Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/igc/igc_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 2c9e2dfd8499..b3883a5a7d7a 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -5352,9 +5352,8 @@ void igc_down(struct igc_adapter *adapter) for (i = 0; i < adapter->num_q_vectors; i++) { if (adapter->q_vector[i]) { - napi_synchronize(&adapter->q_vector[i]->napi); - igc_set_queue_napi(adapter, i, NULL); napi_disable(&adapter->q_vector[i]->napi); + igc_set_queue_napi(adapter, i, NULL); } } From 0565052b7e2f436b7f1541f4849da96dc0aa7a0e Mon Sep 17 00:00:00 2001 From: Matt Vollrath Date: Thu, 16 Apr 2026 23:34:52 -0400 Subject: [PATCH 09/10] igbvf: Fix leak in TX DMA error cleanup If an error is encountered while mapping TX buffers, the driver should unmap any buffers already mapped for that skb. Because count is incremented before each frag mapping, it will always match the correct number of unmappings needed when dma_error is reached. Decrementing count before the while loop in dma_error causes an off-by-one error. If any mapping was successful before an unsuccessful mapping, exactly one DMA mapping (the head) would leak. This bug was introduced by a 2010 fix for an endless loop in dma_error. All other affected drivers have already been fixed. Fixes: c1fa347f20f1 ("e1000/e1000e/igb/igbvf/ixgb/ixgbe: Fix tests of unsigned in *_tx_map()") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-4-7-opus Signed-off-by: Matt Vollrath Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/igbvf/netdev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index 0a3d0a1cba43..c686ee120a14 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -2190,8 +2190,6 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, buffer_info->time_stamp = 0; buffer_info->length = 0; buffer_info->mapped_as_page = false; - if (count) - count--; /* clear timestamp and dma mappings for remaining portion of packet */ while (count--) { From 816419dfea5c88126f35eb7a1b429a1bf546665e Mon Sep 17 00:00:00 2001 From: Dawei Feng Date: Sun, 7 Jun 2026 22:57:06 +0800 Subject: [PATCH 10/10] e1000: fix memory leak in e1000_probe() In the e1000_probe() path, e1000_sw_init() allocates adapter->tx_ring and adapter->rx_ring. If the subsequent CE4100-specific MDIO BAR mapping fails, the error handling jumps past the ring cleanup code, leaking both allocations. Fix this leak by moving the err_mdio_ioremap label above the ring deallocation logic. This guarantees the proper release of these resources and prevents the memory leak. The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1-rc6. An x86_64 allyesconfig build showed no new warnings. As we do not have a CE4100 reference platform to test with, no runtime testing was able to be performed. Fixes: 5377a4160bb65 ("e1000: Add support for the CE4100 reference platform") Cc: stable@vger.kernel.org Signed-off-by: Zilin Guan Signed-off-by: Dawei Feng Reviewed-by: Dima Ruinskiy Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/e1000/e1000_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 9b09eb144b81..d7f5c6f16142 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -1222,11 +1222,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (hw->flash_address) iounmap(hw->flash_address); +err_mdio_ioremap: kfree(adapter->tx_ring); kfree(adapter->rx_ring); err_dma: err_sw_init: -err_mdio_ioremap: iounmap(hw->ce4100_gbe_mdio_base_virt); iounmap(hw->hw_addr); err_ioremap: