Archive-only list for patches
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Long Li <leo.lilong@huawei.com>,
	Chuck Lever <chuck.lever@oracle.com>,
	Sasha Levin <sashal@kernel.org>,
	trondmy@kernel.org, anna@kernel.org, jlayton@kernel.org,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, linux-nfs@vger.kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.12 50/93] sunrpc: fix race in cache cleanup causing stale nextcheck time
Date: Sun,  1 Jun 2025 19:33:17 -0400	[thread overview]
Message-ID: <20250601233402.3512823-50-sashal@kernel.org> (raw)
In-Reply-To: <20250601233402.3512823-1-sashal@kernel.org>

From: Long Li <leo.lilong@huawei.com>

[ Upstream commit 2298abcbe11e9b553d03c0f1d084da786f7eff88 ]

When cache cleanup runs concurrently with cache entry removal, a race
condition can occur that leads to incorrect nextcheck times. This can
delay cache cleanup for the cache_detail by up to 1800 seconds:

1. cache_clean() sets nextcheck to current time plus 1800 seconds
2. While scanning a non-empty bucket, concurrent cache entry removal can
   empty that bucket
3. cache_clean() finds no cache entries in the now-empty bucket to update
   the nextcheck time
4. This maybe delays the next scan of the cache_detail by up to 1800
   seconds even when it should be scanned earlier based on remaining
   entries

Fix this by moving the hash_lock acquisition earlier in cache_clean().
This ensures bucket emptiness checks and nextcheck updates happen
atomically, preventing the race between cleanup and entry removal.

Signed-off-by: Long Li <leo.lilong@huawei.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

Now let me analyze this commit in detail based on what I've learned:
**ANALYSIS:** **YES** - This commit should be backported to stable
kernel trees. ## Detailed Analysis: ### 1. **Bug Impact Assessment**
This commit fixes a **race condition** that can cause cache cleanup
delays of up to **1800 seconds (30 minutes)**. This is a significant
performance regression that affects the SUNRPC cache subsystem's ability
to clean expired entries in a timely manner. ### 2. **Root Cause
Analysis** The race condition occurs in the `cache_clean()` function
between these steps: - **Line 461**: `current_detail->nextcheck =
seconds_since_boot()+30*60;` (sets nextcheck to current time + 1800
seconds) - **Lines 466-469**: The code searches for non-empty buckets
**without holding hash_lock** - **Lines 479-496**: The code then
acquires `hash_lock` and processes entries, updating nextcheck based on
entry expiry times **The race window**: Between lines 466-469 and 479,
concurrent cache operations (like `sunrpc_cache_unhash()`) can remove
entries from buckets, making them empty. When `cache_clean()` later
acquires the hash_lock, it finds empty buckets and cannot update the
nextcheck time appropriately. ### 3. **Code Change Analysis** The fix is
**minimal and surgical**: ```c // BEFORE: hash_lock acquired late (line
479) if (current_detail && current_index < current_detail->hash_size) {
// ... variable declarations ... spin_lock(&current_detail->hash_lock);
// TOO LATE! // AFTER: hash_lock acquired early (before bucket search)
spin_lock(&current_detail->hash_lock); while (current_index <
current_detail->hash_size &&
hlist_empty(&current_detail->hash_table[current_index]))
current_index++; ``` This ensures that: 1. **Atomicity**: Bucket
emptiness checks and nextcheck updates happen atomically 2. **Race
prevention**: No concurrent entry removal can happen during bucket
scanning 3. **Correctness**: nextcheck times are updated based on the
actual state of buckets at scan time ### 4. **Risk Assessment** **Low
Risk**: - **Scope**: Changes only affect the locking order in
`cache_clean()` - **Backwards compatibility**: No API changes - **Side
effects**: Minimal - just holds the lock slightly longer, which is safe
- **Testing**: The change preserves existing logic while fixing the race
### 5. **Stable Tree Criteria Compliance** ✅ **Fixes important bug**:
30-minute cache cleanup delays significantly impact performance ✅
**Small and contained**: Only 12 lines changed in a single function ✅
**No architectural changes**: Just reorders lock acquisition ✅ **Minimal
regression risk**: The change is conservative and preserves existing
behavior ✅ **Clear side effects**: Only improves correctness, no
negative impacts ### 6. **Comparison with Similar Commits** Looking at
the historical examples: - **Similar to Commit #3 (YES)**: Fixes a race
condition with minimal code changes and clear correctness improvement -
**Unlike Commits #1,#2,#4,#5 (NO)**: Those were either reverted,
cosmetic, or changed behavior significantly ### 7. **Critical System
Impact** SUNRPC cache is used by: - **NFS client/server operations** -
**RPC authentication caching** - **Various network filesystem
operations** A 30-minute delay in cache cleanup can cause: - Memory
bloat from stale entries - Performance degradation - Potential service
disruptions **Conclusion**: This is a clear bug fix with minimal risk
that addresses a significant performance issue in a critical kernel
subsystem. It meets all criteria for stable tree backporting.

 net/sunrpc/cache.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 69f26809c56fc..59e6aebf3ece4 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -453,24 +453,21 @@ static int cache_clean(void)
 		}
 	}
 
+	spin_lock(&current_detail->hash_lock);
+
 	/* find a non-empty bucket in the table */
-	while (current_detail &&
-	       current_index < current_detail->hash_size &&
+	while (current_index < current_detail->hash_size &&
 	       hlist_empty(&current_detail->hash_table[current_index]))
 		current_index++;
 
 	/* find a cleanable entry in the bucket and clean it, or set to next bucket */
-
-	if (current_detail && current_index < current_detail->hash_size) {
+	if (current_index < current_detail->hash_size) {
 		struct cache_head *ch = NULL;
 		struct cache_detail *d;
 		struct hlist_head *head;
 		struct hlist_node *tmp;
 
-		spin_lock(&current_detail->hash_lock);
-
 		/* Ok, now to clean this strand */
-
 		head = &current_detail->hash_table[current_index];
 		hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
 			if (current_detail->nextcheck > ch->expiry_time)
@@ -491,8 +488,10 @@ static int cache_clean(void)
 		spin_unlock(&cache_list_lock);
 		if (ch)
 			sunrpc_end_cache_remove_entry(ch, d);
-	} else
+	} else {
+		spin_unlock(&current_detail->hash_lock);
 		spin_unlock(&cache_list_lock);
+	}
 
 	return rv;
 }
-- 
2.39.5


  parent reply	other threads:[~2025-06-01 23:36 UTC|newest]

Thread overview: 93+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-01 23:32 [PATCH AUTOSEL 6.12 01/93] drm/amd/display: disable DPP RCG before DPP CLK enable Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 02/93] drm/bridge: select DRM_KMS_HELPER for AUX_BRIDGE Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 03/93] drm/amdgpu/gfx6: fix CSIB handling Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 04/93] media: imx-jpeg: Check decoding is ongoing for motion-jpeg Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 05/93] drm/rockchip: inno-hdmi: Fix video timing HSYNC/VSYNC polarity setting for rk3036 Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 06/93] drm/dp: add option to disable zero sized address only transactions Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 07/93] sunrpc: update nextcheck time when adding new cache entries Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 08/93] drm/amdgpu: Fix API status offset for MES queue reset Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 09/93] drm/amd/display: DCN32 null data check Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 10/93] drm/bridge: analogix_dp: Add irq flag IRQF_NO_AUTOEN instead of calling disable_irq() Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 11/93] workqueue: Fix race condition in wq->stats incrementation Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 12/93] drm/panel/sharp-ls043t1le01: Use _multi variants Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 13/93] exfat: fix double free in delayed_free Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 14/93] drm/bridge: anx7625: enable HPD interrupts Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 15/93] arm64/cpuinfo: only show one cpu's info in c_show() Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 16/93] drm/panthor: Don't update MMU_INT_MASK in panthor_mmu_irq_handler() Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 17/93] drm/bridge: anx7625: change the gpiod_set_value API Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 18/93] exfat: do not clear volume dirty flag during sync Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 19/93] drm/amdgpu/gfx11: fix CSIB handling Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 20/93] media: nuvoton: npcm-video: Fix stuck due to no video signal error Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 21/93] drm/nouveau: fix hibernate on disabled GPU Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 22/93] media: i2c: imx334: Enable runtime PM before sub-device registration Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 23/93] drm/amd/display: Avoid divide by zero by initializing dummy pitch to 1 Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 24/93] drm/nouveau/gsp: fix rm shutdown wait condition Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 25/93] drm/msm/hdmi: add runtime PM calls to DDC transfer function Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 26/93] media: uapi: v4l: Fix V4L2_TYPE_IS_OUTPUT condition Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 27/93] drm/amd/display: Add NULL pointer checks in dm_force_atomic_commit() Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 28/93] media: verisilicon: Enable wide 4K in AV1 decoder Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 29/93] drm/amd/display: Skip to enable dsc if it has been off Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 30/93] dlm: use SHUT_RDWR for SCTP shutdown Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 31/93] drm/msm/a6xx: Increase HFI response timeout Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 32/93] drm/amd/display: Do Not Consider DSC if Valid Config Not Found Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 33/93] media: i2c: imx334: Fix runtime PM handling in remove function Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 34/93] drm/amdgpu/gfx10: fix CSIB handling Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 35/93] drm: panel-orientation-quirks: Add ZOTAC Gaming Zone Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 36/93] media: ccs-pll: Better validate VT PLL branch Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 37/93] media: uapi: v4l: Change V4L2_TYPE_IS_CAPTURE condition Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 38/93] drm/amd/display: fix zero value for APU watermark_c Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 39/93] drm/ttm/tests: fix incorrect assert in ttm_bo_unreserve_bulk() Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 40/93] drm/amdgpu/gfx7: fix CSIB handling Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 41/93] ext4: ext4: unify EXT4_EX_NOCACHE|NOFAIL flags in ext4_ext_remove_space() Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 42/93] jfs: fix array-index-out-of-bounds read in add_missing_indices Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 43/93] media: ti: cal: Fix wrong goto on error path Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 44/93] drm/amd/display: Correct SSC enable detection for DCN351 Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 45/93] media: rkvdec: h264: Use bytesperline and buffer height as virstride Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 46/93] media: cec: extron-da-hd-4k-plus: Fix Wformat-truncation Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 47/93] media: rkvdec: Initialize the m2m context before the controls Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 48/93] drm/amdgpu: fix MES GFX mask Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 49/93] drm/amdgpu: Disallow partition query during reset Sasha Levin
2025-06-01 23:33 ` Sasha Levin [this message]
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 51/93] ext4: prevent stale extent cache entries caused by concurrent get es_cache Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 52/93] drm/amdgpu/gfx8: fix CSIB handling Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 53/93] drm/amd/display: disable EASF narrow filter sharpening Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 54/93] drm/amdgpu/gfx9: fix CSIB handling Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 55/93] jfs: Fix null-ptr-deref in jfs_ioc_trim Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 56/93] media: renesas: vsp1: Fix media bus code setup on RWPF source pad Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 57/93] drm/msm/dpu: don't select single flush for active CTL blocks Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 58/93] drm/amdkfd: Set SDMA_RLCx_IB_CNTL/SWITCH_INSIDE_IB Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 59/93] media: tc358743: ignore video while HPD is low Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 60/93] media: platform: exynos4-is: Add hardware sync wait to fimc_is_hw_change_mode() Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 61/93] media: i2c: imx334: update mode_3840x2160_regs array Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 62/93] nios2: force update_mmu_cache on spurious tlb-permission--related pagefaults Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 63/93] media: rcar-vin: Fix stride setting for RAW8 formats Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 64/93] drm/xe/uc: Remove static from loop variable Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 65/93] media: qcom: venus: Fix uninitialized variable warning Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 66/93] drm/panel: simple: Add POWERTIP PH128800T004-ZZA01 panel entry Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 67/93] Make 'cc-option' work correctly for the -Wno-xyzzy pattern Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 68/93] ACPI: bus: Bail out if acpi_kobj registration fails Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 69/93] selftests: harness: Mark functions without prototypes static Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 70/93] pmdomain: ti: Fix STANDBY handling of PER power domain Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 71/93] PM: runtime: fix denying of auto suspend in pm_suspend_timer_fn() Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 72/93] ASoC: amd: yc: Add quirk for Lenovo Yoga Pro 7 14ASP9 Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 73/93] thermal/drivers/qcom/tsens: Update conditions to strictly evaluate for IP v2+ Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 74/93] clocksource/drivers/timer-tegra186: Fix watchdog self-pinging Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 75/93] gpio: pxa: Make irq_chip immutable Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 76/93] gpio: grgpio: " Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 77/93] gpio: xgene-sb: " Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 78/93] genirq: Retain disable depth for managed interrupts across CPU hotplug Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 79/93] mmc: sdhci-esdhc-imx: Save tuning value when card stays powered in suspend Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 80/93] mmc: Add quirk to disable DDR50 tuning Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 81/93] ASoC: intel/sdw_utils: Assign initial value in asoc_sdw_rt_amp_spk_rtd_init() Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 82/93] clocksource: Fix the CPUs' choice in the watchdog per CPU verification Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 83/93] ACPICA: Avoid sequence overread in call to strncmp() Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 84/93] ACPICA: utilities: Fix overflow check in vsnprintf() Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 85/93] ACPI: EC: Add device to acpi_ec_no_wakeup[] qurik list Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 86/93] ALSA: seq: Remove unused snd_seq_queue_client_leave_cells Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 87/93] spi: axi-spi-engine: wait for completion in setup Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 88/93] cpufreq: Force sync policy boost with global boost on sysfs update Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 89/93] power: supply: bq27xxx: Retrieve again when busy Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 90/93] pmdomain: core: Reset genpd->states to avoid freeing invalid data Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 91/93] tools/nolibc: use intmax definitions from compiler Sasha Levin
2025-06-01 23:33 ` [PATCH AUTOSEL 6.12 92/93] gpio: ds4520: don't check the 'ngpios' property in the driver Sasha Levin
2025-06-01 23:34 ` [PATCH AUTOSEL 6.12 93/93] ASoC: tas2770: Power cycle amp on ISENSE/VSENSE change Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250601233402.3512823-50-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=anna@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=jlayton@kernel.org \
    --cc=kuba@kernel.org \
    --cc=leo.lilong@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    --cc=trondmy@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox