diff mbox series

[v2,2/3] Linux: Add the sched_setattr and sched_getattr functions

Message ID 1f7f9c80017e91f0af99e1bfd9ec1f59c6cc0da7.1725567796.git.fweimer@redhat.com
State New
Headers show
Series Add the sched_setattr, sched_getattr functions | expand

Commit Message

Florian Weimer Sept. 5, 2024, 8:24 p.m. UTC
And struct sched_attr.

In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
sched_param around the inclusion of <linux/sched/types.h> is quite
ugly, but the definition of struct sched_param has already been
dropped by the kernel, so there is nothing else we can do and maintain
compatibility of <sched.h> with a wide range of kernel header
versions.  (An alternative would involve introducing a separate header
for this functionality, but this seems unnecessary.)

The existing sched_* functions that change scheduler parameters
are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
there is no harm in adding more functionality in this area.

The documentation mostly defers to the Linux manual pages.
---
 NEWS                                          |   3 +
 manual/resource.texi                          | 115 ++++++++++++++++++
 sysdeps/unix/sysv/linux/Makefile              |   3 +
 sysdeps/unix/sysv/linux/Versions              |   4 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist    |   2 +
 sysdeps/unix/sysv/linux/arc/libc.abilist      |   2 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist   |   2 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist   |   2 +
 sysdeps/unix/sysv/linux/bits/sched.h          |  44 ++++++-
 sysdeps/unix/sysv/linux/csky/libc.abilist     |   2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   2 +
 .../sysv/linux/loongarch/lp64/libc.abilist    |   2 +
 .../sysv/linux/m68k/coldfire/libc.abilist     |   2 +
 .../unix/sysv/linux/m68k/m680x0/libc.abilist  |   2 +
 .../sysv/linux/microblaze/be/libc.abilist     |   2 +
 .../sysv/linux/microblaze/le/libc.abilist     |   2 +
 .../sysv/linux/mips/mips32/fpu/libc.abilist   |   2 +
 .../sysv/linux/mips/mips32/nofpu/libc.abilist |   2 +
 .../sysv/linux/mips/mips64/n32/libc.abilist   |   2 +
 .../sysv/linux/mips/mips64/n64/libc.abilist   |   2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist    |   2 +
 sysdeps/unix/sysv/linux/or1k/libc.abilist     |   2 +
 .../linux/powerpc/powerpc32/fpu/libc.abilist  |   2 +
 .../powerpc/powerpc32/nofpu/libc.abilist      |   2 +
 .../linux/powerpc/powerpc64/be/libc.abilist   |   2 +
 .../linux/powerpc/powerpc64/le/libc.abilist   |   2 +
 .../unix/sysv/linux/riscv/rv32/libc.abilist   |   2 +
 .../unix/sysv/linux/riscv/rv64/libc.abilist   |   2 +
 .../unix/sysv/linux/s390/s390-32/libc.abilist |   2 +
 .../unix/sysv/linux/s390/s390-64/libc.abilist |   2 +
 sysdeps/unix/sysv/linux/sched_getattr.c       |  27 ++++
 sysdeps/unix/sysv/linux/sched_setattr.c       |  26 ++++
 sysdeps/unix/sysv/linux/sh/be/libc.abilist    |   2 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist    |   2 +
 .../sysv/linux/sparc/sparc32/libc.abilist     |   2 +
 .../sysv/linux/sparc/sparc64/libc.abilist     |   2 +
 sysdeps/unix/sysv/linux/tst-sched_setattr.c   | 105 ++++++++++++++++
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   2 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   2 +
 41 files changed, 391 insertions(+), 2 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/sched_getattr.c
 create mode 100644 sysdeps/unix/sysv/linux/sched_setattr.c
 create mode 100644 sysdeps/unix/sysv/linux/tst-sched_setattr.c

Comments

Carlos O'Donell Sept. 6, 2024, 12:19 p.m. UTC | #1
On 9/5/24 4:24 PM, Florian Weimer wrote:
> And struct sched_attr.
> 
> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
> sched_param around the inclusion of <linux/sched/types.h> is quite
> ugly, but the definition of struct sched_param has already been
> dropped by the kernel, so there is nothing else we can do and maintain
> compatibility of <sched.h> with a wide range of kernel header
> versions.  (An alternative would involve introducing a separate header
> for this functionality, but this seems unnecessary.)
> 
> The existing sched_* functions that change scheduler parameters
> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
> there is no harm in adding more functionality in this area.
> 
> The documentation mostly defers to the Linux manual pages.

One minor missing "to".

If you fix only the missing "to" then you can keep my RB and push.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  NEWS                                          |   3 +
>  manual/resource.texi                          | 115 ++++++++++++++++++
>  sysdeps/unix/sysv/linux/Makefile              |   3 +
>  sysdeps/unix/sysv/linux/Versions              |   4 +
>  sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   2 +
>  sysdeps/unix/sysv/linux/alpha/libc.abilist    |   2 +
>  sysdeps/unix/sysv/linux/arc/libc.abilist      |   2 +
>  sysdeps/unix/sysv/linux/arm/be/libc.abilist   |   2 +
>  sysdeps/unix/sysv/linux/arm/le/libc.abilist   |   2 +
>  sysdeps/unix/sysv/linux/bits/sched.h          |  44 ++++++-
>  sysdeps/unix/sysv/linux/csky/libc.abilist     |   2 +
>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |   2 +
>  sysdeps/unix/sysv/linux/i386/libc.abilist     |   2 +
>  .../sysv/linux/loongarch/lp64/libc.abilist    |   2 +
>  .../sysv/linux/m68k/coldfire/libc.abilist     |   2 +
>  .../unix/sysv/linux/m68k/m680x0/libc.abilist  |   2 +
>  .../sysv/linux/microblaze/be/libc.abilist     |   2 +
>  .../sysv/linux/microblaze/le/libc.abilist     |   2 +
>  .../sysv/linux/mips/mips32/fpu/libc.abilist   |   2 +
>  .../sysv/linux/mips/mips32/nofpu/libc.abilist |   2 +
>  .../sysv/linux/mips/mips64/n32/libc.abilist   |   2 +
>  .../sysv/linux/mips/mips64/n64/libc.abilist   |   2 +
>  sysdeps/unix/sysv/linux/nios2/libc.abilist    |   2 +
>  sysdeps/unix/sysv/linux/or1k/libc.abilist     |   2 +
>  .../linux/powerpc/powerpc32/fpu/libc.abilist  |   2 +
>  .../powerpc/powerpc32/nofpu/libc.abilist      |   2 +
>  .../linux/powerpc/powerpc64/be/libc.abilist   |   2 +
>  .../linux/powerpc/powerpc64/le/libc.abilist   |   2 +
>  .../unix/sysv/linux/riscv/rv32/libc.abilist   |   2 +
>  .../unix/sysv/linux/riscv/rv64/libc.abilist   |   2 +
>  .../unix/sysv/linux/s390/s390-32/libc.abilist |   2 +
>  .../unix/sysv/linux/s390/s390-64/libc.abilist |   2 +
>  sysdeps/unix/sysv/linux/sched_getattr.c       |  27 ++++
>  sysdeps/unix/sysv/linux/sched_setattr.c       |  26 ++++
>  sysdeps/unix/sysv/linux/sh/be/libc.abilist    |   2 +
>  sysdeps/unix/sysv/linux/sh/le/libc.abilist    |   2 +
>  .../sysv/linux/sparc/sparc32/libc.abilist     |   2 +
>  .../sysv/linux/sparc/sparc64/libc.abilist     |   2 +
>  sysdeps/unix/sysv/linux/tst-sched_setattr.c   | 105 ++++++++++++++++
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   2 +
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   2 +
>  41 files changed, 391 insertions(+), 2 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/sched_getattr.c
>  create mode 100644 sysdeps/unix/sysv/linux/sched_setattr.c
>  create mode 100644 sysdeps/unix/sysv/linux/tst-sched_setattr.c
> 
> diff --git a/NEWS b/NEWS
> index d488874aba..10894e7b5a 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -25,6 +25,9 @@ Major new features:
>    which is why this mode is not enabled by default.  A future version
>    of the library may turn it on by default, however.
>  
> +* On Linux, the sched_setattr and sched_getattr have been added, for
> +  supporting parameterized scheduling policies such as SCHED_DEADLINE.
> +
>  Deprecated and removed features, and other changes affecting compatibility:
>  
>    [Add deprecations, removals and changes affecting compatibility here]
> diff --git a/manual/resource.texi b/manual/resource.texi
> index 25966bcb64..612520d4d9 100644
> --- a/manual/resource.texi
> +++ b/manual/resource.texi
> @@ -478,6 +478,7 @@ POSIX syntax had in mind.
>  * Absolute Priority::               The first tier of priority.  Posix
>  * Realtime Scheduling::             Scheduling among the process nobility
>  * Basic Scheduling Functions::      Get/set scheduling policy, priority
> +* Extensible Scheduling::           Parameterized scheduling policies.
>  * Traditional Scheduling::          Scheduling among the vulgar masses
>  * CPU Affinity::                    Limiting execution to certain CPUs
>  @end menu
> @@ -952,6 +953,120 @@ function, so there are no specific @code{errno} values.
>  
>  @end deftypefun
>  
> +@node Extensible Scheduling
> +@subsection Extensible Scheduling
> +@cindex scheduling, extensible
> +
> +The type @code{struct sched_attr} and the functions @code{sched_setattr}
> +and @code{sched_getattr} are used to implement scheduling policies with
> +multiple parameters (not just priority and niceness).
> +
> +It is expected that these interfaces will be compatible with all future
> +scheduling policies.
> +
> +For additional information about scheduling policies, consult consult
> +the manual pages @manpageurl{sched,7} and @manpageurl{sched_setattr,2}.
> +@xref{Linux Kernel}.
> +
> +@strong{Note:} Calling the @code{sched_setattr} function is incompatible
> +with support for @code{PTHREAD_PRIO_PROTECT} mutexes.
> +
> +@deftp {Data Type} {struct sched_attr}
> +@standards{Linux, sched.h}
> +The @code{sched_attr} structure describes a parameterized scheduling policy.
> +
> +@strong{Portability note:} In the future, additional fields can be added
> +to @code{struct sched_attr} at the end, so that the size of this data
> +type changes.  Do not use it in places where this matters, such as
> +structure fields in installed header files, where such a change could
> +impact the application binary interface (ABI).
> +
> +The following generic fields are available.
> +
> +@table @code
> +@item size
> +The actually used size of the data structure.  See the description of
> +the functions @code{sched_setattr} and @code{sched_getattr} below how this
> +field is used to support extension of @code{struct sched_attr} with
> +more fields.

OK. Completed sentence from last patch.

> +
> +@item sched_policy
> +The scheduling policy.  This field determines which fields in the
> +structure are used, and how the @code{sched_flags} field is interpreted.

OK.

> +
> +@item sched_flags
> +Scheduling flags associated with the scheduling policy.
> +@end table
> +
> +In addition to the generic fields, policy-specific fields are available.
> +For additional information, consult the manual page
> +@manpageurl{sched_setattr,2}.  @xref{Linux Kernel}.
> +@end deftp
> +
> +@deftypefun int sched_setaddr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int flags)
> +@standards{Linux, sched.h}
> +@safety{@mtsafe{}@assafe{}@acsafe{}}
> +This functions applies the scheduling policy described by
> +@code{*@var{attr}} to the thread @var{tid} (the value zero denotes the
> +current thread).
> +
> +It is recommended to initialize unused fields to zero, either using
> +@code{memset}, or using a structure initializer.  The
> +@code{@var{attr->size}} field should be set to @code{sizeof (struct
> +sched_attr)}, to inform the kernel of the structure version in use.
> +
> +The @var{flags} argument must be zero.  Other values may become
> +available in the future.

OK. Clear language around the use of zero.

> +
> +On failure, @code{sched_setattr} returns @math{-1} and sets
> +@code{errno}.  The following errors are related the way

s/related the/related to the/g

> +extensibility is handled.
> +@table @code
> +@item E2BIG
> +A field in @code{*@var{attr}} has a non-zero value, but is unknown to
> +the kernel.  The application could try to apply a modified policy, where
> +more fields are zero.
> +
> +@item EINVAL
> +The policy in @code{@var{attr}->sched_policy} is unknown to the kernel,
> +or flags are set in @code{@var{attr}->sched_flags} that the kernel does

OK. Fixed grammatical error.

> +not know how to interpret.  The application could try with fewer flags
> +set, or a different scheduling policy.
> +
> +This error also occurs if @var{attr} is @code{NULL} or @var{flags} is
> +not zero.
> +
> +@item EPERM
> +The current thread is not sufficiently privileged to assign the policy,
> +either because access to the policy is restricted in general, or because
> +the current thread does not have the rights to change the scheduling
> +policy of the thread @var{tid}.
> +@end table
> +
> +Other error codes depend on the scheduling policy.
> +@end deftypefun
> +
> +@deftypefun int sched_getaddr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int size, unsigned int flags)
> +@standards{Linux, sched.h}
> +@safety{@mtsafe{}@assafe{}@acsafe{}}
> +This function obtains the scheduling policy of the thread @var{tid}
> +(zero denotes the current thread) and store it in @code{*@var{attr}},
> +which must have space for at least @var{size} bytes.
> +
> +The @var{flags} argument must be zero.  Other values may become
> +available in the future.

OK. Nice rewording for clarity.

> +
> +Upon success, @code{@var{attr}->size} contains the size of the structure
> +version used by the kernel.  Fields with offsets greater or equal to
> +@code{@var{attr}->size} are not updated by the kernel.  To obtain
> +predictable values for unknown fields, use @code{memset} to set
> +all @var{size} bytes to zero prior to calling @code{sched_getattr}.
> +
> +On failure, @code{sched_getattr} returns @math{-1} and sets @code{errno}.
> +If @code{errno} is @code{E2BIG}, this means that the buffer is not large
> +large enough, and the application could retry with a larger buffer.
> +@end deftypefun
> +
>  @node Traditional Scheduling
>  @subsection Traditional Scheduling
>  @cindex scheduling, traditional
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 59998c7af4..0b45d4e42b 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -95,6 +95,8 @@ sysdep_routines += \
>    process_vm_writev \
>    pselect32 \
>    readahead \
> +  sched_getattr \
> +  sched_setattr \
>    setfsgid \
>    setfsuid \
>    setvmaname \
> @@ -224,6 +226,7 @@ tests += \
>    tst-process_mrelease \
>    tst-quota \
>    tst-rlimit-infinity \
> +  tst-sched_setattr \
>    tst-scm_rights \
>    tst-sigtimedwait \
>    tst-sync_file_range \
> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> index 268ba1b6ac..213ff5f1fe 100644
> --- a/sysdeps/unix/sysv/linux/Versions
> +++ b/sysdeps/unix/sysv/linux/Versions
> @@ -328,6 +328,10 @@ libc {
>      posix_spawnattr_getcgroup_np;
>      posix_spawnattr_setcgroup_np;
>    }
> +  GLIBC_2.41 {
> +    sched_getattr;
> +    sched_setattr;
> +  }
>    GLIBC_PRIVATE {
>      # functions used in other libraries
>      __syscall_rt_sigqueueinfo;
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 68eeca1c08..38db77e4f7 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2748,3 +2748,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 34c187b721..637bfce9fb 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -3095,6 +3095,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
> index 916c18ea94..4a305cf730 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
> @@ -2509,3 +2509,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index ea95de282a..1d54f71b14 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -2801,6 +2801,8 @@ GLIBC_2.4 xdrstdio_create F
>  GLIBC_2.4 xencrypt F
>  GLIBC_2.4 xprt_register F
>  GLIBC_2.4 xprt_unregister F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index 1cdbc983e1..ff7e8bc40b 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -2798,6 +2798,8 @@ GLIBC_2.4 xdrstdio_create F
>  GLIBC_2.4 xencrypt F
>  GLIBC_2.4 xprt_register F
>  GLIBC_2.4 xprt_unregister F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h
> index a53e1362a0..e5b7efb887 100644
> --- a/sysdeps/unix/sysv/linux/bits/sched.h
> +++ b/sysdeps/unix/sysv/linux/bits/sched.h
> @@ -34,10 +34,39 @@
>  # define SCHED_IDLE		5
>  # define SCHED_DEADLINE		6
>  
> +/* Flags that can be used in policy values.  */
>  # define SCHED_RESET_ON_FORK	0x40000000
> -#endif
>  
> -#ifdef __USE_GNU
> +/* Use "" to work around incorrect macro expansion of the
> +   __has_include argument (GCC PR 80005).  */
> +# ifdef __has_include
> +#  if __has_include ("linux/sched/types.h")
> +/* Some older Linux versions defined sched_param in <linux/sched/types.h>.  */
> +#   define sched_param __glibc_mask_sched_param
> +#   include <linux/sched/types.h>
> +#   undef sched_param
> +#  endif
> +# endif
> +# ifndef SCHED_ATTR_SIZE_VER0
> +#  include <linux/types.h>
> +#  define SCHED_ATTR_SIZE_VER0 48
> +#  define SCHED_ATTR_SIZE_VER1 56
> +struct sched_attr
> +{
> +  __u32 size;
> +  __u32 sched_policy;
> +  __u64 sched_flags;
> +  __s32 sched_nice;
> +  __u32 sched_priority;
> +  __u64 sched_runtime;
> +  __u64 sched_deadline;
> +  __u64 sched_period;
> +  __u32 sched_util_min;
> +  __u32 sched_util_max;
> +  /* Additional fields may be added at the end.  */
> +};
> +# endif /* !SCHED_ATTR_SIZE_VER0 */
> +
>  /* Cloning flags.  */
>  # define CSIGNAL       0x000000ff /* Signal mask to be sent at exit.  */
>  # define CLONE_VM      0x00000100 /* Set if VM shared between processes.  */
> @@ -97,6 +126,17 @@ extern int getcpu (unsigned int *, unsigned int *) __THROW;
>  
>  /* Switch process to namespace of type NSTYPE indicated by FD.  */
>  extern int setns (int __fd, int __nstype) __THROW;
> +
> +/* Apply the scheduling attributes from *ATTR to the process or thread TID.  */
> +int sched_setattr (pid_t tid, struct sched_attr *attr, unsigned int flags)
> +  __THROW __nonnull ((2));
> +
> +/* Obtain the scheduling attributes of the process or thread TID and
> +   store it in *ATTR.  */
> +int sched_getattr (pid_t tid, struct sched_attr *attr, unsigned int size,
> +		   unsigned int flags)
> +  __THROW __nonnull ((2)) __attr_access ((__write_only__, 2, 3));
> +
>  #endif
>  
>  __END_DECLS
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index 96d45961e2..c3ed65467d 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2785,3 +2785,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index fbcd60c2b3..8de7644a59 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2821,6 +2821,8 @@ GLIBC_2.4 sys_errlist D 0x400
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index c989b433c0..4fedf775d4 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -3005,6 +3005,8 @@ GLIBC_2.4 sys_errlist D 0x210
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> index 0023ec1fa1..0024282289 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> @@ -2269,3 +2269,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index d9bd6a9b56..142595eb3e 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -2781,6 +2781,8 @@ GLIBC_2.4 xdrstdio_create F
>  GLIBC_2.4 xencrypt F
>  GLIBC_2.4 xprt_register F
>  GLIBC_2.4 xprt_unregister F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index 439796d693..85e7746c10 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2948,6 +2948,8 @@ GLIBC_2.4 sys_errlist D 0x210
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 1069d3252c..91dc1b8378 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2834,3 +2834,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index 17abe08c8b..3440e90f6f 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2831,3 +2831,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index 799e508950..5ee7b8c52f 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2909,6 +2909,8 @@ GLIBC_2.4 renameat F
>  GLIBC_2.4 symlinkat F
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index 1c10996cbc..6cb6328e7c 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2907,6 +2907,8 @@ GLIBC_2.4 renameat F
>  GLIBC_2.4 symlinkat F
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index 03d9655f26..ae7474c0f0 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2915,6 +2915,8 @@ GLIBC_2.4 renameat F
>  GLIBC_2.4 symlinkat F
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 05e402ed30..cdf040dec2 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2817,6 +2817,8 @@ GLIBC_2.4 renameat F
>  GLIBC_2.4 symlinkat F
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 3aa81766aa..773d4c5873 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2873,3 +2873,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> index 959e59e7e7..c356a11b1c 100644
> --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> @@ -2259,3 +2259,5 @@ GLIBC_2.40 getcontext F
>  GLIBC_2.40 makecontext F
>  GLIBC_2.40 setcontext F
>  GLIBC_2.40 swapcontext F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 9714305608..7937f94cf0 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -3138,6 +3138,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index 0beb52c542..d6e35f31d2 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -3183,6 +3183,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index cfc2ebd3ec..2268d6890d 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2892,6 +2892,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index 8c9efc5a16..7f61b14bc8 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2968,3 +2968,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> index 6397a9cb91..4187241f50 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> @@ -2512,3 +2512,5 @@ GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
>  GLIBC_2.40 __riscv_hwprobe F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index 71bbf94f66..8935beccac 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2712,3 +2712,5 @@ GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
>  GLIBC_2.40 __riscv_hwprobe F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index a7467e2850..e69dc7ccf6 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -3136,6 +3136,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index fd1cb2972d..7d860001d8 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2929,6 +2929,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/sched_getattr.c b/sysdeps/unix/sysv/linux/sched_getattr.c
> new file mode 100644
> index 0000000000..e6b9970fcb
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sched_getattr.c
> @@ -0,0 +1,27 @@
> +/* Reading scheduling policy and attributes.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public License as
> +   published by the Free Software Foundation; either version 2.1 of the
> +   License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sched.h>
> +#include <sysdep.h>
> +
> +int
> +sched_getattr (pid_t pid, struct sched_attr *attr, unsigned int size,
> +               unsigned int flags)
> +{
> +  return INLINE_SYSCALL_CALL (sched_getattr, pid, attr, size, flags);
> +}
> diff --git a/sysdeps/unix/sysv/linux/sched_setattr.c b/sysdeps/unix/sysv/linux/sched_setattr.c
> new file mode 100644
> index 0000000000..25403fb454
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sched_setattr.c
> @@ -0,0 +1,26 @@
> +/* Setting scheduling policy and attributes.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public License as
> +   published by the Free Software Foundation; either version 2.1 of the
> +   License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sched.h>
> +#include <sysdep.h>
> +
> +int
> +sched_setattr (pid_t pid, struct sched_attr *attr, unsigned int flags)
> +{
> +  return INLINE_SYSCALL_CALL (sched_setattr, pid, attr, flags);
> +}
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index ff6e6b1a13..fcb8161841 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2828,6 +2828,8 @@ GLIBC_2.4 sys_errlist D 0x210
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index 449d92bbc5..3fd078d125 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2825,6 +2825,8 @@ GLIBC_2.4 sys_errlist D 0x210
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index e615be759a..1ce1fe9da7 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -3157,6 +3157,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index bd36431dd7..07507b86f6 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2793,6 +2793,8 @@ GLIBC_2.4 sys_errlist D 0x430
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/tst-sched_setattr.c b/sysdeps/unix/sysv/linux/tst-sched_setattr.c
> new file mode 100644
> index 0000000000..a6288a1a7c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-sched_setattr.c
> @@ -0,0 +1,105 @@
> +/* Tests for sched_setattr and sched_getattr.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public License as
> +   published by the Free Software Foundation; either version 2.1 of the
> +   License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sched.h>
> +
> +#include <errno.h>
> +#include <stddef.h>
> +#include <string.h>
> +#include <support/check.h>
> +#include <sys/resource.h>
> +#include <unistd.h>
> +
> +/* Padding struct to detect unexpected writes.   */
> +union
> +{
> +  struct sched_attr attr;
> +  /* Hopefully the kernel will never need as much.  */
> +  unsigned char padding[4096];
> +} u;
> +
> +static void
> +check_unused (void)
> +{
> +  TEST_VERIFY (u.attr.size < sizeof (u));
> +  for (unsigned int i = u.attr.size; i < sizeof (u); ++i)
> +    TEST_COMPARE (u.padding[i], 0xcc);
> +}
> +
> +static int
> +do_test (void)
> +{
> +  TEST_VERIFY (sizeof (struct sched_attr) < sizeof (u));
> +
> +  /* Check that reading and re-applying the current policy works.  */
> +  memset (&u, 0xcc, sizeof (u));
> +  /* Compiler barrier to bypass write access attribute.  */
> +  volatile unsigned int size = sizeof (u);
> +  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
> +  check_unused ();
> +  TEST_COMPARE (sched_setattr (0, &u.attr, 0), 0); /* Apply unchanged.  */
> +
> +  /* Try to switch to the SCHED_OTHER policy.   */
> +  memset (&u, 0, sizeof (u));
> +  u.attr.size = sizeof (u); /* With padding, kernel should accept zeroes.  */
> +  u.attr.sched_policy = SCHED_OTHER; /* Should be the default.  */
> +  {
> +    errno = 0;
> +    int prio = getpriority (PRIO_PROCESS, 0);
> +    if (errno != 0)
> +      prio = 0;
> +    u.attr.sched_nice = prio;
> +  }
> +  TEST_COMPARE (sched_setattr (0, &u.attr, 0), 0);
> +
> +  /* Non-zero values not known to the kernel result in an E2BIG error.  */
> +  memset (&u, 0, sizeof (u));
> +  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
> +  u.padding[u.attr.size] = 0xcc;
> +  u.attr.size = sizeof (u);
> +  errno = 0;
> +  TEST_COMPARE (sched_setattr (0, &u.attr, 0), -1);
> +  TEST_COMPARE (errno, E2BIG);
> +
> +  memset (&u, 0xcc, sizeof (u));
> +  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
> +  TEST_COMPARE (u.attr.sched_policy, SCHED_OTHER);
> +  check_unused ();
> +
> +  /* Raise the niceless level to 19 and observe its effect.  */
> +  TEST_COMPARE (nice (19), 19);
> +  TEST_COMPARE (sched_getattr (0, &u.attr, sizeof (u.attr), 0), 0);
> +  TEST_COMPARE (u.attr.sched_policy, SCHED_OTHER);
> +  TEST_COMPARE (u.attr.sched_nice, 19);

OK. Fixed.

> +  check_unused ();
> +
> +  /* Invalid buffer arguments result in EINVAL (not EFAULT).  */
> +  {
> +    errno = 0;
> +    void *volatile null_pointer = NULL; /* compiler barrier.  */
> +    TEST_COMPARE (sched_setattr (0, null_pointer, 0), -1);
> +    TEST_COMPARE (errno, EINVAL);
> +    errno = 0;
> +    TEST_COMPARE (sched_getattr (0, null_pointer, size, 0), -1);
> +    TEST_COMPARE (errno, EINVAL);
> +  }
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index aea7848ed6..5acf49dbe8 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2744,6 +2744,8 @@ GLIBC_2.4 sys_errlist D 0x420
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index 4ab3681914..02d1bb97dc 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2763,3 +2763,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
Adhemerval Zanella Sept. 6, 2024, 1 p.m. UTC | #2
On 05/09/24 17:24, Florian Weimer wrote:
> And struct sched_attr.
> 
> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
> sched_param around the inclusion of <linux/sched/types.h> is quite
> ugly, but the definition of struct sched_param has already been
> dropped by the kernel, so there is nothing else we can do and maintain
> compatibility of <sched.h> with a wide range of kernel header
> versions.  (An alternative would involve introducing a separate header
> for this functionality, but this seems unnecessary.)
> 
> The existing sched_* functions that change scheduler parameters
> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
> there is no harm in adding more functionality in this area.
> 
> The documentation mostly defers to the Linux manual pages.

So I take that the defined approach for syscalls that accepts extensible
struct arguments would just to document that it can not be used on places
that might affect the ABI, include the kernel definitions if present,
and just pass the size to the kernel then?

I was not sure how to proceed with the openat2 support back when I first
proposed [1] because I felt to me that we did not fully agreed how to
handle this cases.

[1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html

> ---
>  NEWS                                          |   3 +
>  manual/resource.texi                          | 115 ++++++++++++++++++
>  sysdeps/unix/sysv/linux/Makefile              |   3 +
>  sysdeps/unix/sysv/linux/Versions              |   4 +
>  sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   2 +
>  sysdeps/unix/sysv/linux/alpha/libc.abilist    |   2 +
>  sysdeps/unix/sysv/linux/arc/libc.abilist      |   2 +
>  sysdeps/unix/sysv/linux/arm/be/libc.abilist   |   2 +
>  sysdeps/unix/sysv/linux/arm/le/libc.abilist   |   2 +
>  sysdeps/unix/sysv/linux/bits/sched.h          |  44 ++++++-
>  sysdeps/unix/sysv/linux/csky/libc.abilist     |   2 +
>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |   2 +
>  sysdeps/unix/sysv/linux/i386/libc.abilist     |   2 +
>  .../sysv/linux/loongarch/lp64/libc.abilist    |   2 +
>  .../sysv/linux/m68k/coldfire/libc.abilist     |   2 +
>  .../unix/sysv/linux/m68k/m680x0/libc.abilist  |   2 +
>  .../sysv/linux/microblaze/be/libc.abilist     |   2 +
>  .../sysv/linux/microblaze/le/libc.abilist     |   2 +
>  .../sysv/linux/mips/mips32/fpu/libc.abilist   |   2 +
>  .../sysv/linux/mips/mips32/nofpu/libc.abilist |   2 +
>  .../sysv/linux/mips/mips64/n32/libc.abilist   |   2 +
>  .../sysv/linux/mips/mips64/n64/libc.abilist   |   2 +
>  sysdeps/unix/sysv/linux/nios2/libc.abilist    |   2 +
>  sysdeps/unix/sysv/linux/or1k/libc.abilist     |   2 +
>  .../linux/powerpc/powerpc32/fpu/libc.abilist  |   2 +
>  .../powerpc/powerpc32/nofpu/libc.abilist      |   2 +
>  .../linux/powerpc/powerpc64/be/libc.abilist   |   2 +
>  .../linux/powerpc/powerpc64/le/libc.abilist   |   2 +
>  .../unix/sysv/linux/riscv/rv32/libc.abilist   |   2 +
>  .../unix/sysv/linux/riscv/rv64/libc.abilist   |   2 +
>  .../unix/sysv/linux/s390/s390-32/libc.abilist |   2 +
>  .../unix/sysv/linux/s390/s390-64/libc.abilist |   2 +
>  sysdeps/unix/sysv/linux/sched_getattr.c       |  27 ++++
>  sysdeps/unix/sysv/linux/sched_setattr.c       |  26 ++++
>  sysdeps/unix/sysv/linux/sh/be/libc.abilist    |   2 +
>  sysdeps/unix/sysv/linux/sh/le/libc.abilist    |   2 +
>  .../sysv/linux/sparc/sparc32/libc.abilist     |   2 +
>  .../sysv/linux/sparc/sparc64/libc.abilist     |   2 +
>  sysdeps/unix/sysv/linux/tst-sched_setattr.c   | 105 ++++++++++++++++
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   2 +
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   2 +
>  41 files changed, 391 insertions(+), 2 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/sched_getattr.c
>  create mode 100644 sysdeps/unix/sysv/linux/sched_setattr.c
>  create mode 100644 sysdeps/unix/sysv/linux/tst-sched_setattr.c
> 
> diff --git a/NEWS b/NEWS
> index d488874aba..10894e7b5a 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -25,6 +25,9 @@ Major new features:
>    which is why this mode is not enabled by default.  A future version
>    of the library may turn it on by default, however.
>  
> +* On Linux, the sched_setattr and sched_getattr have been added, for
> +  supporting parameterized scheduling policies such as SCHED_DEADLINE.
> +
>  Deprecated and removed features, and other changes affecting compatibility:
>  
>    [Add deprecations, removals and changes affecting compatibility here]
> diff --git a/manual/resource.texi b/manual/resource.texi
> index 25966bcb64..612520d4d9 100644
> --- a/manual/resource.texi
> +++ b/manual/resource.texi
> @@ -478,6 +478,7 @@ POSIX syntax had in mind.
>  * Absolute Priority::               The first tier of priority.  Posix
>  * Realtime Scheduling::             Scheduling among the process nobility
>  * Basic Scheduling Functions::      Get/set scheduling policy, priority
> +* Extensible Scheduling::           Parameterized scheduling policies.
>  * Traditional Scheduling::          Scheduling among the vulgar masses
>  * CPU Affinity::                    Limiting execution to certain CPUs
>  @end menu
> @@ -952,6 +953,120 @@ function, so there are no specific @code{errno} values.
>  
>  @end deftypefun
>  
> +@node Extensible Scheduling
> +@subsection Extensible Scheduling
> +@cindex scheduling, extensible
> +
> +The type @code{struct sched_attr} and the functions @code{sched_setattr}
> +and @code{sched_getattr} are used to implement scheduling policies with
> +multiple parameters (not just priority and niceness).
> +
> +It is expected that these interfaces will be compatible with all future
> +scheduling policies.
> +
> +For additional information about scheduling policies, consult consult
> +the manual pages @manpageurl{sched,7} and @manpageurl{sched_setattr,2}.
> +@xref{Linux Kernel}.
> +
> +@strong{Note:} Calling the @code{sched_setattr} function is incompatible
> +with support for @code{PTHREAD_PRIO_PROTECT} mutexes.
> +
> +@deftp {Data Type} {struct sched_attr}
> +@standards{Linux, sched.h}
> +The @code{sched_attr} structure describes a parameterized scheduling policy.
> +
> +@strong{Portability note:} In the future, additional fields can be added
> +to @code{struct sched_attr} at the end, so that the size of this data
> +type changes.  Do not use it in places where this matters, such as
> +structure fields in installed header files, where such a change could
> +impact the application binary interface (ABI).
> +
> +The following generic fields are available.
> +
> +@table @code
> +@item size
> +The actually used size of the data structure.  See the description of
> +the functions @code{sched_setattr} and @code{sched_getattr} below how this
> +field is used to support extension of @code{struct sched_attr} with
> +more fields.
> +
> +@item sched_policy
> +The scheduling policy.  This field determines which fields in the
> +structure are used, and how the @code{sched_flags} field is interpreted.
> +
> +@item sched_flags
> +Scheduling flags associated with the scheduling policy.
> +@end table
> +
> +In addition to the generic fields, policy-specific fields are available.
> +For additional information, consult the manual page
> +@manpageurl{sched_setattr,2}.  @xref{Linux Kernel}.
> +@end deftp
> +
> +@deftypefun int sched_setaddr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int flags)
> +@standards{Linux, sched.h}
> +@safety{@mtsafe{}@assafe{}@acsafe{}}
> +This functions applies the scheduling policy described by
> +@code{*@var{attr}} to the thread @var{tid} (the value zero denotes the
> +current thread).
> +
> +It is recommended to initialize unused fields to zero, either using
> +@code{memset}, or using a structure initializer.  The
> +@code{@var{attr->size}} field should be set to @code{sizeof (struct
> +sched_attr)}, to inform the kernel of the structure version in use.
> +
> +The @var{flags} argument must be zero.  Other values may become
> +available in the future.
> +
> +On failure, @code{sched_setattr} returns @math{-1} and sets
> +@code{errno}.  The following errors are related the way
> +extensibility is handled.
> +@table @code
> +@item E2BIG
> +A field in @code{*@var{attr}} has a non-zero value, but is unknown to
> +the kernel.  The application could try to apply a modified policy, where
> +more fields are zero.
> +
> +@item EINVAL
> +The policy in @code{@var{attr}->sched_policy} is unknown to the kernel,
> +or flags are set in @code{@var{attr}->sched_flags} that the kernel does
> +not know how to interpret.  The application could try with fewer flags
> +set, or a different scheduling policy.
> +
> +This error also occurs if @var{attr} is @code{NULL} or @var{flags} is
> +not zero.
> +
> +@item EPERM
> +The current thread is not sufficiently privileged to assign the policy,
> +either because access to the policy is restricted in general, or because
> +the current thread does not have the rights to change the scheduling
> +policy of the thread @var{tid}.
> +@end table
> +
> +Other error codes depend on the scheduling policy.
> +@end deftypefun
> +
> +@deftypefun int sched_getaddr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int size, unsigned int flags)
> +@standards{Linux, sched.h}
> +@safety{@mtsafe{}@assafe{}@acsafe{}}
> +This function obtains the scheduling policy of the thread @var{tid}
> +(zero denotes the current thread) and store it in @code{*@var{attr}},
> +which must have space for at least @var{size} bytes.
> +
> +The @var{flags} argument must be zero.  Other values may become
> +available in the future.
> +
> +Upon success, @code{@var{attr}->size} contains the size of the structure
> +version used by the kernel.  Fields with offsets greater or equal to
> +@code{@var{attr}->size} are not updated by the kernel.  To obtain
> +predictable values for unknown fields, use @code{memset} to set
> +all @var{size} bytes to zero prior to calling @code{sched_getattr}.
> +
> +On failure, @code{sched_getattr} returns @math{-1} and sets @code{errno}.
> +If @code{errno} is @code{E2BIG}, this means that the buffer is not large
> +large enough, and the application could retry with a larger buffer.
> +@end deftypefun
> +
>  @node Traditional Scheduling
>  @subsection Traditional Scheduling
>  @cindex scheduling, traditional
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 59998c7af4..0b45d4e42b 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -95,6 +95,8 @@ sysdep_routines += \
>    process_vm_writev \
>    pselect32 \
>    readahead \
> +  sched_getattr \
> +  sched_setattr \
>    setfsgid \
>    setfsuid \
>    setvmaname \
> @@ -224,6 +226,7 @@ tests += \
>    tst-process_mrelease \
>    tst-quota \
>    tst-rlimit-infinity \
> +  tst-sched_setattr \
>    tst-scm_rights \
>    tst-sigtimedwait \
>    tst-sync_file_range \
> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> index 268ba1b6ac..213ff5f1fe 100644
> --- a/sysdeps/unix/sysv/linux/Versions
> +++ b/sysdeps/unix/sysv/linux/Versions
> @@ -328,6 +328,10 @@ libc {
>      posix_spawnattr_getcgroup_np;
>      posix_spawnattr_setcgroup_np;
>    }
> +  GLIBC_2.41 {
> +    sched_getattr;
> +    sched_setattr;
> +  }
>    GLIBC_PRIVATE {
>      # functions used in other libraries
>      __syscall_rt_sigqueueinfo;
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 68eeca1c08..38db77e4f7 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2748,3 +2748,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 34c187b721..637bfce9fb 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -3095,6 +3095,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
> index 916c18ea94..4a305cf730 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
> @@ -2509,3 +2509,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index ea95de282a..1d54f71b14 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -2801,6 +2801,8 @@ GLIBC_2.4 xdrstdio_create F
>  GLIBC_2.4 xencrypt F
>  GLIBC_2.4 xprt_register F
>  GLIBC_2.4 xprt_unregister F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index 1cdbc983e1..ff7e8bc40b 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -2798,6 +2798,8 @@ GLIBC_2.4 xdrstdio_create F
>  GLIBC_2.4 xencrypt F
>  GLIBC_2.4 xprt_register F
>  GLIBC_2.4 xprt_unregister F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h
> index a53e1362a0..e5b7efb887 100644
> --- a/sysdeps/unix/sysv/linux/bits/sched.h
> +++ b/sysdeps/unix/sysv/linux/bits/sched.h
> @@ -34,10 +34,39 @@
>  # define SCHED_IDLE		5
>  # define SCHED_DEADLINE		6
>  
> +/* Flags that can be used in policy values.  */
>  # define SCHED_RESET_ON_FORK	0x40000000
> -#endif
>  
> -#ifdef __USE_GNU
> +/* Use "" to work around incorrect macro expansion of the
> +   __has_include argument (GCC PR 80005).  */
> +# ifdef __has_include
> +#  if __has_include ("linux/sched/types.h")
> +/* Some older Linux versions defined sched_param in <linux/sched/types.h>.  */
> +#   define sched_param __glibc_mask_sched_param
> +#   include <linux/sched/types.h>
> +#   undef sched_param
> +#  endif
> +# endif
> +# ifndef SCHED_ATTR_SIZE_VER0
> +#  include <linux/types.h>
> +#  define SCHED_ATTR_SIZE_VER0 48
> +#  define SCHED_ATTR_SIZE_VER1 56
> +struct sched_attr
> +{
> +  __u32 size;
> +  __u32 sched_policy;
> +  __u64 sched_flags;
> +  __s32 sched_nice;
> +  __u32 sched_priority;
> +  __u64 sched_runtime;
> +  __u64 sched_deadline;
> +  __u64 sched_period;
> +  __u32 sched_util_min;
> +  __u32 sched_util_max;
> +  /* Additional fields may be added at the end.  */
> +};
> +# endif /* !SCHED_ATTR_SIZE_VER0 */
> +
>  /* Cloning flags.  */
>  # define CSIGNAL       0x000000ff /* Signal mask to be sent at exit.  */
>  # define CLONE_VM      0x00000100 /* Set if VM shared between processes.  */
> @@ -97,6 +126,17 @@ extern int getcpu (unsigned int *, unsigned int *) __THROW;
>  
>  /* Switch process to namespace of type NSTYPE indicated by FD.  */
>  extern int setns (int __fd, int __nstype) __THROW;
> +
> +/* Apply the scheduling attributes from *ATTR to the process or thread TID.  */
> +int sched_setattr (pid_t tid, struct sched_attr *attr, unsigned int flags)
> +  __THROW __nonnull ((2));
> +
> +/* Obtain the scheduling attributes of the process or thread TID and
> +   store it in *ATTR.  */
> +int sched_getattr (pid_t tid, struct sched_attr *attr, unsigned int size,
> +		   unsigned int flags)
> +  __THROW __nonnull ((2)) __attr_access ((__write_only__, 2, 3));
> +
>  #endif
>  
>  __END_DECLS
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index 96d45961e2..c3ed65467d 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2785,3 +2785,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index fbcd60c2b3..8de7644a59 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2821,6 +2821,8 @@ GLIBC_2.4 sys_errlist D 0x400
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index c989b433c0..4fedf775d4 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -3005,6 +3005,8 @@ GLIBC_2.4 sys_errlist D 0x210
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> index 0023ec1fa1..0024282289 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> @@ -2269,3 +2269,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index d9bd6a9b56..142595eb3e 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -2781,6 +2781,8 @@ GLIBC_2.4 xdrstdio_create F
>  GLIBC_2.4 xencrypt F
>  GLIBC_2.4 xprt_register F
>  GLIBC_2.4 xprt_unregister F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index 439796d693..85e7746c10 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2948,6 +2948,8 @@ GLIBC_2.4 sys_errlist D 0x210
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 1069d3252c..91dc1b8378 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2834,3 +2834,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index 17abe08c8b..3440e90f6f 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2831,3 +2831,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index 799e508950..5ee7b8c52f 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2909,6 +2909,8 @@ GLIBC_2.4 renameat F
>  GLIBC_2.4 symlinkat F
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index 1c10996cbc..6cb6328e7c 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2907,6 +2907,8 @@ GLIBC_2.4 renameat F
>  GLIBC_2.4 symlinkat F
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index 03d9655f26..ae7474c0f0 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2915,6 +2915,8 @@ GLIBC_2.4 renameat F
>  GLIBC_2.4 symlinkat F
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 05e402ed30..cdf040dec2 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2817,6 +2817,8 @@ GLIBC_2.4 renameat F
>  GLIBC_2.4 symlinkat F
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 3aa81766aa..773d4c5873 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2873,3 +2873,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> index 959e59e7e7..c356a11b1c 100644
> --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> @@ -2259,3 +2259,5 @@ GLIBC_2.40 getcontext F
>  GLIBC_2.40 makecontext F
>  GLIBC_2.40 setcontext F
>  GLIBC_2.40 swapcontext F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 9714305608..7937f94cf0 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -3138,6 +3138,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index 0beb52c542..d6e35f31d2 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -3183,6 +3183,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index cfc2ebd3ec..2268d6890d 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2892,6 +2892,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index 8c9efc5a16..7f61b14bc8 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2968,3 +2968,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> index 6397a9cb91..4187241f50 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> @@ -2512,3 +2512,5 @@ GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
>  GLIBC_2.40 __riscv_hwprobe F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index 71bbf94f66..8935beccac 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2712,3 +2712,5 @@ GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
>  GLIBC_2.40 __riscv_hwprobe F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index a7467e2850..e69dc7ccf6 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -3136,6 +3136,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index fd1cb2972d..7d860001d8 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2929,6 +2929,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/sched_getattr.c b/sysdeps/unix/sysv/linux/sched_getattr.c
> new file mode 100644
> index 0000000000..e6b9970fcb
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sched_getattr.c
> @@ -0,0 +1,27 @@
> +/* Reading scheduling policy and attributes.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public License as
> +   published by the Free Software Foundation; either version 2.1 of the
> +   License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sched.h>
> +#include <sysdep.h>
> +
> +int
> +sched_getattr (pid_t pid, struct sched_attr *attr, unsigned int size,
> +               unsigned int flags)
> +{
> +  return INLINE_SYSCALL_CALL (sched_getattr, pid, attr, size, flags);
> +}
> diff --git a/sysdeps/unix/sysv/linux/sched_setattr.c b/sysdeps/unix/sysv/linux/sched_setattr.c
> new file mode 100644
> index 0000000000..25403fb454
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sched_setattr.c
> @@ -0,0 +1,26 @@
> +/* Setting scheduling policy and attributes.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public License as
> +   published by the Free Software Foundation; either version 2.1 of the
> +   License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sched.h>
> +#include <sysdep.h>
> +
> +int
> +sched_setattr (pid_t pid, struct sched_attr *attr, unsigned int flags)
> +{
> +  return INLINE_SYSCALL_CALL (sched_setattr, pid, attr, flags);
> +}
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index ff6e6b1a13..fcb8161841 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2828,6 +2828,8 @@ GLIBC_2.4 sys_errlist D 0x210
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index 449d92bbc5..3fd078d125 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2825,6 +2825,8 @@ GLIBC_2.4 sys_errlist D 0x210
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index e615be759a..1ce1fe9da7 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -3157,6 +3157,8 @@ GLIBC_2.4 wcstold F
>  GLIBC_2.4 wcstold_l F
>  GLIBC_2.4 wprintf F
>  GLIBC_2.4 wscanf F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index bd36431dd7..07507b86f6 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2793,6 +2793,8 @@ GLIBC_2.4 sys_errlist D 0x430
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/tst-sched_setattr.c b/sysdeps/unix/sysv/linux/tst-sched_setattr.c
> new file mode 100644
> index 0000000000..a6288a1a7c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-sched_setattr.c
> @@ -0,0 +1,105 @@
> +/* Tests for sched_setattr and sched_getattr.
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public License as
> +   published by the Free Software Foundation; either version 2.1 of the
> +   License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <sched.h>
> +
> +#include <errno.h>
> +#include <stddef.h>
> +#include <string.h>
> +#include <support/check.h>
> +#include <sys/resource.h>
> +#include <unistd.h>
> +
> +/* Padding struct to detect unexpected writes.   */
> +union
> +{
> +  struct sched_attr attr;
> +  /* Hopefully the kernel will never need as much.  */
> +  unsigned char padding[4096];
> +} u;
> +
> +static void
> +check_unused (void)
> +{
> +  TEST_VERIFY (u.attr.size < sizeof (u));
> +  for (unsigned int i = u.attr.size; i < sizeof (u); ++i)
> +    TEST_COMPARE (u.padding[i], 0xcc);
> +}
> +
> +static int
> +do_test (void)
> +{
> +  TEST_VERIFY (sizeof (struct sched_attr) < sizeof (u));
> +
> +  /* Check that reading and re-applying the current policy works.  */
> +  memset (&u, 0xcc, sizeof (u));
> +  /* Compiler barrier to bypass write access attribute.  */
> +  volatile unsigned int size = sizeof (u);
> +  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
> +  check_unused ();
> +  TEST_COMPARE (sched_setattr (0, &u.attr, 0), 0); /* Apply unchanged.  */
> +
> +  /* Try to switch to the SCHED_OTHER policy.   */
> +  memset (&u, 0, sizeof (u));
> +  u.attr.size = sizeof (u); /* With padding, kernel should accept zeroes.  */
> +  u.attr.sched_policy = SCHED_OTHER; /* Should be the default.  */
> +  {
> +    errno = 0;
> +    int prio = getpriority (PRIO_PROCESS, 0);
> +    if (errno != 0)
> +      prio = 0;
> +    u.attr.sched_nice = prio;
> +  }
> +  TEST_COMPARE (sched_setattr (0, &u.attr, 0), 0);
> +
> +  /* Non-zero values not known to the kernel result in an E2BIG error.  */
> +  memset (&u, 0, sizeof (u));
> +  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
> +  u.padding[u.attr.size] = 0xcc;
> +  u.attr.size = sizeof (u);
> +  errno = 0;
> +  TEST_COMPARE (sched_setattr (0, &u.attr, 0), -1);
> +  TEST_COMPARE (errno, E2BIG);
> +
> +  memset (&u, 0xcc, sizeof (u));
> +  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
> +  TEST_COMPARE (u.attr.sched_policy, SCHED_OTHER);
> +  check_unused ();
> +
> +  /* Raise the niceless level to 19 and observe its effect.  */
> +  TEST_COMPARE (nice (19), 19);
> +  TEST_COMPARE (sched_getattr (0, &u.attr, sizeof (u.attr), 0), 0);
> +  TEST_COMPARE (u.attr.sched_policy, SCHED_OTHER);
> +  TEST_COMPARE (u.attr.sched_nice, 19);
> +  check_unused ();
> +
> +  /* Invalid buffer arguments result in EINVAL (not EFAULT).  */
> +  {
> +    errno = 0;
> +    void *volatile null_pointer = NULL; /* compiler barrier.  */
> +    TEST_COMPARE (sched_setattr (0, null_pointer, 0), -1);
> +    TEST_COMPARE (errno, EINVAL);
> +    errno = 0;
> +    TEST_COMPARE (sched_getattr (0, null_pointer, size, 0), -1);
> +    TEST_COMPARE (errno, EINVAL);
> +  }
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index aea7848ed6..5acf49dbe8 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2744,6 +2744,8 @@ GLIBC_2.4 sys_errlist D 0x420
>  GLIBC_2.4 sys_nerr D 0x4
>  GLIBC_2.4 unlinkat F
>  GLIBC_2.4 unshare F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
>  GLIBC_2.5 __readlinkat_chk F
>  GLIBC_2.5 inet6_opt_append F
>  GLIBC_2.5 inet6_opt_find F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index 4ab3681914..02d1bb97dc 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2763,3 +2763,5 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
>  GLIBC_2.39 stdc_trailing_zeros_ul F
>  GLIBC_2.39 stdc_trailing_zeros_ull F
>  GLIBC_2.39 stdc_trailing_zeros_us F
> +GLIBC_2.41 sched_getattr F
> +GLIBC_2.41 sched_setattr F
Florian Weimer Sept. 6, 2024, 1:26 p.m. UTC | #3
* Adhemerval Zanella Netto:

> On 05/09/24 17:24, Florian Weimer wrote:
>> And struct sched_attr.
>> 
>> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
>> sched_param around the inclusion of <linux/sched/types.h> is quite
>> ugly, but the definition of struct sched_param has already been
>> dropped by the kernel, so there is nothing else we can do and maintain
>> compatibility of <sched.h> with a wide range of kernel header
>> versions.  (An alternative would involve introducing a separate header
>> for this functionality, but this seems unnecessary.)
>> 
>> The existing sched_* functions that change scheduler parameters
>> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
>> there is no harm in adding more functionality in this area.
>> 
>> The documentation mostly defers to the Linux manual pages.
>
> So I take that the defined approach for syscalls that accepts extensible
> struct arguments would just to document that it can not be used on places
> that might affect the ABI, include the kernel definitions if present,
> and just pass the size to the kernel then?
>
> I was not sure how to proceed with the openat2 support back when I first
> proposed [1] because I felt to me that we did not fully agreed how to
> handle this cases.
>
> [1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html

See the parallel discussion with enh.  I don't think it's a big problem.

We already have struct statx in the installed headers, which behaves
pretty much the same way, except that extensions are currently using up
the padding space.

Thanks,
Florian
Adhemerval Zanella Sept. 6, 2024, 1:43 p.m. UTC | #4
On 06/09/24 10:26, Florian Weimer wrote:
> * Adhemerval Zanella Netto:
> 
>> On 05/09/24 17:24, Florian Weimer wrote:
>>> And struct sched_attr.
>>>
>>> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
>>> sched_param around the inclusion of <linux/sched/types.h> is quite
>>> ugly, but the definition of struct sched_param has already been
>>> dropped by the kernel, so there is nothing else we can do and maintain
>>> compatibility of <sched.h> with a wide range of kernel header
>>> versions.  (An alternative would involve introducing a separate header
>>> for this functionality, but this seems unnecessary.)
>>>
>>> The existing sched_* functions that change scheduler parameters
>>> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
>>> there is no harm in adding more functionality in this area.
>>>
>>> The documentation mostly defers to the Linux manual pages.
>>
>> So I take that the defined approach for syscalls that accepts extensible
>> struct arguments would just to document that it can not be used on places
>> that might affect the ABI, include the kernel definitions if present,
>> and just pass the size to the kernel then?
>>
>> I was not sure how to proceed with the openat2 support back when I first
>> proposed [1] because I felt to me that we did not fully agreed how to
>> handle this cases.
>>
>> [1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html
> 
> See the parallel discussion with enh.  I don't think it's a big problem.
> 
> We already have struct statx in the installed headers, which behaves
> pretty much the same way, except that extensions are currently using up
> the padding space.

The statx is slight different wrt to kABI because it does not really
follow the current behavior or adding the size for the syscall (and
I recall some kernel developers to regret this decision).

I still unsure this is really a good way forward, since it does have some
drawbacks about possible misuse.  This would be first symbol that follow
this new semantic, so I think we should document this properly either
on the wiki that Linux syscall might folow this strategies and how the
wrapper should be added.
Florian Weimer Sept. 6, 2024, 1:58 p.m. UTC | #5
* Adhemerval Zanella Netto:

> On 06/09/24 10:26, Florian Weimer wrote:
>> * Adhemerval Zanella Netto:
>> 
>>> On 05/09/24 17:24, Florian Weimer wrote:
>>>> And struct sched_attr.
>>>>
>>>> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
>>>> sched_param around the inclusion of <linux/sched/types.h> is quite
>>>> ugly, but the definition of struct sched_param has already been
>>>> dropped by the kernel, so there is nothing else we can do and maintain
>>>> compatibility of <sched.h> with a wide range of kernel header
>>>> versions.  (An alternative would involve introducing a separate header
>>>> for this functionality, but this seems unnecessary.)
>>>>
>>>> The existing sched_* functions that change scheduler parameters
>>>> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
>>>> there is no harm in adding more functionality in this area.
>>>>
>>>> The documentation mostly defers to the Linux manual pages.
>>>
>>> So I take that the defined approach for syscalls that accepts extensible
>>> struct arguments would just to document that it can not be used on places
>>> that might affect the ABI, include the kernel definitions if present,
>>> and just pass the size to the kernel then?
>>>
>>> I was not sure how to proceed with the openat2 support back when I first
>>> proposed [1] because I felt to me that we did not fully agreed how to
>>> handle this cases.
>>>
>>> [1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html
>> 
>> See the parallel discussion with enh.  I don't think it's a big problem.
>> 
>> We already have struct statx in the installed headers, which behaves
>> pretty much the same way, except that extensions are currently using up
>> the padding space.
>
> The statx is slight different wrt to kABI because it does not really
> follow the current behavior or adding the size for the syscall (and
> I recall some kernel developers to regret this decision).

Hmm, right.  I think it was expected that it was controlled by the
flags.  In any case, the struct is expected to grow additional fields in
the future, too.

> I still unsure this is really a good way forward, since it does have some
> drawbacks about possible misuse.  This would be first symbol that follow
> this new semantic, so I think we should document this properly either
> on the wiki that Linux syscall might folow this strategies and how the
> wrapper should be added.

There isn't any thing special to the initial addition, as long as we
don't do emulation.  Strucurally, sched_getattr has the same behavior as
recv, for example.  It makes sense to put something into the manual
about extending the struct, and I did that.

Thanks,
Florian
Carlos O'Donell Sept. 6, 2024, 6:33 p.m. UTC | #6
On 9/6/24 9:58 AM, Florian Weimer wrote:
> * Adhemerval Zanella Netto:
> 
>> On 06/09/24 10:26, Florian Weimer wrote:
>>> * Adhemerval Zanella Netto:
>>>
>>>> On 05/09/24 17:24, Florian Weimer wrote:
>>>>> And struct sched_attr.
>>>>>
>>>>> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
>>>>> sched_param around the inclusion of <linux/sched/types.h> is quite
>>>>> ugly, but the definition of struct sched_param has already been
>>>>> dropped by the kernel, so there is nothing else we can do and maintain
>>>>> compatibility of <sched.h> with a wide range of kernel header
>>>>> versions.  (An alternative would involve introducing a separate header
>>>>> for this functionality, but this seems unnecessary.)
>>>>>
>>>>> The existing sched_* functions that change scheduler parameters
>>>>> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
>>>>> there is no harm in adding more functionality in this area.
>>>>>
>>>>> The documentation mostly defers to the Linux manual pages.
>>>>
>>>> So I take that the defined approach for syscalls that accepts extensible
>>>> struct arguments would just to document that it can not be used on places
>>>> that might affect the ABI, include the kernel definitions if present,
>>>> and just pass the size to the kernel then?
>>>>
>>>> I was not sure how to proceed with the openat2 support back when I first
>>>> proposed [1] because I felt to me that we did not fully agreed how to
>>>> handle this cases.
>>>>
>>>> [1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html
>>>
>>> See the parallel discussion with enh.  I don't think it's a big problem.
>>>
>>> We already have struct statx in the installed headers, which behaves
>>> pretty much the same way, except that extensions are currently using up
>>> the padding space.
>>
>> The statx is slight different wrt to kABI because it does not really
>> follow the current behavior or adding the size for the syscall (and
>> I recall some kernel developers to regret this decision).
> 
> Hmm, right.  I think it was expected that it was controlled by the
> flags.  In any case, the struct is expected to grow additional fields in
> the future, too.

It *is* controlled by the flags.

And there is an expansion mechanism:

159 #define STATX__RESERVED         0x80000000U     /* Reserved for future struct statx expansion */

The behaviour is not like sched_setattr/sched_getattr with size though.

e.g.

 62 /*
 63  * Structures for the extended file attribute retrieval system call
 64  * (statx()).
 65  *
 66  * The caller passes a mask of what they're specifically interested in as a
 67  * parameter to statx().  What statx() actually got will be indicated in
 68  * st_mask upon return.
 69  *
 70  * For each bit in the mask argument:
 71  *
 72  * - if the datum is not supported:
 73  *
 74  *   - the bit will be cleared, and
 75  *
 76  *   - the datum will be set to an appropriate fabricated value if one is
 77  *     available (eg. CIFS can take a default uid and gid), otherwise
 78  *
 79  *   - the field will be cleared;
 80  *
 81  * - otherwise, if explicitly requested:
 82  *
 83  *   - the datum will be synchronised to the server if AT_STATX_FORCE_SYNC is
 84  *     set or if the datum is considered out of date, and
 85  *
 86  *   - the field will be filled in and the bit will be set;
 87  *
 88  * - otherwise, if not requested, but available in approximate form without any
 89  *   effort, it will be filled in anyway, and the bit will be set upon return
 90  *   (it might not be up to date, however, and no attempt will be made to
 91  *   synchronise the internal state first);
 92  *
 93  * - otherwise the field and the bit will be cleared before returning.

The last two paragraphs make it difficult to have a smaller userspace strut statx
because the kernel will overflow that structure.

I expect the top reserved bit can be used for a one-time expansion, which isn't much
but more than nothing.

I feel a need to gather our thoughts on this from the glibc side and probably give a
detailed LPC talk about it to look across the interfaces in question and harmonize
some kind of design pattern.

>> I still unsure this is really a good way forward, since it does have some
>> drawbacks about possible misuse.  This would be first symbol that follow
>> this new semantic, so I think we should document this properly either
>> on the wiki that Linux syscall might folow this strategies and how the
>> wrapper should be added.
> 
> There isn't any thing special to the initial addition, as long as we
> don't do emulation.  Strucurally, sched_getattr has the same behavior as
> recv, for example.  It makes sense to put something into the manual
> about extending the struct, and I did that.

Agreed.
Adhemerval Zanella Sept. 6, 2024, 6:52 p.m. UTC | #7
On 06/09/24 15:33, Carlos O'Donell wrote:
> On 9/6/24 9:58 AM, Florian Weimer wrote:
>> * Adhemerval Zanella Netto:
>>
>>> On 06/09/24 10:26, Florian Weimer wrote:
>>>> * Adhemerval Zanella Netto:
>>>>
>>>>> On 05/09/24 17:24, Florian Weimer wrote:
>>>>>> And struct sched_attr.
>>>>>>
>>>>>> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
>>>>>> sched_param around the inclusion of <linux/sched/types.h> is quite
>>>>>> ugly, but the definition of struct sched_param has already been
>>>>>> dropped by the kernel, so there is nothing else we can do and maintain
>>>>>> compatibility of <sched.h> with a wide range of kernel header
>>>>>> versions.  (An alternative would involve introducing a separate header
>>>>>> for this functionality, but this seems unnecessary.)
>>>>>>
>>>>>> The existing sched_* functions that change scheduler parameters
>>>>>> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
>>>>>> there is no harm in adding more functionality in this area.
>>>>>>
>>>>>> The documentation mostly defers to the Linux manual pages.
>>>>>
>>>>> So I take that the defined approach for syscalls that accepts extensible
>>>>> struct arguments would just to document that it can not be used on places
>>>>> that might affect the ABI, include the kernel definitions if present,
>>>>> and just pass the size to the kernel then?
>>>>>
>>>>> I was not sure how to proceed with the openat2 support back when I first
>>>>> proposed [1] because I felt to me that we did not fully agreed how to
>>>>> handle this cases.
>>>>>
>>>>> [1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html
>>>>
>>>> See the parallel discussion with enh.  I don't think it's a big problem.
>>>>
>>>> We already have struct statx in the installed headers, which behaves
>>>> pretty much the same way, except that extensions are currently using up
>>>> the padding space.
>>>
>>> The statx is slight different wrt to kABI because it does not really
>>> follow the current behavior or adding the size for the syscall (and
>>> I recall some kernel developers to regret this decision).
>>
>> Hmm, right.  I think it was expected that it was controlled by the
>> flags.  In any case, the struct is expected to grow additional fields in
>> the future, too.
> 
> It *is* controlled by the flags.
> 
> And there is an expansion mechanism:
> 
> 159 #define STATX__RESERVED         0x80000000U     /* Reserved for future struct statx expansion */
> 
> The behaviour is not like sched_setattr/sched_getattr with size though.
> 
> e.g.
> 
>  62 /*
>  63  * Structures for the extended file attribute retrieval system call
>  64  * (statx()).
>  65  *
>  66  * The caller passes a mask of what they're specifically interested in as a
>  67  * parameter to statx().  What statx() actually got will be indicated in
>  68  * st_mask upon return.
>  69  *
>  70  * For each bit in the mask argument:
>  71  *
>  72  * - if the datum is not supported:
>  73  *
>  74  *   - the bit will be cleared, and
>  75  *
>  76  *   - the datum will be set to an appropriate fabricated value if one is
>  77  *     available (eg. CIFS can take a default uid and gid), otherwise
>  78  *
>  79  *   - the field will be cleared;
>  80  *
>  81  * - otherwise, if explicitly requested:
>  82  *
>  83  *   - the datum will be synchronised to the server if AT_STATX_FORCE_SYNC is
>  84  *     set or if the datum is considered out of date, and
>  85  *
>  86  *   - the field will be filled in and the bit will be set;
>  87  *
>  88  * - otherwise, if not requested, but available in approximate form without any
>  89  *   effort, it will be filled in anyway, and the bit will be set upon return
>  90  *   (it might not be up to date, however, and no attempt will be made to
>  91  *   synchronise the internal state first);
>  92  *
>  93  * - otherwise the field and the bit will be cleared before returning.
> 
> The last two paragraphs make it difficult to have a smaller userspace strut statx
> because the kernel will overflow that structure.
> 
> I expect the top reserved bit can be used for a one-time expansion, which isn't much
> but more than nothing.
> 
> I feel a need to gather our thoughts on this from the glibc side and probably give a
> detailed LPC talk about it to look across the interfaces in question and harmonize
> some kind of design pattern.

What I meant is the syscall is not defined to allow unbounded input expansion,
as recent syscall like openat2.  The statx is currently defined with a static
size and even if kernel not enforce its size through the input argument
(the KABI is similar to the one glibc provides) it does expect userland to
pass the UABI define statx.

If you check the include/uapi/linux/stat.h history, kernel has been carving
out the extra fields from the '__spare' field and once it runs out it would
require a different syscall.

> 
>>> I still unsure this is really a good way forward, since it does have some
>>> drawbacks about possible misuse.  This would be first symbol that follow
>>> this new semantic, so I think we should document this properly either
>>> on the wiki that Linux syscall might folow this strategies and how the
>>> wrapper should be added.
>>
>> There isn't any thing special to the initial addition, as long as we
>> don't do emulation.  Strucurally, sched_getattr has the same behavior as
>> recv, for example.  It makes sense to put something into the manual
>> about extending the struct, and I did that.
Carlos O'Donell Sept. 6, 2024, 8:22 p.m. UTC | #8
On 9/6/24 2:52 PM, Adhemerval Zanella Netto wrote:
> If you check the include/uapi/linux/stat.h history, kernel has been carving
> out the extra fields from the '__spare' field and once it runs out it would
> require a different syscall.

Would it be able to use the reserved bit for that size increase?
Adhemerval Zanella Sept. 6, 2024, 8:28 p.m. UTC | #9
On 06/09/24 17:22, Carlos O'Donell wrote:
> On 9/6/24 2:52 PM, Adhemerval Zanella Netto wrote:
>> If you check the include/uapi/linux/stat.h history, kernel has been carving
>> out the extra fields from the '__spare' field and once it runs out it would
>> require a different syscall.
> 
> Would it be able to use the reserved bit for that size increase?
> 

I think it would be possible, it waste a bit just for size increase
and bits are a finite.  It would also be kinda clunky, since current
approach is to tie the input with the size, not making it implicit
with a flag.
enh Sept. 6, 2024, 9:58 p.m. UTC | #10
On Fri, Sep 6, 2024 at 2:33 PM Carlos O'Donell <carlos@redhat.com> wrote:
>
> On 9/6/24 9:58 AM, Florian Weimer wrote:
> > * Adhemerval Zanella Netto:
> >
> >> On 06/09/24 10:26, Florian Weimer wrote:
> >>> * Adhemerval Zanella Netto:
> >>>
> >>>> On 05/09/24 17:24, Florian Weimer wrote:
> >>>>> And struct sched_attr.
> >>>>>
> >>>>> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
> >>>>> sched_param around the inclusion of <linux/sched/types.h> is quite
> >>>>> ugly, but the definition of struct sched_param has already been
> >>>>> dropped by the kernel, so there is nothing else we can do and maintain
> >>>>> compatibility of <sched.h> with a wide range of kernel header
> >>>>> versions.  (An alternative would involve introducing a separate header
> >>>>> for this functionality, but this seems unnecessary.)
> >>>>>
> >>>>> The existing sched_* functions that change scheduler parameters
> >>>>> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
> >>>>> there is no harm in adding more functionality in this area.
> >>>>>
> >>>>> The documentation mostly defers to the Linux manual pages.
> >>>>
> >>>> So I take that the defined approach for syscalls that accepts extensible
> >>>> struct arguments would just to document that it can not be used on places
> >>>> that might affect the ABI, include the kernel definitions if present,
> >>>> and just pass the size to the kernel then?
> >>>>
> >>>> I was not sure how to proceed with the openat2 support back when I first
> >>>> proposed [1] because I felt to me that we did not fully agreed how to
> >>>> handle this cases.
> >>>>
> >>>> [1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html
> >>>
> >>> See the parallel discussion with enh.  I don't think it's a big problem.
> >>>
> >>> We already have struct statx in the installed headers, which behaves
> >>> pretty much the same way, except that extensions are currently using up
> >>> the padding space.
> >>
> >> The statx is slight different wrt to kABI because it does not really
> >> follow the current behavior or adding the size for the syscall (and
> >> I recall some kernel developers to regret this decision).
> >
> > Hmm, right.  I think it was expected that it was controlled by the
> > flags.  In any case, the struct is expected to grow additional fields in
> > the future, too.
>
> It *is* controlled by the flags.
>
> And there is an expansion mechanism:
>
> 159 #define STATX__RESERVED         0x80000000U     /* Reserved for future struct statx expansion */
>
> The behaviour is not like sched_setattr/sched_getattr with size though.
>
> e.g.
>
>  62 /*
>  63  * Structures for the extended file attribute retrieval system call
>  64  * (statx()).
>  65  *
>  66  * The caller passes a mask of what they're specifically interested in as a
>  67  * parameter to statx().  What statx() actually got will be indicated in
>  68  * st_mask upon return.
>  69  *
>  70  * For each bit in the mask argument:
>  71  *
>  72  * - if the datum is not supported:
>  73  *
>  74  *   - the bit will be cleared, and
>  75  *
>  76  *   - the datum will be set to an appropriate fabricated value if one is
>  77  *     available (eg. CIFS can take a default uid and gid), otherwise
>  78  *
>  79  *   - the field will be cleared;
>  80  *
>  81  * - otherwise, if explicitly requested:
>  82  *
>  83  *   - the datum will be synchronised to the server if AT_STATX_FORCE_SYNC is
>  84  *     set or if the datum is considered out of date, and
>  85  *
>  86  *   - the field will be filled in and the bit will be set;
>  87  *
>  88  * - otherwise, if not requested, but available in approximate form without any
>  89  *   effort, it will be filled in anyway, and the bit will be set upon return
>  90  *   (it might not be up to date, however, and no attempt will be made to
>  91  *   synchronise the internal state first);
>  92  *
>  93  * - otherwise the field and the bit will be cleared before returning.
>
> The last two paragraphs make it difficult to have a smaller userspace strut statx
> because the kernel will overflow that structure.
>
> I expect the top reserved bit can be used for a one-time expansion, which isn't much
> but more than nothing.
>
> I feel a need to gather our thoughts on this from the glibc side and probably give a
> detailed LPC talk about it to look across the interfaces in question and harmonize
> some kind of design pattern.

that would be great ... let me know if/when you do an LPC talk and
i'll try to come -- it's been a long time since my last LPC -- or at
least give you some potted "i also approve this message" soundbites
:-)

for me these kind of upstream interfaces kind of undermine the "we
should default to having the wrappers in libc" philosophy that i
otherwise broadly agree with. but it's obvious from this thread that
we're not all in complete agreement about what exactly we count as
"compatibility" and how much of it we should/can guarantee (or to
whom). as someone -- iirc fweimer -- said elsewhere on the thread, it
would be good to hear from musl too. even if that probably makes it
even less likely we'll have 100% agreement on anything, it's probably
more useful to present the kernel community with the full range of
perspectives!

> >> I still unsure this is really a good way forward, since it does have some
> >> drawbacks about possible misuse.  This would be first symbol that follow
> >> this new semantic, so I think we should document this properly either
> >> on the wiki that Linux syscall might folow this strategies and how the
> >> wrapper should be added.
> >
> > There isn't any thing special to the initial addition, as long as we
> > don't do emulation.  Strucurally, sched_getattr has the same behavior as
> > recv, for example.  It makes sense to put something into the manual
> > about extending the struct, and I did that.
>
> Agreed.
>
> --
> Cheers,
> Carlos.
>
Florian Weimer Sept. 10, 2024, 4:01 p.m. UTC | #11
* Adhemerval Zanella Netto:

> On 05/09/24 17:24, Florian Weimer wrote:
>> And struct sched_attr.
>> 
>> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
>> sched_param around the inclusion of <linux/sched/types.h> is quite
>> ugly, but the definition of struct sched_param has already been
>> dropped by the kernel, so there is nothing else we can do and maintain
>> compatibility of <sched.h> with a wide range of kernel header
>> versions.  (An alternative would involve introducing a separate header
>> for this functionality, but this seems unnecessary.)
>> 
>> The existing sched_* functions that change scheduler parameters
>> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
>> there is no harm in adding more functionality in this area.
>> 
>> The documentation mostly defers to the Linux manual pages.
>
> So I take that the defined approach for syscalls that accepts extensible
> struct arguments would just to document that it can not be used on places
> that might affect the ABI, include the kernel definitions if present,
> and just pass the size to the kernel then?
>
> I was not sure how to proceed with the openat2 support back when I first
> proposed [1] because I felt to me that we did not fully agreed how to
> handle this cases.
>
> [1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html

Adhemerval, according to the minutes (sorry, had to drop), you said
during the Monday call that you don't want to block inclusion of these
changes.

Given that I have a review from Carlos, is it okay now to push these
changes?  I'm still working on documentation of how extensible types are
used within glibc and should have something to post later this week
(hopefully).

Thanks,
Florian
Adhemerval Zanella Sept. 10, 2024, 8:16 p.m. UTC | #12
On 10/09/24 13:01, Florian Weimer wrote:
> * Adhemerval Zanella Netto:
> 
>> On 05/09/24 17:24, Florian Weimer wrote:
>>> And struct sched_attr.
>>>
>>> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
>>> sched_param around the inclusion of <linux/sched/types.h> is quite
>>> ugly, but the definition of struct sched_param has already been
>>> dropped by the kernel, so there is nothing else we can do and maintain
>>> compatibility of <sched.h> with a wide range of kernel header
>>> versions.  (An alternative would involve introducing a separate header
>>> for this functionality, but this seems unnecessary.)
>>>
>>> The existing sched_* functions that change scheduler parameters
>>> are already incompatible with PTHREAD_PRIO_PROTECT mutexes, so
>>> there is no harm in adding more functionality in this area.
>>>
>>> The documentation mostly defers to the Linux manual pages.
>>
>> So I take that the defined approach for syscalls that accepts extensible
>> struct arguments would just to document that it can not be used on places
>> that might affect the ABI, include the kernel definitions if present,
>> and just pass the size to the kernel then?
>>
>> I was not sure how to proceed with the openat2 support back when I first
>> proposed [1] because I felt to me that we did not fully agreed how to
>> handle this cases.
>>
>> [1] https://sourceware.org/pipermail/libc-alpha/2024-April/156319.html
> 
> Adhemerval, according to the minutes (sorry, had to drop), you said
> during the Monday call that you don't want to block inclusion of these
> changes.
> 
> Given that I have a review from Carlos, is it okay now to push these
> changes?  I'm still working on documentation of how extensible types are
> used within glibc and should have something to post later this week
> (hopefully).

Yes. 

Would be too much to add a developer entry, either in wiki or in manual, on 
how to handle the Linux syscall wrappers? Carlos said he intend to write 
down some notes about it, so maybe we can start from there.

I just want to have all the pro and cons of each approach and how glibc
is expected to future Linux syscall wrappers.
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index d488874aba..10894e7b5a 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,9 @@  Major new features:
   which is why this mode is not enabled by default.  A future version
   of the library may turn it on by default, however.
 
+* On Linux, the sched_setattr and sched_getattr have been added, for
+  supporting parameterized scheduling policies such as SCHED_DEADLINE.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/manual/resource.texi b/manual/resource.texi
index 25966bcb64..612520d4d9 100644
--- a/manual/resource.texi
+++ b/manual/resource.texi
@@ -478,6 +478,7 @@  POSIX syntax had in mind.
 * Absolute Priority::               The first tier of priority.  Posix
 * Realtime Scheduling::             Scheduling among the process nobility
 * Basic Scheduling Functions::      Get/set scheduling policy, priority
+* Extensible Scheduling::           Parameterized scheduling policies.
 * Traditional Scheduling::          Scheduling among the vulgar masses
 * CPU Affinity::                    Limiting execution to certain CPUs
 @end menu
@@ -952,6 +953,120 @@  function, so there are no specific @code{errno} values.
 
 @end deftypefun
 
+@node Extensible Scheduling
+@subsection Extensible Scheduling
+@cindex scheduling, extensible
+
+The type @code{struct sched_attr} and the functions @code{sched_setattr}
+and @code{sched_getattr} are used to implement scheduling policies with
+multiple parameters (not just priority and niceness).
+
+It is expected that these interfaces will be compatible with all future
+scheduling policies.
+
+For additional information about scheduling policies, consult consult
+the manual pages @manpageurl{sched,7} and @manpageurl{sched_setattr,2}.
+@xref{Linux Kernel}.
+
+@strong{Note:} Calling the @code{sched_setattr} function is incompatible
+with support for @code{PTHREAD_PRIO_PROTECT} mutexes.
+
+@deftp {Data Type} {struct sched_attr}
+@standards{Linux, sched.h}
+The @code{sched_attr} structure describes a parameterized scheduling policy.
+
+@strong{Portability note:} In the future, additional fields can be added
+to @code{struct sched_attr} at the end, so that the size of this data
+type changes.  Do not use it in places where this matters, such as
+structure fields in installed header files, where such a change could
+impact the application binary interface (ABI).
+
+The following generic fields are available.
+
+@table @code
+@item size
+The actually used size of the data structure.  See the description of
+the functions @code{sched_setattr} and @code{sched_getattr} below how this
+field is used to support extension of @code{struct sched_attr} with
+more fields.
+
+@item sched_policy
+The scheduling policy.  This field determines which fields in the
+structure are used, and how the @code{sched_flags} field is interpreted.
+
+@item sched_flags
+Scheduling flags associated with the scheduling policy.
+@end table
+
+In addition to the generic fields, policy-specific fields are available.
+For additional information, consult the manual page
+@manpageurl{sched_setattr,2}.  @xref{Linux Kernel}.
+@end deftp
+
+@deftypefun int sched_setaddr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int flags)
+@standards{Linux, sched.h}
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+This functions applies the scheduling policy described by
+@code{*@var{attr}} to the thread @var{tid} (the value zero denotes the
+current thread).
+
+It is recommended to initialize unused fields to zero, either using
+@code{memset}, or using a structure initializer.  The
+@code{@var{attr->size}} field should be set to @code{sizeof (struct
+sched_attr)}, to inform the kernel of the structure version in use.
+
+The @var{flags} argument must be zero.  Other values may become
+available in the future.
+
+On failure, @code{sched_setattr} returns @math{-1} and sets
+@code{errno}.  The following errors are related the way
+extensibility is handled.
+@table @code
+@item E2BIG
+A field in @code{*@var{attr}} has a non-zero value, but is unknown to
+the kernel.  The application could try to apply a modified policy, where
+more fields are zero.
+
+@item EINVAL
+The policy in @code{@var{attr}->sched_policy} is unknown to the kernel,
+or flags are set in @code{@var{attr}->sched_flags} that the kernel does
+not know how to interpret.  The application could try with fewer flags
+set, or a different scheduling policy.
+
+This error also occurs if @var{attr} is @code{NULL} or @var{flags} is
+not zero.
+
+@item EPERM
+The current thread is not sufficiently privileged to assign the policy,
+either because access to the policy is restricted in general, or because
+the current thread does not have the rights to change the scheduling
+policy of the thread @var{tid}.
+@end table
+
+Other error codes depend on the scheduling policy.
+@end deftypefun
+
+@deftypefun int sched_getaddr (pid_t @var{tid}, struct sched_attr *@var{attr}, unsigned int size, unsigned int flags)
+@standards{Linux, sched.h}
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+This function obtains the scheduling policy of the thread @var{tid}
+(zero denotes the current thread) and store it in @code{*@var{attr}},
+which must have space for at least @var{size} bytes.
+
+The @var{flags} argument must be zero.  Other values may become
+available in the future.
+
+Upon success, @code{@var{attr}->size} contains the size of the structure
+version used by the kernel.  Fields with offsets greater or equal to
+@code{@var{attr}->size} are not updated by the kernel.  To obtain
+predictable values for unknown fields, use @code{memset} to set
+all @var{size} bytes to zero prior to calling @code{sched_getattr}.
+
+On failure, @code{sched_getattr} returns @math{-1} and sets @code{errno}.
+If @code{errno} is @code{E2BIG}, this means that the buffer is not large
+large enough, and the application could retry with a larger buffer.
+@end deftypefun
+
 @node Traditional Scheduling
 @subsection Traditional Scheduling
 @cindex scheduling, traditional
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 59998c7af4..0b45d4e42b 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -95,6 +95,8 @@  sysdep_routines += \
   process_vm_writev \
   pselect32 \
   readahead \
+  sched_getattr \
+  sched_setattr \
   setfsgid \
   setfsuid \
   setvmaname \
@@ -224,6 +226,7 @@  tests += \
   tst-process_mrelease \
   tst-quota \
   tst-rlimit-infinity \
+  tst-sched_setattr \
   tst-scm_rights \
   tst-sigtimedwait \
   tst-sync_file_range \
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 268ba1b6ac..213ff5f1fe 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -328,6 +328,10 @@  libc {
     posix_spawnattr_getcgroup_np;
     posix_spawnattr_setcgroup_np;
   }
+  GLIBC_2.41 {
+    sched_getattr;
+    sched_setattr;
+  }
   GLIBC_PRIVATE {
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 68eeca1c08..38db77e4f7 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2748,3 +2748,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 34c187b721..637bfce9fb 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -3095,6 +3095,8 @@  GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 916c18ea94..4a305cf730 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2509,3 +2509,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index ea95de282a..1d54f71b14 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -2801,6 +2801,8 @@  GLIBC_2.4 xdrstdio_create F
 GLIBC_2.4 xencrypt F
 GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 1cdbc983e1..ff7e8bc40b 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -2798,6 +2798,8 @@  GLIBC_2.4 xdrstdio_create F
 GLIBC_2.4 xencrypt F
 GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h
index a53e1362a0..e5b7efb887 100644
--- a/sysdeps/unix/sysv/linux/bits/sched.h
+++ b/sysdeps/unix/sysv/linux/bits/sched.h
@@ -34,10 +34,39 @@ 
 # define SCHED_IDLE		5
 # define SCHED_DEADLINE		6
 
+/* Flags that can be used in policy values.  */
 # define SCHED_RESET_ON_FORK	0x40000000
-#endif
 
-#ifdef __USE_GNU
+/* Use "" to work around incorrect macro expansion of the
+   __has_include argument (GCC PR 80005).  */
+# ifdef __has_include
+#  if __has_include ("linux/sched/types.h")
+/* Some older Linux versions defined sched_param in <linux/sched/types.h>.  */
+#   define sched_param __glibc_mask_sched_param
+#   include <linux/sched/types.h>
+#   undef sched_param
+#  endif
+# endif
+# ifndef SCHED_ATTR_SIZE_VER0
+#  include <linux/types.h>
+#  define SCHED_ATTR_SIZE_VER0 48
+#  define SCHED_ATTR_SIZE_VER1 56
+struct sched_attr
+{
+  __u32 size;
+  __u32 sched_policy;
+  __u64 sched_flags;
+  __s32 sched_nice;
+  __u32 sched_priority;
+  __u64 sched_runtime;
+  __u64 sched_deadline;
+  __u64 sched_period;
+  __u32 sched_util_min;
+  __u32 sched_util_max;
+  /* Additional fields may be added at the end.  */
+};
+# endif /* !SCHED_ATTR_SIZE_VER0 */
+
 /* Cloning flags.  */
 # define CSIGNAL       0x000000ff /* Signal mask to be sent at exit.  */
 # define CLONE_VM      0x00000100 /* Set if VM shared between processes.  */
@@ -97,6 +126,17 @@  extern int getcpu (unsigned int *, unsigned int *) __THROW;
 
 /* Switch process to namespace of type NSTYPE indicated by FD.  */
 extern int setns (int __fd, int __nstype) __THROW;
+
+/* Apply the scheduling attributes from *ATTR to the process or thread TID.  */
+int sched_setattr (pid_t tid, struct sched_attr *attr, unsigned int flags)
+  __THROW __nonnull ((2));
+
+/* Obtain the scheduling attributes of the process or thread TID and
+   store it in *ATTR.  */
+int sched_getattr (pid_t tid, struct sched_attr *attr, unsigned int size,
+		   unsigned int flags)
+  __THROW __nonnull ((2)) __attr_access ((__write_only__, 2, 3));
+
 #endif
 
 __END_DECLS
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 96d45961e2..c3ed65467d 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2785,3 +2785,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index fbcd60c2b3..8de7644a59 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2821,6 +2821,8 @@  GLIBC_2.4 sys_errlist D 0x400
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index c989b433c0..4fedf775d4 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -3005,6 +3005,8 @@  GLIBC_2.4 sys_errlist D 0x210
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
index 0023ec1fa1..0024282289 100644
--- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
@@ -2269,3 +2269,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index d9bd6a9b56..142595eb3e 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -2781,6 +2781,8 @@  GLIBC_2.4 xdrstdio_create F
 GLIBC_2.4 xencrypt F
 GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 439796d693..85e7746c10 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2948,6 +2948,8 @@  GLIBC_2.4 sys_errlist D 0x210
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 1069d3252c..91dc1b8378 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2834,3 +2834,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 17abe08c8b..3440e90f6f 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2831,3 +2831,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 799e508950..5ee7b8c52f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2909,6 +2909,8 @@  GLIBC_2.4 renameat F
 GLIBC_2.4 symlinkat F
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 1c10996cbc..6cb6328e7c 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2907,6 +2907,8 @@  GLIBC_2.4 renameat F
 GLIBC_2.4 symlinkat F
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 03d9655f26..ae7474c0f0 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2915,6 +2915,8 @@  GLIBC_2.4 renameat F
 GLIBC_2.4 symlinkat F
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 05e402ed30..cdf040dec2 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2817,6 +2817,8 @@  GLIBC_2.4 renameat F
 GLIBC_2.4 symlinkat F
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 3aa81766aa..773d4c5873 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2873,3 +2873,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
index 959e59e7e7..c356a11b1c 100644
--- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
+++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
@@ -2259,3 +2259,5 @@  GLIBC_2.40 getcontext F
 GLIBC_2.40 makecontext F
 GLIBC_2.40 setcontext F
 GLIBC_2.40 swapcontext F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 9714305608..7937f94cf0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -3138,6 +3138,8 @@  GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 0beb52c542..d6e35f31d2 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -3183,6 +3183,8 @@  GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index cfc2ebd3ec..2268d6890d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2892,6 +2892,8 @@  GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 8c9efc5a16..7f61b14bc8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2968,3 +2968,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 6397a9cb91..4187241f50 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2512,3 +2512,5 @@  GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.40 __riscv_hwprobe F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 71bbf94f66..8935beccac 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2712,3 +2712,5 @@  GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.40 __riscv_hwprobe F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a7467e2850..e69dc7ccf6 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -3136,6 +3136,8 @@  GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index fd1cb2972d..7d860001d8 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2929,6 +2929,8 @@  GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/sched_getattr.c b/sysdeps/unix/sysv/linux/sched_getattr.c
new file mode 100644
index 0000000000..e6b9970fcb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sched_getattr.c
@@ -0,0 +1,27 @@ 
+/* Reading scheduling policy and attributes.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sched.h>
+#include <sysdep.h>
+
+int
+sched_getattr (pid_t pid, struct sched_attr *attr, unsigned int size,
+               unsigned int flags)
+{
+  return INLINE_SYSCALL_CALL (sched_getattr, pid, attr, size, flags);
+}
diff --git a/sysdeps/unix/sysv/linux/sched_setattr.c b/sysdeps/unix/sysv/linux/sched_setattr.c
new file mode 100644
index 0000000000..25403fb454
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sched_setattr.c
@@ -0,0 +1,26 @@ 
+/* Setting scheduling policy and attributes.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sched.h>
+#include <sysdep.h>
+
+int
+sched_setattr (pid_t pid, struct sched_attr *attr, unsigned int flags)
+{
+  return INLINE_SYSCALL_CALL (sched_setattr, pid, attr, flags);
+}
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index ff6e6b1a13..fcb8161841 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2828,6 +2828,8 @@  GLIBC_2.4 sys_errlist D 0x210
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 449d92bbc5..3fd078d125 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2825,6 +2825,8 @@  GLIBC_2.4 sys_errlist D 0x210
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index e615be759a..1ce1fe9da7 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -3157,6 +3157,8 @@  GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index bd36431dd7..07507b86f6 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2793,6 +2793,8 @@  GLIBC_2.4 sys_errlist D 0x430
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/tst-sched_setattr.c b/sysdeps/unix/sysv/linux/tst-sched_setattr.c
new file mode 100644
index 0000000000..a6288a1a7c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-sched_setattr.c
@@ -0,0 +1,105 @@ 
+/* Tests for sched_setattr and sched_getattr.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sched.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <support/check.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+/* Padding struct to detect unexpected writes.   */
+union
+{
+  struct sched_attr attr;
+  /* Hopefully the kernel will never need as much.  */
+  unsigned char padding[4096];
+} u;
+
+static void
+check_unused (void)
+{
+  TEST_VERIFY (u.attr.size < sizeof (u));
+  for (unsigned int i = u.attr.size; i < sizeof (u); ++i)
+    TEST_COMPARE (u.padding[i], 0xcc);
+}
+
+static int
+do_test (void)
+{
+  TEST_VERIFY (sizeof (struct sched_attr) < sizeof (u));
+
+  /* Check that reading and re-applying the current policy works.  */
+  memset (&u, 0xcc, sizeof (u));
+  /* Compiler barrier to bypass write access attribute.  */
+  volatile unsigned int size = sizeof (u);
+  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
+  check_unused ();
+  TEST_COMPARE (sched_setattr (0, &u.attr, 0), 0); /* Apply unchanged.  */
+
+  /* Try to switch to the SCHED_OTHER policy.   */
+  memset (&u, 0, sizeof (u));
+  u.attr.size = sizeof (u); /* With padding, kernel should accept zeroes.  */
+  u.attr.sched_policy = SCHED_OTHER; /* Should be the default.  */
+  {
+    errno = 0;
+    int prio = getpriority (PRIO_PROCESS, 0);
+    if (errno != 0)
+      prio = 0;
+    u.attr.sched_nice = prio;
+  }
+  TEST_COMPARE (sched_setattr (0, &u.attr, 0), 0);
+
+  /* Non-zero values not known to the kernel result in an E2BIG error.  */
+  memset (&u, 0, sizeof (u));
+  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
+  u.padding[u.attr.size] = 0xcc;
+  u.attr.size = sizeof (u);
+  errno = 0;
+  TEST_COMPARE (sched_setattr (0, &u.attr, 0), -1);
+  TEST_COMPARE (errno, E2BIG);
+
+  memset (&u, 0xcc, sizeof (u));
+  TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
+  TEST_COMPARE (u.attr.sched_policy, SCHED_OTHER);
+  check_unused ();
+
+  /* Raise the niceless level to 19 and observe its effect.  */
+  TEST_COMPARE (nice (19), 19);
+  TEST_COMPARE (sched_getattr (0, &u.attr, sizeof (u.attr), 0), 0);
+  TEST_COMPARE (u.attr.sched_policy, SCHED_OTHER);
+  TEST_COMPARE (u.attr.sched_nice, 19);
+  check_unused ();
+
+  /* Invalid buffer arguments result in EINVAL (not EFAULT).  */
+  {
+    errno = 0;
+    void *volatile null_pointer = NULL; /* compiler barrier.  */
+    TEST_COMPARE (sched_setattr (0, null_pointer, 0), -1);
+    TEST_COMPARE (errno, EINVAL);
+    errno = 0;
+    TEST_COMPARE (sched_getattr (0, null_pointer, size, 0), -1);
+    TEST_COMPARE (errno, EINVAL);
+  }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index aea7848ed6..5acf49dbe8 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2744,6 +2744,8 @@  GLIBC_2.4 sys_errlist D 0x420
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 4ab3681914..02d1bb97dc 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2763,3 +2763,5 @@  GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.41 sched_getattr F
+GLIBC_2.41 sched_setattr F