From patchwork Sat Mar 1 06:48:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 13997387 Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) (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 0E85D156861; Sat, 1 Mar 2025 06:53:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.190 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740812008; cv=none; b=e6gOwLB3pkl3iAtS5Zn+dINIa1huDqkc5rpocXY6hz+ipT80L0yPkLd5ZMmIcw9hgkpux7BzUJ3PERPDsRiiY/DkUkdBuSPuQuzRFQWvBySoPZ+JZoob4rqTKursO6DA279hQwv8jQJoG3qnuFSrfwbZHuxAwkLmHanRpb7baNg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740812008; c=relaxed/simple; bh=avlyAo2mFU+WCusiHxsaoeIzSLp/aBamnyHaP4VgmFQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=k+MQUX6XgquHWL+qehdxMhndMKVpREg+Rbj2lwME07OOr14/Xkr6yhBP/rowllDH5nwbGlGqSQFlZwCiD0vuQ1LQOmp8D/OGzDGy2IegPEAqVpBRuCqn9U6IInlEsHMg692laSjtQngegNamqUK2Em0M3exy17LNLr4YnswNRns= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.190 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.234]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4Z4bK707KHz2Cpqd; Sat, 1 Mar 2025 14:49:15 +0800 (CST) Received: from dggpemf500017.china.huawei.com (unknown [7.185.36.126]) by mail.maildlp.com (Postfix) with ESMTPS id 57FF71402E0; Sat, 1 Mar 2025 14:53:22 +0800 (CST) Received: from huawei.com (10.175.104.67) by dggpemf500017.china.huawei.com (7.185.36.126) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Sat, 1 Mar 2025 14:53:21 +0800 From: Long Li To: , , , , , , , , , , , , CC: , , , , , , Subject: [PATCH 1/2] sunrpc: update nextcheck time when adding new cache entries Date: Sat, 1 Mar 2025 14:48:35 +0800 Message-ID: <20250301064836.3285906-2-leo.lilong@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250301064836.3285906-1-leo.lilong@huawei.com> References: <20250301064836.3285906-1-leo.lilong@huawei.com> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To dggpemf500017.china.huawei.com (7.185.36.126) The cache_detail structure uses a "nextcheck" field to control hash table scanning intervals. When a table scan begins, nextcheck is set to current time plus 1800 seconds. During scanning, if cache_detail is not empty and a cache entry's expiry time is earlier than the current nextcheck, the nextcheck is updated to that expiry time. This mechanism ensures that: 1) Empty cache_details are scanned every 1800 seconds to avoid unnecessary scans 2) Non-empty cache_details are scanned based on the earliest expiry time found However, when adding a new cache entry to an empty cache_detail, the nextcheck time was not being updated, remaining at 1800 seconds. This could delay cache cleanup for up to 1800 seconds, potentially blocking threads(such as nfsd) that are waiting for cache cleanup. Fix this by updating the nextcheck time whenever a new cache entry is added. Signed-off-by: Long Li --- net/sunrpc/cache.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 004cdb59f010..d12ab3175d05 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -135,6 +135,8 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail, hlist_add_head_rcu(&new->cache_list, head); detail->entries++; + if (detail->nextcheck > new->expiry_time) + detail->nextcheck = new->expiry_time + 1; cache_get(new); spin_unlock(&detail->hash_lock); From patchwork Sat Mar 1 06:48:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 13997388 Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) (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 3586C156C62; Sat, 1 Mar 2025 06:53:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.191 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740812009; cv=none; b=X/U7jvhHLHjxRBchHxe6bVcSGHO6MfpIT7AdB6Mh5DVQQf0Akow+TDbKO66HWgdNlg6HQmO1iMcaQ6CktLFlAKtDnZutBApbbUx2/SLLSVNMnmzUW37M32Sn1yq3jgVVeuPM4/OJifCJkT/72nC06papTxaY+H6FbieG6thJYKU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740812009; c=relaxed/simple; bh=dibP0T9npb1XSSP1DoTgysZkzWFTRHeVFeqHkNLyq8U=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DFQ4Jbjiq7qZF4GvxfL6X/a3OIXndqUvmzFPw/QNpuJSlJK4x+b+15J40pggGuxDgjfb6pIQ7gax+xxDWwRMcvtIm4NPNQieicqjP5MChw3FBdmKL8sJxs8FcVuKgN6YZT0AaIBpVjHVnfBBUEp3F0ffg+pxY2KUmPBy6Z25aC4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.191 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.163.17]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4Z4bN42Mmqz1R5vD; Sat, 1 Mar 2025 14:51:48 +0800 (CST) Received: from dggpemf500017.china.huawei.com (unknown [7.185.36.126]) by mail.maildlp.com (Postfix) with ESMTPS id 891201A0188; Sat, 1 Mar 2025 14:53:24 +0800 (CST) Received: from huawei.com (10.175.104.67) by dggpemf500017.china.huawei.com (7.185.36.126) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Sat, 1 Mar 2025 14:53:23 +0800 From: Long Li To: , , , , , , , , , , , , CC: , , , , , , Subject: [PATCH 2/2] sunrpc: fix race in cache cleanup causing stale nextcheck time Date: Sat, 1 Mar 2025 14:48:36 +0800 Message-ID: <20250301064836.3285906-3-leo.lilong@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250301064836.3285906-1-leo.lilong@huawei.com> References: <20250301064836.3285906-1-leo.lilong@huawei.com> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To dggpemf500017.china.huawei.com (7.185.36.126) 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 --- 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 d12ab3175d05..b2db0dee3622 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -464,24 +464,21 @@ static int cache_clean(void) } } + spin_lock(¤t_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(¤t_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(¤t_detail->hash_lock); - /* Ok, now to clean this strand */ - head = ¤t_detail->hash_table[current_index]; hlist_for_each_entry_safe(ch, tmp, head, cache_list) { if (current_detail->nextcheck > ch->expiry_time) @@ -502,8 +499,10 @@ static int cache_clean(void) spin_unlock(&cache_list_lock); if (ch) sunrpc_end_cache_remove_entry(ch, d); - } else + } else { + spin_unlock(¤t_detail->hash_lock); spin_unlock(&cache_list_lock); + } return rv; }