From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 245F0187346 for ; Tue, 24 Feb 2026 05:45:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771911941; cv=none; b=dtdf8WCNou8wXId2TSpTn6pUzNNvKsqgIII1i/+cfW27G9KtLkc4lcP/qJKM1DRDQ6Zo49pmUdo9v8+k0syK1hpBA2CkEYkSfmWZMRC/YZak36hsDlByeFX+3uhkt5pox8p7Lam8KosurVn86xGmbIobgruV4zETx2hJwMnuI5M= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771911941; c=relaxed/simple; bh=FOCU7ky6atLZJIqo4lqdbHNvOqA+ZkuKyKkbuO881Zo=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=QmvnfNe+ifUIV/7Wzp+FJy85GvIZv+rAFEyIAdQ20Wov2vJX6q7QZ/941N95Z4uo+DpcY5xMhbHEMd7nQtARMI6BslHagZQmBXVv++jvU49rqZLbNnYVgDn7XY8Kf7TbiDO1AR38ar5NFr55VvNmfkPjFULu+YJ6si5h1kqwTfo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=E+bjJesk; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="E+bjJesk" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-2aaf9191da3so33060205ad.2 for ; Mon, 23 Feb 2026 21:45:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771911939; x=1772516739; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Uq//eKnU0VIy+iDlWT3coRvXqAavfDjJ0UDudhoedEQ=; b=E+bjJeskrcTMXJBRoFNNND6nPWkHroLBekPCAmqr4mS5uRU7lXguBrX8bYPMHI4XA3 N/jyARIVxUzM4yoGPiHneXKBX159CeYEf5yuYIUll+HoR63U+liaklDQMv+Aip4n9nGK iKncDOrlgiWT308a/6TsLs4z/gDFOwvgJbx72MTRlMzTj/U8Fiwd+J65QajwrKC3dxEo iGBQWu7ZdX2MjJuW6I0hrL6rVrvMk8HD21djfx9IW8PcRpxTwo5f5TA84pdXAMPaQv6a Bbgh9JD8YdG+zKufbn3PMtqkNMUHXnh9YbkydcNql6uMEWIycbgxZLMbQQGFOUl7DOUE S68A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771911939; x=1772516739; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Uq//eKnU0VIy+iDlWT3coRvXqAavfDjJ0UDudhoedEQ=; b=xTyZM6Z5pl+/bCteaVwXuhjM7omcH3BXHNOo5hRl3m1GfgFk087x21wbB+wzoYRFNi KNsJn5+gGlbegOEaDiqXtBR1un+bM6F9Lh98aatrF1MiehxGQKo/ODGLF/NiskFJZzjh RfEIlYQolaTdGml0+MOHLvjLy3UdsMCc4xqEX8ThNqy2CBlWEqt9GP2G2rKh7t3k50Wh ojHOmXv2cuMW7eadhNDfzcYf+GflS+UT8lWEwzDxHBFYC7NfvjFtHMqLzhtZ2xaNM2CW UaMf95Ynu8vb1Ntd65BECfnjFnwP8J8V7SLVf+ruqgdwpYRSfYDMsdP5AWVcIosXdyo1 9X5Q== X-Forwarded-Encrypted: i=1; AJvYcCWInXTd/TGs2zMh15IuVAkZNc/91PFnD07PZ2lBgAf3CAa4KpsfBQrOGZUdNZcndUsMfH0CLSc=@vger.kernel.org X-Gm-Message-State: AOJu0YyPQr2LgvDvj9jbESpmDaXfon3LMvCvyS0Rrt6xKavghs3YsoAw NssmD760gyoQ5I3bRcCIWD0KhH78WUcqeIzMh8FCXgj1GgzhV5WMWYkR X-Gm-Gg: ATEYQzykLl/UT+Q+GaFx9tLvnn7XIp/w2RmXWPf+xmSKVDZEwRpELRBc2RVYZeQdXEb TwqRjpqBqZAfWH0nBZ3odkd/5RILx8cgl+rFoEMDLyt5ty4Uu4Qp0TN4POMbxVGLRh7x6pclWzk X/kmDNHCcovFZ5D/Yzyi1e65sR1/zxTEI9Gn5QCvNt1GcfIRNVNk3u+rZiZu5GDAhXi2DXSig3x +g9rj+hmPjgAw88UXNOtay7xFI6zdfRrK3lrZn938TJovkIHYj9RL3dxsZfVATFQEt0weOCHjS+ ppc418kpNQmkN3ydf9N3D+X0m++dytEPcGpMJxZkLAItVGbpIqk1QKVWvHvXV9IMc/4XJuADG7l IEzGYGclHcpRPD6tXA9GQmxvd8FQ1OdKgd27XrBRXU6qKda5ZaNSO2LsnERw1dg8dzlHSyVeZ31 aaUFgR0UalENOIbZn1zrgz9URXBfA0C522dSgKvADbRLxxaMkn9R4k1kZdXwadoXXsdmICfNbR8 jL+aj21tupo X-Received: by 2002:a17:902:ea02:b0:2a9:602c:159 with SMTP id d9443c01a7336-2ad74438618mr91322915ad.19.1771911939394; Mon, 23 Feb 2026 21:45:39 -0800 (PST) Received: from dpc2500057.. (fsb6a9315e.tkyc502.ap.nuro.jp. [182.169.49.94]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2ad7500e062sm125920765ad.48.2026.02.23.21.45.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 21:45:39 -0800 (PST) From: Keita Morisaki To: Tony Nguyen , Przemek Kitszel , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: Alice Michael , Aleksandr Loktionov , Maciej Fijalkowski , Paul Greenwalt , intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Keita Morisaki Subject: [PATCH net v2 RESEND] ice: fix race condition in TX timestamp ring cleanup Date: Tue, 24 Feb 2026 14:45:33 +0900 Message-Id: <20260224054533.3372943-1-kmta1236@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Fix a race condition between ice_free_tx_tstamp_ring() and ice_tx_map() that can cause a NULL pointer dereference. ice_free_tx_tstamp_ring currently clears the ICE_TX_FLAGS_TXTIME flag after NULLing the tstamp_ring. This could allow a concurrent ice_tx_map call on another CPU to dereference the tstamp_ring, which could lead to a NULL pointer dereference. CPU A:ice_free_tx_tstamp_ring() | CPU B:ice_tx_map() --------------------------------|--------------------------------- tx_ring->tstamp_ring = NULL | | ice_is_txtime_cfg() -> true | tstamp_ring = tx_ring->tstamp_ring | tstamp_ring->count // NULL deref! flags &= ~ICE_TX_FLAGS_TXTIME | Fix by: 1. Reordering ice_free_tx_tstamp_ring() to clear the flag before NULLing the pointer, with smp_wmb() to ensure proper ordering. 2. Adding smp_rmb() in ice_tx_map() after the flag check to order the flag read before the pointer read, using READ_ONCE() for the pointer, and adding a NULL check as a safety net. 3. Converting tx_ring->flags from u8 to DECLARE_BITMAP() and using atomic bitops (set_bit(), clear_bit(), test_bit()) for all flag operations throughout the driver: - ICE_TX_RING_FLAGS_XDP - ICE_TX_RING_FLAGS_VLAN_L2TAG1 - ICE_TX_RING_FLAGS_VLAN_L2TAG2 - ICE_TX_RING_FLAGS_TXTIME Fixes: ccde82e909467 ("ice: add E830 Earliest TxTime First Offload support") Signed-off-by: Keita Morisaki Reviewed-by: Aleksandr Loktionov --- Changes in v2: - Convert tx_ring->flags from u8 to DECLARE_BITMAP() and use atomic bitops (set_bit(), clear_bit(), test_bit()) for all flag operations instead of WRITE_ONCE() for flag updates - Rename flags from ICE_TX_FLAGS_RING_* to ICE_TX_RING_FLAGS_* to distinguish from per-packet flags (ICE_TX_FLAGS_*) drivers/net/ethernet/intel/ice/ice.h | 4 ++-- drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 2 +- drivers/net/ethernet/intel/ice/ice_lib.c | 4 ++-- drivers/net/ethernet/intel/ice/ice_txrx.c | 23 ++++++++++++++------ drivers/net/ethernet/intel/ice/ice_txrx.h | 16 +++++++++----- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 00f75d87c73f9..5baeca824cd99 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -753,7 +753,7 @@ static inline bool ice_is_xdp_ena_vsi(struct ice_vsi *vsi) static inline void ice_set_ring_xdp(struct ice_tx_ring *ring) { - ring->flags |= ICE_TX_FLAGS_RING_XDP; + set_bit(ICE_TX_RING_FLAGS_XDP, ring->flags); } /** @@ -778,7 +778,7 @@ static inline bool ice_is_txtime_ena(const struct ice_tx_ring *ring) */ static inline bool ice_is_txtime_cfg(const struct ice_tx_ring *ring) { - return !!(ring->flags & ICE_TX_FLAGS_TXTIME); + return test_bit(ICE_TX_RING_FLAGS_TXTIME, ring->flags); } /** diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c index 9fc8681cc58ea..bd74344271f3f 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c @@ -943,7 +943,7 @@ ice_tx_prepare_vlan_flags_dcb(struct ice_tx_ring *tx_ring, /* if this is not already set it means a VLAN 0 + priority needs * to be offloaded */ - if (tx_ring->flags & ICE_TX_FLAGS_RING_VLAN_L2TAG2) + if (test_bit(ICE_TX_RING_FLAGS_VLAN_L2TAG2, tx_ring->flags)) first->tx_flags |= ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN; else first->tx_flags |= ICE_TX_FLAGS_HW_VLAN; diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index d47af94f31a99..55ff0708d136e 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -1412,9 +1412,9 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi) ring->count = vsi->num_tx_desc; ring->txq_teid = ICE_INVAL_TEID; if (dvm_ena) - ring->flags |= ICE_TX_FLAGS_RING_VLAN_L2TAG2; + set_bit(ICE_TX_RING_FLAGS_VLAN_L2TAG2, ring->flags); else - ring->flags |= ICE_TX_FLAGS_RING_VLAN_L2TAG1; + set_bit(ICE_TX_RING_FLAGS_VLAN_L2TAG1, ring->flags); WRITE_ONCE(vsi->tx_rings[i], ring); } diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index ad76768a42323..564e4e33ecbc3 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -190,9 +190,10 @@ void ice_free_tstamp_ring(struct ice_tx_ring *tx_ring) void ice_free_tx_tstamp_ring(struct ice_tx_ring *tx_ring) { ice_free_tstamp_ring(tx_ring); + clear_bit(ICE_TX_RING_FLAGS_TXTIME, tx_ring->flags); + smp_wmb(); /* order flag clear before pointer NULL */ kfree_rcu(tx_ring->tstamp_ring, rcu); - tx_ring->tstamp_ring = NULL; - tx_ring->flags &= ~ICE_TX_FLAGS_TXTIME; + WRITE_ONCE(tx_ring->tstamp_ring, NULL); } /** @@ -405,7 +406,7 @@ static int ice_alloc_tstamp_ring(struct ice_tx_ring *tx_ring) tx_ring->tstamp_ring = tstamp_ring; tstamp_ring->desc = NULL; tstamp_ring->count = ice_calc_ts_ring_count(tx_ring); - tx_ring->flags |= ICE_TX_FLAGS_TXTIME; + set_bit(ICE_TX_RING_FLAGS_TXTIME, tx_ring->flags); return 0; } @@ -1519,13 +1520,20 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first, return; if (ice_is_txtime_cfg(tx_ring)) { - struct ice_tstamp_ring *tstamp_ring = tx_ring->tstamp_ring; - u32 tstamp_count = tstamp_ring->count; - u32 j = tstamp_ring->next_to_use; + struct ice_tstamp_ring *tstamp_ring; + u32 tstamp_count, j; struct ice_ts_desc *ts_desc; struct timespec64 ts; u32 tstamp; + smp_rmb(); /* order flag read before pointer read */ + tstamp_ring = READ_ONCE(tx_ring->tstamp_ring); + if (unlikely(!tstamp_ring)) + goto ring_kick; + + tstamp_count = tstamp_ring->count; + j = tstamp_ring->next_to_use; + ts = ktime_to_timespec64(first->skb->tstamp); tstamp = ts.tv_nsec >> ICE_TXTIME_CTX_RESOLUTION_128NS; @@ -1553,6 +1561,7 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first, tstamp_ring->next_to_use = j; writel_relaxed(j, tstamp_ring->tail); } else { +ring_kick: writel_relaxed(i, tx_ring->tail); } return; @@ -1812,7 +1821,7 @@ ice_tx_prepare_vlan_flags(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first) */ if (skb_vlan_tag_present(skb)) { first->vid = skb_vlan_tag_get(skb); - if (tx_ring->flags & ICE_TX_FLAGS_RING_VLAN_L2TAG2) + if (test_bit(ICE_TX_RING_FLAGS_VLAN_L2TAG2, tx_ring->flags)) first->tx_flags |= ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN; else first->tx_flags |= ICE_TX_FLAGS_HW_VLAN; diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h index e440c55d9e9f0..d35ffdc3dc84d 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -181,6 +181,14 @@ enum ice_rx_dtype { ICE_RX_DTYPE_SPLIT_ALWAYS = 2, }; +enum ice_tx_ring_flags { + ICE_TX_RING_FLAGS_XDP, + ICE_TX_RING_FLAGS_VLAN_L2TAG1, + ICE_TX_RING_FLAGS_VLAN_L2TAG2, + ICE_TX_RING_FLAGS_TXTIME, + ICE_TX_RING_FLAGS_NBITS, +}; + struct ice_pkt_ctx { u64 cached_phctime; __be16 vlan_proto; @@ -333,11 +341,7 @@ struct ice_tx_ring { u32 txq_teid; /* Added Tx queue TEID */ /* CL4 - 4th cacheline starts here */ struct ice_tstamp_ring *tstamp_ring; -#define ICE_TX_FLAGS_RING_XDP BIT(0) -#define ICE_TX_FLAGS_RING_VLAN_L2TAG1 BIT(1) -#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2) -#define ICE_TX_FLAGS_TXTIME BIT(3) - u8 flags; + DECLARE_BITMAP(flags, ICE_TX_RING_FLAGS_NBITS); u8 dcb_tc; /* Traffic class of ring */ u16 quanta_prof_id; } ____cacheline_internodealigned_in_smp; @@ -349,7 +353,7 @@ static inline bool ice_ring_ch_enabled(struct ice_tx_ring *ring) static inline bool ice_ring_is_xdp(struct ice_tx_ring *ring) { - return !!(ring->flags & ICE_TX_FLAGS_RING_XDP); + return test_bit(ICE_TX_RING_FLAGS_XDP, ring->flags); } enum ice_container_type { base-commit: 18f7fcd5e69a04df57b563360b88be72471d6b62 -- 2.34.1