This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Y2038: provide kernel support indication


On Tue, 25 Sep 2018 13:14:38 PDT (-0700), Arnd Bergmann wrote:
On Tue, Sep 25, 2018 at 9:36 PM Albert ARIBAUD <albert.aribaud@3adev.fr> wrote:

CC:ing Arnd re whether all 32-bit architectures will get 64-bit-time
kernel support.

On Tue, 25 Sep 2018 17:25:39 +0000, Joseph Myers
<joseph@codesourcery.com> wrote :
> On Mon, 24 Sep 2018, Albert ARIBAUD wrote:
> Before we work out what the macro (or macros if more than one is needed)
> is called, and the semantics of it being defined or undefined, we need to
> have a clear understanding of the semantics.  And that in turn requires a
> clear understanding of what the future kernel interfaces will be.
>
> Could you provide a description of what the kernel interfaces will be in
> future for each of the following cases (and any other significantly
> different variants I've missed)?  Then, indicate whether you'd expect the
> __ASSUME_* macro or macros to be defined in each of those cases.
> Hopefully this will help clarify what the interfaces should look like
> within glibc.  (This information will also need to go in the proposed
> glibc commit messages for future versions of the present patch, and quite
> likely some of it should go in comments in glibc code.)
>
>
> 1a. Existing 64-bit architectures, where 64-bit time_t is the only variant
> supported, in both the kernel and (if those architectures already have
> glibc ports) glibc.
>
> My expectation is that these will *not* provide any new syscalls and will
> *not* provide any new __NR_* aliases for existing syscalls.  Is that
> correct?

Yes, that is correct.

I was undecided on this issue actually: it does make some sense to
me to have the syscall macros be the same in the long run, so that
glibc doesn't have to pick between __NR_clock_gettime and
__NR_clock_gettime64 in a few years, after all supported kernels
support __NR_clock_gettime64. Also, 64-bit architectures won't
reuse the number space that we reserve for the new calls on 32-bit
architectures, so the addition is essentially free.

OTOH, it does seem a bit silly to have two syscall numbers that
point to the same symbol.

I don't have a strong preference here, and can do whichever
you like better in glibc.

> If so, would the __ASSUME_* macro be defined for those architectures or
> not?  Whether it is or not, there must *not* be any new variables or
> internal functions defined in glibc at all relating to Y2038 support, or
> any additional levels of function calls / wrappers at runtime when
> time-related glibc functions are used, given that there are no Y2038
> problems for those architectures at present anyway.  (Avoiding such extra
> code and data might involve e.g. __TIMESIZE conditionals.  Naturally it's
> *also* desirable to design the implementation internals to reduce the
> number of places needing such conditionals.)
>
>
> 1b. New 64-bit architectures (not currently supported in the kernel).
>
> My expectation is that these will be the same as old ones - they will
> provide the existing syscalls (minus obsolete ones), under their existing
> names, not any new ones that explicitly reference 64-bit time.  Is that
> correct?  If so, I'd expect them to look exactly like case 1a in glibc.

I think this is correct.

See above.

> 2a. Existing 32-bit architectures, supported in both the kernel and glibc
> with 32-bit time_t.
>
> These will all need to gain new syscalls under new names, with the new
> macro defined when those syscalls are known to be available at runtime.

Correct.

Right.

> 2b. Existing 32-bit architectures, already supported in the kernel, but
> not supported in glibc until after the 64-bit time support is present in
> both places.
>
> >From the point of view of the kernel, these should be exactly like case
> 2a.  But from the point of view of glibc, they might be different - we
> might want to support only 64-bit time for them (so __TIMESIZE would be
> 64, and _TIME_BITS=64 would do nothing).  Is that what you'd intend for
> such new architectures in glibc?  If so, presumably the __ASSUME_* macro
> would still be defined for them, but the combination of that macro and
> __TIMESIZE == 64 might end up doing different things in some places?  And
> would the glibc port for such an architecture allow runtime fallback to
> 32-bit time syscalls, or would it also require a minimum kernel with
> 64-bit time support rather than allowing older kernels from before the
> glibc port was added?
>
> (Of course you can't really test this combination; it may fall to whoever
> adds the first such architecture port to glibc to get it working.)
>
> Another consideration for such architectures is whether you end up with
> the combination of 64-bit time and 32-bit file offsets for them (given
> _TIME_BITS=64 requires _FILE_OFFSET_BITS=64, but here you have 64-bit time
> without defining _TIME_BITS).  It might make sense for such architectures
> also to use 64-bit offsets unconditionally, like 64-bit architectures do,
> so that defining _FILE_OFFSET_BITS=64 for them only affects mangling for a
> few types, not layout.

As you point out, I won't test for this combination, but yes, my
opinion is that 32-bit architectures which are supported in the kernel
but not yet in glibc should only use 64-bit time syscalls when glibc
support is added.

riscv32 falls into this category: there is preliminary kernel support
for it, but no upstream glibc. The riscv maintainers have indicated a
preference that they would actually want to drop the 32-bit time_t
syscalls from the kernel as well, since nobody is relying on them
today. I don't think it makes a difference to glibc, so we'll discuss this
among the kernel folks.

In general, we don't break established user ABIs as a rule, but we
also have lots of precedent for changing interfaces when we are
sure that there are no users that would complain about the change.

Obviously I'm OK deferring to kernel policy here, but my understanding of the rv32 situation is that we decided the rv32 kernel ABI is not stable and will not be marked as stable until our glibc port is upstream -- much the same as we did for the rv64 port. This came up outside the context of 32-bit time_t, but I forget what the actual issue is. That's what I've been telling people in RISC-V land.

I think I'll just start a Linux thread about this, as like you said there isn't a whole lot of glibc involvement here.

> 3. New 32-bit architectures (new in both kernel and glibc after the
> addition of 64-bit time support for 32-bit architectures in the kernel).
>
> My expectation is that these will *only* have the new-named syscalls for
> 64-bit time, not the old-named syscalls that use 32-bit time on 32-bit
> systems (and not the old syscall names but pointing to syscalls that use
> 64-bit time, either).  Is that correct - new-named syscalls only for
> everything involving time on such architectures?

I think this is correct.

Yes, absolutely. Both csky and mips p32 will possibly fall into this
category, but it depends on how soon we can complete the addition
of the 64-bit time_t syscalls.

> > - #define it in sysdeps/unix/sysv/linux/kernel-features.h and then
> >   #undef it in sysdeps/unix/sysv/linux/*/kernel-features.h, and later
> >   when some architecture gets Y2038 syscall support, remove its #undef?
>
> I'd hope all 32-bit architectures get kernel support at the same time.
> Is that the intent, or is something else intended?

Arnd would know this much better than I do.

I have planned to do it that way in the past, but with csky, mips-p32
and rv32 eager to change over as fast as they can, it seems more
likely now that there will be two steps here:

a) some architectures that only support 64-bit time_t from the start,
     possibly in linux-4.21
b) all other architectures supporting 64-bit time_t a little later, possibly
    4.22. This depends on work by Firoz Khan that is still under discussion
    at the moment.

There are also still a few open questions that we would need to resolve
in order to close in on the final ABI:

- The timex  structure for clock_adjtime64. I'd like to use the
   same version that x32 uses today, so we can avoid creating another
   32-bit compat interface for it. If there are any concerns with that,
   please let me know. In glibc, we will then have to change the
   __syscall_slong_t members of timex to a new type that is the
   same length as time_t.

- Whether to update itimerval (setitimer/getitimer) and rusage
  (getrusage, wait4, __kerrnel_waitid) or not. These only carry
  relative times, and they are in an awkward format (timeval).
  If we were to replace them, we'd probably want to use timespec
  on the syscall ABI, but that in turn means that glibc still
  requires a translation between the kernel structure and its
  own POSIX compatible structure. I'd appreciate to hear any
  opinions on this matter, one way or another, or alternative ideas.

- Whether to harmonize the existing syscall tables across all
  architectures while adding the new calls: I think this would be
  a good time to ensure that all architectures support all syscalls
  we have added over time, or at least define the number.
  This includes missing recent additions (io_pgetevents, rseq,
  fsinfo, ...) and those that may only exist as wrappers (ipc,
  socketcall) instead of direct entry points.

- In case we do harmonize the syscall tables, whether to go as
  far as using the same numbers for all of the new calls across
  the traditional architectures. E.g. clock_gettime64 could
  become 400 on x86, sparc, ppc, mips, ia64, etc and be
  followed by other 20 new calls with identical numbers.
  For the generic syscall ABI (arm64, openrisc, riscv, arc, ...)
  we'd probably use lower numbers to avoid a big gap, but at
  least that makes it only two possible numbers instead of 12
  for each call.

       Arnd


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]