From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 455D0372674 for ; Tue, 3 Mar 2026 19:14:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.92.199 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772565255; cv=none; b=ETvQLAH0mVH6qkOx/SSiYsg5MhLfu37xVavXMeh89tvjZJAX8FRa3tTWPBuXbE8UI6M4pp5eB58HBXqNR0OtLsEAq821we1hj1HhXQyWki9CAbqPRqJHougCfUsE0AbX3nJgt260dC9S5z7xVfOU1rquCL6escOW4mx2Gxp2TNw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772565255; c=relaxed/simple; bh=P5G3ptog6OuKPMuF1xlN4VVb4oZRlQ5ACUZGC5SSeXc=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=XydpP3f/EoIX9XymwJPwBgZIlOnQxc0Drau95TXbwj6WIjDZ9siFWcDtykHVF0zK3PJ2oADlr399/2mbVbVnQSJ8arv7RWcJ1fR2jj+nyg6b+8ou6fpUkvBqsgebORo4Xzar0hRpbCsDqHiV/iyqyrAKm89foHRk+pzhL544c4E= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=h4kzjTE4; arc=none smtp.client-ip=90.155.92.199 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="h4kzjTE4" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=lezAGQMyd1lyVf/dM31y0o7l3p2SD8Q9B5FGvbRcQqQ=; b=h4kzjTE4y+LUyECGYuuEfOd01p l1tOhhM8uTfj2UeD6jDMxy393/ODUyBlVpA1QcaOu+T08YIrtQA+yGW/SB2X1DYoE0y9TPMXq/i9y kfBZYPHThQkv7UvGBPDH0gca8eNh1i+Hx7vbm5ExI9IsToaetZ30BYsdrUJn8rmVehhd3mIMPD1IE Bowu2UAxfXl9B6yUd9b7mRQ9Y1+sC6ZX6Ev1Y86YX5JvCTgldq3ONdqCbvhrxNaD+oPuPfnVXEMdU iyIjwfk+Hr/TThikT0eOaj2rtunONkU1zQkSTGpY3WBpAqi3x/Jwg0v75hO8n0pCNEynaL4afqQjk V2cIipEQ==; Received: from 2001-1c00-8d85-5700-266e-96ff-fe07-7dcc.cable.dynamic.v6.ziggo.nl ([2001:1c00:8d85:5700:266e:96ff:fe07:7dcc] helo=noisy.programming.kicks-ass.net) by desiato.infradead.org with esmtpsa (Exim 4.98.2 #2 (Red Hat Linux)) id 1vxVBz-00000003BWc-3dVm; Tue, 03 Mar 2026 19:14:04 +0000 Received: by noisy.programming.kicks-ass.net (Postfix, from userid 1000) id 93447300666; Tue, 03 Mar 2026 20:14:02 +0100 (CET) Date: Tue, 3 Mar 2026 20:14:02 +0100 From: Peter Zijlstra To: Michael Kelley Cc: Thomas Gleixner , LKML , Anna-Maria Behnsen , John Stultz , Stephen Boyd , Daniel Lezcano , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , "x86@kernel.org" , Frederic Weisbecker , Eric Dumazet Subject: Re: [patch 19/48] clockevents: Provide support for clocksource coupled comparators Message-ID: <20260303191402.GL1395266@noisy.programming.kicks-ass.net> References: <20260224163022.795809588@kernel.org> <20260224163430.010425428@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: On Tue, Mar 03, 2026 at 06:44:59PM +0000, Michael Kelley wrote: > > +static inline bool clockevent_set_next_coupled(struct clock_event_device *dev, ktime_t expires) > > +{ > > + u64 cycles; > > + > > + if (unlikely(!(dev->features & CLOCK_EVT_FEAT_CLOCKSOURCE_COUPLED))) > > + return false; > > + > > + if (unlikely(!ktime_expiry_to_cycles(dev->cs_id, expires, &cycles))) > > + return false; > > + > > + if (IS_ENABLED(CONFIG_GENERIC_CLOCKEVENTS_COUPLED_INLINE)) > > Since COUPLED_INLINE is always selected for x64, there's no way to add the Hyper-V > clockevent that is coupled but not inline. Adding the machinery to allow a second > inline clockevent type may not be worth it, but adding a second coupled but not > inline clockevent type on x64 should be supported. Thoughts? > > After fixing the u64 typo, and temporarily not always selecting COUPLED_INLINE in > arch/x86/Kconfig, the coupled Hyper-V TSC page clocksource and timer seem to work > correctly, though I'm still doing some testing. I'm also working on counting the number > of time reads to confirm the expected benefit. > > Michael > > > + arch_inlined_clockevent_set_next_coupled(cycles, dev); How about something deliciously insane like this? :-) Then you can update the static_call to point to an asm function of your choice that pretends to be WRMSR, while the 'native' case replaces the CALL with CS CS CS WRMSR. diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 42447b1e1dff..5426c6fd8ec8 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -1568,3 +1568,12 @@ SYM_FUNC_START(clear_bhb_loop) SYM_FUNC_END(clear_bhb_loop) EXPORT_SYMBOL_FOR_KVM(clear_bhb_loop) STACK_FRAME_NON_STANDARD(clear_bhb_loop) + +.pushsection .text, "ax" +SYM_CODE_START(x86_clockevent_set_next_coupled_thunk) + ANNOTATE_NOENDBR + UNWIND_HINT_FUNC + wrmsr + RET +SYM_CODE_END(x86_clockevent_set_next_coupled_thunk) +.popsection diff --git a/arch/x86/include/asm/clock_inlined.h b/arch/x86/include/asm/clock_inlined.h index b2dee8db2fb9..587f2005ef60 100644 --- a/arch/x86/include/asm/clock_inlined.h +++ b/arch/x86/include/asm/clock_inlined.h @@ -2,6 +2,9 @@ #ifndef _ASM_X86_CLOCK_INLINED_H #define _ASM_X86_CLOCK_INLINED_H +#include +#include +#include #include struct clocksource; @@ -13,10 +16,18 @@ static __always_inline u64 arch_inlined_clocksource_read(struct clocksource *cs) struct clock_event_device; +extern void x86_clockevent_set_next_coupled_thunk(void); + +DECLARE_STATIC_CALL(x86_clockevent_set_next_coupled, x86_clockevent_set_next_coupled_thunk); + static __always_inline void arch_inlined_clockevent_set_next_coupled(u64 cycles, struct clock_event_device *evt) { - native_wrmsrq(MSR_IA32_TSC_DEADLINE, cycles); + asm volatile("1: call " STATIC_CALL_TRAMP_STR(x86_clockevent_set_next_coupled) " \n" + "2:\n" + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR) + : ASM_CALL_CONSTRAINT + : "c" (MSR_IA32_TSC_DEADLINE), "a" ((u32)cycles), "d" ((u32)(cycles >> 32)) : "memory"); } #endif diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 60cab20b7901..194209f857b0 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -67,6 +67,7 @@ #include #include #include +#include #include "local.h" @@ -430,6 +431,8 @@ static int lapic_next_deadline(unsigned long delta, struct clock_event_device *e return 0; } +DEFINE_STATIC_CALL(x86_clockevent_set_next_coupled, x86_clockevent_set_next_coupled_thunk); + static int lapic_timer_shutdown(struct clock_event_device *evt) { unsigned int v; diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c index 61592e41a6b1..4821d155102f 100644 --- a/arch/x86/kernel/static_call.c +++ b/arch/x86/kernel/static_call.c @@ -3,6 +3,7 @@ #include #include #include +#include enum insn_type { CALL = 0, /* site call */ @@ -31,6 +32,11 @@ static const u8 retinsn[] = { RET_INSN_OPCODE, 0xcc, 0xcc, 0xcc, 0xcc }; */ static const u8 warninsn[] = { 0x67, 0x48, 0x0f, 0xb9, 0x3a }; +/* + * cs cs cs wrmsr + */ +static const u8 wrmsrinsn[] = { 0x2e, 0x2e, 0x2e, 0x0f, 0x30 }; + static u8 __is_Jcc(u8 *insn) /* Jcc.d32 */ { u8 ret = 0; @@ -78,6 +84,10 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, emulate = code; code = &warninsn; } + if (func == x86_clockevent_set_next_coupled_thunk) { + emulate = code; + code = &wrmsrinsn; + } break; case NOP: