RE: [PATCH v3] printk: fix zero-valued printk timestamps in early boot

Thomas Gleixner
2026-03-31T09:10:17Z

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