* [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice)
@ 2026-09-08 21:44 Tony Nguyen
2026-09-08 21:44 ` [PATCH net 1/5] idpf: disable DIM work before freeing q_vectors Tony Nguyen
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Tony Nguyen @ 2026-09-08 21:44 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Tony Nguyen, ae878000, mhun512, joshua.a.hay, sridhar.samudrala,
milena.olech, vadim.fedorenko, willemb, jacob.e.keller,
przemyslaw.kitszel, jbrandeb
For idpf:
Myeonghun Pak adds calls to disable DIM work and PTM to allow for proper
cleanup.
Josh adds check, and adjustment, for VLAN headers when processing RSC
packets.
For ice:
Jake adds call to xa_destroy for xarray sched_node_ids; also moving it
from port_info struct to ice_hw to simplify its lifecycle management.
Jakub Kicinski stores trace event data as scalars instead of
dereferencing pointers in TP_printk(), preventing use-after-free issues
during event printing and eliminating double-dereference warnings.
The following are changes since commit e0554c6276da957b6e72849520c70a97404cd1ae:
Merge branch 'net-ethernet-cortina-fix-rx-budget-accounting'
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue 200GbE
Jacob Keller (1):
ice: add missing xa_destroy for sched_node_ids
Jakub Kicinski (1):
eth: ice: don't dereference pointers from TP_printk()
Joshua Hay (1):
idpf: account for VLAN header when parsing RSC packet header
Myeonghun Pak (2):
idpf: disable DIM work before freeing q_vectors
idpf: disable PTM on probe failure and on remove
drivers/net/ethernet/intel/ice/ice_common.c | 9 ++-
drivers/net/ethernet/intel/ice/ice_sched.c | 4 +-
drivers/net/ethernet/intel/ice/ice_trace.h | 64 ++++++++++++++-------
drivers/net/ethernet/intel/ice/ice_type.h | 2 +-
drivers/net/ethernet/intel/idpf/idpf_main.c | 5 ++
drivers/net/ethernet/intel/idpf/idpf_txrx.c | 34 +++++++++--
6 files changed, 86 insertions(+), 32 deletions(-)
--
2.47.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net 1/5] idpf: disable DIM work before freeing q_vectors
2026-09-08 21:44 [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) Tony Nguyen
@ 2026-09-08 21:44 ` Tony Nguyen
2026-09-08 21:44 ` [PATCH net 2/5] idpf: disable PTM on probe failure and on remove Tony Nguyen
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Tony Nguyen @ 2026-09-08 21:44 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Myeonghun Pak, anthony.l.nguyen, ae878000, joshua.a.hay,
sridhar.samudrala, milena.olech, vadim.fedorenko, willemb,
jacob.e.keller, przemyslaw.kitszel, jbrandeb, stable,
Samuel Salin
From: Myeonghun Pak <mhun512@gmail.com>
idpf never drains the Tx/Rx DIM works before freeing the memory they
live in. tx_dim and rx_dim are embedded in struct idpf_q_vector, they
are queued from the NAPI poll via net_dim(), and idpf_vport_intr_rel()
ends with kfree(rsrc->q_vectors). Nothing in the driver cancels them.
idpf_tx_dim_work() and idpf_rx_dim_work() then run on freed memory:
idpf_vport_intr_write_itr() writes the ITR register through
q_vector->intr_reg.tx_itr / rx_itr, void __iomem pointers loaded out of
the freed q_vector. No configuration is needed to get there --
IDPF_ITR_IS_DYNAMIC() is defined as (itr_mode) and idpf_vport_alloc()
initialises both modes to IDPF_ITR_DYNAMIC.
Draining after idpf_vport_intr_napi_dis_all() is not enough on its own.
idpf_net_dim() is called from inside the
"if (napi_complete_done(napi, work_done))" branch of the poll, and
napi_complete_done() has already cleared NAPIF_STATE_SCHED by then.
napi_disable_locked() waits only while (val & (NAPIF_STATE_SCHED |
NAPIF_STATE_NPSVC)), so napi_disable() can return while the poll tail is
still queueing the work, and a plain cancel_work_sync() would be
re-armed behind the drain.
Use disable_work_sync(): schedule_work() on a work with a non-zero
disable count is dropped by clear_pending_if_disabled() before
__queue_work() is reached.
Move idpf_init_dim() to idpf_vport_intr_alloc() so the works are
initialised on every path that can reach the drain -- the three
"goto intr_deinit" sites between idpf_vport_intr_init() and
idpf_vport_intr_ena() get there without the enable side having run.
Nothing re-enables them: rsrc->q_vectors is freed on every exit from
idpf_vport_open() and on every idpf_vport_stop(), so the count dies with
the object.
It is a race, not a deterministic failure -- net_dim() only schedules
once DIM_NEVENTS events have accumulated and the profile index changes.
A KASAN ifup/ifdown loop under load is the way to see it.
Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
Fixes: 3a8845af66ed ("idpf: add RX splitq napi poll support")
Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for <= 6.9
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/idpf/idpf_txrx.c | 24 ++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index 24b91be25676..9ba9c2952d78 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -4145,6 +4145,26 @@ static void idpf_vport_intr_ena_irq_all(struct idpf_vport *vport,
writel(rsrc->noirq_dyn_ctl_ena, rsrc->noirq_dyn_ctl);
}
+/**
+ * idpf_vport_intr_dis_dim_all - Disable DIM work for all q_vectors
+ * @rsrc: pointer to queue and vector resources
+ *
+ * The DIM works are embedded in the q_vector array that
+ * idpf_vport_intr_rel() frees, and the poll arms them after
+ * napi_complete_done() has already cleared NAPI_STATE_SCHED. Disable
+ * rather than just cancel, so that a poll tail still running past
+ * napi_disable() cannot queue them again behind the drain.
+ */
+static void idpf_vport_intr_dis_dim_all(struct idpf_q_vec_rsrc *rsrc)
+{
+ for (u16 v_idx = 0; v_idx < rsrc->num_q_vectors; v_idx++) {
+ struct idpf_q_vector *q_vector = &rsrc->q_vectors[v_idx];
+
+ disable_work_sync(&q_vector->tx_dim.work);
+ disable_work_sync(&q_vector->rx_dim.work);
+ }
+}
+
/**
* idpf_vport_intr_deinit - Release all vector associations for the vport
* @vport: main vport structure
@@ -4155,6 +4175,7 @@ void idpf_vport_intr_deinit(struct idpf_vport *vport,
{
idpf_vport_intr_dis_irq_all(rsrc);
idpf_vport_intr_napi_dis_all(rsrc);
+ idpf_vport_intr_dis_dim_all(rsrc);
idpf_vport_intr_napi_del_all(rsrc);
idpf_vport_intr_rel_irq(vport, rsrc);
}
@@ -4235,7 +4256,6 @@ static void idpf_vport_intr_napi_ena_all(struct idpf_q_vec_rsrc *rsrc)
for (u16 q_idx = 0; q_idx < rsrc->num_q_vectors; q_idx++) {
struct idpf_q_vector *q_vector = &rsrc->q_vectors[q_idx];
- idpf_init_dim(q_vector);
napi_enable(&q_vector->napi);
}
}
@@ -4578,6 +4598,8 @@ int idpf_vport_intr_alloc(struct idpf_vport *vport,
q_coal = &user_config->q_coalesce[v_idx];
q_vector->vport = vport;
+ idpf_init_dim(q_vector);
+
q_vector->tx_itr_value = q_coal->tx_coalesce_usecs;
q_vector->tx_intr_mode = q_coal->tx_intr_mode;
q_vector->tx_itr_idx = VIRTCHNL2_ITR_IDX_1;
--
2.47.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net 2/5] idpf: disable PTM on probe failure and on remove
2026-09-08 21:44 [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) Tony Nguyen
2026-09-08 21:44 ` [PATCH net 1/5] idpf: disable DIM work before freeing q_vectors Tony Nguyen
@ 2026-09-08 21:44 ` Tony Nguyen
2026-09-12 9:36 ` netdev-bot+sashiko
2026-09-08 21:44 ` [PATCH net 3/5] idpf: account for VLAN header when parsing RSC packet header Tony Nguyen
` (3 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: Tony Nguyen @ 2026-09-08 21:44 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Myeonghun Pak, anthony.l.nguyen, ae878000, joshua.a.hay,
sridhar.samudrala, milena.olech, vadim.fedorenko, willemb,
jacob.e.keller, przemyslaw.kitszel, jbrandeb, Aleksandr Loktionov,
Samuel Salin
From: Myeonghun Pak <mhun512@gmail.com>
idpf_probe() enables PCIe Precision Time Measurement with
pci_enable_ptm(), which takes a reference on the device and on every
PTM-capable device up the path to the PTM Root.
Neither the probe error path nor idpf_remove() drops that reference, so
the PTM enable counts of this device and of its upstream path stay
elevated with no bound driver, and the device's PTM control bits remain
set. pcim_enable_device() only arranges for pci_disable_device() and
does not undo the PTM enable.
Add the matching pci_disable_ptm() to the common unwind path.
pci_enable_ptm() failure is not fatal here, so guard the call with
pcie_ptm_enabled(): pci_disable_ptm() decrements dev->ptm_enable_cnt
unconditionally and then recurses upstream, so calling it after a failed
enable would drive this device's count negative and wrongly decrement
parents shared with other endpoints.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: 8d5e12c5921c ("idpf: add initial PTP support")
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
[TN moved call due to commit 6b284aa2ddf3 ("idpf: refactor idpf to use libie_pci APIs")]
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/idpf/idpf_main.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c
index 9840580fbe51..129bccaa6baa 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_main.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
@@ -106,6 +106,11 @@ static int idpf_dev_init(struct idpf_adapter *adapter,
*/
static void idpf_decfg_device(struct idpf_adapter *adapter)
{
+ struct pci_dev *pdev = adapter->pdev;
+
+ if (pcie_ptm_enabled(pdev))
+ pci_disable_ptm(pdev);
+
libie_pci_unmap_all_mmio_regions(&adapter->ctlq_ctx.mmio_info);
}
--
2.47.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net 3/5] idpf: account for VLAN header when parsing RSC packet header
2026-09-08 21:44 [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) Tony Nguyen
2026-09-08 21:44 ` [PATCH net 1/5] idpf: disable DIM work before freeing q_vectors Tony Nguyen
2026-09-08 21:44 ` [PATCH net 2/5] idpf: disable PTM on probe failure and on remove Tony Nguyen
@ 2026-09-08 21:44 ` Tony Nguyen
2026-09-08 21:44 ` [PATCH net 4/5] ice: add missing xa_destroy for sched_node_ids Tony Nguyen
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Tony Nguyen @ 2026-09-08 21:44 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Joshua Hay, anthony.l.nguyen, ae878000, mhun512,
sridhar.samudrala, milena.olech, vadim.fedorenko, willemb,
jacob.e.keller, przemyslaw.kitszel, jbrandeb, Emil Tantilov,
Aleksandr Loktionov, Samuel Salin
From: Joshua Hay <joshua.a.hay@intel.com>
While parsing the header of a Receive Side Coalesced (RSC) packet, check
if a VLAN tag is present and adjust the header parsing accordingly.
Otherwise, Rx TCP traffic is completely broken for any VLAN interface
whose underlying interface has RSC (rx-gro-hw) enabled.
We only need to worry about one VLAN header since Rx packets with
multiple VLAN headers are not candidates for RSC.
Fixes: 3a8845af66edb ("idpf: add RX splitq napi poll support")
Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
Reviewed-by: Emil Tantilov <emil.s.tantilov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/idpf/idpf_txrx.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index 9ba9c2952d78..4311ffa30bb1 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -3299,6 +3299,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
struct libeth_rx_pt decoded)
{
u16 rsc_segments, rsc_seg_len;
+ u16 l3_start = 0;
bool ipv4, ipv6;
int len;
@@ -3321,7 +3322,10 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
NAPI_GRO_CB(skb)->count = rsc_segments;
skb_shinfo(skb)->gso_size = rsc_seg_len;
- skb_reset_network_header(skb);
+ if (unlikely(eth_type_vlan(skb->protocol)))
+ l3_start = VLAN_HLEN;
+
+ skb_set_network_header(skb, l3_start);
if (ipv4) {
struct iphdr *ipv4h = ip_hdr(skb);
@@ -3329,7 +3333,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
/* Reset and set transport header offset in skb */
- skb_set_transport_header(skb, sizeof(struct iphdr));
+ skb_set_transport_header(skb, l3_start + sizeof(struct iphdr));
len = skb->len - skb_transport_offset(skb);
/* Compute the TCP pseudo header checksum*/
@@ -3339,7 +3343,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
- skb_set_transport_header(skb, sizeof(struct ipv6hdr));
+ skb_set_transport_header(skb, l3_start + sizeof(struct ipv6hdr));
len = skb->len - skb_transport_offset(skb);
tcp_hdr(skb)->check =
~tcp_v6_check(len, &ipv6h->saddr, &ipv6h->daddr, 0);
--
2.47.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net 4/5] ice: add missing xa_destroy for sched_node_ids
2026-09-08 21:44 [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) Tony Nguyen
` (2 preceding siblings ...)
2026-09-08 21:44 ` [PATCH net 3/5] idpf: account for VLAN header when parsing RSC packet header Tony Nguyen
@ 2026-09-08 21:44 ` Tony Nguyen
2026-09-08 21:45 ` [PATCH net 5/5] eth: ice: don't dereference pointers from TP_printk() Tony Nguyen
2026-09-10 16:10 ` [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) patchwork-bot+netdevbpf
5 siblings, 0 replies; 8+ messages in thread
From: Tony Nguyen @ 2026-09-08 21:44 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Jacob Keller, anthony.l.nguyen, ae878000, mhun512, joshua.a.hay,
sridhar.samudrala, milena.olech, vadim.fedorenko, willemb,
przemyslaw.kitszel, jbrandeb, Aleksandr Loktionov, Rinitha S
From: Jacob Keller <jacob.e.keller@intel.com>
Commit 16dfa49406bc ("ice: Introduce new parameters in ice_sched_node")
added a sched_node_ids xarray to the port info structure, but never called
xa_destroy on it.
Since xarrays can allocate internal memory, this can result in a memory
leak even if every element in the xarray has been removed.
The xarray is currently embedded in the port_info structure. This appears
to have been done because its use is within functions that take the
port_info as a primary argument.
However, this complicates managing the lifecycle of the field. The
port_info structure is allocated in ice_init_hw() using devm, and it is
not released until the devm cleanup when the driver is unloaded.
The ice_init_hw() function is called in many places, including devlink
reload, and possibly during DDP load after updating the Tx scheduler
layout.
Adding a call of xa_destroy to the ice_deinit_hw() causes Sashiko to raise
multiple concerns due to potential ordering issues and possible ways that
port_info could be a dangling reference.
To handle this, move the sched_node_ids out of port_info and into the hw
structure. All users of the array already have a pointer to hw anyways, and
there is only one sched_node_ids per adapter. While here, remove the overly
verbose comment explaining the nature of the sched_node_ids xarray.
Add the missing xa_destroy to the cleanup path and to ice_deinit_hw(),
ensuring that we properly release the xarray memory.
This was caught by Sashiko during development of unrelated code.
Fixes: 16dfa49406bc ("ice: Introduce new parameters in ice_sched_node")
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ice/ice_common.c | 9 ++++++---
drivers/net/ethernet/intel/ice/ice_sched.c | 4 ++--
drivers/net/ethernet/intel/ice/ice_type.h | 2 +-
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index ef1ce106f81b..04633103e3e6 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -1051,14 +1051,13 @@ int ice_init_hw(struct ice_hw *hw)
hw->evb_veb = true;
- /* init xarray for identifying scheduling nodes uniquely */
- xa_init_flags(&hw->port_info->sched_node_ids, XA_FLAGS_ALLOC);
+ xa_init_flags(&hw->sched_node_ids, XA_FLAGS_ALLOC);
/* Query the allocated resources for Tx scheduler */
status = ice_sched_query_res_alloc(hw);
if (status) {
ice_debug(hw, ICE_DBG_SCHED, "Failed to get scheduler allocated resources\n");
- goto err_unroll_alloc;
+ goto err_unroll_xarray;
}
ice_sched_get_psm_clk_freq(hw);
@@ -1146,6 +1145,8 @@ int ice_init_hw(struct ice_hw *hw)
ice_cleanup_fltr_mgmt_struct(hw);
err_unroll_sched:
ice_sched_cleanup_all(hw);
+err_unroll_xarray:
+ xa_destroy(&hw->sched_node_ids);
err_unroll_alloc:
devm_kfree(ice_hw_to_dev(hw), hw->port_info);
err_unroll_cqinit:
@@ -1186,6 +1187,8 @@ void ice_deinit_hw(struct ice_hw *hw)
/* Clear VSI contexts if not already cleared */
ice_clear_all_vsi_ctx(hw);
+
+ xa_destroy(&hw->sched_node_ids);
}
/**
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c
index fff0c1afdb41..ffa18d86729a 100644
--- a/drivers/net/ethernet/intel/ice/ice_sched.c
+++ b/drivers/net/ethernet/intel/ice/ice_sched.c
@@ -371,7 +371,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
devm_kfree(ice_hw_to_dev(hw), node->children);
kfree(node->name);
- xa_erase(&pi->sched_node_ids, node->id);
+ xa_erase(&hw->sched_node_ids, node->id);
devm_kfree(ice_hw_to_dev(hw), node);
}
@@ -977,7 +977,7 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
if (!new_node->name)
return -ENOMEM;
- status = xa_alloc(&pi->sched_node_ids, &new_node->id, NULL, XA_LIMIT(0, UINT_MAX),
+ status = xa_alloc(&hw->sched_node_ids, &new_node->id, NULL, XA_LIMIT(0, UINT_MAX),
GFP_KERNEL);
if (status) {
ice_debug(hw, ICE_DBG_SCHED, "xa_alloc failed for sched node status =%d\n",
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index d9a5c1aae7c2..cf147a212707 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -765,7 +765,6 @@ struct ice_port_info {
/* List contain profile ID(s) and other params per layer */
struct list_head rl_prof_list[ICE_AQC_TOPO_MAX_LEVEL_NUM];
struct ice_qos_cfg qos_cfg;
- struct xarray sched_node_ids;
u8 is_vf:1;
u8 is_custom_tx_enabled:1;
};
@@ -930,6 +929,7 @@ struct ice_hw {
u8 sw_entry_point_layer;
u16 max_children[ICE_AQC_TOPO_MAX_LEVEL_NUM];
struct list_head agg_list; /* lists all aggregator */
+ struct xarray sched_node_ids;
struct ice_vsi_ctx *vsi_ctx[ICE_MAX_VSI];
u8 evb_veb; /* true for VEB, false for VEPA */
--
2.47.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net 5/5] eth: ice: don't dereference pointers from TP_printk()
2026-09-08 21:44 [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) Tony Nguyen
` (3 preceding siblings ...)
2026-09-08 21:44 ` [PATCH net 4/5] ice: add missing xa_destroy for sched_node_ids Tony Nguyen
@ 2026-09-08 21:45 ` Tony Nguyen
2026-09-10 16:10 ` [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) patchwork-bot+netdevbpf
5 siblings, 0 replies; 8+ messages in thread
From: Tony Nguyen @ 2026-09-08 21:45 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: anthony.l.nguyen, ae878000, mhun512, joshua.a.hay,
sridhar.samudrala, milena.olech, vadim.fedorenko, willemb,
jacob.e.keller, przemyslaw.kitszel, jbrandeb, Alexander Nowlin
From: Jakub Kicinski <kuba@kernel.org>
After forwarding net-next during the v7.3 merge window we started
seeing:
TRACE EVENT ERROR: Event ice_tx_dim_work has double dereference in TP_printk: REC->q_vector->tx.tx_ring->q_index
WARNING: kernel/trace/trace_events.c:420 at test_double_dereference.cold+0x39/0x4b
this is due to extra checks added in tracing subsystem in
commit b5cc230af5e5 ("tracing: Warn when an event dereferences a pointer in TP_printk()").
Printing happens long after the event was recorded, by which point
the pointers may be invalid (the ring or the dim instance).
Copy the eight scalars into the event instead.
Fixes: 3089cf6d3caa ("ice: add tracepoints")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Tested-by: Alexander Nowlin <alexander.nowlin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ice/ice_trace.h | 64 ++++++++++++++--------
1 file changed, 42 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_trace.h b/drivers/net/ethernet/intel/ice/ice_trace.h
index 4f35ef8d6b29..7568c917cdbe 100644
--- a/drivers/net/ethernet/intel/ice/ice_trace.h
+++ b/drivers/net/ethernet/intel/ice/ice_trace.h
@@ -63,23 +63,33 @@
DECLARE_EVENT_CLASS(ice_rx_dim_template,
TP_PROTO(struct ice_q_vector *q_vector, struct dim *dim),
TP_ARGS(q_vector, dim),
- TP_STRUCT__entry(__field(struct ice_q_vector *, q_vector)
- __field(struct dim *, dim)
+ TP_STRUCT__entry(__field(u16, q_index)
+ __field(u8, state)
+ __field(u8, profile_ix)
+ __field(u8, tune_state)
+ __field(u8, steps_right)
+ __field(u8, steps_left)
+ __field(u8, tired)
__string(devname, q_vector->rx.rx_ring->netdev->name)),
- TP_fast_assign(__entry->q_vector = q_vector;
- __entry->dim = dim;
+ TP_fast_assign(__entry->q_index = q_vector->rx.rx_ring->q_index;
+ __entry->state = dim->state;
+ __entry->profile_ix = dim->profile_ix;
+ __entry->tune_state = dim->tune_state;
+ __entry->steps_right = dim->steps_right;
+ __entry->steps_left = dim->steps_left;
+ __entry->tired = dim->tired;
__assign_str(devname);),
TP_printk("netdev: %s Rx-Q: %d dim-state: %d dim-profile: %d dim-tune: %d dim-st-right: %d dim-st-left: %d dim-tired: %d",
__get_str(devname),
- __entry->q_vector->rx.rx_ring->q_index,
- __entry->dim->state,
- __entry->dim->profile_ix,
- __entry->dim->tune_state,
- __entry->dim->steps_right,
- __entry->dim->steps_left,
- __entry->dim->tired)
+ __entry->q_index,
+ __entry->state,
+ __entry->profile_ix,
+ __entry->tune_state,
+ __entry->steps_right,
+ __entry->steps_left,
+ __entry->tired)
);
DEFINE_EVENT(ice_rx_dim_template, ice_rx_dim_work,
@@ -90,23 +100,33 @@ DEFINE_EVENT(ice_rx_dim_template, ice_rx_dim_work,
DECLARE_EVENT_CLASS(ice_tx_dim_template,
TP_PROTO(struct ice_q_vector *q_vector, struct dim *dim),
TP_ARGS(q_vector, dim),
- TP_STRUCT__entry(__field(struct ice_q_vector *, q_vector)
- __field(struct dim *, dim)
+ TP_STRUCT__entry(__field(u16, q_index)
+ __field(u8, state)
+ __field(u8, profile_ix)
+ __field(u8, tune_state)
+ __field(u8, steps_right)
+ __field(u8, steps_left)
+ __field(u8, tired)
__string(devname, q_vector->tx.tx_ring->netdev->name)),
- TP_fast_assign(__entry->q_vector = q_vector;
- __entry->dim = dim;
+ TP_fast_assign(__entry->q_index = q_vector->tx.tx_ring->q_index;
+ __entry->state = dim->state;
+ __entry->profile_ix = dim->profile_ix;
+ __entry->tune_state = dim->tune_state;
+ __entry->steps_right = dim->steps_right;
+ __entry->steps_left = dim->steps_left;
+ __entry->tired = dim->tired;
__assign_str(devname);),
TP_printk("netdev: %s Tx-Q: %d dim-state: %d dim-profile: %d dim-tune: %d dim-st-right: %d dim-st-left: %d dim-tired: %d",
__get_str(devname),
- __entry->q_vector->tx.tx_ring->q_index,
- __entry->dim->state,
- __entry->dim->profile_ix,
- __entry->dim->tune_state,
- __entry->dim->steps_right,
- __entry->dim->steps_left,
- __entry->dim->tired)
+ __entry->q_index,
+ __entry->state,
+ __entry->profile_ix,
+ __entry->tune_state,
+ __entry->steps_right,
+ __entry->steps_left,
+ __entry->tired)
);
DEFINE_EVENT(ice_tx_dim_template, ice_tx_dim_work,
--
2.47.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice)
2026-09-08 21:44 [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) Tony Nguyen
` (4 preceding siblings ...)
2026-09-08 21:45 ` [PATCH net 5/5] eth: ice: don't dereference pointers from TP_printk() Tony Nguyen
@ 2026-09-10 16:10 ` patchwork-bot+netdevbpf
5 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-09-10 16:10 UTC (permalink / raw)
To: Tony Nguyen
Cc: davem, kuba, pabeni, edumazet, andrew+netdev, netdev, ae878000,
mhun512, joshua.a.hay, sridhar.samudrala, milena.olech,
vadim.fedorenko, willemb, jacob.e.keller, przemyslaw.kitszel,
jbrandeb
Hello:
This series was applied to netdev/net.git (main)
by Tony Nguyen <anthony.l.nguyen@intel.com>:
On Tue, 8 Sep 2026 14:44:55 -0700 you wrote:
> For idpf:
> Myeonghun Pak adds calls to disable DIM work and PTM to allow for proper
> cleanup.
>
> Josh adds check, and adjustment, for VLAN headers when processing RSC
> packets.
>
> [...]
Here is the summary with links:
- [net,1/5] idpf: disable DIM work before freeing q_vectors
https://git.kernel.org/netdev/net/c/7dd4c829bac2
- [net,2/5] idpf: disable PTM on probe failure and on remove
https://git.kernel.org/netdev/net/c/650f197d8ea6
- [net,3/5] idpf: account for VLAN header when parsing RSC packet header
https://git.kernel.org/netdev/net/c/cc6d60ef9227
- [net,4/5] ice: add missing xa_destroy for sched_node_ids
https://git.kernel.org/netdev/net/c/53432c4c3e86
- [net,5/5] eth: ice: don't dereference pointers from TP_printk()
https://git.kernel.org/netdev/net/c/b8bf9bfda5f6
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net 2/5] idpf: disable PTM on probe failure and on remove
2026-09-08 21:44 ` [PATCH net 2/5] idpf: disable PTM on probe failure and on remove Tony Nguyen
@ 2026-09-12 9:36 ` netdev-bot+sashiko
0 siblings, 0 replies; 8+ messages in thread
From: netdev-bot+sashiko @ 2026-09-12 9:36 UTC (permalink / raw)
To: anthony.l.nguyen
Cc: davem, kuba, pabeni, edumazet, andrew+netdev, netdev, ae878000,
mhun512, joshua.a.hay, sridhar.samudrala, milena.olech,
vadim.fedorenko, willemb, jacob.e.keller, przemyslaw.kitszel,
jbrandeb, alexander.nowlin
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 1 (1) · Low: 0
- [Medium] Incomplete unwind: the new `pcie_ptm_enabled(pdev)` guard in
`idpf_decfg_device()`…
Pre-existing issues:
- [Medium] Unserialized read-modify-write on shared upstream PTM state:
`idpf_decfg_device()` (idpf_main.c:111-112) now calls…
--
idpf: disable PTM on probe failure and on remove
idpf_probe() enables PCIe PTM but never disables it, so the PTM enable
counts of the device and of its upstream path stay elevated after probe
failure or removal. This adds a pci_disable_ptm() call to
idpf_decfg_device(), guarded by pcie_ptm_enabled() so that a failed
pci_enable_ptm() does not drive the count negative.
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c
> index 9840580fbe51..129bccaa6baa 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_main.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
> @@ -106,6 +106,11 @@ static int idpf_dev_init(struct idpf_adapter *adapter,
> */
> static void idpf_decfg_device(struct idpf_adapter *adapter)
> {
> + struct pci_dev *pdev = adapter->pdev;
> +
> + if (pcie_ptm_enabled(pdev))
> + pci_disable_ptm(pdev);
> +
[Severity: Medium]
Does the pcie_ptm_enabled() guard skip the disable in exactly the case
the commit message describes as broken?
pcie_ptm_enabled() only looks at this device's own count:
static inline bool pcie_ptm_enabled(struct pci_dev *dev)
{
return dev && atomic_read(&dev->ptm_enable_cnt) > 0;
}
But pci_enable_ptm() in drivers/pci/pcie/ptm.c enables the upstream path
first, and only then tries the local device:
parent = pci_upstream_ptm(dev);
if (!parent)
return -EINVAL;
/* Enable PTM for the parent */
rc = pci_enable_ptm(parent);
if (rc)
return rc;
...
if (atomic_inc_return(&dev->ptm_enable_cnt) > 1)
return 0;
rc = __pci_enable_ptm(dev);
if (rc) {
atomic_dec(&dev->ptm_enable_cnt);
return rc;
}
So when __pci_enable_ptm(dev) fails, the local count returns to zero but
the parents that were just enabled and refcounted are never unwound.
__pci_enable_ptm() fails locally for a device with no PTM capability, and
for an endpoint that is not a PTM requester:
if (!ptm)
return -EINVAL;
...
case PCI_EXP_TYPE_ENDPOINT:
case PCI_EXP_TYPE_LEG_END:
if (!dev->ptm_requester)
return -EINVAL;
idpf_cfg_device() discards that error and continues probing:
err = pci_enable_ptm(pdev);
if (err)
pci_dbg(pdev, "PCIe PTM is not supported by PCIe bus/controller\n");
In that state pdev->ptm_enable_cnt is 0 while each upstream PTM device
sits at +1, pcie_ptm_enabled(pdev) is false, and idpf_decfg_device() does
nothing on probe failure or on remove.
Doesn't that leave the upstream enable counts and PTM Control bits
elevated with no bound driver, which is what the changelog says this fixes
("the PTM enable counts of this device and of its upstream path stay
elevated with no bound driver")? Every bind/unbind cycle of such a
function, for example an idpf VF under a PTM-capable upstream port, would
add another leaked upstream reference, and a sibling endpoint's later
pci_disable_ptm() can then never bring the shared parent back to zero.
Calling pci_disable_ptm() unconditionally is not the answer either, for
the reason given in the changelog. Would it make sense to record whether
pci_enable_ptm() succeeded in idpf_cfg_device() and key the unwind off
that instead, or to have the PCI core unwind the parent enables on local
failure?
[Severity: Medium]
This is a pre-existing issue in the PCI core and was not introduced by
this patch, but this is the first place idpf reaches it, so noting it
here.
pci_disable_ptm() recurses over bridges shared with sibling endpoints,
and the counter transition and the config-space write are separate steps
with no common lock:
if (atomic_dec_and_test(&dev->ptm_enable_cnt))
__pci_disable_ptm(dev);
parent = pci_upstream_ptm(dev);
if (parent)
pci_disable_ptm(parent);
pci_enable_ptm() is symmetric:
if (atomic_inc_return(&dev->ptm_enable_cnt) > 1)
return 0;
rc = __pci_enable_ptm(dev);
Can a remove running idpf_decfg_device() (shared parent 1 -> 0, then the
disable write) interleave with an asynchronous probe of a sibling under
the same upstream port (0 -> 1, then the enable write)? If the sibling's
enable write lands before the remover's disable write, the shared parent
ends up PTM-disabled in hardware while ptm_enable_cnt is 1, and the
sibling would then gate on pcie_ptm_enabled() in idpf_ptp and offer
getcrosststamp over a PTM path that is off.
The window is narrow and confined to driver bind/unbind, and every
pci_disable_ptm() caller in the tree has the same exposure, so this looks
like something for the PCI core rather than this patch.
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260908214502.528440-1-anthony.l.nguyen%40intel.com
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-12 9:36 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-08 21:44 [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) Tony Nguyen
2026-09-08 21:44 ` [PATCH net 1/5] idpf: disable DIM work before freeing q_vectors Tony Nguyen
2026-09-08 21:44 ` [PATCH net 2/5] idpf: disable PTM on probe failure and on remove Tony Nguyen
2026-09-12 9:36 ` netdev-bot+sashiko
2026-09-08 21:44 ` [PATCH net 3/5] idpf: account for VLAN header when parsing RSC packet header Tony Nguyen
2026-09-08 21:44 ` [PATCH net 4/5] ice: add missing xa_destroy for sched_node_ids Tony Nguyen
2026-09-08 21:45 ` [PATCH net 5/5] eth: ice: don't dereference pointers from TP_printk() Tony Nguyen
2026-09-10 16:10 ` [PATCH net 0/5][pull request] Intel Wired LAN Driver Updates 2026-09-08 (idpf, ice) patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox