2019-08-13 09:07:25

by Arnd Bergmann

[permalink] [raw]
Subject: New kernel interface for sys_tz and timewarp?

The riscv32 kernel port uses the new time64 syscall interface that has no
'settimeofday', only 'clock_settime64'. During the review of the glibc port,
the question arose how to deal with the (old, horrible, deprecated) timezone
portion of the settimeofday() libc API.

Typical uses of timezones in gettimeofday() are broken and should use
the normal user space timezone handling built into localtime() instead,
so the initial idea was to just not bother on new architectures and
break any application at build time that tries to access the struct timezone
members to ensure they are finally fixed, and also do the same thing
across all architectures for consistency.

As it turns out, both util-linux/hwclock and systemd make use of the
timezone field in settimeofday purely for the purpose of setting the
kernel itself into a known state, for three traditional uses:

- gettimeofday reports the timezone that was last set with settimeofday,
something that is highly discouraged relying on but that has always
worked.

- a few device drivers and file systems (e.g. fs/fat, full list below) are
documented as storing timestamps in local time, so the global sys_tz variable
is used to decide the offset, in addition to a in-superblock offset in most
cases.

- on x86, windows dual-boot has traditionally (since linux-0.12) allowed the
hack that the first settimeofday() call after boot decides whether the RTC
is interpreted as localtime or UTC. This is particularly important because
with NTP enabled, the time warped mode also updates the RTC with
the kernel time every 11 minutes. See kernel/time/ntp.c:sync_hw_clock()
and timekeeping_warp_clock() .

The relevant discussion on libc-alpha and on for systemd is archived at:
https://patchwork.ozlabs.org/patch/1121610/
https://github.com/systemd/systemd/issues/13305

Now, to the actual questions:

* Should we allow setting the sys_tz on new architectures that use only
time64 interfaces at all, or should we try to get away from that anyway?

* Should the NTP timewarp setting ("int persistent_clock_is_local" and
its offset) be controllable separately from the timezone used in other
drivers?

* If we want keep having a way to set the sys_tz, what interface
should that use?

Suggestions so far include
- adding a clock_settimeofday_time64() syscall on all 32-bit architectures to
maintain the traditional behavior,
- adding a sysctl interface for accessing sys_tz.tz_tminuteswest,
- using a new field in 'struct timex' for the timewarp offset, and
- adding an ioctl command on /dev/rtc/ to control the timewarp
offset of that particular device.

Arnd
---
Appendix A: full list of kernel code using sys_tz

$ git grep -wl sys_tz drivers/ fs/ net/
drivers/media/platform/vivid/vivid-rds-gen.c
drivers/media/platform/vivid/vivid-vbi-gen.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-sas.c
drivers/scsi/aacraid/commsup.c
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/mvumi.c
drivers/scsi/mvumi.h
drivers/scsi/smartpqi/smartpqi_init.c
fs/affs/amigaffs.c
fs/affs/inode.c
fs/fat/misc.c
fs/hfs/hfs_fs.h
fs/hfs/inode.c
fs/hfs/sysdep.c
fs/hpfs/hpfs_fn.h
fs/udf/udftime.c
net/netfilter/xt_time.c


2019-08-13 17:14:00

by John Stultz

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Tue, Aug 13, 2019 at 2:06 AM Arnd Bergmann <[email protected]> wrote:
> Now, to the actual questions:
>
> * Should we allow setting the sys_tz on new architectures that use only
> time64 interfaces at all, or should we try to get away from that anyway?

So I'd probably cut this question a bit differently:

1) Do we want to deprecate sys_tz tracking in the kernel? If new
architectures don't have ways to set it, for consistency we should
probably deprecate in-kernel tracking of that value (start returning
an error when folks try to set it and always return 0 when its
accessed).

2) If we deprecate the sys_tz tracking in the kernel, how do we
address the in-kernel systohc syncing with local-time (non-UTC) RTCs
on x86 systems (I'm not aware of other arches that utilize non-UTC
RTCs)


> * Should the NTP timewarp setting ("int persistent_clock_is_local" and
> its offset) be controllable separately from the timezone used in other
> drivers?

For the discussion, I'm not sure I'd call this NTP timewarp, but maybe
systohc rtc offset is more clear?

Its really not connected to NTP, except that we only want to
automatically sync the RTC to the system clock when we know the system
clock is right (and that signal comes from NTP).


> * If we want keep having a way to set the sys_tz, what interface
> should that use?
>
> Suggestions so far include
> - adding a clock_settimeofday_time64() syscall on all 32-bit architectures to
> maintain the traditional behavior,

If the answer to #1 above is no, we want to preserve the
functionality, then I think this is probably the best solution.
Alternatively one could add a new syscall/sysctrl that just sets the
timezone, but most 64 bit architectures already have
clock_settimeofday_time64() equiv call, so this is probably the least
duplicative.

> - adding a sysctl interface for accessing sys_tz.tz_tminuteswest,
> - using a new field in 'struct timex' for the timewarp offset, and

I'd push back on this one. The timewarp offset is really a RTC offset,
and has nothing to do with ntp, so we shoudn't be adding things to
adjtimex about it.

> - adding an ioctl command on /dev/rtc/ to control the timewarp
> offset of that particular device.

If the answer to #1 above is yes, then I think this makes more sense
to me, since the offset is a property of how we interpret the RTC (ie:
is it UTC or local time).

Getting more aggressive, from irc discussions, it sounded like
Alexandre would like to deprecate the in-kernel systohc and hctosys
logic, so if that were the case, and the answer to #1 above was yes,
then we could probably skip all of this and just drop systohc work and
keep the UTC/local logic to userland.

thanks
-john

2019-08-13 17:56:20

by Paul Eggert

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

Linus Torvalds wrote:
> I assume/think that glibc uses (a) environment
> variables and (b) a filesystem-set default (per-user file with a
> system-wide default? I don't know what people do).
glibc relies on the TZ environment variable, with a system-wide default
specified in /etc/localtime or suchlike (there is no per-user default). glibc
ignores the kernel's 'struct timezone' settings for of this, as 'struct
timezone' is obsolete/vestigial and doesn't contain enough info to do proper
conversions anyway.

I've been thinking of adding NetBSD's localtime_rz etc. functions to glibc.
These functions let user programs specify the time zone for each conversion
between time_t and local time, and simplify and/or speed up applications dealing
with many requests coming from different time zones. These functions also ignore
'struct timezone'.

There's no need to put any of this stuff into the kernel.

2019-08-13 18:31:28

by Linus Torvalds

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Tue, Aug 13, 2019 at 2:06 AM Arnd Bergmann <[email protected]> wrote:
>
> * Should we allow setting the sys_tz on new architectures that use only
> time64 interfaces at all, or should we try to get away from that anyway?

We should not do TZ on a kernel level at all. At least not a global
one. It makes no sense.

If the original TZ had been defined to have some sane model (perhaps
per session? Something like that), it would be worth doing. As it is,
a global TZ is just plain wrong. Per process would be sane (but
largely useless, I suspect).

> * Should the NTP timewarp setting ("int persistent_clock_is_local" and
> its offset) be controllable separately from the timezone used in other
> drivers?
>
> * If we want keep having a way to set the sys_tz, what interface
> should that use?

I suspect we need to have _some_ way to set the kernel TZ for legacy
reasons, but it should be deprecated and if we can make do without it
entirely on architectures where the legacy doesn't make sense, then
all the better.

I suspect the only actual _valid_ use in the kernel for a time zone
setting is likely for RTC clock setting, but even that isn't really
"global", as much as "per RTC".

That said, if glibc has some sane semantics for TZ, maybe the kernel
can help with that. But I assume/think that glibc uses (a) environment
variables and (b) a filesystem-set default (per-user file with a
system-wide default? I don't know what people do). I suspect the
kernel can't really do any better.

Linus

2019-08-13 19:33:29

by Florian Weimer

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

* Paul Eggert:

> Linus Torvalds wrote:
>> I assume/think that glibc uses (a) environment
>> variables and (b) a filesystem-set default (per-user file with a
>> system-wide default? I don't know what people do).

> glibc relies on the TZ environment variable, with a system-wide
> default specified in /etc/localtime or suchlike (there is no
> per-user default). glibc ignores the kernel's 'struct timezone'
> settings for of this, as 'struct timezone' is obsolete/vestigial and
> doesn't contain enough info to do proper conversions anyway.

I think the configuration value that settimeofday changes is not
actually a time zone, but an time offset used to interpret various
things, mostly in a dual-boot environment with Windows, apparently
(Like the default time offset for extracting timetamps from FAT
volumes.)

This data has to come from *somewhere*. The TZ variable and
/etc/localtime cover something else entirely.

Maybe it is possible to replace these things with other mechanisms
which exist today. For example, the mount program could read a
configuration file to determine the system default for the time_offset
mount option and apply the value automatically. The real-time clock
offset could be maintained by whatever mechanism hwclock uses.

I think whatever we end up doing, we should maintain consistency after
a system upgrade after architectures. It does not make sense to keep
using the settimeofday hack on amd64 indefinitely, and switch to a
different mechanism on RV32, so that the two ways of supplying the
offset are never reconciled across architectures.

2019-08-13 20:06:04

by Arnd Bergmann

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Tue, Aug 13, 2019 at 9:31 PM Florian Weimer <[email protected]> wrote:
> * Paul Eggert:
> > Linus Torvalds wrote:
> >> I assume/think that glibc uses (a) environment
> >> variables and (b) a filesystem-set default (per-user file with a
> >> system-wide default? I don't know what people do).
>
> > glibc relies on the TZ environment variable, with a system-wide
> > default specified in /etc/localtime or suchlike (there is no
> > per-user default). glibc ignores the kernel's 'struct timezone'
> > settings for of this, as 'struct timezone' is obsolete/vestigial and
> > doesn't contain enough info to do proper conversions anyway.
>
> I think the configuration value that settimeofday changes is not
> actually a time zone, but an time offset used to interpret various
> things, mostly in a dual-boot environment with Windows, apparently
> (Like the default time offset for extracting timetamps from FAT
> volumes.)
>
> This data has to come from *somewhere*. The TZ variable and
> /etc/localtime cover something else entirely.

systemd and hwclock call localtime_r() when setting initial
system time an tz information at boot time, so that information
comes from /etc/localtime.

/etc/adjtime is used to determine whether to set warp the
time at boot and rtc update or not warp it.

Arnd

2019-08-13 21:49:06

by Alexandre Belloni

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On 13/08/2019 10:10:53-0700, John Stultz wrote:
> On Tue, Aug 13, 2019 at 2:06 AM Arnd Bergmann <[email protected]> wrote:
> > Now, to the actual questions:
> >
> > * Should we allow setting the sys_tz on new architectures that use only
> > time64 interfaces at all, or should we try to get away from that anyway?
>
> So I'd probably cut this question a bit differently:
>
> 1) Do we want to deprecate sys_tz tracking in the kernel? If new
> architectures don't have ways to set it, for consistency we should
> probably deprecate in-kernel tracking of that value (start returning
> an error when folks try to set it and always return 0 when its
> accessed).
>
> 2) If we deprecate the sys_tz tracking in the kernel, how do we
> address the in-kernel systohc syncing with local-time (non-UTC) RTCs
> on x86 systems (I'm not aware of other arches that utilize non-UTC
> RTCs)
>
>
> > * Should the NTP timewarp setting ("int persistent_clock_is_local" and
> > its offset) be controllable separately from the timezone used in other
> > drivers?
>
> For the discussion, I'm not sure I'd call this NTP timewarp, but maybe
> systohc rtc offset is more clear?
>
> Its really not connected to NTP, except that we only want to
> automatically sync the RTC to the system clock when we know the system
> clock is right (and that signal comes from NTP).
>

Well, the only function in systohc.c is rtc_set_ntp_time and its only
user is kernel/time/ntp.c. That why I suggested on IRC to move it to the
kernel timekeeping instead of having it in the rtc subsystem. Also, this
function only works properly on systems with an MC146818 compatible RTC.

>
> > * If we want keep having a way to set the sys_tz, what interface
> > should that use?
> >
> > Suggestions so far include
> > - adding a clock_settimeofday_time64() syscall on all 32-bit architectures to
> > maintain the traditional behavior,
>
> If the answer to #1 above is no, we want to preserve the
> functionality, then I think this is probably the best solution.
> Alternatively one could add a new syscall/sysctrl that just sets the
> timezone, but most 64 bit architectures already have
> clock_settimeofday_time64() equiv call, so this is probably the least
> duplicative.
>
> > - adding a sysctl interface for accessing sys_tz.tz_tminuteswest,
> > - using a new field in 'struct timex' for the timewarp offset, and
>
> I'd push back on this one. The timewarp offset is really a RTC offset,
> and has nothing to do with ntp, so we shoudn't be adding things to
> adjtimex about it.
>
> > - adding an ioctl command on /dev/rtc/ to control the timewarp
> > offset of that particular device.
>
> If the answer to #1 above is yes, then I think this makes more sense
> to me, since the offset is a property of how we interpret the RTC (ie:
> is it UTC or local time).
>

The main issue I have with that is that while the offset is possibly
specific to an RTC, it is something that is not used by the rtc
subsystem as this offset handling is done by the caller. i.e. hwclock
handles local time vs UTC time. That is why sync_rtc_clock also had to
do it. It would be awkward to have different paths in the rtc core
depending on whether the set_time call is coming from userspace or the
kernel.

> Getting more aggressive, from irc discussions, it sounded like
> Alexandre would like to deprecate the in-kernel systohc and hctosys
> logic, so if that were the case, and the answer to #1 above was yes,
> then we could probably skip all of this and just drop systohc work and
> keep the UTC/local logic to userland.
>

My point is that userspace has all the necessary info to do a correct
job. It is even more flexible because currently the kernel is limited
to the rtc selected at compile time (this often ends up being rtc0 which
may or may not be functional or battery backed) and the 11 minute
interval is fixed.


--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

2019-08-13 21:57:27

by Alexandre Belloni

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On 13/08/2019 10:30:34-0700, Linus Torvalds wrote:
> On Tue, Aug 13, 2019 at 2:06 AM Arnd Bergmann <[email protected]> wrote:
> >
> > * Should we allow setting the sys_tz on new architectures that use only
> > time64 interfaces at all, or should we try to get away from that anyway?
>
> We should not do TZ on a kernel level at all. At least not a global
> one. It makes no sense.
>
> If the original TZ had been defined to have some sane model (perhaps
> per session? Something like that), it would be worth doing. As it is,
> a global TZ is just plain wrong. Per process would be sane (but
> largely useless, I suspect).
>
> > * Should the NTP timewarp setting ("int persistent_clock_is_local" and
> > its offset) be controllable separately from the timezone used in other
> > drivers?
> >
> > * If we want keep having a way to set the sys_tz, what interface
> > should that use?
>
> I suspect we need to have _some_ way to set the kernel TZ for legacy
> reasons, but it should be deprecated and if we can make do without it
> entirely on architectures where the legacy doesn't make sense, then
> all the better.
>
> I suspect the only actual _valid_ use in the kernel for a time zone
> setting is likely for RTC clock setting, but even that isn't really
> "global", as much as "per RTC".
>

Userspace doesn't need help from the kernel to set the RTC using local
time if necessary, this info is in /etc/adjtime and hwclock uses it
correctly. It is only needed when the kernel sets the rtc time

> That said, if glibc has some sane semantics for TZ, maybe the kernel
> can help with that. But I assume/think that glibc uses (a) environment
> variables and (b) a filesystem-set default (per-user file with a
> system-wide default? I don't know what people do). I suspect the
> kernel can't really do any better.
>
> Linus

--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

2019-08-14 00:10:28

by Theodore Ts'o

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Tue, Aug 13, 2019 at 10:30:34AM -0700, Linus Torvalds wrote:
>
> I suspect the only actual _valid_ use in the kernel for a time zone
> setting is likely for RTC clock setting, but even that isn't really
> "global", as much as "per RTC".

As I recall (and I may or may not have been original for the original
sys_tz; it was many years ago, and my memories of 1992 are a bit
fuzzy) the only reason why we added it was because x86 systems that
were dual-booting with Windows had a RTC which ticked localtime, and
originally, the system time was fetched from the RTC in early boot,
and then when the timezone was set, the time would be warped so it
would be correct.

Trying to use this for anything else is probably a bad idea, and in a
world where we can have initrd's and reading the RTC gets done by
userspace as opposed to kernel, it probably doesn't make any sence to
keep it.

Cheers,

- Ted

2019-08-14 08:33:22

by Arnd Bergmann

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Wed, Aug 14, 2019 at 2:06 AM Theodore Y. Ts'o <[email protected]> wrote:
> On Tue, Aug 13, 2019 at 10:30:34AM -0700, Linus Torvalds wrote:
> >
> > I suspect the only actual _valid_ use in the kernel for a time zone
> > setting is likely for RTC clock setting, but even that isn't really
> > "global", as much as "per RTC".
>
> As I recall (and I may or may not have been original for the original
> sys_tz; it was many years ago, and my memories of 1992 are a bit
> fuzzy) the only reason why we added it was because x86 systems that
> were dual-booting with Windows had a RTC which ticked localtime, and
> originally, the system time was fetched from the RTC in early boot,
> and then when the timezone was set, the time would be warped so it
> would be correct.

I think this was the case from 1992 to commit 84e345e4e209 ("time,
Fix setting of hardware clock in NTP code") in 2013, when we started
taking the time warp into account during the periodic sync_cmos_clock()
call from kernel/time/ntp.c.

> Trying to use this for anything else is probably a bad idea, and in a
> world where we can have initrd's and reading the RTC gets done by
> userspace as opposed to kernel, it probably doesn't make any sence to
> keep it.

As Alexandre keeps pointing out, we really ought to do this from user
space, but in systemd today still relies on the kernel setting the
initial time using CONFIG_RTC_HCTOSYS, but this breaks e.g.
when the rtc driver itself is a loadable module.

From what I understand it would be easy for systemd to sync the
rtc to system time at boot and let distros disable CONFIG_RTC_HCTOSYS,
but it still has to do the initial settimeofday(NULL, tz) call to
ensure the correct offset is used for sync_hw_clock() in case
CONFIG_GENERIC_CMOS_UPDATE or CONFIG_RTC_SYSTOHC
are set (which they tend to be at the moment).

In the long run, a distro can decide to avoid this all, once these
bits come together:

- glibc stops passing the caller timezone argument to the kernel
- the distro kernel disables CONFIG_RTC_HCTOSYS,
CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
- systemd reads the RTC at boot and sets the system
time according to the configuration in /etc/localtime and /etc/adjtime
- systemd, ntp or something else in user space takes care of the periodic
rtc update, again taking configuration into account.

When someone mixes today's glibc/systemd/kernel with other
components past that migration, things can go wrong somewhat
annoying but non-fatal ways:
- Users that dual-boot with windows may have to force Windows
to set the RTC to UTC mode rather than setting Linux to
localtime.
- if neither the kernel not user space do the periodic RTC update,
it may be out of sync and cause a larger time jump after the
next boot time ntp synchronization

Creating a kernel interface for systemd to see or contol how the
11-minute update is done in the kernel would help part of that
transition.

Arnd

2019-08-14 09:18:39

by Lennart Poettering

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:

> - glibc stops passing the caller timezone argument to the kernel
> - the distro kernel disables CONFIG_RTC_HCTOSYS,
> CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE

What's the benefit of letting userspace do this? It sounds a lot more
fragile to leave this syncing to userspace if the kernel can do this
trivially on its own.

IIRC there are uses in kernel that use CLOCK_REALTIME already before
userspace starts. e.g. iirc networking generally prefers
CLOCK_REALTIME timestamps over CLOCK_MONOTONIC timestamps
(i.e. SO_TIMESTAMP and friends are still CLOCK_REALTIME only so far,
unless I am missing something). If the kernel comes up with a
CLOCK_REALTIME that starts at 0 this is pretty annoying I
figure... Hence, so far I suggested to distros to continue turning on
the options above, and let the kernel do this on its own without
involving userspace in that.

Lennart

--
Lennart Poettering, Berlin

2019-08-14 09:34:27

by Alexandre Belloni

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
>
> > - glibc stops passing the caller timezone argument to the kernel
> > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
>
> What's the benefit of letting userspace do this? It sounds a lot more
> fragile to leave this syncing to userspace if the kernel can do this
> trivially on its own.
>

It does it trivially and badly:

- hctosys will always think the RTC is in UTC so if the RTC is in
local time, you will anyway have up to 12 hours difference until
userspace fixes that.

- the way systohc and hctosys are working will lead up to a 2 second
drift until ntp runs which is an issue for NTP stratum servers. My
tests show that there is a way for userspace to reduce that to tens of
nanoseconds but this means having a one or two seconds delay when setting
and reading the time. I want that to be opt-in.

- the RTC to be used for hctosys and systohc is hardcoded in Kconfig
and distro usually let the default rtc0 but many platforms have a non
functional RTC that ends up being rtc0. I would prefer that to be a
userspace configuration change instead of a kernel configuration change

> IIRC there are uses in kernel that use CLOCK_REALTIME already before
> userspace starts. e.g. iirc networking generally prefers
> CLOCK_REALTIME timestamps over CLOCK_MONOTONIC timestamps
> (i.e. SO_TIMESTAMP and friends are still CLOCK_REALTIME only so far,
> unless I am missing something). If the kernel comes up with a
> CLOCK_REALTIME that starts at 0 this is pretty annoying I
> figure... Hence, so far I suggested to distros to continue turning on
> the options above, and let the kernel do this on its own without
> involving userspace in that.
>
> Lennart
>
> --
> Lennart Poettering, Berlin

--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

2019-08-14 12:17:17

by Lennart Poettering

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Mi, 14.08.19 11:32, Alexandre Belloni ([email protected]) wrote:

> On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> >
> > > - glibc stops passing the caller timezone argument to the kernel
> > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> >
> > What's the benefit of letting userspace do this? It sounds a lot more
> > fragile to leave this syncing to userspace if the kernel can do this
> > trivially on its own.
> >
>
> It does it trivially and badly:
>
> - hctosys will always think the RTC is in UTC so if the RTC is in
> local time, you will anyway have up to 12 hours difference until
> userspace fixes that.

Sure, but 12h off is not that bad, much better than being 39years
off. Moreover, it's off only for those who actually dual boot Windows
and make use of the RTC-in-local-time functionality. For them having
the time slightly off during early boot is not great but also not
totally afwul, and the whole concept of RTC-in-local-time is not that
great anyway. It's not a reason to penalize everybody else who has the
RTC in UTC, as they should.

> - the RTC to be used for hctosys and systohc is hardcoded in Kconfig
> and distro usually let the default rtc0 but many platforms have a non
> functional RTC that ends up being rtc0. I would prefer that to be a
> userspace configuration change instead of a kernel configuration
> change

Well, but how do you think userspace would figure out which RTC to use
in a way the kernel couldn't do equally well or better?

On PCs at least it's very clear which RTC driver is the right one. And
if non-PC hardware comes with borked RTC hw then it's probably a good
idea not to compile support for such RTCs into the kernel in the first
place...

I know that there are some environments where RTC devices are compiled
as modules. But that means they are loaded relatively late during the
boot process, i.e. at a time where udevd is started and triggers all
busses, but that's *very* late in most cases, and it woud suck
having timestamps in early-boot logs that are 39y off until that
point.

I'd argue that in the vast majority of cases the person building the
kernel for a device knows very well which RTC is connected to the
device they are interested in, and should just build that driver in,
and don't bother with userspace complexity, later userspace module
loading or anything like that.

Lennart

--
Lennart Poettering, Berlin

2019-08-14 16:27:35

by David Laight

[permalink] [raw]
Subject: RE: New kernel interface for sys_tz and timewarp?

From: Theodore Y. Ts'o
> Sent: 14 August 2019 01:06
> On Tue, Aug 13, 2019 at 10:30:34AM -0700, Linus Torvalds wrote:
> >
> > I suspect the only actual _valid_ use in the kernel for a time zone
> > setting is likely for RTC clock setting, but even that isn't really
> > "global", as much as "per RTC".
>
> As I recall (and I may or may not have been original for the original
> sys_tz; it was many years ago, and my memories of 1992 are a bit
> fuzzy) the only reason why we added it was because x86 systems that
> were dual-booting with Windows had a RTC which ticked localtime, and
> originally, the system time was fetched from the RTC in early boot,
> and then when the timezone was set, the time would be warped so it
> would be correct.

x86 systems are very likely to have the RTC set by the bios config.
In which case it will almost certainly get set to local time.
It is certainly the default for windows installs - I don't even know
if you have any other option.

The 'real fun' (tm) happens when a dual boot system changes from
winter to summer time.
ISTR that it is quite easy to get both (or more) OS to change the
RTC by an hour (I went home an hour early one year).
Although the x86 RTC chip has a bit defined for 'summertime', nothing
sets it (at least when I looked).

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

2019-08-14 16:50:07

by H. Peter Anvin

[permalink] [raw]
Subject: RE: New kernel interface for sys_tz and timewarp?

On August 14, 2019 9:26:36 AM PDT, David Laight <[email protected]> wrote:
>From: Theodore Y. Ts'o
>> Sent: 14 August 2019 01:06
>> On Tue, Aug 13, 2019 at 10:30:34AM -0700, Linus Torvalds wrote:
>> >
>> > I suspect the only actual _valid_ use in the kernel for a time zone
>> > setting is likely for RTC clock setting, but even that isn't really
>> > "global", as much as "per RTC".
>>
>> As I recall (and I may or may not have been original for the original
>> sys_tz; it was many years ago, and my memories of 1992 are a bit
>> fuzzy) the only reason why we added it was because x86 systems that
>> were dual-booting with Windows had a RTC which ticked localtime, and
>> originally, the system time was fetched from the RTC in early boot,
>> and then when the timezone was set, the time would be warped so it
>> would be correct.
>
>x86 systems are very likely to have the RTC set by the bios config.
>In which case it will almost certainly get set to local time.
>It is certainly the default for windows installs - I don't even know
>if you have any other option.
>
>The 'real fun' (tm) happens when a dual boot system changes from
>winter to summer time.
>ISTR that it is quite easy to get both (or more) OS to change the
>RTC by an hour (I went home an hour early one year).
>Although the x86 RTC chip has a bit defined for 'summertime', nothing
>sets it (at least when I looked).
>
> David
>
>-
>Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes,
>MK1 1PT, UK
>Registration No: 1397386 (Wales)

I believe Windows 10 changed the default RTC to UTC, although perhaps only if running under UEFI.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2019-08-15 15:01:01

by Arnd Bergmann

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Wed, Aug 14, 2019 at 6:48 PM <[email protected]> wrote:
>
> I believe Windows 10 changed the default RTC to UTC, although perhaps
> only if running under UEFI.

I looked at the efi rtc driver now, and found two things:

- The EFI get_time() call passes down timezone information, so we know what
UTC is, and can just ignore the timezone. This is good.

- The RTC_DRV_EFI depends on !X86 as of commit 7efe665903d0 ("rtc:
Disable EFI rtc for x86"). This unfortunately means we always fall back to
either the rtc-cmos driver or the x86 specific read_persistent_clock64()
implementation even when the EFI RTC is reliable.

If 64-bit Windows relies on a working EFI RTC implementation, we could
decide to leave the driver enabled on 64-bit and only disable it for
32-bit EFI. That way, future distros would no longer have to worry about
the localtime hack, at least the ones that have dropped support for
32-bit x86 kernels.

Arnd

2019-08-15 16:03:54

by H. Peter Anvin

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On August 15, 2019 8:05:30 AM PDT, "Theodore Y. Ts'o" <[email protected]> wrote:
>On Thu, Aug 15, 2019 at 03:22:45PM +0200, Arnd Bergmann wrote:
>> If 64-bit Windows relies on a working EFI RTC implementation, we
>could
>> decide to leave the driver enabled on 64-bit and only disable it for
>> 32-bit EFI. That way, future distros would no longer have to worry
>about
>> the localtime hack, at least the ones that have dropped support for
>> 32-bit x86 kernels.
>
>... and who have also dropped support for legacy (non-UEFI) 64-bit
>boot. Keep in mind that even for distributions which may install with
>UEFI by default, if people have been upgrading from (for example)
>Debian Jessie to Stretch to Buster, they may still be using non-UEFI
>boot. This might be especially true on small Linode servers (such as,
>for example, the one which is currently running my mail smarthost....)
>
> - Ted

There is also the ACPI TAD device, which can be used to expose this through ACPI. We might also be able to request that the ACPI information for the RTC be augmented with a CMOS timezone location.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2019-08-15 17:15:40

by Theodore Ts'o

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Thu, Aug 15, 2019 at 03:22:45PM +0200, Arnd Bergmann wrote:
> If 64-bit Windows relies on a working EFI RTC implementation, we could
> decide to leave the driver enabled on 64-bit and only disable it for
> 32-bit EFI. That way, future distros would no longer have to worry about
> the localtime hack, at least the ones that have dropped support for
> 32-bit x86 kernels.

... and who have also dropped support for legacy (non-UEFI) 64-bit
boot. Keep in mind that even for distributions which may install with
UEFI by default, if people have been upgrading from (for example)
Debian Jessie to Stretch to Buster, they may still be using non-UEFI
boot. This might be especially true on small Linode servers (such as,
for example, the one which is currently running my mail smarthost....)

- Ted

2019-08-19 11:10:18

by Karel Zak

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Wed, Aug 14, 2019 at 11:32:08AM +0200, Alexandre Belloni wrote:
> On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> >
> > > - glibc stops passing the caller timezone argument to the kernel
> > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> >
> > What's the benefit of letting userspace do this? It sounds a lot more
> > fragile to leave this syncing to userspace if the kernel can do this
> > trivially on its own.

Good point, why CONFIG_RTC_SYSTOHC has been added to the kernel?

If I good remember than it's because synchronize userspace hwclock
with rtc is pretty fragile and frustrating. We have improved this
hwclock code many times and it will never be perfect. See for example
hwclock --delay= option, sometimes hwclock has no clue about RTC behaviour.

> It does it trivially and badly:
>
> - hctosys will always think the RTC is in UTC so if the RTC is in
> local time, you will anyway have up to 12 hours difference until
> userspace fixes that.

Cannot we provide all necessary information for example on kernel
command line, or/and as rtc module option?

Karel

--
Karel Zak <[email protected]>
http://karelzak.blogspot.com

2019-08-19 13:46:06

by Thomas Gleixner

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Mon, 19 Aug 2019, Karel Zak wrote:
> On Wed, Aug 14, 2019 at 11:32:08AM +0200, Alexandre Belloni wrote:
> > On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> > >
> > > > - glibc stops passing the caller timezone argument to the kernel
> > > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> > >
> > > What's the benefit of letting userspace do this? It sounds a lot more
> > > fragile to leave this syncing to userspace if the kernel can do this
> > > trivially on its own.
>
> Good point, why CONFIG_RTC_SYSTOHC has been added to the kernel?

023f333a99ce ("NTP: Add a CONFIG_RTC_SYSTOHC configuration")

2019-08-19 13:52:06

by Thomas Gleixner

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Mon, 19 Aug 2019, Thomas Gleixner wrote:
> On Mon, 19 Aug 2019, Karel Zak wrote:
> > On Wed, Aug 14, 2019 at 11:32:08AM +0200, Alexandre Belloni wrote:
> > > On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > > > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> > > >
> > > > > - glibc stops passing the caller timezone argument to the kernel
> > > > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> > > >
> > > > What's the benefit of letting userspace do this? It sounds a lot more
> > > > fragile to leave this syncing to userspace if the kernel can do this
> > > > trivially on its own.
> >
> > Good point, why CONFIG_RTC_SYSTOHC has been added to the kernel?
>
> 023f333a99ce ("NTP: Add a CONFIG_RTC_SYSTOHC configuration")

Just for the record. Not a single defconfig enables, but it's selected by
SPARC for whatever reason.

Thanks,

tglx

2019-08-20 18:47:13

by Alexandre Belloni

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On 19/08/2019 15:49:24+0200, Thomas Gleixner wrote:
> On Mon, 19 Aug 2019, Thomas Gleixner wrote:
> > On Mon, 19 Aug 2019, Karel Zak wrote:
> > > On Wed, Aug 14, 2019 at 11:32:08AM +0200, Alexandre Belloni wrote:
> > > > On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > > > > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> > > > >
> > > > > > - glibc stops passing the caller timezone argument to the kernel
> > > > > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > > > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> > > > >
> > > > > What's the benefit of letting userspace do this? It sounds a lot more
> > > > > fragile to leave this syncing to userspace if the kernel can do this
> > > > > trivially on its own.
> > >
> > > Good point, why CONFIG_RTC_SYSTOHC has been added to the kernel?
> >
> > 023f333a99ce ("NTP: Add a CONFIG_RTC_SYSTOHC configuration")
>
> Just for the record. Not a single defconfig enables, but it's selected by
> SPARC for whatever reason.
>

I think the issue is that most of the common distributions enable it.

--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

2019-08-20 18:49:18

by Alexandre Belloni

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On 19/08/2019 15:43:03+0200, Thomas Gleixner wrote:
> On Mon, 19 Aug 2019, Karel Zak wrote:
> > On Wed, Aug 14, 2019 at 11:32:08AM +0200, Alexandre Belloni wrote:
> > > On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > > > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> > > >
> > > > > - glibc stops passing the caller timezone argument to the kernel
> > > > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> > > >
> > > > What's the benefit of letting userspace do this? It sounds a lot more
> > > > fragile to leave this syncing to userspace if the kernel can do this
> > > > trivially on its own.
> >
> > Good point, why CONFIG_RTC_SYSTOHC has been added to the kernel?
>
> 023f333a99ce ("NTP: Add a CONFIG_RTC_SYSTOHC configuration")

This answers only half the question. The follow up is then why do we
need update_persistent_clock?

--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

2019-08-20 18:59:45

by Alexandre Belloni

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On 19/08/2019 13:09:03+0200, Karel Zak wrote:
> On Wed, Aug 14, 2019 at 11:32:08AM +0200, Alexandre Belloni wrote:
> > On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> > >
> > > > - glibc stops passing the caller timezone argument to the kernel
> > > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> > >
> > > What's the benefit of letting userspace do this? It sounds a lot more
> > > fragile to leave this syncing to userspace if the kernel can do this
> > > trivially on its own.
>
> Good point, why CONFIG_RTC_SYSTOHC has been added to the kernel?
>
> If I good remember than it's because synchronize userspace hwclock
> with rtc is pretty fragile and frustrating. We have improved this
> hwclock code many times and it will never be perfect. See for example
> hwclock --delay= option, sometimes hwclock has no clue about RTC behaviour.
>

With a bit of care, we can reliably set the rtc to the system time from
userspace. It takes a bit of time (up to 2 seconds) but it can be
reliably set with an accuracy of a few ms on a slow system and an rtc on
a slow bus or a few ns with a fast system and a fast bus.
I know I did say I would implement it in hwclock and I still didn't
(sorry) but we could do better than the --delay option.

> > It does it trivially and badly:
> >
> > - hctosys will always think the RTC is in UTC so if the RTC is in
> > local time, you will anyway have up to 12 hours difference until
> > userspace fixes that.
>
> Cannot we provide all necessary information for example on kernel
> command line, or/and as rtc module option?
>

We could but from a distro point of view, would that be convenient?

--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

2019-08-27 16:30:37

by Arnd Bergmann

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On Tue, Aug 20, 2019 at 8:58 PM Alexandre Belloni
<[email protected]> wrote:
>
> On 19/08/2019 13:09:03+0200, Karel Zak wrote:
> > On Wed, Aug 14, 2019 at 11:32:08AM +0200, Alexandre Belloni wrote:
> > > On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > > > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> > > >
> > > > > - glibc stops passing the caller timezone argument to the kernel
> > > > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> > > >
> > > > What's the benefit of letting userspace do this? It sounds a lot more
> > > > fragile to leave this syncing to userspace if the kernel can do this
> > > > trivially on its own.
> >
> > Good point, why CONFIG_RTC_SYSTOHC has been added to the kernel?
> >
> > If I good remember than it's because synchronize userspace hwclock
> > with rtc is pretty fragile and frustrating. We have improved this
> > hwclock code many times and it will never be perfect. See for example
> > hwclock --delay= option, sometimes hwclock has no clue about RTC behaviour.
> >
>
> With a bit of care, we can reliably set the rtc to the system time from
> userspace. It takes a bit of time (up to 2 seconds) but it can be
> reliably set with an accuracy of a few ms on a slow system and an rtc on
> a slow bus or a few ns with a fast system and a fast bus.
> I know I did say I would implement it in hwclock and I still didn't
> (sorry) but we could do better than the --delay option.

Would you use the regular RTC_SET_TIME ioctl for that, or
add a new RTC_SYS_TO_HC command that takes an explicit
offset? It sounds to me that the synchronization bit (actually
waiting for the right moment to update the rtc registers) is better
done in the kernel, while the decision about the offset and when
to call into the driver is better done in user space.

Arnd

2019-08-27 16:33:20

by Alexandre Belloni

[permalink] [raw]
Subject: Re: New kernel interface for sys_tz and timewarp?

On 27/08/2019 18:27:32+0200, Arnd Bergmann wrote:
> On Tue, Aug 20, 2019 at 8:58 PM Alexandre Belloni
> <[email protected]> wrote:
> >
> > On 19/08/2019 13:09:03+0200, Karel Zak wrote:
> > > On Wed, Aug 14, 2019 at 11:32:08AM +0200, Alexandre Belloni wrote:
> > > > On 14/08/2019 11:09:36+0200, Lennart Poettering wrote:
> > > > > On Mi, 14.08.19 10:31, Arnd Bergmann ([email protected]) wrote:
> > > > >
> > > > > > - glibc stops passing the caller timezone argument to the kernel
> > > > > > - the distro kernel disables CONFIG_RTC_HCTOSYS,
> > > > > > CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
> > > > >
> > > > > What's the benefit of letting userspace do this? It sounds a lot more
> > > > > fragile to leave this syncing to userspace if the kernel can do this
> > > > > trivially on its own.
> > >
> > > Good point, why CONFIG_RTC_SYSTOHC has been added to the kernel?
> > >
> > > If I good remember than it's because synchronize userspace hwclock
> > > with rtc is pretty fragile and frustrating. We have improved this
> > > hwclock code many times and it will never be perfect. See for example
> > > hwclock --delay= option, sometimes hwclock has no clue about RTC behaviour.
> > >
> >
> > With a bit of care, we can reliably set the rtc to the system time from
> > userspace. It takes a bit of time (up to 2 seconds) but it can be
> > reliably set with an accuracy of a few ms on a slow system and an rtc on
> > a slow bus or a few ns with a fast system and a fast bus.
> > I know I did say I would implement it in hwclock and I still didn't
> > (sorry) but we could do better than the --delay option.
>
> Would you use the regular RTC_SET_TIME ioctl for that, or
> add a new RTC_SYS_TO_HC command that takes an explicit
> offset? It sounds to me that the synchronization bit (actually
> waiting for the right moment to update the rtc registers) is better
> done in the kernel, while the decision about the offset and when
> to call into the driver is better done in user space.
>

The existing ioctls are fine to do that, see:
https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/rtc-tools.git/tree/rtc-sync.c

--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com