Re: [PATCH] efivarfs: Rate limit statfs() handler

Richard Lyu <[email protected]>
Newsgroups org.kernel.vger.linux-efi,org.kernel.vger.stable
Message-ID <aob-R-ULD6S38waw@r1chard>
On 2026/08/18 16:11, Ard Biesheuvel wrote:
>Ravi reports that statfs() may be called by unprivileged users on the
>efivarfs mount point, which may result in a flood of calls to the
>QueryVariableInfo() runtime service. These calls are disproportionately
>costly on x86 systems where the variable store is backed by SMM, as each
>SMM entry requires a rendez-vous of all the CPUs.
>
>So rate limit the calls to QueryVariableInfo() at twice per second, and
>return the most recently obtained values for calls that are elided.
>
>Cc: <[email protected]>
>Cc: Anisse Astier <[email protected]>
>Reported-by: Ravi Bangoria <[email protected]>
>Fixes: d86ff3333cb1 ("efivarfs: expose used and total size")
>Signed-off-by: Ard Biesheuvel <[email protected]>
>---
>This supersedes [0], which had some issues, the main one being that a
>cache that requires explicit invalidation may go out of sync due to
>direct calls to SetVariable() made by other drivers.
>
>[0] https://lore.kernel.org/all/[email protected]/
>
> fs/efivarfs/super.c | 30 ++++++++++++++++----
> 1 file changed, 24 insertions(+), 6 deletions(-)
>
>diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
>index 733c19571f1c..8d33f11db2a1 100644
>--- a/fs/efivarfs/super.c
>+++ b/fs/efivarfs/super.c
>@@ -89,12 +89,30 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
> 	/* Some UEFI firmware does not implement QueryVariableInfo() */
> 	storage_space = remaining_space = 0;
> 	if (efi_rt_services_supported(EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO)) {
>-		status = efivar_query_variable_info(attr, &storage_space,
>-						    &remaining_space,
>-						    &max_variable_size);
>-		if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED)
>-			pr_warn_ratelimited("query_variable_info() failed: 0x%lx\n",
>-					    status);
>+		static DEFINE_RATELIMIT_STATE(_rs, 2 * HZ, 5);
>+		static u64 storage, remaining;
>+		static DEFINE_SPINLOCK(lock);
>+
>+		if (!__ratelimit(&_rs)) {
>+			ratelimit_set_flags(&_rs, RATELIMIT_MSG_ON_RELEASE);
>+
>+			spin_lock(&lock);
>+			storage_space = storage;
>+			remaining_space = remaining;
>+			spin_unlock(&lock);
>+		} else {
>+			status = efivar_query_variable_info(attr, &storage_space,
>+							    &remaining_space,
>+							    &max_variable_size);
>+			if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED)
>+				pr_warn("query_variable_info() failed: 0x%lx\n",
>+					status);
>+
>+			spin_lock(&lock);
>+			storage = storage_space;
>+			remaining = remaining_space;
>+			spin_unlock(&lock);
>+		}
> 	}
>
> 	/*
>-- 
>2.55.0.699.gb54405d56f-goog
>
>

Reviewed-by: Richard Lyu <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.