diff mbox series

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

Message ID 339e01b7497955870e9bf3382306f47a0f85a53f.1725561027.git.fweimer@redhat.com
State New
Headers show
Series Add the sched_setattr, sched_getattr functions | expand

Commit Message

Florian Weimer Sept. 5, 2024, 6:33 p.m. UTC
And struct sched_attr.

In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
_glibc_mask_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                          | 103 +++++++++++++++++
 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   | 104 ++++++++++++++++++
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   2 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   2 +
 41 files changed, 378 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. 5, 2024, 7:50 p.m. UTC | #1
On 9/5/24 2:33 PM, Florian Weimer wrote:
> And struct sched_attr.
> 
> In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines
> _glibc_mask_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.

Agreed.

> (An alternative would involve introducing a separate header
> for this functionality, but this seems unnecessary.)

Not needed IMO.

> 
> 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.

Agreed.

> The documentation mostly defers to the Linux manual pages.

That's acceptable and the reason we added this ability to defer.


Needs a v2:

- Incomplete sentence.
- Some grammatical corrections.
- Missing a nice <-> sched_priority comparison in test.

Question: Why not use syscalls.list?

e.g.
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 9ac42c3436..63d4068cdd 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -59,6 +59,8 @@ sched_gets    -       sched_getscheduler      i:i     __sched_getscheduler    sched_getscheduler
 sched_primax   -       sched_get_priority_max  i:i     __sched_get_priority_max        sched_get_priority_max
 sched_primin   -       sched_get_priority_min  i:i     __sched_get_priority_min        sched_get_priority_min
 sched_setp     -       sched_setparam  i:ip    __sched_setparam        sched_setparam
+sched_setattr  ...
+sched_getattr  ...
 sched_sets     -       sched_setscheduler      i:iip   __sched_setscheduler    sched_setscheduler
 sched_yield    -       sched_yield     i:      __sched_yield   sched_yield
 setfsgid       EXTRA   setfsgid        i:i     setfsgid

> ---
>  NEWS                                          |   3 +
>  manual/resource.texi                          | 103 +++++++++++++++++
>  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   | 104 ++++++++++++++++++
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   2 +
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   2 +
>  41 files changed, 378 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.
> +

OK.

>  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..68adc5dd59 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.

OK.

>  * Traditional Scheduling::          Scheduling among the vulgar masses
>  * CPU Affinity::                    Limiting execution to certain CPUs
>  @end menu
> @@ -952,6 +953,108 @@ 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}.

OK. Correct 'man 7 sched' being very thorough here (modulo the fork vs. clone language).

> +
> +@strong{Note:} Calling the @code{sched_setattr} function is incompatible
> +with support for @code{PTHREAD_PRIO_PROTECT} mutexes.

OK. Good note.

> +
> +@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).

OK. Agreed.

> +
> +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

Incomplete sentence?

> +
> +@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 @var{flags} argument currently must be 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} the kernel does not

s/the kernel/that the kernel/g

> +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 currently must be zero.

OK. Omph, sentence adverbs like "currently" can be confusing, this is OK.
I checked quickly and there are some instances of similar phrasing in the man pages.

> +
> +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 \

OK. Both routines.

>    setfsgid \
>    setfsuid \
>    setvmaname \
> @@ -224,6 +226,7 @@ tests += \
>    tst-process_mrelease \
>    tst-quota \
>    tst-rlimit-infinity \
> +  tst-sched_setattr \

OK. Add a test.

>    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;
> +  }

OK. Part of the new ABI.

>    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>.  */

OK. Correct.

> +#   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

OK. SCHED_ATTR_SIZE_VER0 is 48

OK. SCHED_ATTR_SIZE_VER1 is 56

> +struct sched_attr
> +{
> +  __u32 size;

OK. __u32 match size.

> +  __u32 sched_policy;

OK. __u32 match sched_policy.

> +  __u64 sched_flags;

OK. __u64 match sched_flags.

> +  __s32 sched_nice;

OK. __s32 match sched_nice for SCHED_OTHER/SCHED_NORMAL and SCHED_BATCH

> +  __u32 sched_priority;

OK. __u32 match schec_priority for SCHED_FIFO and SCHED_RR.

> +  __u64 sched_runtime;
> +  __u64 sched_deadline;
> +  __u64 sched_period;

OK. __u64, __u64, __u64 match sched_[runtime, deadline, period] for SCHED_DEADLINE.

> +  __u32 sched_util_min;
> +  __u32 sched_util_max;

OK. __u32, __u32 match sched_util_min/max utilization hints.

OK. No further fields.

> +  /* 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));

OK.

> +
> +/* 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));

OK.

> +
>  #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.

OK. Wrapper.

> +   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);
> +}

OK. pid, attr, size, flags match.

> 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);
> +}

OK pid, attr, flags, match.

> 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..81875b92b0
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-sched_setattr.c
> @@ -0,0 +1,104 @@
> +/* Tests for sched_setattr and sched_getattr.

OK. Test.

> +   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;

OK. Oh, nice! Testing for unexpected writes is good.

> +
> +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);

OK.

> +}
> +
> +static int
> +do_test (void)
> +{
> +  TEST_VERIFY (sizeof (struct sched_attr) < sizeof (u));

OK. Should be or we have a weird compiler problem.

> +
> +  /* Check that reading and re-applying the current policy works.  */
> +  memset (&u, 0xcc, sizeof (u));

OK. Set expected values.

> +  /* 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.  */

OK. Get -> Set with the same values should work.

> +
> +  /* Try to switch to the SCHED_OTHER policy.   */

OK. SCHED_OTHER should be the default, so this should work.

> +  memset (&u, 0, sizeof (u));

OK.

> +  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);

OK. Attempt to set priority. For SCHED_OTHER priority should be 0, but it might be
something else, default to 0 if we can't find out.

> +
> +  /* 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);

OK. Nice that you can trigger this.

> +
> +  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 ();

OK.

> +
> +  /* 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);

Missing TEST_COMPARE (u.attr.sched_priority, 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);

OK. I was about to ask how you stop the compiler from complaining :-)

> +    errno = 0;
> +    TEST_COMPARE (sched_getattr (0, null_pointer, size, 0), -1);
> +    TEST_COMPARE (errno, EINVAL);

OK.

> +  }
> +
> +  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. 5, 2024, 9:04 p.m. UTC | #2
* Carlos O'Donell:

> Question: Why not use syscalls.list?

Adhemerval wants us to use C wrappers for all system calls.  Sign vs
zero extension for arguments can be tricky, but is probably harmless
here.  The kernel uses unsigned int, not unsigned long, in its system
call definition.

>> +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
>
> Incomplete sentence?

Yes, and more, I didn't actually elaborate on the size field below. 8->
Fixed.

>> +@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} the kernel does not
>
> s/the kernel/that the kernel/g

Fixed.

>> +@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 currently must be zero.
>
> OK. Omph, sentence adverbs like "currently" can be confusing, this is OK.
> I checked quickly and there are some instances of similar phrasing in
> the man pages.

Switched to:

The @var{flags} argument must be zero.  Other values may become
available in the future.

>> +  /* 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);
>
> Missing TEST_COMPARE (u.attr.sched_priority, 19) ?

Right, fixed.

Thanks,
Florian
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..68adc5dd59 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,108 @@  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
+
+@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 @var{flags} argument currently must be zero.
+
+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} 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 currently must be zero.
+
+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..81875b92b0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-sched_setattr.c
@@ -0,0 +1,104 @@ 
+/* 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);
+  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