From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C3E51202C2D; Wed, 4 Jun 2025 01:02:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748998964; cv=none; b=cqufaAicCixmRk/uADFujkb3u+hZqH8dBdIyQNqwYZbJuZETL44v2bUQ3fkbtkDncy83rb9HDTpqtoHh96At3uzy5G4QbTihvsyZgsSkirX2WjwkorTzbtfnQZJf12/2ru2L5M0m/wVAdMJNETHkrjyXSYn6NCos9ZlxVmG+joM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748998964; c=relaxed/simple; bh=skJVp1A4SQu1EaAAekUcY9sfms4LpepaF8Unp0It5Cc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bqBziK7jKf8yRvTwtRXG6t1a3Y6wWXryqx2/P10397f9oWDgBNj3n8621tfzPE94TZd3e6B0Sl18f8SiuZ7fO8nKtE0EBKkeBgpz8XfS9qs0qFA4/0RhDCsiDFqPnR5TXkzjBfo1Lj8zrotRiP1k7jWXNmxaJflmpUfLG38vbXQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e8/9TCNH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e8/9TCNH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D75CC4CEED; Wed, 4 Jun 2025 01:02:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748998964; bh=skJVp1A4SQu1EaAAekUcY9sfms4LpepaF8Unp0It5Cc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e8/9TCNHEg6h865ExMKQsY7FEKN/IkPKOKv5kslizaYWTNuRVEpn8Tou3Q6f2YFw+ F5AgAy9qPyjXkjZoazDY15powCCisDOejzsULarCXQtX6IMTJppOUhM0u+sAhcN3Tn 09G8EfsVNUXbPplmDF3LsweepXpEjW17hMQ5UaU13d4Itc6yAuNIvOsLUpQwCDCgZ0 EL20ex4HxPvF5xdCgPCFiac9OFoJKt4vfEi2OM3w5pBangLKwzoXXYQrlMW8DnrjKY 7mcGAto9G+xsFQ/M4Ucn08aR91mLENwI97/3sQrf8XqHvrmFdWzuGpbfTN7nEf17Nq T2VrYnzlmgeBQ== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: Moon Yeounsu , Jakub Kicinski , Sasha Levin , horms@kernel.org, tglx@linutronix.de, mingo@kernel.org, davem@davemloft.net Subject: [PATCH AUTOSEL 6.6 15/62] net: dlink: add synchronization for stats update Date: Tue, 3 Jun 2025 21:01:26 -0400 Message-Id: <20250604010213.3462-15-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250604010213.3462-1-sashal@kernel.org> References: <20250604010213.3462-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.6.92 Content-Transfer-Encoding: 8bit From: Moon Yeounsu [ Upstream commit 12889ce926e9a9baf6b83d809ba316af539b89e2 ] This patch synchronizes code that accesses from both user-space and IRQ contexts. The `get_stats()` function can be called from both context. `dev->stats.tx_errors` and `dev->stats.collisions` are also updated in the `tx_errors()` function. Therefore, these fields must also be protected by synchronized. There is no code that accessses `dev->stats.tx_errors` between the previous and updated lines, so the updating point can be moved. Signed-off-by: Moon Yeounsu Link: https://patch.msgid.link/20250515075333.48290-1-yyyynoom@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- **YES** This commit should be backported to stable kernel trees for the following reasons: **1. Critical Data Race Fix**: The commit addresses a real data race condition where `dev->stats.tx_errors` and `dev->stats.collisions` can be accessed concurrently from user-space (`get_stats()` function) and IRQ context (`tx_error()` function). This is a genuine bug that can cause statistics corruption. **2. User-Visible Impact**: The race condition affects network statistics that are exposed to userspace through standard interfaces like `/proc/net/dev` and ethtool. Corrupted statistics can mislead network monitoring tools and system administrators. **3. Low Risk, High Value Fix**: The changes are minimal and follow established kernel synchronization patterns: - Adds a single `spinlock_t stats_lock` field to the driver's private structure - Protects critical sections with `spin_lock_irqsave()`/`spin_unlock_irqrestore()` in `get_stats()` - Protects IRQ-context updates in `tx_error()` with the same spinlock - No functional logic changes, only synchronization additions **4. Self- Contained Changes**: The fix is entirely within the dl2k driver (`drivers/net/ethernet/dlink/dl2k.c` and `dl2k.h`), making it safe to backport without affecting other subsystems. **5. Precedent from Similar Commits**: This closely mirrors "Similar Commit #5" (net: stmmac: protect updates of 64-bit statistics counters) which was marked as "Backport Status: YES" for addressing the same type of statistics synchronization issue. **6. Follows Stable Tree Criteria**: - Fixes an important bug affecting users - Changes are small and contained - Minimal risk of regression - No new features or architectural changes The fix prevents potential data corruption in network statistics, which is exactly the type of bug that stable kernels should address to maintain system reliability and data integrity. drivers/net/ethernet/dlink/dl2k.c | 14 +++++++++++++- drivers/net/ethernet/dlink/dl2k.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c index ce46f3ac3b5a1..fad5a72d3b167 100644 --- a/drivers/net/ethernet/dlink/dl2k.c +++ b/drivers/net/ethernet/dlink/dl2k.c @@ -146,6 +146,8 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) np->ioaddr = ioaddr; np->chip_id = chip_idx; np->pdev = pdev; + + spin_lock_init(&np->stats_lock); spin_lock_init (&np->tx_lock); spin_lock_init (&np->rx_lock); @@ -866,7 +868,6 @@ tx_error (struct net_device *dev, int tx_status) frame_id = (tx_status & 0xffff0000); printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n", dev->name, tx_status, frame_id); - dev->stats.tx_errors++; /* Ttransmit Underrun */ if (tx_status & 0x10) { dev->stats.tx_fifo_errors++; @@ -903,9 +904,15 @@ tx_error (struct net_device *dev, int tx_status) rio_set_led_mode(dev); /* Let TxStartThresh stay default value */ } + + spin_lock(&np->stats_lock); /* Maximum Collisions */ if (tx_status & 0x08) dev->stats.collisions++; + + dev->stats.tx_errors++; + spin_unlock(&np->stats_lock); + /* Restart the Tx */ dw32(MACCtrl, dr16(MACCtrl) | TxEnable); } @@ -1074,7 +1081,9 @@ get_stats (struct net_device *dev) int i; #endif unsigned int stat_reg; + unsigned long flags; + spin_lock_irqsave(&np->stats_lock, flags); /* All statistics registers need to be acknowledged, else statistic overflow could cause problems */ @@ -1124,6 +1133,9 @@ get_stats (struct net_device *dev) dr16(TCPCheckSumErrors); dr16(UDPCheckSumErrors); dr16(IPCheckSumErrors); + + spin_unlock_irqrestore(&np->stats_lock, flags); + return &dev->stats; } diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h index 0e33e2eaae960..56aff2f0bdbfa 100644 --- a/drivers/net/ethernet/dlink/dl2k.h +++ b/drivers/net/ethernet/dlink/dl2k.h @@ -372,6 +372,8 @@ struct netdev_private { struct pci_dev *pdev; void __iomem *ioaddr; void __iomem *eeprom_addr; + // To ensure synchronization when stats are updated. + spinlock_t stats_lock; spinlock_t tx_lock; spinlock_t rx_lock; unsigned int rx_buf_sz; /* Based on MTU+slack. */ -- 2.39.5