lib/once.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Pointless overhead to use a work queue to reset the static key
for a DO_ONCE_SLEEPABLE() invocation.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
lib/once.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/once.c b/lib/once.c
index 2c306f0e891e..d83bdde78ced 100644
--- a/lib/once.c
+++ b/lib/once.c
@@ -93,6 +93,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
{
*done = true;
mutex_unlock(&once_mutex);
- once_disable_jump(once_key, mod);
+ BUG_ON(!static_key_enabled(once_key));
+ static_branch_disable(once_key);
}
EXPORT_SYMBOL(__do_once_sleepable_done);
--
2.52.0
On Thu, 8 Jan 2026 15:27:17 -0800 Tony Luck <tony.luck@intel.com> wrote:
> Pointless overhead to use a work queue to reset the static key
> for a DO_ONCE_SLEEPABLE() invocation.
>
> ...
>
> --- a/lib/once.c
> +++ b/lib/once.c
> @@ -93,6 +93,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
> {
> *done = true;
> mutex_unlock(&once_mutex);
> - once_disable_jump(once_key, mod);
> + BUG_ON(!static_key_enabled(once_key));
Sauron's eye is upon us. Can we either justify nuking the kernel or
use a WARN_ON?
> + static_branch_disable(once_key);
> }
> EXPORT_SYMBOL(__do_once_sleepable_done);
> --
> 2.52.0
Hi Tony,
On 1/8/26 3:27 PM, Tony Luck wrote:
> Pointless overhead to use a work queue to reset the static key
> for a DO_ONCE_SLEEPABLE() invocation.
>
> Reported-by: Reinette Chatre <reinette.chatre@intel.com>
> Signed-off-by: Tony Luck <tony.luck@intel.com>
> ---
> lib/once.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/lib/once.c b/lib/once.c
> index 2c306f0e891e..d83bdde78ced 100644
> --- a/lib/once.c
> +++ b/lib/once.c
> @@ -93,6 +93,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
> {
> *done = true;
> mutex_unlock(&once_mutex);
> - once_disable_jump(once_key, mod);
> + BUG_ON(!static_key_enabled(once_key));
> + static_branch_disable(once_key);
Can this be simplified more by disabling once_key with once_mutex held to eliminate the need for the
done boolean? Unless static_branch_disable() is considered to be so slow that it should also be
avoided in sleepable context, deferring to a mutex protected boolean until it completes ...
If "done" boolean is removed this may need an additional check of once_key within
__do_once_sleepable_start() just in case a second caller was blocked on once_mutex.
Reinette
Pointless overhead to use a work queue to reset the static key
for a DO_ONCE_SLEEPABLE() invocation.
Note that the previous code path included a BUG_ON() if the static key
was already disabled. Dropped that as part of this change because:
1) Use of BUG_ON() is highly discouraged.
2) There is a WARN_ON() in the static_branch_disable() code path
that would provide adequate breadcrumbs to debug any issue.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
Changes since v1:
Andrew Morton pointed out that adding a new BUG_ON() was ill-advised.
Drop it (but explain why it isn't needed in the commit message).
lib/once.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/once.c b/lib/once.c
index 2c306f0e891e..8557eb489f34 100644
--- a/lib/once.c
+++ b/lib/once.c
@@ -93,6 +93,6 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
{
*done = true;
mutex_unlock(&once_mutex);
- once_disable_jump(once_key, mod);
+ static_branch_disable(once_key);
}
EXPORT_SYMBOL(__do_once_sleepable_done);
--
2.52.0
© 2016 - 2026 Red Hat, Inc.