[v6] y2038: Introduce __ASSUME_TIME64_SYSCALLS define

Message ID 20190529122200.19883-1-lukma@denx.de
State Committed
Headers

Commit Message

Lukasz Majewski May 29, 2019, 12:22 p.m. UTC
  This define indicates if the Linux kernel provides 64 bit time syscalls
on systems where:

1. __WORDSIZE == 64 - the 64 bit time is supported by already available set
  of syscalls.

2. __WORDSIZE == 32 - the new set of syscalls has been added to v5.1
  kernel to provide 64 bit time ABI.

  List of new syscalls added to v5.1. kernel (they accept data based on
  struct timespec and timeval with 64 bit tv_sec):

   clock_gettime64
   clock_settime64
   clock_adjtime64
   clock_getres_time64
   clock_nanosleep_time64
   timer_gettime64
   timer_settime64
   timerfd_gettime64
   timerfd_settime64
   utimensat_time64
   pselect6_time64
   ppoll_time64
   io_pgetevents_time64
   recvmmsg_time64
   mq_timedsend_time64
   mq_timedreceive_time64
   semtimedop_time64
   rt_sigtimedwait_time64
   futex_time64
   sched_rr_get_interval_time64

3. __WORDSIZE == 32 && _SYSCALL_WORDSIZE == 64 - a special case for machine
  with ILP32 data model, but already supporting 64 bit time (the 'x32'
  architecture to be precise).

Different syscalls with different numbers can be used to achieve the goal
(for example either __NR_clock_settime or __NR_clock_settime64) if they
provide exactly equivalent interface. Ones which doesn't (like
semtimedop_time64) would require special handling.

In other words the __ASSUME_TIME64_SYSCALLS does not indicate the presence
of particular syscalls, but the generic ability which they provide (64 bit
time support).

Moreover, this flag will be removed one day when glibc's minimal supported
kernel version passes 5.1, as one would be sure that it provides 64 bit
time ABI.


* sysdeps/unix/sysv/linux/kernel-features.h:
(__ASSUME_TIME64_SYSCALLS): Define.

---
Changes for v6:
- Change the logical meaning of __ASSUME_TIME64_SYSCALLS - now it
  indicates if the system supports the 64 bit time ABI (if for both
  __WORDSIZE==64 and __WORDSIZE==32 systems equally functional syscalls
  are provided).
- Update commit description

Changes for v5:
- Rewrite the in-code comment (x32 description more precise)
- Change patch description (for x32)

Changes for v4:
- Exclude this patch from the clock_settime64 patch series
- Rewrite the in-code comment
- Change patch description

Changes for v3:
- Provide more detailed and verbose description
- Change name to __ASSUME_TIME64_SYSCALLS
- Undefine __ASSUME_TIME64_SYSCALLS on x32

Changes for v2:
- New patch
---
 sysdeps/unix/sysv/linux/kernel-features.h | 37 +++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
  

Comments

Joseph Myers May 30, 2019, 4:01 p.m. UTC | #1
On Wed, 29 May 2019, Lukasz Majewski wrote:

>   List of new syscalls added to v5.1. kernel (they accept data based on
>   struct timespec and timeval with 64 bit tv_sec):
> 
>    clock_gettime64
>    clock_settime64
>    clock_adjtime64
>    clock_getres_time64
>    clock_nanosleep_time64
>    timer_gettime64
>    timer_settime64
>    timerfd_gettime64
>    timerfd_settime64
>    utimensat_time64
>    pselect6_time64
>    ppoll_time64
>    io_pgetevents_time64
>    recvmmsg_time64
>    mq_timedsend_time64
>    mq_timedreceive_time64
>    semtimedop_time64
>    rt_sigtimedwait_time64
>    futex_time64
>    sched_rr_get_interval_time64

I do *not* think semtimedop_time64 should be included in the set of 
syscalls.  I think that if the macro is defined on systems with __WORDSIZE 
== 64, it should *only* relate to syscalls where the syscall semantics are 
*identical* for both the old syscall (on systems where __WORDSIZE or 
__SYSCALL_WORDSIZE is 64) and for the new one, so that no code will ever 
have to handle the two syscalls differently.  And the comment should 
explicitly say that it is only for that subset of syscalls.

I also think the list has to go in the comment defining the semantics, not 
just the commit message, to make clear exactly what syscalls are covered - 
and thus that it does not cover any other syscalls relating to time that 
may be added in later kernel versions.

> In other words the __ASSUME_TIME64_SYSCALLS does not indicate the presence
> of particular syscalls, but the generic ability which they provide (64 bit
> time support).

The whole point of __ASSUME_* macros is to indicate availability of 
specific interfaces - syscalls, in this case.  It simply happens that the 
name of the syscalls in question depends on the architecture.

> +/* This flag indicates support for Linux kernel syscalls, which are able
> +   to handle 64 bit time ABI. It is defined for architectures with both
> +   intrinsic 64 bit time support as well as ones gaining it with new
> +   syscalls added to Linux kernel version 5.1.

"intrinsic 64 bit time support" is the sort of vague description that does 
not belong anywhere in code related to time in glibc.  The support on 
architectures where the syscalls have a name involving "64" is neither 
more nor less intrinsic than the support on architectures where the 
syscalls have names not involving "64".

I think you mean syscall ABIs (not architectures, this depends on the ABI 
for some architectures) for which the size of "long int" is 64-bit.  The 
size of "long int" for the syscall ABI, in turn, is always the same as the 
size of "long int" in the userspace ABI, except for x32.
  
Stepan Golosunov May 31, 2019, 10:55 a.m. UTC | #2

  
Stepan Golosunov June 1, 2019, 11 a.m. UTC | #3
Resending as this was truncated yesterday.

31.05.2019 в 14:49:02 +0400 Stepan Golosunov написал:
> 30.05.2019 в 16:01:12 +0000 Joseph Myers написал:
> > On Wed, 29 May 2019, Lukasz Majewski wrote:
> > 
> > >   List of new syscalls added to v5.1. kernel (they accept data based on
> > >   struct timespec and timeval with 64 bit tv_sec):
> > > 
> > >    clock_gettime64
> > >    clock_settime64
> > >    clock_adjtime64
> > >    clock_getres_time64
> > >    clock_nanosleep_time64
> > >    timer_gettime64
> > >    timer_settime64
> > >    timerfd_gettime64
> > >    timerfd_settime64
> > >    utimensat_time64
> > >    pselect6_time64
> > >    ppoll_time64
> > >    io_pgetevents_time64
> > >    recvmmsg_time64
> > >    mq_timedsend_time64
> > >    mq_timedreceive_time64
> > >    semtimedop_time64
> > >    rt_sigtimedwait_time64
> > >    futex_time64
> > >    sched_rr_get_interval_time64
> > 
> > I do *not* think semtimedop_time64 should be included in the set of 
> > syscalls.  I think that if the macro is defined on systems with __WORDSIZE 
> > == 64, it should *only* relate to syscalls where the syscall semantics are 
> > *identical* for both the old syscall (on systems where __WORDSIZE or 
> > __SYSCALL_WORDSIZE is 64) and for the new one, so that no code will ever 
> > have to handle the two syscalls differently.  And the comment should 
> > explicitly say that it is only for that subset of syscalls.
> 
> There is already a macro to specify whether semtimedop semantics is
> available: __ASSUME_DIRECT_SYSVIPC_SYSCALLS.  It should be always
> defined for 5.1+ kernels.  (Lack of support for __NR_semtimedop_time64
> in glibc is one of the obstacles in the way of defining
> __ASSUME_DIRECT_SYSVIPC_SYSCALLS currently.)
> 
> I see how splitting semtimedop/semtimedop_time64
> availability from __ASSUME_DIRECT_SYSVIPC_SYSCALLS can help to
> untangle __ASSUME_DIRECT_SYSVIPC_SYSCALLS from time64.  (It would
> probably be overkill though—in the end splitted macro would be defined
> exactly at the same time as __ASSUME_DIRECT_SYSVIPC_SYSCALLS.)
> 
> I fail to see how not using __ASSUME_TIME64_SYSCALLS can add anything
> but extra complexity into the following logic:
> 
> defined __ASSUME_TIME64_SYSCALLS
>   && defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
>   && defined __NR_semtimedop_time64:
>     call semtimedop_time64
> 
> defined __ASSUME_TIME64_SYSCALLS
>   && defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
>   && !defined __NR_semtimedop_time64:
>     call semtimedop
> 
> defined __ASSUME_TIME64_SYSCALLS
>   && !defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS:
>     (must not happen when __LINUX_KERNEL_VERSION >= 0x050100)
>     call ipc with IPCOP_semtimedop
> 
> !defined __ASSUME_TIME64_SYSCALLS
>   && defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS:
>     try __NR_semtimedop_time64, fallback to 32-bit semtimedop
> 
> !defined __ASSUME_TIME64_SYSCALLS
>   && !defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS:
>     try __NR_semtimedop_time64, fallback to 32-bit ipc with IPCOP_semtimedop
>
  
Lukasz Majewski June 3, 2019, 9:26 a.m. UTC | #4
Hi Joseph,

> On Wed, 29 May 2019, Lukasz Majewski wrote:
> 
> >   List of new syscalls added to v5.1. kernel (they accept data
> > based on struct timespec and timeval with 64 bit tv_sec):
> > 
> >    clock_gettime64
> >    clock_settime64
> >    clock_adjtime64
> >    clock_getres_time64
> >    clock_nanosleep_time64
> >    timer_gettime64
> >    timer_settime64
> >    timerfd_gettime64
> >    timerfd_settime64
> >    utimensat_time64
> >    pselect6_time64
> >    ppoll_time64
> >    io_pgetevents_time64
> >    recvmmsg_time64
> >    mq_timedsend_time64
> >    mq_timedreceive_time64
> >    semtimedop_time64
> >    rt_sigtimedwait_time64
> >    futex_time64
> >    sched_rr_get_interval_time64  
> 
> I do *not* think semtimedop_time64 should be included in the set of 
> syscalls. 

Ok.

> I think that if the macro is defined on systems with
> __WORDSIZE == 64, it should *only* relate to syscalls where the
> syscall semantics are *identical* for both the old syscall (on
> systems where __WORDSIZE or __SYSCALL_WORDSIZE is 64) and for the new
> one, so that no code will ever have to handle the two syscalls
> differently.  And the comment should explicitly say that it is only
> for that subset of syscalls.

I do agree.

> 
> I also think the list has to go in the comment defining the
> semantics, not just the commit message, to make clear exactly what
> syscalls are covered - and thus that it does not cover any other
> syscalls relating to time that may be added in later kernel versions.

I will move the list from the commit message to the comment in the
kernel-features.h file.

> 
> > In other words the __ASSUME_TIME64_SYSCALLS does not indicate the
> > presence of particular syscalls, but the generic ability which they
> > provide (64 bit time support).  
> 
> The whole point of __ASSUME_* macros is to indicate availability of 
> specific interfaces - syscalls, in this case.  It simply happens that
> the name of the syscalls in question depends on the architecture.

Ok.

> 
> > +/* This flag indicates support for Linux kernel syscalls, which
> > are able
> > +   to handle 64 bit time ABI. It is defined for architectures with
> > both
> > +   intrinsic 64 bit time support as well as ones gaining it with
> > new
> > +   syscalls added to Linux kernel version 5.1.  
> 
> "intrinsic 64 bit time support" is the sort of vague description that
> does not belong anywhere in code related to time in glibc.  The
> support on architectures where the syscalls have a name involving
> "64" is neither more nor less intrinsic than the support on
> architectures where the syscalls have names not involving "64".
> 
> I think you mean syscall ABIs (not architectures, this depends on the
> ABI for some architectures) for which the size of "long int" is
> 64-bit.  The size of "long int" for the syscall ABI, in turn, is
> always the same as the size of "long int" in the userspace ABI,
> except for x32.
> 

Correct. The "intrinsic 64 bit time support" was supposed to mean
exactly what you described above.

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
  
Lukasz Majewski June 3, 2019, 10:08 a.m. UTC | #5
Hi Stepan,

> Resending as this was truncated yesterday.
> 
> 31.05.2019 в 14:49:02 +0400 Stepan Golosunov написал:
> > 30.05.2019 в 16:01:12 +0000 Joseph Myers написал:  
> > > On Wed, 29 May 2019, Lukasz Majewski wrote:
> > >   
> > > >   List of new syscalls added to v5.1. kernel (they accept data
> > > > based on struct timespec and timeval with 64 bit tv_sec):
> > > > 
> > > >    clock_gettime64
> > > >    clock_settime64
> > > >    clock_adjtime64
> > > >    clock_getres_time64
> > > >    clock_nanosleep_time64
> > > >    timer_gettime64
> > > >    timer_settime64
> > > >    timerfd_gettime64
> > > >    timerfd_settime64
> > > >    utimensat_time64
> > > >    pselect6_time64
> > > >    ppoll_time64
> > > >    io_pgetevents_time64
> > > >    recvmmsg_time64
> > > >    mq_timedsend_time64
> > > >    mq_timedreceive_time64
> > > >    semtimedop_time64
> > > >    rt_sigtimedwait_time64
> > > >    futex_time64
> > > >    sched_rr_get_interval_time64  
> > > 
> > > I do *not* think semtimedop_time64 should be included in the set
> > > of syscalls.  I think that if the macro is defined on systems
> > > with __WORDSIZE == 64, it should *only* relate to syscalls where
> > > the syscall semantics are *identical* for both the old syscall
> > > (on systems where __WORDSIZE or __SYSCALL_WORDSIZE is 64) and for
> > > the new one, so that no code will ever have to handle the two
> > > syscalls differently.  And the comment should explicitly say that
> > > it is only for that subset of syscalls.  
> > 
> > There is already a macro to specify whether semtimedop semantics is
> > available: __ASSUME_DIRECT_SYSVIPC_SYSCALLS.  It should be always
> > defined for 5.1+ kernels.  (Lack of support for
> > __NR_semtimedop_time64 in glibc is one of the obstacles in the way
> > of defining __ASSUME_DIRECT_SYSVIPC_SYSCALLS currently.)
> > 
> > I see how splitting semtimedop/semtimedop_time64
> > availability from __ASSUME_DIRECT_SYSVIPC_SYSCALLS can help to
> > untangle __ASSUME_DIRECT_SYSVIPC_SYSCALLS from time64.  (It would
> > probably be overkill though—in the end splitted macro would be
> > defined exactly at the same time as
> > __ASSUME_DIRECT_SYSVIPC_SYSCALLS.)

Please correct me if I'm wrong:

1. As we discussed the __ASSUME_TIME64_SYSCALLS is supposed to indicate
64 bit time support in a way that syscall ABI is the same for old and
new syscalls (there is no need to add any extra code in handling them).

2. The new syscalls - like semtimedop_time64, which need extra code for
handling, shall be excluded from __ASSUME_TIME64_SYSCALLS and hence
would receive new flag(s) - as proposed: __ASSUME_SEMTIMEDOP_TIME64

> > 
> > I fail to see how not using __ASSUME_TIME64_SYSCALLS can add
> > anything but extra complexity into the following logic:

Could you be more specific here (or rephase the above sentence)? 

> > __ASSUME_SEMTIMEDOP_TIME64
> > defined __ASSUME_TIME64_SYSCALLS
> >   && defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
> >   && defined __NR_semtimedop_time64:
> >     call semtimedop_time64
> > 
> > defined __ASSUME_TIME64_SYSCALLS
> >   && defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
> >   && !defined __NR_semtimedop_time64:
> >     call semtimedop
> > 
> > defined __ASSUME_TIME64_SYSCALLS
> >   && !defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS:
> >     (must not happen when __LINUX_KERNEL_VERSION >= 0x050100)
> >     call ipc with IPCOP_semtimedop
> > 
> > !defined __ASSUME_TIME64_SYSCALLS
> >   && defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS:
> >     try __NR_semtimedop_time64, fallback to 32-bit semtimedop
> > 
> > !defined __ASSUME_TIME64_SYSCALLS
> >   && !defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS:
> >     try __NR_semtimedop_time64, fallback to 32-bit ipc with
> > IPCOP_semtimedop 

Now at sysdeps/unix/sysv/linux/semtimedop.c we do have:

#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
  return INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, timeout);
#else
  return INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
                              SEMTIMEDOP_IPC_ARGS (nsops, sops,
timeout));
#endif

And yes, this code would be more complicated when we follow the
conversion paradigm described here:

https://www.gnu.org/software/libc/manual/html_mono/libc.html#g_t64_002dbit-time-symbol-handling


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
  
Joseph Myers June 3, 2019, 5:28 p.m. UTC | #6
On Sat, 1 Jun 2019, Stepan Golosunov wrote:

> > I see how splitting semtimedop/semtimedop_time64
> > availability from __ASSUME_DIRECT_SYSVIPC_SYSCALLS can help to
> > untangle __ASSUME_DIRECT_SYSVIPC_SYSCALLS from time64.  (It would
> > probably be overkill though—in the end splitted macro would be defined
> > exactly at the same time as __ASSUME_DIRECT_SYSVIPC_SYSCALLS.)
> > 
> > I fail to see how not using __ASSUME_TIME64_SYSCALLS can add anything
> > but extra complexity into the following logic:

The basic rule, for each syscall covered by __ASSUME_TIME64_SYSCALLS, if 
we use the semantics that __ASSUME_TIME64_SYSCALLS is defined 
unconditionally for existing 64-bit syscall ABIs, is that the following is 
always OK:

#ifdef __ASSUME_TIME64_SYSCALLS
# ifndef __NR_foo_time64
#  define __NR_foo_time64 __NR_foo
# endif
/* Implementation that uses foo_time64 unconditionally.  */
#else
/* Implementation that needs fallback code.  */
#endif

My understanding is that this would not work for semtimedop, because not 
all 64-bit syscall ABIs have __NR_semtimedop.  (Or, equivalently, it would 
work for semtimedop *only* if the syscall ABIs in question avoided 
defining __ASSUME_TIME64_SYSCALLS before Linux 5.1 - but since those ABIs 
do have the other syscalls, that wouldn't be helpful.)

Splitting semtimedop out of what the comment on __ASSUME_TIME64_SYSCALLS 
says its semantics are seems cleaner to me than having more complicated 
semantics that are different as regards semtimedop than as regards all the 
other syscalls.  You can then have __ASSUME_SEMTIMEDOP_TIME64 with a 
comment explaining exactly what the semantics of that macro are for 64-bit 
syscall ABIs without a semtimedop syscall.

Note: I haven't verified if all 64-bit syscall ABIs did have all the other 
syscalls in the list as of Linux 3.2, or if any other cases should also be 
split out.
  
Stepan Golosunov June 4, 2019, 7:38 a.m. UTC | #7
03.06.2019 в 17:28:51 +0000 Joseph Myers написал:
> On Sat, 1 Jun 2019, Stepan Golosunov wrote:
> 
> > > I see how splitting semtimedop/semtimedop_time64
> > > availability from __ASSUME_DIRECT_SYSVIPC_SYSCALLS can help to
> > > untangle __ASSUME_DIRECT_SYSVIPC_SYSCALLS from time64.  (It would
> > > probably be overkill though—in the end splitted macro would be defined
> > > exactly at the same time as __ASSUME_DIRECT_SYSVIPC_SYSCALLS.)
> > > 
> > > I fail to see how not using __ASSUME_TIME64_SYSCALLS can add anything
> > > but extra complexity into the following logic:
> 
> The basic rule, for each syscall covered by __ASSUME_TIME64_SYSCALLS, if 
> we use the semantics that __ASSUME_TIME64_SYSCALLS is defined 
> unconditionally for existing 64-bit syscall ABIs, is that the following is 
> always OK:
> 
> #ifdef __ASSUME_TIME64_SYSCALLS
> # ifndef __NR_foo_time64
> #  define __NR_foo_time64 __NR_foo
> # endif
> /* Implementation that uses foo_time64 unconditionally.  */
> #else
> /* Implementation that needs fallback code.  */
> #endif
> 
> My understanding is that this would not work for semtimedop, because not 
> all 64-bit syscall ABIs have __NR_semtimedop.

Yes, in this form it won't work.

> (Or, equivalently, it would 
> work for semtimedop *only* if the syscall ABIs in question avoided 
> defining __ASSUME_TIME64_SYSCALLS before Linux 5.1 - but since those ABIs 
> do have the other syscalls, that wouldn't be helpful.)

If "fallback code" means runtime fallback to 32-bit syscalls then this
won't work either.  And if it means any fallback code then some
condition for fallback to 32-bit syscalls is needed inside it.  Which
happens to be what __ASSUME_TIME64_SYSCALLS means otherwise.


If semantics for __ASSUME_TIME64_SYSCALLS is defined as "fallback to
syscalls with 32-bit time_t is not needed (and must not be used)" then
in most cases affected functions can be implemented as

#ifdef __ASSUME_TIME64_SYSCALLS
# ifndef __NR_foo_time64
#  define __NR_foo_time64 __NR_foo
# endif
/* Traditional implementation with foo replaced by foo_time64.  */
#else
/* Try foo_time64.  */
/* Convert input to 32-bit time_t.  */
/* Traditional implementation.  */
/* Convert output from 32-bit time_t.  */
#endif

This would work for semtimedop too (provided that definition of
__ASSUME_DIRECT_SYSVIPC_SYSCALLS is updated to reflect changes in
Linux 5.1).


> Splitting semtimedop out of what the comment on __ASSUME_TIME64_SYSCALLS 
> says its semantics are seems cleaner to me than having more complicated 
> semantics that are different as regards semtimedop than as regards all the 
> other syscalls.  You can then have __ASSUME_SEMTIMEDOP_TIME64 with a 
> comment explaining exactly what the semantics of that macro are for 64-bit 
> syscall ABIs without a semtimedop syscall.

Do you mean that __ASSUME_SEMTIMEDOP_TIME64 should be separate from
__ASSUME_TIME64_SYSCALLS so that they can have different wordings
explaining the same "fallback to syscalls with 32-bit time_t is not
needed" semantics?


Or should __ASSUME_TIME64_SYSCALLS for semtimedop be split into
__ASSUME_SEMTIMEDOP_TIME64 and __ASSUME_IPC_TIME64 so that
implementation replaces

__ASSUME_TIME64_SYSCALLS
__ASSUME_DIRECT_SYSVIPC_SYSCALLS

with

__ASSUME_SEMTIMEDOP_TIME64
__ASSUME_IPC_TIME64
__ASSUME_DIRECT_SYSVIPC_SYSCALLS

?
  
Lukasz Majewski June 5, 2019, 4:41 p.m. UTC | #8
Hi Stepan, Joseph,

> 03.06.2019 в 17:28:51 +0000 Joseph Myers написал:
> > On Sat, 1 Jun 2019, Stepan Golosunov wrote:
> >   
> > > > I see how splitting semtimedop/semtimedop_time64
> > > > availability from __ASSUME_DIRECT_SYSVIPC_SYSCALLS can help to
> > > > untangle __ASSUME_DIRECT_SYSVIPC_SYSCALLS from time64.  (It
> > > > would probably be overkill though—in the end splitted macro
> > > > would be defined exactly at the same time as
> > > > __ASSUME_DIRECT_SYSVIPC_SYSCALLS.)
> > > > 
> > > > I fail to see how not using __ASSUME_TIME64_SYSCALLS can add
> > > > anything but extra complexity into the following logic:  
> > 
> > The basic rule, for each syscall covered by
> > __ASSUME_TIME64_SYSCALLS, if we use the semantics that
> > __ASSUME_TIME64_SYSCALLS is defined unconditionally for existing
> > 64-bit syscall ABIs, is that the following is always OK:
> > 
> > #ifdef __ASSUME_TIME64_SYSCALLS
> > # ifndef __NR_foo_time64
> > #  define __NR_foo_time64 __NR_foo
> > # endif
> > /* Implementation that uses foo_time64 unconditionally.  */
> > #else
> > /* Implementation that needs fallback code.  */
> > #endif
> > 
> > My understanding is that this would not work for semtimedop,
> > because not all 64-bit syscall ABIs have __NR_semtimedop.  
> 
> Yes, in this form it won't work.
> 
> > (Or, equivalently, it would 
> > work for semtimedop *only* if the syscall ABIs in question avoided 
> > defining __ASSUME_TIME64_SYSCALLS before Linux 5.1 - but since
> > those ABIs do have the other syscalls, that wouldn't be helpful.)  
> 
> If "fallback code" means runtime fallback to 32-bit syscalls then this
> won't work either.  And if it means any fallback code then some
> condition for fallback to 32-bit syscalls is needed inside it.  Which
> happens to be what __ASSUME_TIME64_SYSCALLS means otherwise.
> 
> 
> If semantics for __ASSUME_TIME64_SYSCALLS is defined as "fallback to
> syscalls with 32-bit time_t is not needed (and must not be used)" then
> in most cases affected functions can be implemented as

If I understood correctly the __ASSUME_TIME64_SYSCALLS is defined as:

It indicates 64 bit time support in a way that syscall ABI is the same
for old and new syscalls (there is no need to add any extra code in
handling them).

Moreover, if it is defined, there is no need for 32 bit time_t syscalls
(and those must not be used).

With such definition we can follow below pattern (similar to the
already posted code for clock_settime):

> 
> #ifdef __ASSUME_TIME64_SYSCALLS
> # ifndef __NR_foo_time64
> #  define __NR_foo_time64 __NR_foo
> # endif
> /* Traditional implementation with foo replaced by foo_time64.  */
> #else
> /* Try foo_time64.  */
> /* Convert input to 32-bit time_t.  */
> /* Traditional implementation.  */
> /* Convert output from 32-bit time_t.  */
> #endif
> 
> This would work for semtimedop too (provided that definition of
> __ASSUME_DIRECT_SYSVIPC_SYSCALLS is updated to reflect changes in
> Linux 5.1).
> 
> 
> > Splitting semtimedop out of what the comment on
> > __ASSUME_TIME64_SYSCALLS says its semantics are seems cleaner to me
> > than having more complicated semantics that are different as
> > regards semtimedop than as regards all the other syscalls.  You can
> > then have __ASSUME_SEMTIMEDOP_TIME64 with a comment explaining
> > exactly what the semantics of that macro are for 64-bit syscall
> > ABIs without a semtimedop syscall.  
> 
> Do you mean that __ASSUME_SEMTIMEDOP_TIME64 should be separate from
> __ASSUME_TIME64_SYSCALLS so that they can have different wordings
> explaining the same "fallback to syscalls with 32-bit time_t is not
> needed" semantics?
> 
> 
> Or should __ASSUME_TIME64_SYSCALLS for semtimedop be split into
> __ASSUME_SEMTIMEDOP_TIME64 and __ASSUME_IPC_TIME64 so that
> implementation replaces
> 
> __ASSUME_TIME64_SYSCALLS
> __ASSUME_DIRECT_SYSVIPC_SYSCALLS
> 
> with
> 
> __ASSUME_SEMTIMEDOP_TIME64
> __ASSUME_IPC_TIME64
> __ASSUME_DIRECT_SYSVIPC_SYSCALLS
> 
> ?

Is there any idea on how to solve the above problem?


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
  
Joseph Myers June 6, 2019, 9:48 p.m. UTC | #9
On Tue, 4 Jun 2019, Stepan Golosunov wrote:

> > Splitting semtimedop out of what the comment on __ASSUME_TIME64_SYSCALLS 
> > says its semantics are seems cleaner to me than having more complicated 
> > semantics that are different as regards semtimedop than as regards all the 
> > other syscalls.  You can then have __ASSUME_SEMTIMEDOP_TIME64 with a 
> > comment explaining exactly what the semantics of that macro are for 64-bit 
> > syscall ABIs without a semtimedop syscall.
> 
> Do you mean that __ASSUME_SEMTIMEDOP_TIME64 should be separate from
> __ASSUME_TIME64_SYSCALLS so that they can have different wordings
> explaining the same "fallback to syscalls with 32-bit time_t is not
> needed" semantics?

It might well have a different definition as well, depending on what 
semantics make the most sense for it.

It's entirely OK to define some __ASSUME_* macros in terms of other 
__ASSUME_* macros, if that helps make the different cases and their 
relations clearer.  (E.g. look at the sets of macros we used to have 
relating to accept4, recvmmsg, sendmmsg, to deal with cases where they 
might sometimes be available with socketcall but not with a syscall, until 
the minimum kernel version became recent enough that we could always 
assume the functionality, if not a syscall for it, to be available, and so 
could simplify the code.)

__ASSUME_TIME64_SYSCALLS should have the simplest, clearest semantics that 
work for its purpose.  If any syscall needs something slightly different, 
it's appropriate to separate it out.  That includes if the previous 
versions of any of the other syscalls listed for __ASSUME_TIME64_SYSCALLS 
were not in fact present in 3.2 for all architectures supported by glibc 
(something I haven't checked, but which needs to be checked) - if any 
syscall has that as a complication, take it out of the list to which 
__ASSUME_TIME64_SYSCALLS applies and deal with that complication 
separately, later.
  
Lukasz Majewski June 7, 2019, 12:07 p.m. UTC | #10
Hi Joseph, Stepan

> On Tue, 4 Jun 2019, Stepan Golosunov wrote:
> 
> > > Splitting semtimedop out of what the comment on
> > > __ASSUME_TIME64_SYSCALLS says its semantics are seems cleaner to
> > > me than having more complicated semantics that are different as
> > > regards semtimedop than as regards all the other syscalls.  You
> > > can then have __ASSUME_SEMTIMEDOP_TIME64 with a comment
> > > explaining exactly what the semantics of that macro are for
> > > 64-bit syscall ABIs without a semtimedop syscall.  
> > 
> > Do you mean that __ASSUME_SEMTIMEDOP_TIME64 should be separate from
> > __ASSUME_TIME64_SYSCALLS so that they can have different wordings
> > explaining the same "fallback to syscalls with 32-bit time_t is not
> > needed" semantics?  
> 
> It might well have a different definition as well, depending on what 
> semantics make the most sense for it.
> 
> It's entirely OK to define some __ASSUME_* macros in terms of other 
> __ASSUME_* macros, if that helps make the different cases and their 
> relations clearer.  (E.g. look at the sets of macros we used to have 
> relating to accept4, recvmmsg, sendmmsg, to deal with cases where
> they might sometimes be available with socketcall but not with a
> syscall, until the minimum kernel version became recent enough that
> we could always assume the functionality, if not a syscall for it, to
> be available, and so could simplify the code.)
> 
> __ASSUME_TIME64_SYSCALLS should have the simplest, clearest semantics
> that work for its purpose.  If any syscall needs something slightly
> different, it's appropriate to separate it out.  That includes if the
> previous versions of any of the other syscalls listed for
> __ASSUME_TIME64_SYSCALLS were not in fact present in 3.2 for all
> architectures supported by glibc (something I haven't checked, but
> which needs to be checked) - if any syscall has that as a
> complication, take it out of the list to which
> __ASSUME_TIME64_SYSCALLS applies and deal with that complication
> separately, later.
> 

Can we assume the above sentence as a "consensus" for
__ASSUME_TIME64_SYSCALLS semantics definition ?

Or are there any other open topics for discussion?

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
  
Joseph Myers June 10, 2019, 3:40 p.m. UTC | #11
On Fri, 7 Jun 2019, Lukasz Majewski wrote:

> > __ASSUME_TIME64_SYSCALLS should have the simplest, clearest semantics
> > that work for its purpose.  If any syscall needs something slightly
> > different, it's appropriate to separate it out.  That includes if the
> > previous versions of any of the other syscalls listed for
> > __ASSUME_TIME64_SYSCALLS were not in fact present in 3.2 for all
> > architectures supported by glibc (something I haven't checked, but
> > which needs to be checked) - if any syscall has that as a
> > complication, take it out of the list to which
> > __ASSUME_TIME64_SYSCALLS applies and deal with that complication
> > separately, later.
> > 
> 
> Can we assume the above sentence as a "consensus" for
> __ASSUME_TIME64_SYSCALLS semantics definition ?

Whether or not there is consensus on it, it should be clear that a 
detailed review will be needed to establish whether every syscall listed 
was indeed present in 3.2 (or the first kernel version supported by glibc 
for an architecture, if later) for all glibc architectures.
  
Lukasz Majewski June 10, 2019, 4:13 p.m. UTC | #12
Hi Joseph,

> On Fri, 7 Jun 2019, Lukasz Majewski wrote:
> 
> > > __ASSUME_TIME64_SYSCALLS should have the simplest, clearest
> > > semantics that work for its purpose.  If any syscall needs
> > > something slightly different, it's appropriate to separate it
> > > out.  That includes if the previous versions of any of the other
> > > syscalls listed for __ASSUME_TIME64_SYSCALLS were not in fact
> > > present in 3.2 for all architectures supported by glibc
> > > (something I haven't checked, but which needs to be checked) - if
> > > any syscall has that as a complication, take it out of the list
> > > to which __ASSUME_TIME64_SYSCALLS applies and deal with that
> > > complication separately, later.
> > >   
> > 
> > Can we assume the above sentence as a "consensus" for
> > __ASSUME_TIME64_SYSCALLS semantics definition ?  
> 
> Whether or not there is consensus on it, it should be clear that a 
> detailed review will be needed to establish whether every syscall
> listed was indeed present in 3.2 (or the first kernel version
> supported by glibc for an architecture, if later) 

If I understood you correctly - the "syscall" - for example
clock_settime (with either 32 or 64 bit ABI) needs to be defined in
kernel 3.2 (the oldest supported kernel).

If it is not defined (or has different implementation), then it is
excluded from the list of syscalls eligible to __ASSUME_TIME64_SYSCALLS?


> for all glibc architectures.
> 

I'm a bit puzzled with the above sentence. We now focus on Linux
implementation - for example __ASSUME_TIME64_SYSCALLS is defined in:
sysdeps/unix/sysv/linux/kernel-features.h

Do you mean by "all glibc architectures" - all the architectures
supported by Linux kernel?

Was there previously any similar flag defined in a way similar to
__ASSUME_TIME64_SYSCALLS ? I would like to have a reference.




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
  
Joseph Myers June 10, 2019, 4:46 p.m. UTC | #13
On Mon, 10 Jun 2019, Lukasz Majewski wrote:

> > Whether or not there is consensus on it, it should be clear that a 
> > detailed review will be needed to establish whether every syscall
> > listed was indeed present in 3.2 (or the first kernel version
> > supported by glibc for an architecture, if later) 
> 
> If I understood you correctly - the "syscall" - for example
> clock_settime (with either 32 or 64 bit ABI) needs to be defined in
> kernel 3.2 (the oldest supported kernel).

Yes.

> If it is not defined (or has different implementation), then it is
> excluded from the list of syscalls eligible to __ASSUME_TIME64_SYSCALLS?

Yes.

> > for all glibc architectures.
> 
> I'm a bit puzzled with the above sentence. We now focus on Linux
> implementation - for example __ASSUME_TIME64_SYSCALLS is defined in:
> sysdeps/unix/sysv/linux/kernel-features.h
> 
> Do you mean by "all glibc architectures" - all the architectures
> supported by Linux kernel?

All architectures supported by both glibc and the Linux kernel.  We're not 
concerned with the various architectures supported by the Linux kernel but 
not by glibc; when a new glibc port is added that has been around so long 
in the Linux kernel that it doesn't use the generic syscall interface, 
that's when we'd need to check for such architectures whether the generic 
kernel-features.h is accurate for them.  (Architectures using the 
asm-generic syscall interface aren't such a problem as they all get new 
syscalls at once, only needing to be defined in a single place, except for 
the compat syscall table case.)

We're also not concerned with syscall ABIs not supported by glibc for 
architectures that are supported by glibc.  For example, we don't care 
whether some syscall was supported in the 64-bit hppa ABI, because the 
glibc hppa port is 32-bit only.  Likewise for 64-bit sh.

Note that when checking for syscall support in old kernels you need to 
check *both* the syscall table for the architecture (arranged in a 
different way for every architecture, in old kernels) *and* the 
asm/unistd.h header - only very recently has the kernel moved to a uniform 
format for syscall tables.  In addition, you need to check any relevant 
compat syscall tables.
  

Patch

diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index bc5c959f58..fd5958cb64 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -143,3 +143,40 @@ 
    */
 
 #define __ASSUME_CLONE_DEFAULT 1
+
+/* This flag indicates support for Linux kernel syscalls, which are able
+   to handle 64 bit time ABI. It is defined for architectures with both
+   intrinsic 64 bit time support as well as ones gaining it with new
+   syscalls added to Linux kernel version 5.1.
+
+   To be more specific - this flag focuses on higer level of abstraction,
+   which indicates the system's ability to support 64 bit time.
+
+   In the other words we do not focus on particular syscalls, but on the
+   ability which is provided by them.
+
+   As an example - the syscall to set clock (clock_settime) - if the
+   __ASSUME_TIME64_SYSCALLS is defined, it indicates that 64 bit time can
+   be set in the system.
+
+   On systems with __WORDSIZE == 64 the __NR_clock_settime syscall is used
+   to achieve this goal. Contrary, systems with __WORDSIZE == 32 do use
+   new __NR_clock_settime64 syscall available from Linux version 5.1.
+
+   The __ASSUME_TIME64_SYSCALLS is defined for:
+
+   1. Systems with intrinsic 64 bit time support (__WORDSIZE == 64).
+
+   2. For x32 architecture, which is a special case in respect to 64 bit
+      time support (it has __WORDSIZE==32 but __TIMESIZE==64)
+
+   3. Systems with __WORDSIZE==32, which gain 64 bit time support
+      with new set of syscalls added to Linux kernel 5.1.  */
+
+#include <bits/wordsize.h>
+#if (__WORDSIZE == 64                                                   \
+     || (__WORDSIZE == 32                                               \
+         && (__LINUX_KERNEL_VERSION >= 0x050100                         \
+             || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64))))
+# define __ASSUME_TIME64_SYSCALLS 1
+#endif