mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo()
@ 2026-09-28 20:34 Prashant Singh
  2026-09-28 20:47 ` sashiko-bot
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Prashant Singh @ 2026-09-28 20:34 UTC (permalink / raw)
  To: ardb, jk
  Cc: bigeasy, clrkwllms, rostedt, corbet, skhan, rdunlap, lgoncalv,
	93sam, linux-efi, linux-kernel, linux-doc, linux-rt-devel,
	Prashant Singh

QueryVariableInfo() is an EFI runtime service that, on some firmware,
takes tens of milliseconds and runs with preemption disabled, stalling
the CPU that services it. efivarfs_statfs() calls it (rate-limited since
commit b2326338dc68 ("efivarfs: Rate limit statfs() handler")) to report
the variable-store used/available capacity, so any statfs(2) -- e.g.
every "df" -- can inject that stall into unrelated latency-sensitive
workloads on the same CPU.

Add a negatable "nostatfs" mount option: with nostatfs, statfs(2) skips
QueryVariableInfo() and reports zero used/available; with statfs it
reports the capacity as before. It defaults to nostatfs on
CONFIG_PREEMPT_RT so real-time kernels do not take the stall out of the
box, but statfs can be passed there to force reporting back on -- e.g.
for tools such as fwupd that need the efivars free space to update Secure
Boot key databases.

The option can also be toggled on a live mount via remount, so reporting
can be enabled only for the duration of a firmware update without
unmounting the boot-time efivarfs mount:

  mount -o remount,statfs   /sys/firmware/efi/efivars   # reporting on
  mount -o remount,nostatfs /sys/firmware/efi/efivars   # reporting off

Tested on an Intel Xeon E5-2628L v4, 6.12 kernel, via
"strace -T -e trace=statfs df" on the efivarfs mount.

Cost of the firmware call (CONFIG_PREEMPT_RT not set, so reporting is
enabled by default). Default mount calls QueryVariableInfo() and returns
the real store capacity, ~66-129 ms per call:

  statfs("/sys/firmware/efi/efivars", {f_type=EFIVARFS_MAGIC,
      f_bsize=1, f_blocks=90024, f_bfree=33387, f_bavail=28267, ...})
      = 0 <0.129124>

With -o nostatfs the firmware call is skipped, capacity reported as
zero, ~11 us per call:

  statfs("/sys/firmware/efi/efivars", {f_type=EFIVARFS_MAGIC,
      f_bsize=1, f_blocks=0, f_bfree=0, f_bavail=0, ...}) = 0 <0.000011>

PREEMPT_RT default and live remount toggle (CONFIG_PREEMPT_RT=y). The
boot-time mount defaults to nostatfs (mount shows nostatfs); no firmware
call, capacity zero:

  statfs(... f_blocks=0, f_bfree=0, f_bavail=0, ...) = 0 <0.000018>

Enabling reporting in place with "mount -o remount,statfs" (mount now
shows statfs) takes the ~70 ms firmware call and returns the real
capacity, without unmounting:

  statfs(... f_blocks=90024, f_bfree=30315, f_bavail=25195, ...)
      = 0 <0.070293>

Disabling it again with "mount -o remount,nostatfs" returns to the fast,
zero-capacity path:

  statfs(... f_blocks=0, f_bfree=0, f_bavail=0, ...) = 0 <0.000014>

An unrelated remount that does not respecify the option preserves it: a
"mount -o remount,rw" after "remount,statfs" leaves the mount showing
statfs.

Suggested-by: Ard Biesheuvel <ardb@kernel.org>
Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Prashant Singh <singhpra@juniper.net>
---
Changes since v3:
- Drop the show_options "statfs" branch; the absence of "nostatfs" now
  indicates reporting is on (Ard Biesheuvel).
- Drop the uid/gid copies on the remount path; efivarfs_reconfigure()
  applies only nostatfs, so they were dead code (Ard Biesheuvel).

Changes since v2:
- Make the flag negatable (fsparam_flag_no): "statfs" forces reporting
  back on, "nostatfs" skips QueryVariableInfo(). Default stays nostatfs
  on PREEMPT_RT. This lets fwupd get the efivars free space it needs for
  Secure Boot key (KEK/DB/DBX) updates on an RT kernel by mounting with
  -o statfs (Luis Claudio R. Goncalves, Steve McIntyre).
- Support toggling the option on a live mount via remount, so reporting
  can be enabled just for a firmware update without unmounting efivarfs
  (Sebastian Andrzej Siewior). Options not respecified on remount are
  preserved.
- Add PREEMPT_RT + remount test data to the commit message.

Changes since v1:
- Replace the sysctl with a mount option named "nostatfs", per review
  (Ard Biesheuvel).

v1: https://lore.kernel.org/all/20260917071600.5587-1-singhpra@juniper.net/
v2: https://lore.kernel.org/all/20260919044124.8268-1-singhpra@juniper.net/
v3: https://lore.kernel.org/all/20260925113145.7396-1-singhpra@juniper.net/

 Documentation/filesystems/efivarfs.rst | 16 +++++++++++
 fs/efivarfs/internal.h                 |  1 +
 fs/efivarfs/super.c                    | 38 ++++++++++++++++++++++----
 3 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/Documentation/filesystems/efivarfs.rst b/Documentation/filesystems/efivarfs.rst
index f646c3f0980f..cd81ee84115b 100644
--- a/Documentation/filesystems/efivarfs.rst
+++ b/Documentation/filesystems/efivarfs.rst
@@ -37,6 +37,22 @@ accidentally.
           |4_bytes_of_attributes + efivar_data|
           +-----------------------------------+
 
+Mount options
+=============
+
+statfs / nostatfs
+      Control whether ``statfs(2)`` reports the variable-store used/available
+      capacity. Obtaining it requires the ``QueryVariableInfo()`` EFI runtime
+      service, which on some firmware takes tens of milliseconds and runs with
+      preemption disabled, stalling the calling CPU. With ``nostatfs`` the call
+      is skipped and ``statfs(2)`` reports zero. The default is to report,
+      except on ``CONFIG_PREEMPT_RT`` where it defaults to ``nostatfs``; pass
+      ``statfs`` there to force reporting back on (e.g. for tools such as fwupd
+      that need the free space for firmware updates). The option can also be
+      flipped on a live mount with ``mount -o remount,statfs`` /
+      ``mount -o remount,nostatfs``, so reporting can be enabled only for the
+      duration of a firmware update without unmounting efivarfs.
+
 *See also:*
 
 - Documentation/admin-guide/acpi/ssdt-overlays.rst
diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h
index f913b6824289..0cb053884b4b 100644
--- a/fs/efivarfs/internal.h
+++ b/fs/efivarfs/internal.h
@@ -11,6 +11,7 @@
 struct efivarfs_mount_opts {
 	kuid_t uid;
 	kgid_t gid;
+	bool nostatfs;		/* skip QueryVariableInfo() in statfs() */
 };
 
 struct efivarfs_fs_info {
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index 8d33f11db2a1..efeada6e314f 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -74,6 +74,9 @@ static int efivarfs_show_options(struct seq_file *m, struct dentry *root)
 	if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
 		seq_printf(m, ",gid=%u",
 				from_kgid_munged(&init_user_ns, opts->gid));
+	/* Absence of nostatfs means statfs() reports real capacity. */
+	if (opts->nostatfs)
+		seq_puts(m, ",nostatfs");
 	return 0;
 }
 
@@ -82,13 +85,19 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	const u32 attr = EFI_VARIABLE_NON_VOLATILE |
 			 EFI_VARIABLE_BOOTSERVICE_ACCESS |
 			 EFI_VARIABLE_RUNTIME_ACCESS;
+	struct efivarfs_fs_info *sfi = dentry->d_sb->s_fs_info;
 	u64 storage_space, remaining_space, max_variable_size;
 	u64 id = huge_encode_dev(dentry->d_sb->s_dev);
 	efi_status_t status;
 
-	/* Some UEFI firmware does not implement QueryVariableInfo() */
+	/*
+	 * Some UEFI firmware does not implement QueryVariableInfo(); the
+	 * nostatfs mount option also disables this (preempt-disabled,
+	 * potentially slow) call entirely, reporting zero used/available.
+	 */
 	storage_space = remaining_space = 0;
-	if (efi_rt_services_supported(EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO)) {
+	if (!READ_ONCE(sfi->mount_opts.nostatfs) &&
+	    efi_rt_services_supported(EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO)) {
 		static DEFINE_RATELIMIT_STATE(_rs, 2 * HZ, 5);
 		static u64 storage, remaining;
 		static DEFINE_SPINLOCK(lock);
@@ -323,12 +332,13 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
 }
 
 enum {
-	Opt_uid, Opt_gid,
+	Opt_uid, Opt_gid, Opt_statfs,
 };
 
 static const struct fs_parameter_spec efivarfs_parameters[] = {
 	fsparam_uid("uid", Opt_uid),
 	fsparam_gid("gid", Opt_gid),
+	fsparam_flag_no("statfs", Opt_statfs),
 	{},
 };
 
@@ -350,6 +360,9 @@ static int efivarfs_parse_param(struct fs_context *fc, struct fs_parameter *para
 	case Opt_gid:
 		opts->gid = result.gid;
 		break;
+	case Opt_statfs:
+		opts->nostatfs = result.negated;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -402,11 +415,17 @@ static int efivarfs_get_tree(struct fs_context *fc)
 
 static int efivarfs_reconfigure(struct fs_context *fc)
 {
+	struct efivarfs_fs_info *sfi = fc->root->d_sb->s_fs_info;
+	struct efivarfs_fs_info *new_sfi = fc->s_fs_info;
+
 	if (!efivar_supports_writes() && !(fc->sb_flags & SB_RDONLY)) {
 		pr_err("Firmware does not support SetVariableRT. Can not remount with rw\n");
 		return -EINVAL;
 	}
 
+	/* statfs() reads nostatfs without s_umount; mark the concurrent update. */
+	WRITE_ONCE(sfi->mount_opts.nostatfs, new_sfi->mount_opts.nostatfs);
+
 	return 0;
 }
 
@@ -524,8 +543,17 @@ static int efivarfs_init_fs_context(struct fs_context *fc)
 	if (!sfi)
 		return -ENOMEM;
 
-	sfi->mount_opts.uid = GLOBAL_ROOT_UID;
-	sfi->mount_opts.gid = GLOBAL_ROOT_GID;
+	if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
+		/* nostatfs is writable via remount; keep it if not respecified. */
+		struct efivarfs_fs_info *old = fc->root->d_sb->s_fs_info;
+
+		sfi->mount_opts.nostatfs = READ_ONCE(old->mount_opts.nostatfs);
+	} else {
+		sfi->mount_opts.uid = GLOBAL_ROOT_UID;
+		sfi->mount_opts.gid = GLOBAL_ROOT_GID;
+		/* QueryVariableInfo() stalls the CPU; default nostatfs on PREEMPT_RT. */
+		sfi->mount_opts.nostatfs = IS_ENABLED(CONFIG_PREEMPT_RT);
+	}
 
 	fc->s_fs_info = sfi;
 	fc->ops = &efivarfs_context_ops;

base-commit: 9b87fdc9af2fbfcdb5c24a64139685ef80f6573f
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo()
  2026-09-28 20:34 [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo() Prashant Singh
@ 2026-09-28 20:47 ` sashiko-bot
  2026-09-29  6:32 ` Ard Biesheuvel
  2026-09-29  7:43 ` Sebastian Andrzej Siewior
  2 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-09-28 20:47 UTC (permalink / raw)
  To: Prashant Singh; +Cc: linux-rt-devel, linux-kernel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] vfs: missing READ_ONCE() for opts->nostatfs in efivarfs_show_options()
--

commit 8539129e21537b2431de520ca79339783ffada2d
Author: Prashant Singh <singhpra@juniper.net>
Subject: efivarfs: add nostatfs mount option to skip QueryVariableInfo()

This commit adds a negatable "nostatfs" mount option to efivarfs. It skips
the EFI QueryVariableInfo() call during statfs(2), which can take tens of
milliseconds and run with preemption disabled. The option can also be toggled
on a live mount via remount.

> diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
> index 8d33f11db2a1b..efeada6e314f4 100644
> --- a/fs/efivarfs/super.c
> +++ b/fs/efivarfs/super.c
> @@ -74,6 +74,9 @@ static int efivarfs_show_options(struct seq_file *m, struct dentry *root)
>  	if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
>  		seq_printf(m, ",gid=%u",
>  				from_kgid_munged(&init_user_ns, opts->gid));
> +	/* Absence of nostatfs means statfs() reports real capacity. */
> +	if (opts->nostatfs)
       ^^^^

[Severity: Low]
Is a READ_ONCE() needed here?

This plain C read of opts->nostatfs in efivarfs_show_options() can race with
the concurrent WRITE_ONCE() in efivarfs_reconfigure() during a remount. 

A userspace process reading /proc/mounts calls efivarfs_show_options() holding
only namespace_sem for read, while a concurrent mount -o remount calls
efivarfs_reconfigure() holding only sb->s_umount for write. Because no common
lock serializes these two paths, missing the READ_ONCE() here could lead to a
KCSAN data race splat.

> +		seq_puts(m, ",nostatfs");
>  	return 0;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260928203445.72318-1-singhpra@juniper.net?part=1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo()
  2026-09-28 20:34 [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo() Prashant Singh
  2026-09-28 20:47 ` sashiko-bot
@ 2026-09-29  6:32 ` Ard Biesheuvel
  2026-09-29  7:43 ` Sebastian Andrzej Siewior
  2 siblings, 0 replies; 6+ messages in thread
From: Ard Biesheuvel @ 2026-09-29  6:32 UTC (permalink / raw)
  To: Prashant Singh, Jeremy Kerr
  Cc: Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt,
	Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Luis Claudio R. Goncalves, Steve McIntyre, linux-efi,
	linux-kernel, linux-doc, linux-rt-devel



On Mon, 28 Sep 2026, at 22:34, Prashant Singh wrote:
> QueryVariableInfo() is an EFI runtime service that, on some firmware,
> takes tens of milliseconds and runs with preemption disabled, stalling
> the CPU that services it. efivarfs_statfs() calls it (rate-limited since
> commit b2326338dc68 ("efivarfs: Rate limit statfs() handler")) to report
> the variable-store used/available capacity, so any statfs(2) -- e.g.
> every "df" -- can inject that stall into unrelated latency-sensitive
> workloads on the same CPU.
>
> Add a negatable "nostatfs" mount option: with nostatfs, statfs(2) skips
> QueryVariableInfo() and reports zero used/available; with statfs it
> reports the capacity as before. It defaults to nostatfs on
> CONFIG_PREEMPT_RT so real-time kernels do not take the stall out of the
> box, but statfs can be passed there to force reporting back on -- e.g.
> for tools such as fwupd that need the efivars free space to update Secure
> Boot key databases.
>
> The option can also be toggled on a live mount via remount, so reporting
> can be enabled only for the duration of a firmware update without
> unmounting the boot-time efivarfs mount:
>
>   mount -o remount,statfs   /sys/firmware/efi/efivars   # reporting on
>   mount -o remount,nostatfs /sys/firmware/efi/efivars   # reporting off
>
> Tested on an Intel Xeon E5-2628L v4, 6.12 kernel, via
> "strace -T -e trace=statfs df" on the efivarfs mount.
>
> Cost of the firmware call (CONFIG_PREEMPT_RT not set, so reporting is
> enabled by default). Default mount calls QueryVariableInfo() and returns
> the real store capacity, ~66-129 ms per call:
>
>   statfs("/sys/firmware/efi/efivars", {f_type=EFIVARFS_MAGIC,
>       f_bsize=1, f_blocks=90024, f_bfree=33387, f_bavail=28267, ...})
>       = 0 <0.129124>
>
> With -o nostatfs the firmware call is skipped, capacity reported as
> zero, ~11 us per call:
>
>   statfs("/sys/firmware/efi/efivars", {f_type=EFIVARFS_MAGIC,
>       f_bsize=1, f_blocks=0, f_bfree=0, f_bavail=0, ...}) = 0 <0.000011>
>
> PREEMPT_RT default and live remount toggle (CONFIG_PREEMPT_RT=y). The
> boot-time mount defaults to nostatfs (mount shows nostatfs); no firmware
> call, capacity zero:
>
>   statfs(... f_blocks=0, f_bfree=0, f_bavail=0, ...) = 0 <0.000018>
>
> Enabling reporting in place with "mount -o remount,statfs" (mount now
> shows statfs) takes the ~70 ms firmware call and returns the real
> capacity, without unmounting:
>
>   statfs(... f_blocks=90024, f_bfree=30315, f_bavail=25195, ...)
>       = 0 <0.070293>
>
> Disabling it again with "mount -o remount,nostatfs" returns to the fast,
> zero-capacity path:
>
>   statfs(... f_blocks=0, f_bfree=0, f_bavail=0, ...) = 0 <0.000014>
>
> An unrelated remount that does not respecify the option preserves it: a
> "mount -o remount,rw" after "remount,statfs" leaves the mount showing
> statfs.
>
> Suggested-by: Ard Biesheuvel <ardb@kernel.org>
> Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Prashant Singh <singhpra@juniper.net>
> ---
> Changes since v3:
> - Drop the show_options "statfs" branch; the absence of "nostatfs" now
>   indicates reporting is on (Ard Biesheuvel).
> - Drop the uid/gid copies on the remount path; efivarfs_reconfigure()
>   applies only nostatfs, so they were dead code (Ard Biesheuvel).
>

Please don't respond to questions by respinning the patch without
having any discussion at all.

I asked you an honest question, and it seems Sashiko spotted an
issue here too.

Is there a problem with how the current code deals with uid and gid
on a remount?


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo()
  2026-09-28 20:34 [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo() Prashant Singh
  2026-09-28 20:47 ` sashiko-bot
  2026-09-29  6:32 ` Ard Biesheuvel
@ 2026-09-29  7:43 ` Sebastian Andrzej Siewior
  2026-09-29 12:22   ` Ard Biesheuvel
  2 siblings, 1 reply; 6+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-09-29  7:43 UTC (permalink / raw)
  To: Prashant Singh
  Cc: ardb, jk, clrkwllms, rostedt, corbet, skhan, rdunlap, lgoncalv,
	93sam, linux-efi, linux-kernel, linux-doc, linux-rt-devel

On 2026-09-28 13:34:45 [-0700], Prashant Singh wrote:
> QueryVariableInfo() is an EFI runtime service that, on some firmware,
> takes tens of milliseconds and runs with preemption disabled, stalling
> the CPU that services it. efivarfs_statfs() calls it (rate-limited since
> commit b2326338dc68 ("efivarfs: Rate limit statfs() handler")) to report
> the variable-store used/available capacity, so any statfs(2) -- e.g.
> every "df" -- can inject that stall into unrelated latency-sensitive
> workloads on the same CPU.
> 
> Add a negatable "nostatfs" mount option: with nostatfs, statfs(2) skips
> QueryVariableInfo() and reports zero used/available; with statfs it
> reports the capacity as before. It defaults to nostatfs on
> CONFIG_PREEMPT_RT so real-time kernels do not take the stall out of the
> box, but statfs can be passed there to force reporting back on -- e.g.
> for tools such as fwupd that need the efivars free space to update Secure
> Boot key databases.
> 
> The option can also be toggled on a live mount via remount, so reporting
> can be enabled only for the duration of a firmware update without
> unmounting the boot-time efivarfs mount:
> 
>   mount -o remount,statfs   /sys/firmware/efi/efivars   # reporting on
>   mount -o remount,nostatfs /sys/firmware/efi/efivars   # reporting off
> 
> Tested on an Intel Xeon E5-2628L v4, 6.12 kernel, via
> "strace -T -e trace=statfs df" on the efivarfs mount.

This until the end looks extremely verbose. Even if that statfs takes
ages, that important part is that it does so with disables preemption.
There has been also the introduction of the efi_runtime workqueue which
can be pinned to a single CPU. I guess this doesn't work for you or the
EFI firmware takes all other CPUs down until the all completes.

> Cost of the firmware call (CONFIG_PREEMPT_RT not set, so reporting is
> enabled by default). Default mount calls QueryVariableInfo() and returns
> the real store capacity, ~66-129 ms per call:
> 
>   statfs("/sys/firmware/efi/efivars", {f_type=EFIVARFS_MAGIC,
>       f_bsize=1, f_blocks=90024, f_bfree=33387, f_bavail=28267, ...})
>       = 0 <0.129124>
> 
> With -o nostatfs the firmware call is skipped, capacity reported as
> zero, ~11 us per call:
> 
>   statfs("/sys/firmware/efi/efivars", {f_type=EFIVARFS_MAGIC,
>       f_bsize=1, f_blocks=0, f_bfree=0, f_bavail=0, ...}) = 0 <0.000011>
> 
> PREEMPT_RT default and live remount toggle (CONFIG_PREEMPT_RT=y). The
> boot-time mount defaults to nostatfs (mount shows nostatfs); no firmware
> call, capacity zero:
> 
>   statfs(... f_blocks=0, f_bfree=0, f_bavail=0, ...) = 0 <0.000018>
> 
> Enabling reporting in place with "mount -o remount,statfs" (mount now
> shows statfs) takes the ~70 ms firmware call and returns the real
> capacity, without unmounting:
> 
>   statfs(... f_blocks=90024, f_bfree=30315, f_bavail=25195, ...)
>       = 0 <0.070293>
> 
> Disabling it again with "mount -o remount,nostatfs" returns to the fast,
> zero-capacity path:
> 
>   statfs(... f_blocks=0, f_bfree=0, f_bavail=0, ...) = 0 <0.000014>
> 
> An unrelated remount that does not respecify the option preserves it: a
> "mount -o remount,rw" after "remount,statfs" leaves the mount showing
> statfs.
> 
…
> Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Prashant Singh <singhpra@juniper.net>
> ---
> Changes since v3:
> - Drop the show_options "statfs" branch; the absence of "nostatfs" now
>   indicates reporting is on (Ard Biesheuvel).
> - Drop the uid/gid copies on the remount path; efivarfs_reconfigure()
>   applies only nostatfs, so they were dead code (Ard Biesheuvel).
> 
> Changes since v2:
> - Make the flag negatable (fsparam_flag_no): "statfs" forces reporting
>   back on, "nostatfs" skips QueryVariableInfo(). Default stays nostatfs
>   on PREEMPT_RT. This lets fwupd get the efivars free space it needs for
>   Secure Boot key (KEK/DB/DBX) updates on an RT kernel by mounting with
>   -o statfs (Luis Claudio R. Goncalves, Steve McIntyre).
> - Support toggling the option on a live mount via remount, so reporting
>   can be enabled just for a firmware update without unmounting efivarfs
>   (Sebastian Andrzej Siewior). Options not respecified on remount are
>   preserved.
> - Add PREEMPT_RT + remount test data to the commit message.
> 
> Changes since v1:
> - Replace the sysctl with a mount option named "nostatfs", per review
>   (Ard Biesheuvel).
> 
> v1: https://lore.kernel.org/all/20260917071600.5587-1-singhpra@juniper.net/
> v2: https://lore.kernel.org/all/20260919044124.8268-1-singhpra@juniper.net/
> v3: https://lore.kernel.org/all/20260925113145.7396-1-singhpra@juniper.net/
> 
>  Documentation/filesystems/efivarfs.rst | 16 +++++++++++
>  fs/efivarfs/internal.h                 |  1 +
>  fs/efivarfs/super.c                    | 38 ++++++++++++++++++++++----
>  3 files changed, 50 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/filesystems/efivarfs.rst b/Documentation/filesystems/efivarfs.rst
> index f646c3f0980f..cd81ee84115b 100644
> --- a/Documentation/filesystems/efivarfs.rst
> +++ b/Documentation/filesystems/efivarfs.rst
> @@ -37,6 +37,22 @@ accidentally.
>            |4_bytes_of_attributes + efivar_data|
>            +-----------------------------------+
>  
> +Mount options
> +=============
> +
> +statfs / nostatfs
> +      Control whether ``statfs(2)`` reports the variable-store used/available
> +      capacity. Obtaining it requires the ``QueryVariableInfo()`` EFI runtime
> +      service, which on some firmware takes tens of milliseconds and runs with
> +      preemption disabled, stalling the calling CPU. With ``nostatfs`` the call
> +      is skipped and ``statfs(2)`` reports zero. The default is to report,
> +      except on ``CONFIG_PREEMPT_RT`` where it defaults to ``nostatfs``; pass
> +      ``statfs`` there to force reporting back on (e.g. for tools such as fwupd
> +      that need the free space for firmware updates). The option can also be
> +      flipped on a live mount with ``mount -o remount,statfs`` /
> +      ``mount -o remount,nostatfs``, so reporting can be enabled only for the
> +      duration of a firmware update without unmounting efivarfs.

could this be, I don't know something smaller not including the
commandline where I would expect that people know how to use it.

===================     =========================================================
(no)statfs		Control whether ``statfs(2)`` reports the variable-store
			used/ available. Disabling it skips the EFI runtime 
			service call, which might block the CPU for a few milliseconds,
			reporting 0 for used and capacity. Enabled by default on
			PREEMPT_RT.
===================     =========================================================

It might make sense to add this knob to Documentation/core-api/real-time/hardware.rst.
I am not sure yet but slowly we are getting more knobs that I have
expected.

> +
>  *See also:*
>  
>  - Documentation/admin-guide/acpi/ssdt-overlays.rst
> diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h
> index f913b6824289..0cb053884b4b 100644
> --- a/fs/efivarfs/internal.h
> +++ b/fs/efivarfs/internal.h
> @@ -11,6 +11,7 @@
>  struct efivarfs_mount_opts {
>  	kuid_t uid;
>  	kgid_t gid;
> +	bool nostatfs;		/* skip QueryVariableInfo() in statfs() */
Here and below you add a comment to every change you make. What about
focusing on the important parts, that deserve an explanation why a
change has been made. For instance why nostatfs has the READ_ONCE/
WRITE_ONCE accessors and sometimes it does not.

>  };
>  

Sebastian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo()
  2026-09-29  7:43 ` Sebastian Andrzej Siewior
@ 2026-09-29 12:22   ` Ard Biesheuvel
  2026-09-29 15:14     ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 6+ messages in thread
From: Ard Biesheuvel @ 2026-09-29 12:22 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior, Prashant Singh
  Cc: Jeremy Kerr, Clark Williams, Steven Rostedt, Jonathan Corbet,
	Shuah Khan, Randy Dunlap, Luis Claudio R. Goncalves,
	Steve McIntyre, linux-efi, linux-kernel, linux-doc,
	linux-rt-devel

Hi Sebastian,

Thanks for taking a look.

On Tue, 29 Sep 2026, at 09:43, Sebastian Andrzej Siewior wrote:
> On 2026-09-28 13:34:45 [-0700], Prashant Singh wrote:
>> QueryVariableInfo() is an EFI runtime service that, on some firmware,
>> takes tens of milliseconds and runs with preemption disabled, stalling
>> the CPU that services it. efivarfs_statfs() calls it (rate-limited since
>> commit b2326338dc68 ("efivarfs: Rate limit statfs() handler")) to report
>> the variable-store used/available capacity, so any statfs(2) -- e.g.
>> every "df" -- can inject that stall into unrelated latency-sensitive
>> workloads on the same CPU.
>> 
>> Add a negatable "nostatfs" mount option: with nostatfs, statfs(2) skips
>> QueryVariableInfo() and reports zero used/available; with statfs it
>> reports the capacity as before. It defaults to nostatfs on
>> CONFIG_PREEMPT_RT so real-time kernels do not take the stall out of the
>> box, but statfs can be passed there to force reporting back on -- e.g.
>> for tools such as fwupd that need the efivars free space to update Secure
>> Boot key databases.
>> 
>> The option can also be toggled on a live mount via remount, so reporting
>> can be enabled only for the duration of a firmware update without
>> unmounting the boot-time efivarfs mount:
>> 
>>   mount -o remount,statfs   /sys/firmware/efi/efivars   # reporting on
>>   mount -o remount,nostatfs /sys/firmware/efi/efivars   # reporting off
>> 
>> Tested on an Intel Xeon E5-2628L v4, 6.12 kernel, via
>> "strace -T -e trace=statfs df" on the efivarfs mount.
>
> This until the end looks extremely verbose. Even if that statfs takes
> ages, that important part is that it does so with disables preemption.
> There has been also the introduction of the efi_runtime workqueue which
> can be pinned to a single CPU. I guess this doesn't work for you or the
> EFI firmware takes all other CPUs down until the all completes.
>

Yeah the most severe issue is that entering SMM requires a rendez-vous
of all the cores, and so whether preemption is enabled or not is
actually kind of irrelevant, given that all the other cores just
disappear.


...
>> diff --git a/Documentation/filesystems/efivarfs.rst b/Documentation/filesystems/efivarfs.rst
>> index f646c3f0980f..cd81ee84115b 100644
>> --- a/Documentation/filesystems/efivarfs.rst
>> +++ b/Documentation/filesystems/efivarfs.rst
>> @@ -37,6 +37,22 @@ accidentally.
>>            |4_bytes_of_attributes + efivar_data|
>>            +-----------------------------------+
>>  
>> +Mount options
>> +=============
>> +
>> +statfs / nostatfs
>> +      Control whether ``statfs(2)`` reports the variable-store used/available
>> +      capacity. Obtaining it requires the ``QueryVariableInfo()`` EFI runtime
>> +      service, which on some firmware takes tens of milliseconds and runs with
>> +      preemption disabled, stalling the calling CPU. With ``nostatfs`` the call
>> +      is skipped and ``statfs(2)`` reports zero. The default is to report,
>> +      except on ``CONFIG_PREEMPT_RT`` where it defaults to ``nostatfs``; pass
>> +      ``statfs`` there to force reporting back on (e.g. for tools such as fwupd
>> +      that need the free space for firmware updates). The option can also be
>> +      flipped on a live mount with ``mount -o remount,statfs`` /
>> +      ``mount -o remount,nostatfs``, so reporting can be enabled only for the
>> +      duration of a firmware update without unmounting efivarfs.
>
> could this be, I don't know something smaller not including the
> commandline where I would expect that people know how to use it.
>
> ===================     
> =========================================================
> (no)statfs		Control whether ``statfs(2)`` reports the variable-store
> 			used/ available. Disabling it skips the EFI runtime 
> 			service call, which might block the CPU for a few milliseconds,
> 			reporting 0 for used and capacity. Enabled by default on
> 			PREEMPT_RT.
> ===================     
> =========================================================
>

+1

> It might make sense to add this knob to 
> Documentation/core-api/real-time/hardware.rst.
> I am not sure yet but slowly we are getting more knobs that I have
> expected.
>
>> +
>>  *See also:*
>>  
>>  - Documentation/admin-guide/acpi/ssdt-overlays.rst
>> diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h
>> index f913b6824289..0cb053884b4b 100644
>> --- a/fs/efivarfs/internal.h
>> +++ b/fs/efivarfs/internal.h
>> @@ -11,6 +11,7 @@
>>  struct efivarfs_mount_opts {
>>  	kuid_t uid;
>>  	kgid_t gid;
>> +	bool nostatfs;		/* skip QueryVariableInfo() in statfs() */
> Here and below you add a comment to every change you make. What about
> focusing on the important parts, that deserve an explanation why a
> change has been made. For instance why nostatfs has the READ_ONCE/
> WRITE_ONCE accessors and sometimes it does not.
>

AIUI the READ_ONCE/WRITE_ONCE were added because Sashiko warned about
potential KCSAN splats? It would be nice to mention that.

In any case, KCSAN is runtime instrumentation, and efi_reboot_required()
is only called after all other CPUs have been brought down. So if anything,
this should just wrap the read on the reboot path in a data_race() so
that we don't trigger any instrumentation inadvertently on the way down.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo()
  2026-09-29 12:22   ` Ard Biesheuvel
@ 2026-09-29 15:14     ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 6+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-09-29 15:14 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Prashant Singh, Jeremy Kerr, Clark Williams, Steven Rostedt,
	Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Luis Claudio R. Goncalves, Steve McIntyre, linux-efi,
	linux-kernel, linux-doc, linux-rt-devel

On 2026-09-29 14:22:31 [+0200], Ard Biesheuvel wrote:
> Hi Sebastian,
Hi Ard,

> Thanks for taking a look.

doing my best…

> >> --- a/fs/efivarfs/internal.h
> >> +++ b/fs/efivarfs/internal.h
> >> @@ -11,6 +11,7 @@
> >>  struct efivarfs_mount_opts {
> >>  	kuid_t uid;
> >>  	kgid_t gid;
> >> +	bool nostatfs;		/* skip QueryVariableInfo() in statfs() */
> > Here and below you add a comment to every change you make. What about
> > focusing on the important parts, that deserve an explanation why a
> > change has been made. For instance why nostatfs has the READ_ONCE/
> > WRITE_ONCE accessors and sometimes it does not.
> >
> 
> AIUI the READ_ONCE/WRITE_ONCE were added because Sashiko warned about
> potential KCSAN splats? It would be nice to mention that.

:)

> In any case, KCSAN is runtime instrumentation, and efi_reboot_required()
> is only called after all other CPUs have been brought down. So if anything,
> this should just wrap the read on the reboot path in a data_race() so
> that we don't trigger any instrumentation inadvertently on the way down.

Right. So if anything, there could be a data_race() in one place instead
inconsistent READ/ WRITE once as we have it now.

Sebastian

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-29 15:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-28 20:34 [PATCH v4] efivarfs: add nostatfs mount option to skip QueryVariableInfo() Prashant Singh
2026-09-28 20:47 ` sashiko-bot
2026-09-29  6:32 ` Ard Biesheuvel
2026-09-29  7:43 ` Sebastian Andrzej Siewior
2026-09-29 12:22   ` Ard Biesheuvel
2026-09-29 15:14     ` Sebastian Andrzej Siewior

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®