From: "tip-bot2 for Dmitry Ilvokhin" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Peter Zijlstra <peterz@infradead.org>,
Dmitry Ilvokhin <d@ilvokhin.com>, Juergen Gross <jgross@suse.com>,
x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: locking/core] x86/paravirt: Trace contended_release on unlock
Date: Fri, 07 Aug 2026 15:59:59 -0000 [thread overview]
Message-ID: <178611839980.708.13617653015052531574.tip-bot2@tip-bot2> (raw)
In-Reply-To: <17fa67f9fa4cf93f1150725e89f5f916e41a9b6f.1785778551.git.d@ilvokhin.com>
The following commit has been merged into the locking/core branch of tip:
Commit-ID: 087116fefbf343ce63b8911cf494e059e9679432
Gitweb: https://git.kernel.org/tip/087116fefbf343ce63b8911cf494e059e9679432
Author: Dmitry Ilvokhin <d@ilvokhin.com>
AuthorDate: Tue, 04 Aug 2026 07:15:45
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 07 Aug 2026 17:58:10 +02:00
x86/paravirt: Trace contended_release on unlock
On PARAVIRT_SPINLOCKS=y kernels queued_spin_unlock() is dispatched
through a static_call(). Those PARAVIRT_SPINLOCKS=y kernels are quite
popular. Gating contended_release behind a static branch would leave a
NOP on the unlock hot path even, when the tracepoint is disabled.
Since the static_call() is already present, swap its target to a traced
unlock, when the tracepoint is enabled instead. When contended_release
tracepoint is disabled the target is the plain unlock (an inline store
on native x86_64), so the unlock path is unchanged and the tracepoint is
truly zero-cost.
Provide two traced variants, native_queued_spin_unlock_traced() and
pv_queued_spin_unlock_traced(), so each tail-calls its own base unlock
directly rather than recursing through the now-traced static_call().
Teach pv_is_native_spin_unlock() that the traced native variant still
counts as native.
Only PARAVIRT_SPINLOCKS=y is affected. PARAVIRT_SPINLOCKS=n keeps the
generic static-branch path.
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Juergen Gross <jgross@suse.com>
Link: https://patch.msgid.link/17fa67f9fa4cf93f1150725e89f5f916e41a9b6f.1785778551.git.d@ilvokhin.com
---
arch/x86/include/asm/paravirt-spinlock.h | 2 +-
arch/x86/kernel/paravirt-spinlocks.c | 53 ++++++++++++++++++++++-
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/paravirt-spinlock.h b/arch/x86/include/asm/paravirt-spinlock.h
index ff73583..302bc2b 100644
--- a/arch/x86/include/asm/paravirt-spinlock.h
+++ b/arch/x86/include/asm/paravirt-spinlock.h
@@ -99,6 +99,8 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu);
void __init native_pv_lock_init(void);
__visible void __native_queued_spin_unlock(struct qspinlock *lock);
+__visible void native_queued_spin_unlock_traced(struct qspinlock *lock);
+__visible void pv_queued_spin_unlock_traced(struct qspinlock *lock);
bool pv_is_native_spin_unlock(void);
__visible bool __native_vcpu_is_preempted(long cpu);
bool pv_is_native_vcpu_is_preempted(void);
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c
index ddc19dc..ca12b36 100644
--- a/arch/x86/kernel/paravirt-spinlocks.c
+++ b/arch/x86/kernel/paravirt-spinlocks.c
@@ -7,6 +7,7 @@
#include <linux/spinlock.h>
#include <linux/export.h>
#include <linux/jump_label.h>
+#include <trace/events/lock.h>
DEFINE_STATIC_KEY_FALSE(virt_spin_lock_key);
@@ -30,10 +31,58 @@ EXPORT_STATIC_CALL_TRAMP(queued_spin_lock_slowpath);
DEFINE_STATIC_CALL(queued_spin_unlock, __raw_callee_save___native_queued_spin_unlock);
EXPORT_STATIC_CALL_TRAMP(queued_spin_unlock);
+/*
+ * Traced unlock variants, swapped in via static_call while the
+ * contended_release tracepoint is enabled. Two of them, so each tail calls its
+ * own base directly.
+ */
+__visible void native_queued_spin_unlock_traced(struct qspinlock *lock)
+{
+ if (queued_spin_is_contended(lock))
+ trace_call__contended_release(lock);
+ native_queued_spin_unlock(lock);
+}
+PV_CALLEE_SAVE_REGS_THUNK(native_queued_spin_unlock_traced);
+
+__visible void pv_queued_spin_unlock_traced(struct qspinlock *lock)
+{
+ if (queued_spin_is_contended(lock))
+ trace_call__contended_release(lock);
+ __raw_callee_save___pv_queued_spin_unlock(lock);
+}
+PV_CALLEE_SAVE_REGS_THUNK(pv_queued_spin_unlock_traced);
+
bool pv_is_native_spin_unlock(void)
{
- return static_call_query(queued_spin_unlock) ==
- __raw_callee_save___native_queued_spin_unlock;
+ void *unlock = static_call_query(queued_spin_unlock);
+
+ return unlock == __raw_callee_save___native_queued_spin_unlock ||
+ unlock == __raw_callee_save_native_queued_spin_unlock_traced;
+}
+
+int arch_contended_release_trace_reg(void)
+{
+ void *cur = static_call_query(queued_spin_unlock);
+
+ if (cur == __raw_callee_save___native_queued_spin_unlock)
+ static_call_update(queued_spin_unlock,
+ __raw_callee_save_native_queued_spin_unlock_traced);
+ else if (cur == __raw_callee_save___pv_queued_spin_unlock)
+ static_call_update(queued_spin_unlock,
+ __raw_callee_save_pv_queued_spin_unlock_traced);
+ return 0;
+}
+
+void arch_contended_release_trace_unreg(void)
+{
+ void *cur = static_call_query(queued_spin_unlock);
+
+ if (cur == __raw_callee_save_native_queued_spin_unlock_traced)
+ static_call_update(queued_spin_unlock,
+ __raw_callee_save___native_queued_spin_unlock);
+ else if (cur == __raw_callee_save_pv_queued_spin_unlock_traced)
+ static_call_update(queued_spin_unlock,
+ __raw_callee_save___pv_queued_spin_unlock);
}
__visible bool __native_vcpu_is_preempted(long cpu)
next prev parent reply other threads:[~2026-08-07 16:00 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 7:15 [PATCH 0/5] locking/qspinlock: Add contended_release tracepoint Dmitry Ilvokhin
2026-08-04 7:15 ` [PATCH 1/5] x86/paravirt: Use static_call() for the paravirt spinlock ops Dmitry Ilvokhin
2026-08-04 19:00 ` Borislav Petkov
2026-08-04 19:54 ` Peter Zijlstra
2026-08-07 16:00 ` [tip: locking/core] " tip-bot2 for Peter Zijlstra
2026-08-04 7:15 ` [PATCH 2/5] locking: Factor out queued_spin_release() Dmitry Ilvokhin
2026-08-07 16:00 ` [tip: locking/core] " tip-bot2 for Dmitry Ilvokhin
2026-08-04 7:15 ` [PATCH 3/5] locking/qspinlock: Add contended_release tracepoint Dmitry Ilvokhin
2026-08-07 16:00 ` [tip: locking/core] " tip-bot2 for Dmitry Ilvokhin
2026-08-04 7:15 ` [PATCH 4/5] tracing/lock: Use TRACE_EVENT_FN() for contended_release Dmitry Ilvokhin
2026-08-07 16:00 ` [tip: locking/core] " tip-bot2 for Dmitry Ilvokhin
2026-08-04 7:15 ` [PATCH 5/5] x86/paravirt: Trace contended_release on unlock Dmitry Ilvokhin
2026-08-07 15:59 ` tip-bot2 for Dmitry Ilvokhin [this message]
2026-08-04 7:57 ` [PATCH 0/5] locking/qspinlock: Add contended_release tracepoint Juergen Gross
2026-08-04 10:39 ` Peter Zijlstra
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=178611839980.708.13617653015052531574.tip-bot2@tip-bot2 \
--to=tip-bot2@linutronix.de \
--cc=d@ilvokhin.com \
--cc=jgross@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=peterz@infradead.org \
--cc=x86@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
all inboxes | Powered by JetHome®