* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: David Laight @ 2026-03-30 13:38 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Bird, Tim, pmladek@suse.com, rostedt@goodmis.org,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de, francesco@valla.it,
geert@linux-m68k.org, linux-embedded@vger.kernel.org,
linux-kernel@vger.kernel.org, x86, Paolo Bonzini,
Sean Christopherson, KVM
In-Reply-To: <87fr5ib6ks.ffs@tglx>
On Mon, 30 Mar 2026 00:42:59 +0200
Thomas Gleixner <tglx@kernel.org> wrote:
...
> If you want to have early timestamps then you have to go through the low
> level code on every architecture and do the proper sanity checks,
> enumerations, etc. no matter what. There is no guarantee that you can
> use any clock unconditionally during very early boot.
>
> As you have to do that anyway, there is _zero_ justification for an
> extra facility side stepping sched clock, which would just create
> another pile of technical debt.
>
> Quite the contrary, I'm going to get rid of technical debt:
>
> The get_cycles() related changes in tsc.h are going to end up in a
> obviously revised formal patch tomorrow as there is exactly _zero_
> requirement to provide this as a functional interface.
>
> 1) The default implementation in asm-generic returns 0
>
> Ergo any code depending on a functional implementation is broken
> by definition.
>
> 2) The ops/cycles metrics are as bogus as the infamous BogoMIPS metrics
>
> The "cycle" counter runs on almost all contemporary CPUs at a fixed
> frequency, which is completely unrelated to the actual CPU
> frequency and therefore to the actual CPU cycles.
>
> The only realistic metric is ops/sec and nothing else and that can
> be trivially achieved by using the generic time getter interfaces.
ops/sec is also horrid because you get all all the interrupt time getting
in the way.
Additionally it is only any use for relative comparisons done on exactly
the same hardware, and is entirely useless is you are trying to show that
a short code loop is running at/near the theoretical rate.
The only thing I've found that works is the PERF_COUNT_HW_CPU_CYCLES
counter (low 32 bits).
In userspace you do have to directly read the register (rather than using
the library function - too much overhead), and ignore any silly values
generated by interrupts and process switches.
But it is accurate enough to time single function calls and see the
effect of things like mispredicted branches and the data-dependency of
divide instructions.
But I do agree that the TSC is entirely useless for measuring what it was
originally intended to measure.
David
>
> Those might end up resulting in bogus benchmark results too if the
> underlying clocksource is jiffies, but that's again a matter of
> accepting reality.
>
> If people really mandate that ops/bogo_cycles is required for the
> very wrong reasons, then I'm happy to bring it back with a global
> name change from get_cycles() to get_bogo_cycles() which excludes
> it from any serious usage including printk.
>
> Thanks,
>
> tglx
^ permalink raw reply
* RE: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Bird, Tim @ 2026-03-30 20:42 UTC (permalink / raw)
To: Thomas Gleixner, pmladek@suse.com, rostedt@goodmis.org,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de
Cc: francesco@valla.it, geert@linux-m68k.org,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <87jyuvboo2.ffs@tglx>
Thomas,
Your response is both very helpful and a bit frustrating. See below.
> -----Original Message-----
> From: Thomas Gleixner <tglx@kernel.org>
> Tim!
>
> On Fri, Mar 27 2026 at 18:48, Tim Bird wrote:
> > Well, this is using get_cycles(), which already exists on most architectures.
>
> The fact that get_cycles() exists does not make it a good choice. There
> is a reason why anything which deals with even remotely reliable time
> requirements stopped using it. It's still there as a low level
> architecture specific interface and most other usage is purely
> historical or wrong to begin with and should be removed completely.
>
> A lot of people spent a significant amount of time to get rid of this
> ill defined mechanism and it's just sad that they did not manage to
> eliminate it completely.
>
That's good to know. Thanks. For what it's worth, I wouldn't describe
my desired usage as being for remotely reliable time requirements.
> > This patch just adds a funky way to use cycles (which are available
> > from power on, rather than from the start of kernel timekeeping) to
> > allow saving timing data for some early printks (usually about 20 to
> > 60 printks).
>
> I can see that, but I'm not accepting yet another ill defined glued on
> mechanism which relies on a historical ill defined mistake.
>
> > Also, my current plan is to back off of adjusting the offset of
> > unrelated (non-pre-time_init()) printks, and limit the effect in the
> > system to just those first early (pre-time_init()) printks. The
> > complication to add an offset to all following printks was just to
> > avoid a discontinuity in printk timestamps, once time_init() was
> > called and "real" timestamps started producing non-zeros. Given how
> > confusing this seems to have made things, I'm thinking of backing off
> > of that approach.
>
> This discontinuity results from the fact that you glued it into the
> printk code and sched_clock() does not know about it.
Yes. Of course. That was intentional.
>
> >> printk()
> >>
> >> time_ns = local_clock();
> > that's ts_nsec = local_clock()
>
> That obviously changes the illustrative nature of my narrative
> significantly. Thanks for pointing it out.
I was confused by the variable in your narrative, since I hadn't seen it.
I grepped and reexamined the code. I clarified what I believed to
be the variable you were referencing. I could have worded this better,
but I don't believe you needed to respond with sarcasm.
>
> >> As this needs to be supported by the architecture/platform in any case
> >> there is close to zero benefit from creating complicated generic
> >> infrastructure for this.
> >
> > The problem with this is that tsc_early_uncalibrated() can't return
> > nanoseconds until after calibration.
>
> In theory it could for most modern x86 CPUs as they advertise the
> nominal TSC frequency in CPUID. Other architectures have well known
> clocksource frequencies, e.g. S390 has a known nominal frequency of 1GHz
> (IIRC).
>
> But that does not solve any of the other problems. See below.
>
> > I don't think it's a good idea to returns cycles sometimes and nanoseconds
> > at other times, from a deep-seated timing function like this.
> > Also tsc_available() might itself depend on initialization that hasn't happened yet
> > (in early boot).
>
> Access to the TSC requires the X86_FEATURE_TSC bit being set, which
> happens in early_cpu_init(). Before that get_cycles() returns firmly 0.
>
Yes.
> > My approach of saving cycles in ts_nsec for the early printks works
> > because there's a limited number of places (only 2) inside the printk
> > code where ts_nsec is accessed, meaning that the code to detect a
> > cycles value instead of a nanoseconds value can be constrained to just
> > those two places. Basically, I'm doing the conversion from cycles to
> > nanoseconds at printk presentation time, rather than at the time of
> > printk message submission.
>
> I know, but that again requires to add more ill defined infrastructure.
Quite possibly you are right. Are you saying that the general concept
of saving cycles to be converted later to nanoseconds is the ill-defined
infrastructure, or are you saying using get_cycles() is not safe or
accurate enough?
From what you say below, I believe you are saying the latter.
If you don't like the deferred cycles conversion, that's fine. I like the approach
you demonstrated in your subsequent PoC patch to show super-early
tsc calibration (using a kernel param). I can certainly live with 14 microseconds
of missed optimization information, if that's all it is.
>
> We are not aiming to add more, we want to get rid of it completely to
> the extent possible.
OK.
>
> > The approach that I originally started with
> > (see https://lore.kernel.org/linux-embedded/39b09edb-8998-4ebd-a564-7d594434a981@bird.org/
> > was to use hardcoded multiplier and shift values for converting from cycles
> > to nanoseconds. These multiplier and shift values would be set at kernel
> > configuration time (ie, using CONFIG values).
>
> Which makes it unusable for distro kernels and therefore a non-starter.
Can you elaborate on this? Indeed distro kernels would not be able to pre-set
TCS calibration values, and would not turn on this feature (in that version
of the patch) for production release kernels. But it sounds like you are saying that
anything that requires a configuration that is non-general (or indeed used
temporarily during development) is not acceptable upstream. Is that your position?
This "feature" is intended as a tool for developers who are optimizing Linux
kernel boot time. (I'm not sure who else would be interested in getting
timing data for these (currently zero-timestamped) printks during the
first 100-400 milliseconds of kernel boot). This would be, I believe, developers
who can change their configs and compile their kernels. The v1 version of
the patch included calculations and printks to help developers set the
calibration values for their hardware, so it was not targeted at my machine
only.
This patch is part of a larger effort on my part to help automate boot-time tuning
of the kernel. Many other parts of that effort rely on reconfiguration and recompilation
of the kernel, which makes the whole thing a development-time effort, not so much
a run-time, end-user, or production-level feature. And very much not a thing that
can be accomplished with distro-only configs.
>
> > There are other approaches, but none really work early enough in the
> > kernel boot to not be a pain. The goal is to provide timing info
> > before: timekeeping init, jiffies startup, and even CPU features
> > determination,
>
> As I pointed out before that's wishful thinking:
>
> You _cannot_ access a resource before it has been determined to be
> available.
>
> Period.
>
> It does not matter at all if _you_ know for sure that it is the case in
> _your_ personal setup.
I used get_cycles(), which has a check for availability in it, so the patch didn't
access a resource before it was determined to be available.
It sounds like you're responding to my wording above and not the patch itself.
It is not my intent to handle only my personal setup.
Your help to make sure that this feature is as general as possible is much appreciated.
>
> > and to keep the effect narrow -- limited only to printks, and the
> > first few pre-time_init() printk messages, at that.
>
> Either it is solved in a generic way or we have to agree that it's not
> solvable at all.
I disagree that solving this limited problem (zero-valued timestamps
in early boot) has to be solved in a generic way.
I already limited the solution space to only processors that I believed
had reliable, pre-kernel-initialized cycle generators.
I think it's fair to have a specialized solution to a specialized problem, if
it can be made to have very limited effect on other code.
I tried to avoid affecting any other timekeeping mechanism
(ie re-engineering local_clock), specifically to avoid unwanted
side effects.
> Your narrow effect argument is bogus and you know that
> very well.
This sounds like you believe I am arguing in bad faith.
I don't believe that I am.
>
> > I'm now researching a suggestion from Shashank Balaji to use the
> > existing calibration data from tsc initialization, which might
> > simplify the current patch even further. I'll make sure to CC you on
> > the next version of the patch.
>
> If you want to use the calibration data from tsc_early_init() then you
> achieve exactly _nothing_ because tsc_early_init() also enables the
> early sched clock on bare metal. On a VM with KVM clock available the
> KVM clock setup enables the early sched clock even before that via
> init_hypervisor_platform().
In the v3 patch, the timing of sched_clock activation is independent of the
timing of the use of the tsc calibration values. I don't understand
how this comment is relevant to my patch.
>
> The early TSC init happens in setup_arch() via tsc_early_init() and it's
> completely unclear whether you can always access the TSC safely before
> that unconditionally due to SNP, which requires to enable the secure TSC
> first. There is a reason why all of this is ordered the way it is.
OK. Thanks for that info. I'll take a look at that.
What happens if you try a rdtsc() before tsc_early_init? If it returns zero, I can
live with that. If it faults or returns random data that's a problem.
>
> While reading TSC way before that might work on bare metal and in most
> VMs, it's not guaranteed to be safe unconditionally unless someone sits
> down and provides proof to the contrary. As always I'm happy to be
> proven wrong.
>
> When tsc_early_init() was introduced for the very same reason you are
> looking into that, quite some people spent a lot of time to come up with
> a solution which was deemed safe enough to be used unconditionally.
>
> Please consult the LKML archive for the full history. The commit links
> will give you a proper starting point.
OK - thanks for the information and the pointers. get_cycles() does
have a CPU features check, so my access to the tsc was not completely
unconditional. I'll do some more research here and try to make the
ultimate solution as safe as possible.
> That said, I completely understand the itch you are trying to scratch
> and I'm the least person to prevent an architecturally sound solution,
> but I'm also the first person to NAK any attempt which is based on
> uninformed claims and 'works for me' arguments.
Well, one of the purposes of posting patches is to get feedback
on different approaches. I'm honestly not trying to create a solution that only
works on my hardware. But neither am I trying to boil the ocean
here.
It's not clear to me that there's much harm in having
a single discontinuity early in the printk timestamps. No one has told
me yet that printk timestamps absolutely MUST be monotonically
increasing, everywhere.
Trying to solve that issue led to a more convoluted solution than
my first approach (deferred cycles conversion versus compile-time
calibration data).
I also don't think there's much harm if the data for these few printks
is unavailable or wrong on some hardware. Maybe that's an area where
we differ in opinion.
>
> The only clean way to solve this cleanly is moving the sched clock
> initialization to the earliest point possible and accepting that due to
> hardware, enumeration and virtualization constraints this point might be
> suboptimal. Everything else is just an attempt to defy reality.
I think we're willing to accept different areas of sub-optimality.
I can live with having to configure the feature, and statically configure
the TSC clock calibration, at the expense of non-monotonic printk
timestamps for the early printks.
Personally, I think that altering sched_clock or any other
kernel timekeeping is overkill for this.
I do like the solution proposed in your patch. I considered a
solution using an early-parsed kernel command line arg, but didn't
know how early I could do that. I'll review your patch. Thanks!
And I appreciate the time you took to educate me about some of the
other issues involved (especially secure TSC and possible TSC unavailability,
and VM timekeeping issues, which complicate this.)
Regards,
-- Tim
^ permalink raw reply
* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Geert Uytterhoeven @ 2026-03-31 8:17 UTC (permalink / raw)
To: Bird, Tim
Cc: Thomas Gleixner, pmladek@suse.com, rostedt@goodmis.org,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de, francesco@valla.it,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <MW5PR13MB5632B55CAD0BEA34188EE88EFD52A@MW5PR13MB5632.namprd13.prod.outlook.com>
Hi TIm,
On Mon, 30 Mar 2026 at 22:42, Bird, Tim <Tim.Bird@sony.com> wrote:
> > From: Thomas Gleixner <tglx@kernel.org>
> > > There are other approaches, but none really work early enough in the
> > > kernel boot to not be a pain. The goal is to provide timing info
> > > before: timekeeping init, jiffies startup, and even CPU features
> > > determination,
> >
> > As I pointed out before that's wishful thinking:
> >
> > You _cannot_ access a resource before it has been determined to be
> > available.
> >
> > Period.
> >
> > It does not matter at all if _you_ know for sure that it is the case in
> > _your_ personal setup.
>
> I used get_cycles(), which has a check for availability in it, so the patch didn't
> access a resource before it was determined to be available.
Note that such a check is only available in the MIPS and x86 versions.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* RE: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Thomas Gleixner @ 2026-03-31 9:10 UTC (permalink / raw)
To: Bird, Tim, pmladek@suse.com, rostedt@goodmis.org,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de
Cc: francesco@valla.it, geert@linux-m68k.org,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <MW5PR13MB5632B55CAD0BEA34188EE88EFD52A@MW5PR13MB5632.namprd13.prod.outlook.com>
Tim!
On Mon, Mar 30 2026 at 20:42, Tim Bird wrote:
>> From: Thomas Gleixner <tglx@kernel.org>
>> > The approach that I originally started with
>> > (see https://lore.kernel.org/linux-embedded/39b09edb-8998-4ebd-a564-7d594434a981@bird.org/
>> > was to use hardcoded multiplier and shift values for converting from cycles
>> > to nanoseconds. These multiplier and shift values would be set at kernel
>> > configuration time (ie, using CONFIG values).
>>
>> Which makes it unusable for distro kernels and therefore a non-starter.
>
> Can you elaborate on this? Indeed distro kernels would not be able to pre-set
> TCS calibration values, and would not turn on this feature (in that version
> of the patch) for production release kernels. But it sounds like you are saying that
> anything that requires a configuration that is non-general (or indeed used
> temporarily during development) is not acceptable upstream. Is that your position?
The point is that we really want to provide general available
functionality as much as we can. The problem with all these special
features is that they add to the overall maintainence burden. We do them
when there is no other way.
> This "feature" is intended as a tool for developers who are optimizing Linux
> kernel boot time. (I'm not sure who else would be interested in getting
> timing data for these (currently zero-timestamped) printks during the
> first 100-400 milliseconds of kernel boot). This would be, I believe, developers
The existing early TSC enablement on x86 starts providing printk
timestamps at about 30ms after boot out of the box when I remove
'earlyprintk' from the command line on the same VM/host combo I tested
the PoC. That too uses sched clock and not some special mechanism.
The real question is whether this boot time optimization really needs to
have earlier time stamps and whether the hacks required for that are
actually worth it.
> This patch is part of a larger effort on my part to help automate
> boot-time tuning of the kernel. Many other parts of that effort rely
> on reconfiguration and recompilation of the kernel, which makes the
> whole thing a development-time effort, not so much a run-time,
> end-user, or production-level feature. And very much not a thing that
> can be accomplished with distro-only configs.
I understand that, but when you can achieve it by utilizing what's there
already just by providing access to the TSC at the earliest possible
time, then adding new infrastructure is obviously not the right thing to
do.
>>
>> > There are other approaches, but none really work early enough in the
>> > kernel boot to not be a pain. The goal is to provide timing info
>> > before: timekeeping init, jiffies startup, and even CPU features
>> > determination,
>>
>> As I pointed out before that's wishful thinking:
>>
>> You _cannot_ access a resource before it has been determined to be
>> available.
>>
>> Period.
>>
>> It does not matter at all if _you_ know for sure that it is the case in
>> _your_ personal setup.
>
> I used get_cycles(), which has a check for availability in it, so the patch didn't
> access a resource before it was determined to be available.
> It sounds like you're responding to my wording above and not the patch itself.
Correct: '... and even CPU feature determination'
>> Either it is solved in a generic way or we have to agree that it's not
>> solvable at all.
>
> I disagree that solving this limited problem (zero-valued timestamps
> in early boot) has to be solved in a generic way.
> I already limited the solution space to only processors that I believed
> had reliable, pre-kernel-initialized cycle generators.
>
> I think it's fair to have a specialized solution to a specialized problem, if
> it can be made to have very limited effect on other code.
This 'my problem is special' mindset is exactly what frustrates me to be
honest. It causes technical debt and I've spent several decades of work to
mop up the technical debt caused by it.
> I tried to avoid affecting any other timekeeping mechanism
> (ie re-engineering local_clock), specifically to avoid unwanted
> side effects.
As I demonstrated there is no need to even touch printk or local clock
at all.
>> The early TSC init happens in setup_arch() via tsc_early_init() and it's
>> completely unclear whether you can always access the TSC safely before
>> that unconditionally due to SNP, which requires to enable the secure TSC
>> first. There is a reason why all of this is ordered the way it is.
>
> OK. Thanks for that info. I'll take a look at that.
> What happens if you try a rdtsc() before tsc_early_init? If it returns zero, I can
> live with that. If it faults or returns random data that's a problem.
As I said it's unclear.
>> The only clean way to solve this cleanly is moving the sched clock
>> initialization to the earliest point possible and accepting that due to
>> hardware, enumeration and virtualization constraints this point might be
>> suboptimal. Everything else is just an attempt to defy reality.
>
> I think we're willing to accept different areas of sub-optimality.
> I can live with having to configure the feature, and statically configure
> the TSC clock calibration, at the expense of non-monotonic printk
> timestamps for the early printks.
>
> Personally, I think that altering sched_clock or any other
> kernel timekeeping is overkill for this.
I'm not asking to change any of that. I clearly pointed out to you
in my first reply that the existing local clock path is where you want
to add your 'even earlier' access.
That said, let me come back to the question I asked earlier.
The existing early sched clock enablement, which happens either in the
hypervisor detection for VMs and/or tsc_early_init() is around 30ms into
the boot process.
The initialization which happens before that is pretty much the bare
minimum to get so far. The optimization potential of that stage is very
close to zero.
So the real good question is whether the extra information of how long
that earliest init takes is really relevant to the goal of optimizing
boot time. The expensive part of the boot process definitely comes after
that.
Thanks,
tglx
^ permalink raw reply
* RE: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Thomas Gleixner @ 2026-03-31 23:36 UTC (permalink / raw)
To: Bird, Tim, pmladek@suse.com, rostedt@goodmis.org,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de
Cc: francesco@valla.it, geert@linux-m68k.org,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <87jyus9xft.ffs@tglx>
Tim!
On Tue, Mar 31 2026 at 11:10, Thomas Gleixner wrote:
> So the real good question is whether the extra information of how long
> that earliest init takes is really relevant to the goal of optimizing
> boot time. The expensive part of the boot process definitely comes after
> that.
That actually made me curious and so I hacked up the kernel with the
patch below to compensate for the difference between:
x86_64_start_reservations()
i.e. the C entry point of the kernel and the actual earliest
point (ASM entry code aside) where the kernel can take a
timestamp, which is modulo the sanity checks in the PoC the same
thing, right?
and
tsc_early_init()
where the upstream kernel enables TSC sched clock today with all
sanity checks and enumeration in place.
Here is the result on a bare metal 256 CPU machine:
[ 0.000000] Linux version 7.0.0-rc3-dirty ...
....
[ 0.000000] tsc: Detected 2100.000 MHz processor
[ 0.012482] e820: update [mem 0x00000000-0x00000fff] System RAM ==> device reserved
That's ~12ms of time which is not accounted for in the overall boot time
until the machine reaches the init process:
[ 12.289141] Run /init as init process
That means we are talking about ~0.1% of overall boot time in this case.
Starting a 4 CPU guest with the same kernel image on the same physical
machine and additionally 'no-kvmclock' on the command line to make the
hack work:
[ 0.000000] Linux version 7.0.0-rc3-dirty ...
...
[ 0.000000] tsc: Detected 2094.965 MHz processor
[ 0.015122] last_pfn = 0x280000 max_arch_pfn = 0x400000000
Unsurpringly it takes a bit longer because during that phase the guest
takes a gazillion of vmexits.
[ 0.995082] Run /init as init process
Now in this 4 CPU case we are talking about 1.5% of the overall boot
time.
With the same setup and 32 CPUs in the VM:
[ 0.015150] e820: remove [mem 0x000a0000-0x000fffff] System RAM
The initial phase takes 30us more than with 4 CPUs, which is in the
noise and the machine ends up in init at:
[ 3.329398] Run /init as init process
which means in total we are up to 0.45% of the overall boot time now.
I'm honestly confused. May I politely ask which problem you are trying
to solve?
Thanks,
tglx
---
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -291,6 +291,8 @@ asmlinkage __visible void __init __noret
x86_64_start_reservations(real_mode_data);
}
+extern u64 start_ts;
+
void __init __noreturn x86_64_start_reservations(char *real_mode_data)
{
/* version is always not zero if it is copied */
@@ -307,6 +309,8 @@ void __init __noreturn x86_64_start_rese
break;
}
+ start_ts = rdtsc();
+
start_kernel();
}
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -53,6 +53,9 @@ static DEFINE_STATIC_KEY_FALSE_RO(__use_
int tsc_clocksource_reliable;
+extern u64 start_ts;
+u64 start_ts;
+
static int __read_mostly tsc_force_recalibrate;
static struct clocksource_base art_base_clk = {
@@ -207,7 +210,7 @@ static void __init cyc2ns_init_boot_cpu(
struct cyc2ns *c2n = this_cpu_ptr(&cyc2ns);
seqcount_latch_init(&c2n->seq);
- __set_cyc2ns_scale(tsc_khz, smp_processor_id(), rdtsc());
+ __set_cyc2ns_scale(tsc_khz, smp_processor_id(), start_ts);
}
/*
^ permalink raw reply
* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Steven Rostedt @ 2026-04-01 0:05 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Bird, Tim, pmladek@suse.com, senozhatsky@chromium.org,
Shashank Balaji, john.ogness@linutronix.de, francesco@valla.it,
geert@linux-m68k.org, linux-embedded@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <87ldf78tc5.ffs@tglx>
On Wed, 01 Apr 2026 01:36:26 +0200
Thomas Gleixner <tglx@kernel.org> wrote:
> On Tue, Mar 31 2026 at 11:10, Thomas Gleixner wrote:
> > So the real good question is whether the extra information of how long
> > that earliest init takes is really relevant to the goal of optimizing
> > boot time. The expensive part of the boot process definitely comes after
> > that.
>
> That actually made me curious and so I hacked up the kernel with the
> patch below to compensate for the difference between:
>
> x86_64_start_reservations()
>
> i.e. the C entry point of the kernel and the actual earliest
> point (ASM entry code aside) where the kernel can take a
> timestamp, which is modulo the sanity checks in the PoC the same
> thing, right?
>
> and
>
> tsc_early_init()
>
> where the upstream kernel enables TSC sched clock today with all
> sanity checks and enumeration in place.
>
> Here is the result on a bare metal 256 CPU machine:
>
> [ 0.000000] Linux version 7.0.0-rc3-dirty ...
>
> ....
>
> [ 0.000000] tsc: Detected 2100.000 MHz processor
> [ 0.012482] e820: update [mem 0x00000000-0x00000fff] System RAM ==> device reserved
>
> That's ~12ms of time which is not accounted for in the overall boot time
> until the machine reaches the init process:
>
> [ 12.289141] Run /init as init process
12 seconds! Holly crap, that would fail every Chromebook requirement we
have. In most cases, we shoot for a 3 second boot up and 8 second max.
That's from hitting the power button to login screen. FYI, 30ms is
considered a really long time.
We spend a lot of time looking at every thing that slows down the boot
process, and yes we do a lot of tricks in user space as well (see
ureadahead[1]).
I'm sure there's various devices that have issues between the kernel C
starting point and where timing begins. When I was looking into boot times,
I did find that the biggest issue with boot up was the initcalls. They are
all serial. If one sleeps, it causes everything to back up. I would love to
have initcalls have more parallelism, but there's a lot of code that
depends on things running in serial :-(
Point being, I'm sure Tim is worried about devices that require fast boot
up times. Not machines with 256 CPUs.
I haven't needed to look at what is happening before time stamps are
running, as we track that time via the firmware timestamps. I'm just
pointing out that the machine you used in this example isn't the target of
the work that is looking into fast bootup times.
-- Steve
[1] https://github.com/rostedt/ureadahead
^ permalink raw reply
* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Brian Masney @ 2026-04-01 1:16 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Bird, Tim, pmladek@suse.com, rostedt@goodmis.org,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de, francesco@valla.it,
geert@linux-m68k.org, linux-embedded@vger.kernel.org,
linux-kernel@vger.kernel.org, Eric Chanudet
In-Reply-To: <87ldf78tc5.ffs@tglx>
Hi Thomas,
On Wed, Apr 01, 2026 at 01:36:26AM +0200, Thomas Gleixner wrote:
> On Tue, Mar 31 2026 at 11:10, Thomas Gleixner wrote:
> > So the real good question is whether the extra information of how long
> > that earliest init takes is really relevant to the goal of optimizing
> > boot time. The expensive part of the boot process definitely comes after
> > that.
>
> That actually made me curious and so I hacked up the kernel with the
> patch below to compensate for the difference between:
>
> x86_64_start_reservations()
>
> i.e. the C entry point of the kernel and the actual earliest
> point (ASM entry code aside) where the kernel can take a
> timestamp, which is modulo the sanity checks in the PoC the same
> thing, right?
>
> and
>
> tsc_early_init()
>
> where the upstream kernel enables TSC sched clock today with all
> sanity checks and enumeration in place.
>
> Here is the result on a bare metal 256 CPU machine:
>
> [ 0.000000] Linux version 7.0.0-rc3-dirty ...
>
> ....
>
> [ 0.000000] tsc: Detected 2100.000 MHz processor
> [ 0.012482] e820: update [mem 0x00000000-0x00000fff] System RAM ==> device reserved
>
> That's ~12ms of time which is not accounted for in the overall boot time
> until the machine reaches the init process:
>
> [ 12.289141] Run /init as init process
>
> That means we are talking about ~0.1% of overall boot time in this case.
>
> Starting a 4 CPU guest with the same kernel image on the same physical
> machine and additionally 'no-kvmclock' on the command line to make the
> hack work:
>
> [ 0.000000] Linux version 7.0.0-rc3-dirty ...
>
> ...
>
> [ 0.000000] tsc: Detected 2094.965 MHz processor
> [ 0.015122] last_pfn = 0x280000 max_arch_pfn = 0x400000000
>
> Unsurpringly it takes a bit longer because during that phase the guest
> takes a gazillion of vmexits.
>
> [ 0.995082] Run /init as init process
>
> Now in this 4 CPU case we are talking about 1.5% of the overall boot
> time.
>
> With the same setup and 32 CPUs in the VM:
>
> [ 0.015150] e820: remove [mem 0x000a0000-0x000fffff] System RAM
>
> The initial phase takes 30us more than with 4 CPUs, which is in the
> noise and the machine ends up in init at:
>
> [ 3.329398] Run /init as init process
>
> which means in total we are up to 0.45% of the overall boot time now.
>
> I'm honestly confused. May I politely ask which problem you are trying
> to solve?
A recent example of where this was a problem was in the creation of the
arm64 linear map:
https://lore.kernel.org/all/20240412131908.433043-1-ryan.roberts@arm.com/
The boot time was all reported as 0, however we could tell there was a
boot delay based on the timing of the firmware / other linux logs in the
serial console. Eric Chanudet @ Red Hat (CCed) used the cntvct arch
counters on arm64 to track down this unreported time to the linear map
creation.
With this patch set, on a 32GB RAM arm64 system we have the linear map
creation time went from ~350ms to 25ms. Again, the boot time was all
reported as 0 in dmesg.
What Tim is trying to do is to identify if we have points like this on
other systems, or if boot regressions are introduced in the future.
Brian
^ permalink raw reply
* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Geert Uytterhoeven @ 2026-04-01 7:36 UTC (permalink / raw)
To: Steven Rostedt
Cc: Thomas Gleixner, Bird, Tim, pmladek@suse.com,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de, francesco@valla.it,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20260331200519.58930ece@gandalf.local.home>
On Wed, 1 Apr 2026 at 02:04, Steven Rostedt <rostedt@goodmis.org> wrote:
> On Wed, 01 Apr 2026 01:36:26 +0200
> Thomas Gleixner <tglx@kernel.org> wrote:
> > [ 12.289141] Run /init as init process
>
> 12 seconds! Holly crap, that would fail every Chromebook requirement we
> have. In most cases, we shoot for a 3 second boot up and 8 second max.
So that's why my Sony HD Handycam never boots Linux, but instead still
resumes the system Tim suspended 18 years ago ;-)
Looks like the old CE Linux Forum Boot Time Working Group needs more
blood...
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Thomas Gleixner @ 2026-04-01 8:33 UTC (permalink / raw)
To: Steven Rostedt
Cc: Bird, Tim, pmladek@suse.com, senozhatsky@chromium.org,
Shashank Balaji, john.ogness@linutronix.de, francesco@valla.it,
geert@linux-m68k.org, linux-embedded@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20260331200519.58930ece@gandalf.local.home>
Steven!
On Tue, Mar 31 2026 at 20:05, Steven Rostedt wrote:
> On Wed, 01 Apr 2026 01:36:26 +0200
> Thomas Gleixner <tglx@kernel.org> wrote:
>> That's ~12ms of time which is not accounted for in the overall boot time
>> until the machine reaches the init process:
>>
>> [ 12.289141] Run /init as init process
>
> 12 seconds! Holly crap, that would fail every Chromebook requirement we
> have. In most cases, we shoot for a 3 second boot up and 8 second max.
> That's from hitting the power button to login screen. FYI, 30ms is
> considered a really long time.
Which 30ms are you talking about?
The first timestamp is 12ms into the boot on bare metal as you can see
from the quoted text above. On a 4 CPU VM running on that very same host
it's 15ms due to the VM exit costs.
Which means with your 3 seconds aim, that's ~0.4% of the overall
time. Even with your 30ms it's still only 1% according to my old school
understanding of math.
> Point being, I'm sure Tim is worried about devices that require fast boot
> up times. Not machines with 256 CPUs.
You're clearly missing the point.
As I've demonstrated the time until the first time stamp is available
has nothing to do with the number of CPUs and is more or less constant:
VM with 4 CPUs:
[ 0.015122] last_pfn = 0x280000 max_arch_pfn = 0x400000000
VM with 32 CPUs:
[ 0.015150] e820: remove [mem 0x000a0000-0x000fffff] System RAM
The costs of the number of CPUs comes later in the boot process:
VM with 4 CPUs:
[ 0.995082] Run /init as init process
VM with 32 CPUs:
[ 3.329398] Run /init as init process
No?
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Thomas Gleixner @ 2026-04-01 9:19 UTC (permalink / raw)
To: Brian Masney
Cc: Bird, Tim, pmladek@suse.com, rostedt@goodmis.org,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de, francesco@valla.it,
geert@linux-m68k.org, linux-embedded@vger.kernel.org,
linux-kernel@vger.kernel.org, Eric Chanudet
In-Reply-To: <acxx9Bt0N3nhtLgN@redhat.com>
Brian!
On Tue, Mar 31 2026 at 21:16, Brian Masney wrote:
> With this patch set, on a 32GB RAM arm64 system we have the linear map
> creation time went from ~350ms to 25ms. Again, the boot time was all
> reported as 0 in dmesg.
Impressive!
> What Tim is trying to do is to identify if we have points like this on
> other systems, or if boot regressions are introduced in the future.
I completely understand that and as I clearly said from the very
beginning I'm not trying to prevent that at all.
What I'm arguing against is the approach of creating an ad hoc wart in
printk as that's creating yet another long term maintenance burden.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Steven Rostedt @ 2026-04-01 15:12 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Bird, Tim, pmladek@suse.com, senozhatsky@chromium.org,
Shashank Balaji, john.ogness@linutronix.de, francesco@valla.it,
geert@linux-m68k.org, linux-embedded@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <87h5pv84h5.ffs@tglx>
On Wed, 01 Apr 2026 10:33:26 +0200
Thomas Gleixner <tglx@kernel.org> wrote:
> Steven!
>
> On Tue, Mar 31 2026 at 20:05, Steven Rostedt wrote:
> > On Wed, 01 Apr 2026 01:36:26 +0200
> > Thomas Gleixner <tglx@kernel.org> wrote:
> >> That's ~12ms of time which is not accounted for in the overall boot time
> >> until the machine reaches the init process:
> >>
> >> [ 12.289141] Run /init as init process
> >
> > 12 seconds! Holly crap, that would fail every Chromebook requirement we
> > have. In most cases, we shoot for a 3 second boot up and 8 second max.
> > That's from hitting the power button to login screen. FYI, 30ms is
> > considered a really long time.
>
> Which 30ms are you talking about?
Sorry, that was from your previous email:
The existing early TSC enablement on x86 starts providing printk
timestamps at about 30ms after boot out of the box when I remove
'earlyprintk' from the command line on the same VM/host combo I tested
the PoC. That too uses sched clock and not some special mechanism.
We actually try to account for pretty much every 10ms and if there's a 30ms
gap somewhere, we look to see what it was doing.
>
> As I've demonstrated the time until the first time stamp is available
> has nothing to do with the number of CPUs and is more or less constant:
So my question is, if something changes in this time frame, where it goes
from 30ms to 300ms, how would we find out?
Again, for Chromebooks, we get these timestamps from the firmware and it's
very useful.
-- Steve
^ permalink raw reply
* Re: [PATCH v3] printk: fix zero-valued printk timestamps in early boot
From: Thomas Gleixner @ 2026-04-01 19:37 UTC (permalink / raw)
To: Steven Rostedt
Cc: Bird, Tim, pmladek@suse.com, senozhatsky@chromium.org,
Shashank Balaji, john.ogness@linutronix.de, francesco@valla.it,
geert@linux-m68k.org, linux-embedded@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20260401111244.5057a89c@gandalf.local.home>
On Wed, Apr 01 2026 at 11:12, Steven Rostedt wrote:
> On Wed, 01 Apr 2026 10:33:26 +0200
> Thomas Gleixner <tglx@kernel.org> wrote:
>> As I've demonstrated the time until the first time stamp is available
>> has nothing to do with the number of CPUs and is more or less constant:
>
> So my question is, if something changes in this time frame, where it goes
> from 30ms to 300ms, how would we find out?
>
> Again, for Chromebooks, we get these timestamps from the firmware and it's
> very useful.
I understand all of that and I'm not opposed to make that happen if it's
integrated properly into sched clock as I demonstrated with the PoC
hack.
Thanks,
tglx
^ permalink raw reply
* RE: Earlier tsc init patch (was RE: [PATCH v3] printk: fix zero-valued printk timestamps in early boot)
From: Bird, Tim @ 2026-04-07 20:34 UTC (permalink / raw)
To: Thomas Gleixner, pmladek@suse.com, rostedt@goodmis.org,
senozhatsky@chromium.org, Shashank Balaji,
john.ogness@linutronix.de
Cc: francesco@valla.it, geert@linux-m68k.org,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org,
x86@kernel.org, Paolo Bonzini, Sean Christopherson, KVM
In-Reply-To: <87fr5ib6ks.ffs@tglx>
Thomas,
Thanks for posting this PoC patch. I found the code interesting and informative.
Please see my comments below.
> -----Original Message-----
> From: Thomas Gleixner <tglx@kernel.org>
> Tim!
>
> On Sat, Mar 28 2026 at 22:59, Thomas Gleixner wrote:
> > The only clean way to solve this cleanly is moving the sched clock
> > initialization to the earliest point possible and accepting that due to
> > hardware, enumeration and virtualization constraints this point might be
> > suboptimal. Everything else is just an attempt to defy reality.
>
> As the wheather was lousy, I sat down for a couple of hours and
> implemented the obviously incomplete PoC below for illustration.
>
> As the FIXME comment in tsc_early_boot_setup() tells clearly, this is far
> from complete and needs way more thoughts and scrutiny, but it's good
> enough to prove the point:
>
> [ 0.000019] tsc: Boot sched clock enabled
>
> As early as possible, but with at least the minimal safe guards in place.
>
> [ 0.000041] Linux version 7.0.0-rc5+ (tglx@tglx-pladt) (gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44) #893 SMP
> PREEMPT_DYNAMIC Sun Mar 29 21:38:08 CEST 2026
> [ 0.000043] Command line: BOOT_IMAGE=/boot/vmlinuz-7.0.0-rc5+ root=UUID=fa44d501-1716-402a-8602-6315c3166f7b ro console=tty0
> console=ttyS0,115200n8 ftrace_dump_on_oops earlyprintk=ttyS0,115200n8 tsc_early_khz=2095070 no-kvmclock
>
> 1) tsc_early_khz is required because KVM does not provide the frequency
> leaf.
>
> 2) no-kvmclock is required because KVM thinks it is more important than
> everything else.
>
> Both issues are completely unrelated to the problem at hand.
I don't really want to add more complexity to the boot code, or complicate any other timing
mechanisms in the kernel, just to instrument a few early printks.
Adding additional code, command line variables, etc. is antithetical to the goal of reducing boot time
and reducing technical debt.
The instrumentation that I want to add is for printks that are currently showing as zero, while
also allowing to get useful timing data on temporary printks in that early region of boot.
>
> [ 0.009415] BIOS-provided physical RAM map:
> [ 0.009416] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] System RAM
> ...
> [ 0.009473] printk: legacy bootconsole [earlyser0] enabled
> ...
> [ 0.021037] Hypervisor detected: KVM
>
> Without 'no-kvmclock' KVM would take over sched clock and reset sched
> clock time to 0 because KVM... Trivial problem to be solved and left as
> an exercise for the reader.
>
> [ 0.021256] last_pfn = 0x7ffdb max_arch_pfn = 0x400000000
> [ 0.051429] tsc: Fast TSC calibration using PIT
> [ 0.051699] tsc: Detected 2094.808 MHz processor
> [ 0.051990] tsc: Detected 2095.070 MHz TSC
>
> That's in tsc_early_init() which enables the sched clock static key.
>
> [ 0.052871] e820: update [mem 0x00000000-0x00000fff] System RAM ==> device reserved
>
> Unsurprisingly time continues without a gap, jumping backwards or whatever.
That's not a problem I care about.
>
> If you want to have early timestamps then you have to go through the low
> level code on every architecture and do the proper sanity checks,
> enumerations, etc. no matter what. There is no guarantee that you can
> use any clock unconditionally during very early boot.
For the TSC on x86_64 and cntvct_el0 on arm64, I think you are incorrect.
In those architectures I believe you are guaranteed that the instruction to
get the cycle counter will work to retrieve a cycles value before any initialization
code in the kernel, even under emulation or virtualization. But even if not, I do not
believe it matters (see below).
Now, in order to get the clock frequency (and thus convert
to a units/sec timestamp value), additional work may be required (as shown in your POC)
OR you need some mechanism to provide the frequency to the kernel
(such as a command line option or kernel config parameter).
However, all this is moot.
I believe if a platform developer can't guarantee that the clock they decide
to use for this will be functional when the kernel starts (because either the
hardware or the pre-kernel firmware doesn't start it automatically before
the kernel loads), then the developer should not use my proposed early
times feature.
I don't think this feature has any value for regular production kernels,
and it is only intended to be useful for boot-time researchers and developers.
Indeed, it's probably better if it is left turned off for production or distro kernels.
>
> As you have to do that anyway, there is _zero_ justification for an
> extra facility side stepping sched clock, which would just create
> another pile of technical debt.
I think this POC adds much more complexity and technical debt
than any version of my early-times patch.
Since you want to get rid of technical debt on the use of get_cycles(),
I'll re-work the patch to eliminate use of that function, and revert
to something similar to my earlier version of the patch that was less
complicated.
>
> Quite the contrary, I'm going to get rid of technical debt:
>
> The get_cycles() related changes in tsc.h are going to end up in a
> obviously revised formal patch tomorrow as there is exactly _zero_
> requirement to provide this as a functional interface.
>
> 1) The default implementation in asm-generic returns 0
>
> Ergo any code depending on a functional implementation is broken
> by definition.
>
> 2) The ops/cycles metrics are as bogus as the infamous BogoMIPS metrics
>
> The "cycle" counter runs on almost all contemporary CPUs at a fixed
> frequency, which is completely unrelated to the actual CPU
> frequency and therefore to the actual CPU cycles.
>
> The only realistic metric is ops/sec and nothing else and that can
> be trivially achieved by using the generic time getter interfaces.
>
> Those might end up resulting in bogus benchmark results too if the
> underlying clocksource is jiffies, but that's again a matter of
> accepting reality.
>
> If people really mandate that ops/bogo_cycles is required for the
> very wrong reasons, then I'm happy to bring it back with a global
> name change from get_cycles() to get_bogo_cycles() which excludes
> it from any serious usage including printk.
>
> Thanks,
>
> tglx
> ---
> arch/x86/include/asm/tsc.h | 11 ++--
> arch/x86/kernel/platform-quirks.c | 2
> arch/x86/kernel/tsc.c | 96 ++++++++++++++++++++++++++++++--------
> 3 files changed, 85 insertions(+), 24 deletions(-)
>
> --- a/arch/x86/include/asm/tsc.h
> +++ b/arch/x86/include/asm/tsc.h
> @@ -76,10 +76,7 @@ extern void disable_TSC(void);
>
> static inline cycles_t get_cycles(void)
> {
> - if (!IS_ENABLED(CONFIG_X86_TSC) &&
> - !cpu_feature_enabled(X86_FEATURE_TSC))
> - return 0;
> - return rdtsc();
> + return 0;
Eliminating get_cycles() completely seems like an over-reaction to my patch.
But it sounds like something you've wanted to eliminate for a while now,
and I wouldn't stand in your way, or contribute to the technical debt associated
with it by using it in my proposals. By my count there are about 80 current users of
get_cycles() outside of arch-specific code, in the 7.0-rc6 kernel.
> }
> #define get_cycles get_cycles
>
> @@ -114,6 +111,12 @@ static inline void tsc_verify_tsc_adjust
> static inline void check_tsc_sync_target(void) { }
> #endif
>
> +#if defined(CONFIG_X86_TSC) && defined(CONFIG_X86_64)
> +void tsc_early_boot_setup(void);
> +#else
> +static inline void tsc_early_boot_setup(void) { }
> +#endif
> +
> extern int notsc_setup(char *);
> extern void tsc_save_sched_clock_state(void);
> extern void tsc_restore_sched_clock_state(void);
> --- a/arch/x86/kernel/platform-quirks.c
> +++ b/arch/x86/kernel/platform-quirks.c
> @@ -32,6 +32,8 @@ void __init x86_early_init_platform_quir
>
> if (x86_platform.set_legacy_features)
> x86_platform.set_legacy_features();
> +
> + tsc_early_boot_setup();
> }
>
> bool __init x86_pnpbios_disabled(void)
> --- a/arch/x86/kernel/tsc.c
> +++ b/arch/x86/kernel/tsc.c
> @@ -18,6 +18,7 @@
> #include <linux/static_call.h>
>
> #include <asm/cpuid/api.h>
> +#include <asm/cmdline.h>
> #include <asm/hpet.h>
> #include <asm/timer.h>
> #include <asm/vgtod.h>
> @@ -48,6 +49,7 @@ EXPORT_SYMBOL(tsc_khz);
> */
> static int __read_mostly tsc_unstable;
> static unsigned int __initdata tsc_early_khz;
> +static bool tsc_early_boot_enabled __ro_after_init;
>
> static DEFINE_STATIC_KEY_FALSE_RO(__use_tsc);
>
> @@ -202,12 +204,12 @@ static void set_cyc2ns_scale(unsigned lo
> /*
> * Initialize cyc2ns for boot cpu
> */
> -static void __init cyc2ns_init_boot_cpu(void)
> +static void __init cyc2ns_init_boot_cpu(unsigned long khz)
> {
> struct cyc2ns *c2n = this_cpu_ptr(&cyc2ns);
>
> seqcount_latch_init(&c2n->seq);
> - __set_cyc2ns_scale(tsc_khz, smp_processor_id(), rdtsc());
> + __set_cyc2ns_scale(khz, smp_processor_id(), rdtsc());
> }
>
> /*
> @@ -231,17 +233,24 @@ static void __init cyc2ns_init_secondary
> }
> }
>
> +static __always_inline u64 __native_sched_clock(void)
> +{
> + u64 tsc_now = rdtsc();
> +
> + /* return the value in ns */
> + return __cycles_2_ns(tsc_now);
> +}
> +
> /*
> * Scheduler clock - returns current time in nanosec units.
> */
> noinstr u64 native_sched_clock(void)
> {
> - if (static_branch_likely(&__use_tsc)) {
> - u64 tsc_now = rdtsc();
> + if (static_branch_likely(&__use_tsc))
> + return __native_sched_clock();
>
> - /* return the value in ns */
> - return __cycles_2_ns(tsc_now);
> - }
> + if (tsc_early_boot_enabled)
> + return __native_sched_clock();
>
> /*
> * Fall back to jiffies if there's no TSC available:
> @@ -371,12 +380,12 @@ static u64 tsc_read_refs(u64 *p, int hpe
> int i;
>
> for (i = 0; i < MAX_RETRIES; i++) {
> - t1 = get_cycles();
> + t1 = rdtsc();
> if (hpet)
> *p = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
> else
> *p = acpi_pm_read_early();
> - t2 = get_cycles();
> + t2 = rdtsc();
> if ((t2 - t1) < thresh)
> return t2;
> }
> @@ -468,13 +477,13 @@ static unsigned long pit_calibrate_tsc(u
> outb(latch & 0xff, 0x42);
> outb(latch >> 8, 0x42);
>
> - tsc = t1 = t2 = get_cycles();
> + tsc = t1 = t2 = rdtsc();
>
> pitcnt = 0;
> tscmax = 0;
> tscmin = ULONG_MAX;
> while ((inb(0x61) & 0x20) == 0) {
> - t2 = get_cycles();
> + t2 = rdtsc();
> delta = t2 - tsc;
> tsc = t2;
> if ((unsigned long) delta < tscmin)
> @@ -553,9 +562,9 @@ static inline int pit_expect_msb(unsigne
> if (!pit_verify_msb(val))
> break;
> prev_tsc = tsc;
> - tsc = get_cycles();
> + tsc = rdtsc();
> }
> - *deltap = get_cycles() - prev_tsc;
> + *deltap = rdtsc() - prev_tsc;
> *tscp = tsc;
>
> /*
> @@ -745,19 +754,23 @@ unsigned long native_calibrate_tsc(void)
>
> static unsigned long cpu_khz_from_cpuid(void)
> {
> - unsigned int eax_base_mhz, ebx_max_mhz, ecx_bus_mhz, edx;
> + struct cpuid_regs regs;
>
> - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
> + /* Do it manually as this can be called _before_ boot_cpu_data is initialized */
> + cpuid_leaf(0, ®s);
> + /* Intel only */
> + if (regs.ebx != 0x756e6547 && regs.ecx != 0x6c65746e && regs.edx != 0x49656e69)
> return 0;
>
> - if (boot_cpu_data.cpuid_level < CPUID_LEAF_FREQ)
> + if (regs.eax < CPUID_LEAF_FREQ)
> return 0;
>
> - eax_base_mhz = ebx_max_mhz = ecx_bus_mhz = edx = 0;
> + memset(®s, 0, sizeof(®s));
>
> - cpuid(CPUID_LEAF_FREQ, &eax_base_mhz, &ebx_max_mhz, &ecx_bus_mhz, &edx);
> + cpuid_leaf(CPUID_LEAF_FREQ, ®s);
>
> - return eax_base_mhz * 1000;
> + /* EAX contains base MHz */
> + return regs.eax * 1000;
> }
>
> /*
> @@ -1512,8 +1525,9 @@ static void __init tsc_enable_sched_cloc
>
> /* Sanitize TSC ADJUST before cyc2ns gets initialized */
> tsc_store_and_check_tsc_adjust(true);
> - cyc2ns_init_boot_cpu();
> + cyc2ns_init_boot_cpu(tsc_khz);
> static_branch_enable(&__use_tsc);
> + tsc_early_boot_enabled = false;
> }
>
> void __init tsc_early_init(void)
> @@ -1576,6 +1590,48 @@ void __init tsc_init(void)
> detect_art();
> }
>
> +/* Only 64bit guarantees that CPUID is available */
> +#ifdef CONFIG_X86_64
> +void __init tsc_early_boot_setup(void)
> +{
> + struct cpuid_regs regs;
> + unsigned long khz = 0;
> + char optstr[64];
> +
> + if (cmdline_find_option_bool(boot_command_line, "notsc"))
> + return;
> +
> + // FIXME: This needs way more sanity checks vs. virt etc.
> + if (cc_platform_has(CC_ATTR_GUEST_SNP_SECURE_TSC))
> + return;
> +
> + // Why don't we have proper leaf structs yet?
> + cpuid_leaf(0, ®s);
> + if (regs.eax < 1)
> + return;
> +
> + /* TSC enabled in CPUID? */
> + cpuid_leaf(1, ®s);
> + if (!(regs.edx & BIT(4)))
> + return;
> +
> + if (cmdline_find_option(boot_command_line, "tsc_early_khz", optstr, sizeof(optstr)) > 0) {
> + // Shut up must check by doing a pointless zeroing
> + if (kstrtoul(optstr, 10, &khz) < 0)
> + khz = 0;
> + }
> +
> + if (!khz)
> + khz = cpu_khz_from_cpuid();
> + if (!khz)
> + return;
> +
> + cyc2ns_init_boot_cpu(khz);
> + tsc_early_boot_enabled = true;
> + pr_info("Boot sched clock enabled\n");
> +}
> +#endif
> +
> #ifdef CONFIG_SMP
> /*
> * Check whether existing calibration data can be reused.
Overall, this code achieves the result of initializing clocks on some
x86_64 platforms earlier (and moreso when properly configured via the
command line). This achieves a lot of the value I was looking for.
Compared to my solution, it puts pre-timekeeping timestamps
into the same time sequence space as subsequent "regular" ones.
However, I don't think the discontinuity is actually a big problem.
This PoC does an admirable job of addressing the problem space I am interested in,
but at the expense of adding more complexity to the boot sequence.
At the same time, it still leaves a blind spot in the kernel bootup sequence.
The blind spot is much shorter, but still exists. And the PoCpatch is unfinished,
and supports only one architecture. I wouldn't ask someone else to finish
it for me, nor am I willing to commit to extend it (e.g. to finalize support
for AMD processors) or maintain it going forward.
The discontinuity in timestamps is a tradeoff I'm willing to make in order keep
the code simple and to cover more of the blind sport.
I prefer my original approach. I'll send an updated patch for consideration soon.
Thanks,
-- Tim
^ permalink raw reply
* [PATCH v4 0/1] printk: fix zero-valued printk timestamps
From: Tim Bird @ 2026-04-10 20:37 UTC (permalink / raw)
To: pmladek, rostedt, john.ogness, senozhatsky
Cc: francesco, geert, tglx, shashankbalaji02, linux-embedded,
linux-kernel, Tim Bird
Some kernel messages emitted before kernel timekeeping is started
have a timestamp value of zero. However, some platforms
have a cycle counter or timer register that is initialized
before the kernel starts (either in hardware or pre-kernel
firmware), and it can be accessed to provide uncalibrated
values before any other kernel initialization. I refer
to this period where kernel timestamps are zero as the
printk timing "blind spot".
The following patch allows developers to set a config value
CONFIG_EARLY_CYCLES_KHZ, that will be used to provide
useful timestamps on early printk messages.
This calibration value is set as a static configuration
variable, since it must be available from the very first kernel
instruction. Since this value is machine-specific, it cannot
be used in the .config for a generic distribution kernel.
The feature is presented here as something useful for
kernel developers working on boot-time optimization
(ie, as something that can be used temporarily during boot
time research and development work, and not necessarily
a runtime option for the average user).
Different platforms have different blind spot durations.
On an x86_64 platform, due to early tsc initialization, the
blind spot may be as small at 16 milliseconds. On a
Raspberry Pi 4 board, it is approximately 180 milliseconds.
On a RISC V BeagleV Fire board, it can be up to 1700
milliseconds (1.7 seconds). On some platforms, the blind spot
duration is a significant percentage of the time before user-space
initialization in the kernel (greater than 20%).
This feature uses a different mechanism to gather timestamp values.
When kernel timekeeping starts, the printk timestamps change
to a new timebase based on local_clock(), and timestamp values
reset to the baseline used for kernel timekeeping. This results in a
one-time discontinuity in timestamps between early printks and later
printks. The discontinuity should be obvious to humans, but could
possibly confuse tools.
Here is before and after dmesg output for a Raspberry PI 4 board:
before:
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
[ 0.000000] Linux version 7.0.0-rc3-v8+ (tbird@timdesk) (aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #5 SMP PREEMPT Wed Mar 11 18:30:18 MDT 2026
[ 0.000000] KASLR enabled
[ 0.000000] random: crng init done
[ 0.000000] Machine model: Raspberry Pi 4 Model B Rev 1.5
[ 0.000000] efi: UEFI not found.
...
[ 0.000000] Root IRQ handler: gic_handle_irq
[ 0.000000] GIC: Using split EOI/Deactivate mode
[ 0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[ 0.000000] arch_timer: cp15 timer running at 54.00MHz (phys).
[ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xc743ce346, max_idle_ns: 440795203123 ns
[ 0.000000] sched_clock: 56 bits at 54MHz, resolution 18ns, wraps every 4398046511102ns
[ 0.000161] Console: colour dummy device 80x25
[ 0.000170] printk: legacy console [tty1] enabled
after:
[ 0.002975] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
[ 0.002998] Linux version 7.0.0-rc6-v8+ (tbird@timdesk) (aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #20 SMP PREEMPT Fri Apr 10 11:57:48 MDT 2026
[ 0.003002] KASLR enabled
[ 0.003338] random: crng init done
[ 0.003866] Machine model: Raspberry Pi 4 Model B Rev 1.5
[ 0.004495] efi: UEFI not found.
...
[ 0.183552] Root IRQ handler: gic_handle_irq
[ 0.183561] GIC: Using split EOI/Deactivate mode
[ 0.183699] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[ 0.183958] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xc743ce346, max_idle_ns: 440795203123 ns
[ 0.183952] arch_timer: cp15 timer running at 54.00MHz (phys).
[ 0.000000] sched_clock: 56 bits at 54MHz, resolution 18ns, wraps every 4398046511102ns
[ 0.000157] Console: colour dummy device 80x25
[ 0.000165] printk: legacy console [tty1] enabled
Tim Bird (1):
printk: fix zero-valued printk timestamps in early boot
include/linux/early_times.h | 55 +++++++++++++++++++++++++++++++++++++
init/Kconfig | 30 ++++++++++++++++++++
kernel/printk/printk.c | 3 ++
3 files changed, 88 insertions(+)
create mode 100644 include/linux/early_times.h
--
2.43.0
^ permalink raw reply
* [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: Tim Bird @ 2026-04-10 20:37 UTC (permalink / raw)
To: pmladek, rostedt, john.ogness, senozhatsky
Cc: francesco, geert, tglx, shashankbalaji02, linux-embedded,
linux-kernel, Tim Bird
In-Reply-To: <20260410203741.997410-1-tim.bird@sony.com>
During early boot, printk timestamps are reported as zero before
kernel timekeeping starts (i.e. before time_init()). This
hinders boot-time optimization efforts. This period ranges from
17 to 1700 milliseconds on different embedded machines running Linux.
Add support for early timestamps based on processor cycle-generators
that need no kernel initialization. Use a statically-configured
frequency value for converting cycles to nanoseconds. This means
that this feature cannot be turned on in generic distro kernels.
It is intended for temporary use during kernel development and
boot-time research and optimization only.
This yields non-zero timestamps for printks from the very start
of kernel execution. The timestamps are relative to the start of
an architecture-specific counter (e.g. tsc on x86_64 and cntvct_el0
on arm64). Affected timestamps reflect time from cycle counter
init (usually machine power-on or virtual machine start) instead of
time from the kernel's timekeeping initialization. This results in a
discontinuity in the printk timestamp values, one time, when
kernel timekeeping starts.
Signed-off-by: Tim Bird <tim.bird@sony.com>
---
V3 -> V4
Replace config vars with single one: CONFIG_EARLY_CYCLES_KHZ
Replace runtime calibration with static config variable
Remove reference to get_cycles()
Add support for RISCV platforms
V2 -> V3
Default CONFIG option to 'n'
Move more code into early_times.h (reduce ifdefs in init/main.c)
Use match64 helper routines
Use cycles_t instead of u64 type
Add #defines for EARLY_CYCLES_BIT and EARLY_CYCLES_MASK
Invert if logic in adjust_early_ts()
V1 -> V2
Remove calibration CONFIG vars
Add 'depends on' to restrict arches (to handle ppc bug)
Add early_ts_offset to avoid discontinuity
Save cycles in ts_nsec, and convert on output
Move conditional code to include file (early_times.h>
---
include/linux/early_times.h | 55 +++++++++++++++++++++++++++++++++++++
init/Kconfig | 30 ++++++++++++++++++++
kernel/printk/printk.c | 3 ++
3 files changed, 88 insertions(+)
create mode 100644 include/linux/early_times.h
diff --git a/include/linux/early_times.h b/include/linux/early_times.h
new file mode 100644
index 000000000000..82bacfd0e26b
--- /dev/null
+++ b/include/linux/early_times.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _EARLY_TIMES_H
+#define _EARLY_TIMES_H
+
+#include <linux/timekeeping.h>
+#ifdef CONFIG_ARM64
+#include <asm/sysreg.h>
+#endif
+
+#ifdef CONFIG_EARLY_CYCLES_KHZ
+static inline u64 early_unsafe_cycles(void)
+{
+#if defined(CONFIG_X86_64)
+ /*
+ * This rdtsc may happen before secure TSC is initialized, and
+ * it is unordered. So please don't use this value for cryptography
+ * or after SMP is initialized.
+ */
+ return rdtsc();
+#elif defined(CONFIG_ARM64)
+ return read_sysreg(cntvct_el0);
+#elif defined(CONFIG_RISCV_TIMER)
+ u64 val;
+
+ asm volatile("rdtime %0" : "=r"(val));
+ return val;
+#else
+ return 0;
+#endif
+}
+
+#define NS_PER_KHZ 1000000UL
+
+/* returns a nanosecond value based on early cycles */
+static inline u64 early_times_ns(void)
+{
+ if (CONFIG_EARLY_CYCLES_KHZ)
+ /*
+ * Note: the multiply must precede the division to avoid
+ * truncation and loss of resolution
+ * Don't use fancier MULT/SHIFT math here. Since this is
+ * static, the compiler can optimize the math operations.
+ */
+ return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
+ return 0;
+}
+#else
+static inline u64 early_times_ns(void)
+{
+ return 0;
+}
+#endif
+
+#endif /* _EARLY_TIMES_H */
diff --git a/init/Kconfig b/init/Kconfig
index 7484cd703bc1..40c3123c2c27 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -792,6 +792,36 @@ config IKHEADERS
or similar programs. If you build the headers as a module, a module called
kheaders.ko is built which can be loaded on-demand to get access to headers.
+config EARLY_CYCLES_KHZ
+ int "Frequency of the early times cycle counter, in KHz"
+ default 0
+ depends on PRINTK
+ depends on ARM64 || X86_64 || RISCV_TIMER
+ help
+ Specifies the frequency value (in KHz) of the cycle counter
+ used for early times information.
+
+ Set this to provide timing information for printks in early boot
+ (before the start of kernel timekeeping), that would otherwise
+ show as 0.
+
+ To calculate the value for your system, boot your system, and
+ use the value expressed on the tsc or cntvct_el0 calibration line
+ in your kernel message log:
+ ex x86_64: tsc: Refined TSC clocksource calibration: 2095.057 MHz
+ In that case, use the value 2095057.
+ ex arm64: arch_timer: cp15 timer running at 54.00MHz (phys).
+ In that case, use the value of 54000.
+
+ Note that this causes the kernel to show, for some early printks,
+ times that are relative to processor power on, instead of
+ relative to the start of kernel timekeeping. When kernel
+ timekeeping starts, the timestamps values reset, causing
+ a discontinuity in the timestamp values. If you see
+ non-monotonic printk timestamps, please don't freak out.
+
+ Set to 0 to disable this feature.
+
config LOG_BUF_SHIFT
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
range 12 25
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 0323149548f6..ddeab81f04ef 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -46,6 +46,7 @@
#include <linux/ctype.h>
#include <linux/uio.h>
#include <linux/sched/clock.h>
+#include <linux/early_times.h>
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
#include <linux/panic.h>
@@ -2294,6 +2295,8 @@ int vprintk_store(int facility, int level,
* timestamp with respect to the caller.
*/
ts_nsec = local_clock();
+ if (unlikely(!ts_nsec))
+ ts_nsec = early_times_ns();
caller_id = printk_caller_id();
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: kernel test robot @ 2026-04-12 10:10 UTC (permalink / raw)
To: Tim Bird, pmladek, rostedt, john.ogness, senozhatsky
Cc: oe-kbuild-all, francesco, geert, tglx, shashankbalaji02,
linux-embedded, linux-kernel, Tim Bird
In-Reply-To: <20260410203741.997410-2-tim.bird@sony.com>
Hi Tim,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linus/master]
[also build test WARNING on v7.0-rc7 next-20260410]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Tim-Bird/printk-fix-zero-valued-printk-timestamps-in-early-boot/20260412-134726
base: linus/master
patch link: https://lore.kernel.org/r/20260410203741.997410-2-tim.bird%40sony.com
patch subject: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
config: arm64-allnoconfig (https://download.01.org/0day-ci/archive/20260412/202604121822.OvOLcTnO-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260412/202604121822.OvOLcTnO-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604121822.OvOLcTnO-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from kernel/printk/printk.c:49:
include/linux/early_times.h: In function 'early_times_ns':
>> include/linux/early_times.h:45:61: warning: division by zero [-Wdiv-by-zero]
45 | return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
| ^
vim +45 include/linux/early_times.h
34
35 /* returns a nanosecond value based on early cycles */
36 static inline u64 early_times_ns(void)
37 {
38 if (CONFIG_EARLY_CYCLES_KHZ)
39 /*
40 * Note: the multiply must precede the division to avoid
41 * truncation and loss of resolution
42 * Don't use fancier MULT/SHIFT math here. Since this is
43 * static, the compiler can optimize the math operations.
44 */
> 45 return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
46 return 0;
47 }
48 #else
49 static inline u64 early_times_ns(void)
50 {
51 return 0;
52 }
53 #endif
54
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: kernel test robot @ 2026-04-12 11:12 UTC (permalink / raw)
To: Tim Bird, pmladek, rostedt, john.ogness, senozhatsky
Cc: llvm, oe-kbuild-all, francesco, geert, tglx, shashankbalaji02,
linux-embedded, linux-kernel, Tim Bird
In-Reply-To: <20260410203741.997410-2-tim.bird@sony.com>
Hi Tim,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linus/master]
[also build test WARNING on v7.0-rc7 next-20260410]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Tim-Bird/printk-fix-zero-valued-printk-timestamps-in-early-boot/20260412-134726
base: linus/master
patch link: https://lore.kernel.org/r/20260410203741.997410-2-tim.bird%40sony.com
patch subject: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
config: um-defconfig (https://download.01.org/0day-ci/archive/20260412/202604121907.nsngvl5u-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project ae825cb8cea7f3ac8e5e4096f22713845cf5e501)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260412/202604121907.nsngvl5u-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604121907.nsngvl5u-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from kernel/printk/printk.c:49:
include/linux/early_times.h:20:9: error: call to undeclared function 'rdtsc'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
20 | return rdtsc();
| ^
>> include/linux/early_times.h:45:47: warning: division by zero is undefined [-Wdivision-by-zero]
45 | return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
| ^ ~~~~~~~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
vim +45 include/linux/early_times.h
34
35 /* returns a nanosecond value based on early cycles */
36 static inline u64 early_times_ns(void)
37 {
38 if (CONFIG_EARLY_CYCLES_KHZ)
39 /*
40 * Note: the multiply must precede the division to avoid
41 * truncation and loss of resolution
42 * Don't use fancier MULT/SHIFT math here. Since this is
43 * static, the compiler can optimize the math operations.
44 */
> 45 return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
46 return 0;
47 }
48 #else
49 static inline u64 early_times_ns(void)
50 {
51 return 0;
52 }
53 #endif
54
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: kernel test robot @ 2026-04-12 12:55 UTC (permalink / raw)
To: Tim Bird, pmladek, rostedt, john.ogness, senozhatsky
Cc: llvm, oe-kbuild-all, francesco, geert, tglx, shashankbalaji02,
linux-embedded, linux-kernel, Tim Bird
In-Reply-To: <20260410203741.997410-2-tim.bird@sony.com>
Hi Tim,
kernel test robot noticed the following build errors:
[auto build test ERROR on linus/master]
[also build test ERROR on v7.0-rc7 next-20260410]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Tim-Bird/printk-fix-zero-valued-printk-timestamps-in-early-boot/20260412-134726
base: linus/master
patch link: https://lore.kernel.org/r/20260410203741.997410-2-tim.bird%40sony.com
patch subject: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
config: um-defconfig (https://download.01.org/0day-ci/archive/20260412/202604122037.R14cnXpl-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project ae825cb8cea7f3ac8e5e4096f22713845cf5e501)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260412/202604122037.R14cnXpl-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604122037.R14cnXpl-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from kernel/printk/printk.c:49:
>> include/linux/early_times.h:20:9: error: call to undeclared function 'rdtsc'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
20 | return rdtsc();
| ^
include/linux/early_times.h:45:47: warning: division by zero is undefined [-Wdivision-by-zero]
45 | return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
| ^ ~~~~~~~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
vim +/rdtsc +20 include/linux/early_times.h
10
11 #ifdef CONFIG_EARLY_CYCLES_KHZ
12 static inline u64 early_unsafe_cycles(void)
13 {
14 #if defined(CONFIG_X86_64)
15 /*
16 * This rdtsc may happen before secure TSC is initialized, and
17 * it is unordered. So please don't use this value for cryptography
18 * or after SMP is initialized.
19 */
> 20 return rdtsc();
21 #elif defined(CONFIG_ARM64)
22 return read_sysreg(cntvct_el0);
23 #elif defined(CONFIG_RISCV_TIMER)
24 u64 val;
25
26 asm volatile("rdtime %0" : "=r"(val));
27 return val;
28 #else
29 return 0;
30 #endif
31 }
32
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* RE: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: Bird, Tim @ 2026-04-13 17:58 UTC (permalink / raw)
To: kernel test robot, pmladek@suse.com, rostedt@goodmis.org,
john.ogness@linutronix.de, senozhatsky@chromium.org
Cc: oe-kbuild-all@lists.linux.dev, francesco@valla.it,
geert@linux-m68k.org, tglx@kernel.org, shashankbalaji02@gmail.com,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <202604121822.OvOLcTnO-lkp@intel.com>
Hmmm,
This is a false positive warning from the compiler (see below).
I apologize for not catching it. I did test with CONFIG_EARLY_CYCLES=0
and I'm not sure why I didn't see the warning.
I'll see if I can silence this warning.
> -----Original Message-----
> From: kernel test robot <lkp@intel.com>
> Sent: Sunday, April 12, 2026 4:11 AM
> Hi Tim,
>
> kernel test robot noticed the following build warnings:
>
> [auto build test WARNING on linus/master]
> [also build test WARNING on v7.0-rc7 next-20260410]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Tim-Bird/printk-fix-zero-valued-printk-timestamps-in-early-boot/20260412-134726
> base: linus/master
> patch link: https://lore.kernel.org/r/20260410203741.997410-2-tim.bird%40sony.com
> patch subject: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
> config: arm64-allnoconfig (https://download.01.org/0day-ci/archive/20260412/202604121822.OvOLcTnO-lkp@intel.com/config)
> compiler: aarch64-linux-gcc (GCC) 15.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260412/202604121822.OvOLcTnO-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202604121822.OvOLcTnO-lkp@intel.com/
>
> All warnings (new ones prefixed by >>):
>
> In file included from kernel/printk/printk.c:49:
> include/linux/early_times.h: In function 'early_times_ns':
> >> include/linux/early_times.h:45:61: warning: division by zero [-Wdiv-by-zero]
> 45 | return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
> | ^
>
>
> vim +45 include/linux/early_times.h
>
> 34
> 35 /* returns a nanosecond value based on early cycles */
> 36 static inline u64 early_times_ns(void)
> 37 {
> 38 if (CONFIG_EARLY_CYCLES_KHZ)
> 39 /*
> 40 * Note: the multiply must precede the division to avoid
> 41 * truncation and loss of resolution
> 42 * Don't use fancier MULT/SHIFT math here. Since this is
> 43 * static, the compiler can optimize the math operations.
> 44 */
> > 45 return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
Based on this conditional, it's not possible for CONFIG_EARLY_CYCLES_KHZ to be zero
on this line of code. Does GCC not catch this?
if (0)
x = <some expression>/0;
So this is a false positive.
> 46 return 0;
> 47 }
> 48 #else
> 49 static inline u64 early_times_ns(void)
> 50 {
> 51 return 0;
> 52 }
> 53 #endif
> 54
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: David Laight @ 2026-04-13 20:17 UTC (permalink / raw)
To: Bird, Tim
Cc: kernel test robot, pmladek@suse.com, rostedt@goodmis.org,
john.ogness@linutronix.de, senozhatsky@chromium.org,
oe-kbuild-all@lists.linux.dev, francesco@valla.it,
geert@linux-m68k.org, tglx@kernel.org, shashankbalaji02@gmail.com,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <MW5PR13MB563241C9F7C8BCAF0D5F3D21FD242@MW5PR13MB5632.namprd13.prod.outlook.com>
On Mon, 13 Apr 2026 17:58:34 +0000
"Bird, Tim" <Tim.Bird@sony.com> wrote:
> Hmmm,
>
> This is a false positive warning from the compiler (see below).
>
> I apologize for not catching it. I did test with CONFIG_EARLY_CYCLES=0
> and I'm not sure why I didn't see the warning.
>
> I'll see if I can silence this warning.
>
> > -----Original Message-----
> > From: kernel test robot <lkp@intel.com>
> > Sent: Sunday, April 12, 2026 4:11 AM
> > Hi Tim,
> >
> > kernel test robot noticed the following build warnings:
> >
> > [auto build test WARNING on linus/master]
> > [also build test WARNING on v7.0-rc7 next-20260410]
> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > And when submitting patch, we suggest to use '--base' as documented in
> > https://git-scm.com/docs/git-format-patch#_base_tree_information]
> >
> > url: https://github.com/intel-lab-lkp/linux/commits/Tim-Bird/printk-fix-zero-valued-printk-timestamps-in-early-boot/20260412-134726
> > base: linus/master
> > patch link: https://lore.kernel.org/r/20260410203741.997410-2-tim.bird%40sony.com
> > patch subject: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
> > config: arm64-allnoconfig (https://download.01.org/0day-ci/archive/20260412/202604121822.OvOLcTnO-lkp@intel.com/config)
> > compiler: aarch64-linux-gcc (GCC) 15.2.0
> > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260412/202604121822.OvOLcTnO-lkp@intel.com/reproduce)
> >
> > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > the same patch/commit), kindly add following tags
> > | Reported-by: kernel test robot <lkp@intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202604121822.OvOLcTnO-lkp@intel.com/
> >
> > All warnings (new ones prefixed by >>):
> >
> > In file included from kernel/printk/printk.c:49:
> > include/linux/early_times.h: In function 'early_times_ns':
> > >> include/linux/early_times.h:45:61: warning: division by zero [-Wdiv-by-zero]
> > 45 | return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
> > | ^
> >
> >
> > vim +45 include/linux/early_times.h
> >
> > 34
> > 35 /* returns a nanosecond value based on early cycles */
> > 36 static inline u64 early_times_ns(void)
> > 37 {
> > 38 if (CONFIG_EARLY_CYCLES_KHZ)
> > 39 /*
> > 40 * Note: the multiply must precede the division to avoid
> > 41 * truncation and loss of resolution
> > 42 * Don't use fancier MULT/SHIFT math here. Since this is
> > 43 * static, the compiler can optimize the math operations.
> > 44 */
> > > 45 return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
> Based on this conditional, it's not possible for CONFIG_EARLY_CYCLES_KHZ to be zero
> on this line of code. Does GCC not catch this?
> if (0)
> x = <some expression>/0;
>
> So this is a false positive.
I suspect the warning is being generated before the optimiser throws
the code away as unreachable.
You might have to do:
return (early_unsafe_cycles() * NS_PER_KHZ) / (CONFIG_EARLY_CYCLES_KHZ ?: 1);
David
>
> > 46 return 0;
> > 47 }
> > 48 #else
> > 49 static inline u64 early_times_ns(void)
> > 50 {
> > 51 return 0;
> > 52 }
> > 53 #endif
> > 54
> >
> > --
> > 0-DAY CI Kernel Test Service
> > https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: Geert Uytterhoeven @ 2026-04-14 7:03 UTC (permalink / raw)
To: Tim Bird
Cc: pmladek, rostedt, john.ogness, senozhatsky, francesco, tglx,
shashankbalaji02, linux-embedded, linux-kernel
In-Reply-To: <20260410203741.997410-2-tim.bird@sony.com>
Hi Tim,
Thanks for your patch!
On Fri, 10 Apr 2026 at 22:38, Tim Bird <tim.bird@sony.com> wrote:
> During early boot, printk timestamps are reported as zero before
> kernel timekeeping starts (i.e. before time_init()). This
> hinders boot-time optimization efforts. This period ranges from
> 17 to 1700 milliseconds on different embedded machines running Linux.
>
> Add support for early timestamps based on processor cycle-generators
> that need no kernel initialization. Use a statically-configured
> frequency value for converting cycles to nanoseconds. This means
> that this feature cannot be turned on in generic distro kernels.
> It is intended for temporary use during kernel development and
> boot-time research and optimization only.
>
> This yields non-zero timestamps for printks from the very start
> of kernel execution. The timestamps are relative to the start of
> an architecture-specific counter (e.g. tsc on x86_64 and cntvct_el0
> on arm64). Affected timestamps reflect time from cycle counter
> init (usually machine power-on or virtual machine start) instead of
> time from the kernel's timekeeping initialization. This results in a
> discontinuity in the printk timestamp values, one time, when
> kernel timekeeping starts.
Won't it be hard to see where the discontinuity happens in some cases?
Perhaps this can be made more obvious by not doing the time conversion
in kernelspace, like in your first version?
> Signed-off-by: Tim Bird <tim.bird@sony.com>
> --- /dev/null
> +++ b/include/linux/early_times.h
> +/* returns a nanosecond value based on early cycles */
> +static inline u64 early_times_ns(void)
> +{
> + if (CONFIG_EARLY_CYCLES_KHZ)
> + /*
> + * Note: the multiply must precede the division to avoid
> + * truncation and loss of resolution
> + * Don't use fancier MULT/SHIFT math here. Since this is
> + * static, the compiler can optimize the math operations.
> + */
> + return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
Still, this contains a 64-by-32 division, so let's see how this works
out on 32-bit (RISCV_TIMER is set on rv32!). If the compiler would
generate a function call to a libgcc helper, you will have to switch
to the mul_u64_u32_div() helper...
> + return 0;
> +}
> +#else
> +static inline u64 early_times_ns(void)
> +{
> + return 0;
> +}
> +#endif
> +
> +#endif /* _EARLY_TIMES_H */
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: Roberto A. Foglietta @ 2026-04-14 9:51 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Tim Bird, pmladek, rostedt, john.ogness, senozhatsky, francesco,
tglx, shashankbalaji02, linux-embedded, linux-kernel
In-Reply-To: <CAMuHMdX-jeO83JQQaQXkk2oFsFH=K_p8Nmta7s5J-_BgwF5KXQ@mail.gmail.com>
On Tue, 14 Apr 2026 at 09:03, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Tim,
>
> Thanks for your patch!
>
> On Fri, 10 Apr 2026 at 22:38, Tim Bird <tim.bird@sony.com> wrote:
> > During early boot, printk timestamps are reported as zero before
> > kernel timekeeping starts (i.e. before time_init()). This
...
> Won't it be hard to see where the discontinuity happens in some cases?
> Perhaps this can be made more obvious by not doing the time conversion
> in kernelspace, like in your first version?
>
> > Signed-off-by: Tim Bird <tim.bird@sony.com>
>
> > --- /dev/null
> > +++ b/include/linux/early_times.h
>
> > +/* returns a nanosecond value based on early cycles */
> > +static inline u64 early_times_ns(void)
> > +{
> > + if (CONFIG_EARLY_CYCLES_KHZ)
> > + /*
> > + * Note: the multiply must precede the division to avoid
> > + * truncation and loss of resolution
> > + * Don't use fancier MULT/SHIFT math here. Since this is
> > + * static, the compiler can optimize the math operations.
> > + */
> > + return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
>
> Still, this contains a 64-by-32 division, so let's see how this works
> out on 32-bit (RISCV_TIMER is set on rv32!). If the compiler would
> generate a function call to a libgcc helper, you will have to switch
> to the mul_u64_u32_div() helper...
Interesting.
https://github.com/robang74/uchaosys/blob/53e72d169/cnfg/printk-fix-early-boot-timestamps-patch-v4.txt#L92
Elvis the King (A?:), R-
^ permalink raw reply
* Re: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: Thomas Gleixner @ 2026-04-14 22:38 UTC (permalink / raw)
To: Tim Bird, pmladek, rostedt, john.ogness, senozhatsky
Cc: francesco, geert, shashankbalaji02, linux-embedded, linux-kernel,
Tim Bird
In-Reply-To: <20260410203741.997410-2-tim.bird@sony.com>
On Fri, Apr 10 2026 at 14:37, Tim Bird wrote:
> +
> +#include <linux/timekeeping.h>
> +#ifdef CONFIG_ARM64
> +#include <asm/sysreg.h>
> +#endif
> +
> +#ifdef CONFIG_EARLY_CYCLES_KHZ
> +static inline u64 early_unsafe_cycles(void)
> +{
> +#if defined(CONFIG_X86_64)
> + /*
> + * This rdtsc may happen before secure TSC is initialized, and
> + * it is unordered. So please don't use this value for cryptography
> + * or after SMP is initialized.
> + */
> + return rdtsc();
> +#elif defined(CONFIG_ARM64)
> + return read_sysreg(cntvct_el0);
> +#elif defined(CONFIG_RISCV_TIMER)
> + u64 val;
> +
> + asm volatile("rdtime %0" : "=r"(val));
> + return val;
> +#else
> + return 0;
> +#endif
> +}
No. Generic code and generic headers have no business to implement any
architecture specific code and there is zero justification for
architecture specific #ifdefs in generic code.
Ask your favourite AI assistant for an opinion.
> +#define NS_PER_KHZ 1000000UL
The existing nomenclature for nanosecond related constants is NSEC_*
> +
> +/* returns a nanosecond value based on early cycles */
> +static inline u64 early_times_ns(void)
> +{
> + if (CONFIG_EARLY_CYCLES_KHZ)
> + /*
> + * Note: the multiply must precede the division to avoid
> + * truncation and loss of resolution
> + * Don't use fancier MULT/SHIFT math here. Since this is
> + * static, the compiler can optimize the math operations.
> + */
> + return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
This code will result in a division by zero warning from any reasonable
compiler because this is evaluated _before_ it is eliminated.
> @@ -2294,6 +2295,8 @@ int vprintk_store(int facility, int level,
> * timestamp with respect to the caller.
> */
> ts_nsec = local_clock();
> + if (unlikely(!ts_nsec))
> + ts_nsec = early_times_ns();
I explained to you how this wants to be implemented to be useful and you
declared that you are unwilling to put the effort in.
My NAK for this disgusting and tasteless hack still applies.
Either you are willing to work with the community and the relevant
maintainers or you can keep your hackery maintained out of tree for
those who care about it and are willing to ignore the fallout.
Thanks,
tglx
^ permalink raw reply
* RE: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: Thomas Gleixner @ 2026-04-14 22:48 UTC (permalink / raw)
To: Bird, Tim, kernel test robot, pmladek@suse.com,
rostedt@goodmis.org, john.ogness@linutronix.de,
senozhatsky@chromium.org
Cc: oe-kbuild-all@lists.linux.dev, francesco@valla.it,
geert@linux-m68k.org, shashankbalaji02@gmail.com,
linux-embedded@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <MW5PR13MB563241C9F7C8BCAF0D5F3D21FD242@MW5PR13MB5632.namprd13.prod.outlook.com>
On Mon, Apr 13 2026 at 17:58, Tim Bird wrote:
> This is a false positive warning from the compiler (see below).
This is _NOT_ a false positive warning. The compiler is absolutely
correct.
>> 34
>> 35 /* returns a nanosecond value based on early cycles */
>> 36 static inline u64 early_times_ns(void)
>> 37 {
>> 38 if (CONFIG_EARLY_CYCLES_KHZ)
>> 39 /*
>> 40 * Note: the multiply must precede the division to avoid
>> 41 * truncation and loss of resolution
>> 42 * Don't use fancier MULT/SHIFT math here. Since this is
>> 43 * static, the compiler can optimize the math operations.
>> 44 */
>> > 45 return (early_unsafe_cycles() * NS_PER_KHZ) / CONFIG_EARLY_CYCLES_KHZ;
> Based on this conditional, it's not possible for CONFIG_EARLY_CYCLES_KHZ to be zero
> on this line of code. Does GCC not catch this?
> if (0)
> x = <some expression>/0;
>
> So this is a false positive.
You clearly fail to understand how compilers work. The dead code
elimination happens _after_ the evaluation of the code and the compiler
does not care whether your initial condition evaluated to false or
not. That's documented compiler behaviour,
Whether GCC complains about it or not is completely irrelevant.
> I'll see if I can silence this warning.
Don't put much effort into it. This whole hack is going nowhere.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH v4 1/1] printk: fix zero-valued printk timestamps in early boot
From: Roberto A. Foglietta @ 2026-04-15 0:19 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Tim Bird, pmladek, rostedt, john.ogness, senozhatsky, francesco,
geert, shashankbalaji02, linux-embedded, linux-kernel
In-Reply-To: <87qzohdv6i.ffs@tglx>
On Wed, 15 Apr 2026 at 00:38, Thomas Gleixner <tglx@kernel.org> wrote:
>
> On Fri, Apr 10 2026 at 14:37, Tim Bird wrote:
> > +
> > +#include <linux/timekeeping.h>
> > +#ifdef CONFIG_ARM64
> > +#include <asm/sysreg.h>
> > +#endif
> > +
> > +#ifdef CONFIG_EARLY_CYCLES_KHZ
> > +static inline u64 early_unsafe_cycles(void)
> > +{
> > +#if defined(CONFIG_X86_64)
> > + /*
> > + * This rdtsc may happen before secure TSC is initialized, and
> > + * it is unordered. So please don't use this value for cryptography
> > + * or after SMP is initialized.
> > + */
> > + return rdtsc();
> > +#elif defined(CONFIG_ARM64)
> > + return read_sysreg(cntvct_el0);
> > +#elif defined(CONFIG_RISCV_TIMER)
> > + u64 val;
> > +
> > + asm volatile("rdtime %0" : "=r"(val));
> > + return val;
> > +#else
> > + return 0;
> > +#endif
> > +}
>
> No. Generic code and generic headers have no business to implement any
> architecture specific code and there is zero justification for
> architecture specific #ifdefs in generic code.
This translates in practice in early_unsafe_cycles() various
instances, one for each architecture supported. Even better a macro
for each architecture like this example below (untested code, just for
exemplification):
ts_nsec = local_clock();
#ifdef CONFIG_EARLY_CYCLES_KHZ
#if defined(CONFIG_ARM64)
#include <asm/sysreg.h>
#define early_unsafe_cycles read_sysreg(cntvct_el0);
#elif defined(CONFIG_X86_64)
#define early_unsafe_cycles rdtsc()
#elif defined(CONFIG_RISCV_TIMER)
#define early_unsafe_cycles ({ u64 val; asm volatile("rdtime %0" :
"=r"(val)); val; })
#else
#define early_unsafe_cycles 0
#endif
+ if (unlikely(!ts_nsec))
+ ts_nsec = early_times_ns();
#endif // CONFIG_EARLY_CYCLES_KHZ
caller_id = printk_caller_id();
While keeping architectures separate is for abstraction layer best
practice, in very specific cases abstraction can be a meaningless
concept or much less important than having a single file for a single
feature (the complementary way of organising stuff). Because in Linux
the abstraction layer approach applies for architectures, the gap
between aesthetic and a specific case like an early boot macros set
hack for debugging is to clarify the exception from the general rule
in the header itself.
On Wed, 15 Apr 2026 at 00:38, Thomas Gleixner <tglx@kernel.org> wrote: (to TIM)
>
> Ask your favourite AI assistant for an opinion.
(Roberto maintaining the cold blood in front of "Tim's overlooking a
false positive gcc warning" and check Thomas suggestion just for the
sake of curiosity)
Gemini Thinking AI: Whether or not you can justify this exception
depends entirely on whether this is a permanent feature or a transient
debug hack.
Cheers, R-
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox