diff --git a/glibc-RHEL-56627-1.patch b/glibc-RHEL-56627-1.patch new file mode 100644 index 0000000..a82a047 --- /dev/null +++ b/glibc-RHEL-56627-1.patch @@ -0,0 +1,451 @@ +Partial backport (without ABI changes, using libc_nonshared.a instead) +of: + +commit 21571ca0d70302909cf72707b2a7736cf12190a0 +Author: Florian Weimer +Date: Wed Sep 11 10:05:08 2024 +0200 + + Linux: Add the sched_setattr and sched_getattr functions + + And struct sched_attr. + + In sysdeps/unix/sysv/linux/bits/sched.h, the hack that defines + sched_param around the inclusion of 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 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. + + Reviewed-by: Carlos O'Donell + +Conflicts: + sysdeps/unix/sysv/linux/Makefile + (variables not sorted downstream, libc_nonshared.a + integration downstream) + sysdeps/unix/sysv/linux/Versions + (not backported) + sysdeps/unix/sysv/linux/*/libc.abilist + (not backported) + +The implementation uses the syscall function, not , +to avoid implicit TCB layout dependencies. Such dependencies +could happen if the system call macros use information in the +TCB to select the way the kernel is entered. + + +diff --git a/manual/resource.texi b/manual/resource.texi +index 37462abc9e467690..bddff67d3d1e414e 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 08b4e7765c07f6a3..d6381fe846c905d6 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -66,7 +66,16 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \ + fxstatat fxstatat64 \ + xmknod xmknodat convert_scm_timestamps \ + closefrom_fallback \ +- clone3 clone-internal ++ clone3 clone-internal \ ++ sched_getattr \ ++ sched_setattr \ ++ # sysdep_routines ++ ++# The implementations go into libc_nonshared.a, to preserve ABI. ++static-only-routines += \ ++ sched_getattr \ ++ sched_setattr \ ++ # static-only-routines + + CFLAGS-gethostid.c = -fexceptions + CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables +@@ -128,6 +137,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-fdopendir-o_path \ + tst-linux-mremap1 \ + tst-sched-affinity-inheritance \ ++ tst-sched_setattr \ + # tests + + # Test for the symbol version of fcntl that was replaced in glibc 2.28. +diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h +index cd450fdfe510f397..5e0f70a69181bc26 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 . */ ++# define sched_param __glibc_mask_sched_param ++# include ++# undef sched_param ++# endif ++# endif ++# ifndef SCHED_ATTR_SIZE_VER0 ++# include ++# 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. */ +@@ -93,6 +122,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/sched_getattr.c b/sysdeps/unix/sysv/linux/sched_getattr.c +new file mode 100644 +index 0000000000000000..64f0b70514f2b143 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sched_getattr.c +@@ -0,0 +1,30 @@ ++/* 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 ++ . */ ++ ++#include ++#include ++#include ++ ++int ++attribute_hidden ++sched_getattr (pid_t pid, struct sched_attr *attr, unsigned int size, ++ unsigned int flags) ++{ ++ /* Use the syscall function for compatibility with libc_nonshared.a. */ ++ return syscall (__NR_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 0000000000000000..2a24a734e8d5125b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sched_setattr.c +@@ -0,0 +1,29 @@ ++/* 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 ++ . */ ++ ++#include ++#include ++#include ++ ++int ++attribute_hidden ++sched_setattr (pid_t pid, struct sched_attr *attr, unsigned int flags) ++{ ++ /* Use the syscall function for compatibility with libc_nonshared.a. */ ++ return syscall (__NR_sched_setattr, pid, attr, flags); ++} +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 0000000000000000..a6288a1a7cc2d01b +--- /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 ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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 diff --git a/glibc-RHEL-56627-2.patch b/glibc-RHEL-56627-2.patch new file mode 100644 index 0000000..8015b59 --- /dev/null +++ b/glibc-RHEL-56627-2.patch @@ -0,0 +1,143 @@ +commit c444cc1d8335243c5c4e636d6a26c472df85522c +Author: Florian Weimer +Date: Wed Sep 11 10:05:08 2024 +0200 + + Linux: Add missing scheduler constants to + + And add a test, misc/tst-sched-consts, that checks + consistency with . + + Reviewed-by: Carlos O'Donell + +Conflicts: + sysdeps/unix/sysv/linux/Makefile + (missing tests downstream) + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index d6381fe846c905d6..a7004f57a3f40fb1 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -247,6 +247,16 @@ $(objpfx)tst-mman-consts.out: ../sysdeps/unix/sysv/linux/tst-mman-consts.py + < /dev/null > $@ 2>&1; $(evaluate-test) + $(objpfx)tst-mman-consts.out: $(sysdeps-linux-python-deps) + ++tests-special += \ ++ $(objpfx)tst-sched-consts.out \ ++ # tests-special ++$(objpfx)tst-sched-consts.out: ../sysdeps/unix/sysv/linux/tst-sched-consts.py ++ $(sysdeps-linux-python) \ ++ ../sysdeps/unix/sysv/linux/tst-sched-consts.py \ ++ $(sysdeps-linux-python-cc) \ ++ < /dev/null > $@ 2>&1; $(evaluate-test) ++$(objpfx)tst-sched-consts.out: $(sysdeps-linux-python-deps) ++ + tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0 + + endif # $(subdir) == misc +diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h +index 5e0f70a69181bc26..d4ac158d99e4c350 100644 +--- a/sysdeps/unix/sysv/linux/bits/sched.h ++++ b/sysdeps/unix/sysv/linux/bits/sched.h +@@ -29,6 +29,7 @@ + #define SCHED_FIFO 1 + #define SCHED_RR 2 + #ifdef __USE_GNU ++# define SCHED_NORMAL SCHED_OTHER + # define SCHED_BATCH 3 + # define SCHED_ISO 4 + # define SCHED_IDLE 5 +@@ -37,6 +38,19 @@ + /* Flags that can be used in policy values. */ + # define SCHED_RESET_ON_FORK 0x40000000 + ++/* Flags for the sched_flags field in struct sched_attr. */ ++#define SCHED_FLAG_RESET_ON_FORK 0x01 ++#define SCHED_FLAG_RECLAIM 0x02 ++#define SCHED_FLAG_DL_OVERRUN 0x04 ++#define SCHED_FLAG_KEEP_POLICY 0x08 ++#define SCHED_FLAG_KEEP_PARAMS 0x10 ++#define SCHED_FLAG_UTIL_CLAMP_MIN 0x20 ++#define SCHED_FLAG_UTIL_CLAMP_MAX 0x40 ++ ++/* Combinations of sched_flags fields. */ ++#define SCHED_FLAG_KEEP_ALL 0x18 ++#define SCHED_FLAG_UTIL_CLAMP 0x60 ++ + /* Use "" to work around incorrect macro expansion of the + __has_include argument (GCC PR 80005). */ + # ifdef __has_include +diff --git a/sysdeps/unix/sysv/linux/tst-sched-consts.py b/sysdeps/unix/sysv/linux/tst-sched-consts.py +new file mode 100644 +index 0000000000000000..70071dcd974fe064 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-sched-consts.py +@@ -0,0 +1,56 @@ ++#!/usr/bin/python3 ++# Test that glibc's sched.h constants match the kernel's. ++# Copyright (C) 2018-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 ++# . ++ ++import argparse ++import sys ++ ++import glibcextract ++import glibcsyscalls ++ ++ ++def main(): ++ """The main entry point.""" ++ parser = argparse.ArgumentParser( ++ description="Test that glibc's sched.h constants " ++ "match the kernel's.") ++ parser.add_argument('--cc', metavar='CC', ++ help='C compiler (including options) to use') ++ args = parser.parse_args() ++ linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) ++ linux_version_glibc = (6, 10) ++ sys.exit(glibcextract.compare_macro_consts( ++ '#define _GNU_SOURCE 1\n' ++ '#include \n', ++ '#define _GNU_SOURCE 1\n' ++ '#include \n' ++ '#include \n', ++ args.cc, ++ 'SCHED_.*', ++ # SCHED_ISO is reserved, but not implemented in the kernel. ++ # SCHED_OTHER is the standard name for SCHED_NORMAL. ++ # SCHED_FLAG_ALL will receive more and more flags, so ++ # exposing it to userspace does not seem useful. ++ 'SCHED_ISO' ++ '|SCHED_OTHER' ++ '|SCHED_FLAG_ALL', ++ linux_version_glibc > linux_version_headers, ++ linux_version_headers > linux_version_glibc)) ++ ++if __name__ == '__main__': ++ main() +diff --git a/sysdeps/unix/sysv/linux/tst-sched_setattr.c b/sysdeps/unix/sysv/linux/tst-sched_setattr.c +index a6288a1a7cc2d01b..fbb73c31a72de311 100644 +--- a/sysdeps/unix/sysv/linux/tst-sched_setattr.c ++++ b/sysdeps/unix/sysv/linux/tst-sched_setattr.c +@@ -44,6 +44,8 @@ check_unused (void) + static int + do_test (void) + { ++ _Static_assert (SCHED_OTHER == SCHED_NORMAL, ++ "SCHED_OTHER, SCHED_NORMAL values"); + TEST_VERIFY (sizeof (struct sched_attr) < sizeof (u)); + + /* Check that reading and re-applying the current policy works. */ diff --git a/glibc-RHEL-56627-3.patch b/glibc-RHEL-56627-3.patch new file mode 100644 index 0000000..70be7a5 --- /dev/null +++ b/glibc-RHEL-56627-3.patch @@ -0,0 +1,73 @@ +commit b3a6bd625ce96bcec0e5d41b9835b1367d97e548 +Author: Florian Weimer +Date: Mon Jan 20 09:57:09 2025 +0100 + + Linux: Do not check unused bytes after sched_getattr in tst-sched_setattr + + Linux 6.13 was released with a change that overwrites those bytes. + This means that the check_unused subtest fails. + + Update the manual accordingly. + + Tested-by: Xi Ruoyao + Reviewed-by: Adhemerval Zanella + +diff --git a/manual/resource.texi b/manual/resource.texi +index bddff67d3d1e414e..f9fba2ad9cd84c14 100644 +--- a/manual/resource.texi ++++ b/manual/resource.texi +@@ -1058,9 +1058,9 @@ 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}. ++@code{@var{attr}->size} may not be overwritten 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 +diff --git a/sysdeps/unix/sysv/linux/tst-sched_setattr.c b/sysdeps/unix/sysv/linux/tst-sched_setattr.c +index fbb73c31a72de311..6b0913aebae96abe 100644 +--- a/sysdeps/unix/sysv/linux/tst-sched_setattr.c ++++ b/sysdeps/unix/sysv/linux/tst-sched_setattr.c +@@ -33,14 +33,6 @@ union + 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) + { +@@ -53,7 +45,6 @@ do_test (void) + /* 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. */ +@@ -81,14 +72,12 @@ do_test (void) + 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). */ + { diff --git a/glibc-RHEL-56627-4.patch b/glibc-RHEL-56627-4.patch new file mode 100644 index 0000000..e8bb32a --- /dev/null +++ b/glibc-RHEL-56627-4.patch @@ -0,0 +1,47 @@ +commit 517846c85dfc48aa231e28e95e8f90a6d8a8efde +Author: Florian Weimer +Date: Wed Mar 12 11:29:10 2025 +0100 + + Makefile: Clean up pthread_atfork integration + + Do not add the pthread_atfork routine again in nptl/Makefile, + instead rely on sysdeps/pthread/Makefile for the integration + (as this is the directory that contains the source file). + + In sysdeps/pthread/Makefile, add to static-only-routines. + + Reviewed-by: Joseph Myers + +diff --git a/nptl/Makefile b/nptl/Makefile +index 455703bbd763d516..d03846c2e04afa2f 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -58,7 +58,6 @@ routines = \ + old_pthread_cond_signal \ + old_pthread_cond_timedwait \ + old_pthread_cond_wait \ +- pthread_atfork \ + pthread_attr_copy \ + pthread_attr_destroy \ + pthread_attr_extension \ +@@ -204,7 +203,6 @@ routines = \ + vars \ + # routines + +-static-only-routines = pthread_atfork + libpthread-routines = libpthread-compat + libpthread-shared-only-routines = libpthread-compat + +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index 58c33a8e49d517ad..fa70a33e25f23230 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -145,7 +145,7 @@ tests-time64 := \ + tst-sem5-time64 \ + tst-thrd-sleep-time64 \ + +-static-only-routines = pthread_atfork ++static-only-routines += pthread_atfork + + # Files which must not be linked with libpthread. + tests-nolibpthread += tst-unload diff --git a/glibc-RHEL-56627-5.patch b/glibc-RHEL-56627-5.patch new file mode 100644 index 0000000..6375614 --- /dev/null +++ b/glibc-RHEL-56627-5.patch @@ -0,0 +1,223 @@ +Partial backport (without ABI changes, using libc_nonshared.a instead) +of: + +commit 74d463c50bb1096efef47022405c7db33f83fb5a +Author: Florian Weimer +Date: Wed Mar 12 10:16:31 2025 +0100 + + Linux: Add the pthread_gettid_np function (bug 27880) + + Current Bionic has this function, with enhanced error checking + (the undefined case terminates the process). + + Reviewed-by: Joseph Myers + +Conflicts: + sysdeps/unix/sysv/linux/*/libc.abilist + (not backported) + nptl/Versions + (not backported) + +The alternate libc_nonshared.a implementation relies on the UAPI +encoding of pthread_getcpuclockid, and avoids a TCB layout +dependency. + +diff --git a/manual/process.texi b/manual/process.texi +index 9307379194c6f666..8535363546520d62 100644 +--- a/manual/process.texi ++++ b/manual/process.texi +@@ -238,6 +238,24 @@ especially regarding reuse of the IDs of threads which have exited. + This function is specific to Linux. + @end deftypefun + ++@deftypefun pid_t pthread_gettid_np (pthread_t @var{thread}) ++@standards{Linux, pthread.h} ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++This function returns the same value that @code{gettid} would return if ++executed on the running thread @var{thread}. ++ ++If @var{thread} is no longer running but it is joinable, it is ++unspecified whether this function returns @minus{}1, or if it returns ++the thread ID of the thread while it was running. If @var{thread} is ++not running and is not joinable, the behavior is undefined. ++ ++@strong{Portability Note:} Linux thread IDs can be reused rather quickly, ++so this function differs from the @code{pthread_getunique_np} function ++found on other systems. ++ ++This function is specific to Linux. ++@end deftypefun ++ + @node Creating a Process + @section Creating a Process + +diff --git a/nptl/Makefile b/nptl/Makefile +index d03846c2e04afa2f..cac75eb8f5b68320 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -118,6 +118,7 @@ routines = \ + pthread_getname \ + pthread_getschedparam \ + pthread_getspecific \ ++ pthread_gettid_np \ + pthread_join \ + pthread_join_common \ + pthread_key_create \ +@@ -203,6 +204,10 @@ routines = \ + vars \ + # routines + ++static-only-routines += \ ++ pthread_gettid_np \ ++ # static-only-routines ++ + libpthread-routines = libpthread-compat + libpthread-shared-only-routines = libpthread-compat + +@@ -314,6 +319,7 @@ tests = \ + tst-pthread-timedlock-lockloop \ + tst-pthread_exit-nothreads \ + tst-pthread_exit-nothreads-static \ ++ tst-pthread_gettid_np \ + tst-robust-fork \ + tst-robustpi1 \ + tst-robustpi2 \ +diff --git a/nptl/pthread_gettid_np.c b/nptl/pthread_gettid_np.c +new file mode 100644 +index 0000000000000000..b602eb7a30bf42a5 +--- /dev/null ++++ b/nptl/pthread_gettid_np.c +@@ -0,0 +1,32 @@ ++/* Get the Linux TID from a pthread_t handle. ++ Copyright (C) 2025 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; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++ ++pid_t ++attribute_hidden ++pthread_gettid_np (pthread_t threadid) ++{ ++ clockid_t clock; ++ if (pthread_getcpuclockid (threadid, &clock) != 0) ++ return -1; ++ /* Reverse the clock ID encoding to obtain the TID. This is part of ++ the kernel/userspace interface, so it is stable ABI. */ ++ return ~(clock >> 3); ++} +diff --git a/nptl/tst-pthread_gettid_np.c b/nptl/tst-pthread_gettid_np.c +new file mode 100644 +index 0000000000000000..6a98d864e222b9f5 +--- /dev/null ++++ b/nptl/tst-pthread_gettid_np.c +@@ -0,0 +1,79 @@ ++/* Test for pthread_gettid_np. ++ Copyright (C) 2025 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; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static pthread_barrier_t barrier; ++ ++static pid_t thread_tid; ++ ++static void * ++thread_func (void *ignored) ++{ ++ thread_tid = gettid (); ++ TEST_VERIFY (thread_tid != getpid ()); ++ TEST_COMPARE (thread_tid, pthread_gettid_np (pthread_self ())); ++ xpthread_barrier_wait (&barrier); ++ /* The main thread calls pthread_gettid_np here. */ ++ xpthread_barrier_wait (&barrier); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ TEST_COMPARE (pthread_gettid_np (pthread_self ()), getpid ()); ++ TEST_COMPARE (pthread_gettid_np (pthread_self ()), gettid ()); ++ ++ xpthread_barrier_init (&barrier, NULL, 2); ++ ++ pthread_t thr = xpthread_create (NULL, thread_func, NULL); ++ xpthread_barrier_wait (&barrier); ++ TEST_COMPARE (thread_tid, pthread_gettid_np (thr)); ++ xpthread_barrier_wait (&barrier); ++ ++ while (true) ++ { ++ /* Check if the kernel thread is still running. */ ++ if (tgkill (getpid (), thread_tid, 0)) ++ { ++ TEST_COMPARE (errno, ESRCH); ++ break; ++ } ++ ++ pid_t tid = pthread_gettid_np (thr); ++ if (tid != thread_tid) ++ { ++ TEST_COMPARE (tid, -1); ++ break; ++ } ++ TEST_COMPARE (sched_yield (), 0); ++ } ++ ++ TEST_VERIFY (xpthread_join (thr) == NULL); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h +index 43146e91c9d9579b..b8bd9213da5c9bc0 100644 +--- a/sysdeps/nptl/pthread.h ++++ b/sysdeps/nptl/pthread.h +@@ -1317,6 +1317,11 @@ extern int pthread_getcpuclockid (pthread_t __thread_id, + __THROW __nonnull ((2)); + #endif + ++#ifdef __USE_GNU ++/* Return the Linux TID for THREAD_ID. Returns -1 on failure. */ ++extern pid_t pthread_gettid_np (pthread_t __thread_id); ++#endif ++ + + /* Install handlers to be called when a new process is created with FORK. + The PREPARE handler is called in the parent process just before performing diff --git a/glibc-RHEL-56627-6.patch b/glibc-RHEL-56627-6.patch new file mode 100644 index 0000000..7fe51f5 --- /dev/null +++ b/glibc-RHEL-56627-6.patch @@ -0,0 +1,20 @@ +commit 6e30efe570f1ba135747c6d8f4004e78cd24c49c +Author: Florian Weimer +Date: Wed Mar 12 11:10:14 2025 +0100 + + nptl: Include in tst-pthread_gettid_np.c + + The test uses the while (true) construct. + +diff --git a/nptl/tst-pthread_gettid_np.c b/nptl/tst-pthread_gettid_np.c +index 6a98d864e222b9f5..ced42915106f5390 100644 +--- a/nptl/tst-pthread_gettid_np.c ++++ b/nptl/tst-pthread_gettid_np.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/glibc-RHEL-56627-7.patch b/glibc-RHEL-56627-7.patch new file mode 100644 index 0000000..2ba59e0 --- /dev/null +++ b/glibc-RHEL-56627-7.patch @@ -0,0 +1,21 @@ +commit 74c68fa61b5ebf4c64605a3cc5e47154a66671ce +Author: Florian Weimer +Date: Wed Mar 12 10:23:47 2025 +0100 + + Linux: Remove attribute access from sched_getattr (bug 32781) + + The GCC attribute expects an element count, not bytes. + +diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h +index d4ac158d99e4c350..3bdd258bb987d49b 100644 +--- a/sysdeps/unix/sysv/linux/bits/sched.h ++++ b/sysdeps/unix/sysv/linux/bits/sched.h +@@ -145,7 +145,7 @@ int sched_setattr (pid_t tid, struct sched_attr *attr, unsigned int flags) + 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)); ++ __THROW __nonnull ((2)); + + #endif + diff --git a/glibc-RHEL-56627-8.patch b/glibc-RHEL-56627-8.patch new file mode 100644 index 0000000..b6f14f6 --- /dev/null +++ b/glibc-RHEL-56627-8.patch @@ -0,0 +1,149 @@ +commit 1ec411f7aec1bb7fb0992c8e23a42cea306305aa +Author: Florian Weimer +Date: Wed Mar 12 10:23:47 2025 +0100 + + Linux: Add new test misc/tst-sched_setattr-thread + + The straightforward sched_getattr call serves as a test for + bug 32781, too. + + Reviewed-by: Joseph Myers + +Conflicts: + sysdeps/unix/sysv/linux/Makefile + (Makefile not reformatted downstream) + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index a7004f57a3f40fb1..460ba54a8afcc515 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -138,6 +138,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-linux-mremap1 \ + tst-sched-affinity-inheritance \ + tst-sched_setattr \ ++ tst-sched_setattr-thread \ + # tests + + # Test for the symbol version of fcntl that was replaced in glibc 2.28. +diff --git a/sysdeps/unix/sysv/linux/tst-sched_setattr-thread.c b/sysdeps/unix/sysv/linux/tst-sched_setattr-thread.c +new file mode 100644 +index 0000000000000000..4600be92fd0a4c28 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-sched_setattr-thread.c +@@ -0,0 +1,116 @@ ++/* Test for sched_setattr, sched_getattr involving multiple threads. ++ Copyright (C) 2024-2025 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 ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++enum { initial_nice_value = 15 }; ++ ++/* Check that thread TID has nice value EXPECTED. */ ++static void ++check_nice_value (int tid, int expected) ++{ ++ struct sched_attr attr; ++ if (sched_getattr (tid, &attr, sizeof (attr), 0) != 0) ++ FAIL_EXIT1 ("sched_getattr (%d) failed: %m", tid); ++ TEST_COMPARE (attr.sched_policy, SCHED_OTHER); ++ int nice_value = attr.sched_nice; ++ if (attr.sched_nice != expected) ++ FAIL_EXIT1 ("thread %d: expected nice value %d, got %d" ++ " (called from thread %d)", ++ tid, expected, nice_value, (int) gettid ()); ++ printf ("info: thread %d: nice value %d (called from thread %d)\n", ++ tid, nice_value, (int) gettid ()); ++} ++ ++/* Set the nice value for TID to VALUE. */ ++static void ++set_nice_value (int tid, int value) ++{ ++ struct sched_attr attr = ++ { ++ .size = sizeof (attr), ++ .sched_policy = SCHED_OTHER, ++ .sched_nice = value, ++ }; ++ if (sched_setattr (tid, &attr, 0) != 0) ++ FAIL_EXIT1 ("sched_setattr (%d) failed: %m", tid); ++} ++ ++static pthread_barrier_t barrier; ++ ++static void * ++thread_routine (void *nice_value_ptr) ++{ ++ int nice_value = *(int *) nice_value_ptr; ++ /* Check that the nice value was inherited. */ ++ check_nice_value (gettid (), initial_nice_value); ++ xpthread_barrier_wait (&barrier); ++ /* Main thread sets nice value. */ ++ xpthread_barrier_wait (&barrier); ++ check_nice_value (gettid (), nice_value); ++ set_nice_value (gettid (), nice_value + 2); ++ xpthread_barrier_wait (&barrier); ++ /* Main thread sets checks value. */ ++ xpthread_barrier_wait (&barrier); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ if (nice (initial_nice_value) != initial_nice_value) ++ FAIL_UNSUPPORTED ("cannot set nice value to initial_nice_value: %m"); ++ ++ xpthread_barrier_init (&barrier, NULL, 3); ++ ++ check_nice_value (0, initial_nice_value); ++ check_nice_value (gettid (), initial_nice_value); ++ ++ int nice0 = initial_nice_value + 1; ++ pthread_t thr0 = xpthread_create (NULL, thread_routine, &nice0); ++ int nice1 = initial_nice_value + 2; ++ pthread_t thr1 = xpthread_create (NULL, thread_routine, &nice1); ++ check_nice_value (pthread_gettid_np (thr0), initial_nice_value); ++ check_nice_value (pthread_gettid_np (thr1), initial_nice_value); ++ xpthread_barrier_wait (&barrier); ++ set_nice_value (pthread_gettid_np (thr0), nice0); ++ check_nice_value (pthread_gettid_np (thr0), nice0); ++ check_nice_value (pthread_gettid_np (thr1), initial_nice_value); ++ set_nice_value (pthread_gettid_np (thr1), nice1); ++ check_nice_value (pthread_gettid_np (thr0), nice0); ++ check_nice_value (pthread_gettid_np (thr1), nice1); ++ xpthread_barrier_wait (&barrier); ++ /* Threads set nice value. */ ++ xpthread_barrier_wait (&barrier); ++ check_nice_value (pthread_gettid_np (thr0), nice0 + 2); ++ check_nice_value (pthread_gettid_np (thr1), nice1 + 2); ++ xpthread_barrier_wait (&barrier); ++ ++ TEST_VERIFY (xpthread_join (thr1) == NULL); ++ TEST_VERIFY (xpthread_join (thr0) == NULL); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc.spec b/glibc.spec index 0bc6036..b185390 100644 --- a/glibc.spec +++ b/glibc.spec @@ -157,7 +157,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 175%{?dist} +Release: 176%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1140,6 +1140,14 @@ Patch832: glibc-RHEL-55471-7.patch Patch833: glibc-RHEL-55471-8.patch Patch834: glibc-RHEL-55471-9.patch Patch835: glibc-RHEL-55471-10.patch +Patch836: glibc-RHEL-56627-1.patch +Patch837: glibc-RHEL-56627-2.patch +Patch838: glibc-RHEL-56627-3.patch +Patch839: glibc-RHEL-56627-4.patch +Patch840: glibc-RHEL-56627-5.patch +Patch841: glibc-RHEL-56627-6.patch +Patch842: glibc-RHEL-56627-7.patch +Patch843: glibc-RHEL-56627-8.patch ############################################################################## # Continued list of core "glibc" package information: @@ -3133,6 +3141,9 @@ update_gconv_modules_cache () %endif %changelog +* Wed Mar 12 2025 Florian Weimer - 2.34-176 +- Add sched_setattr, sched_getattr, pthread_gettid_np (RHEL-56627, RHEL-83017) + * Mon Mar 10 2025 Tulio Magno Quites Machado Filho - 2.34-175 - Backport fwrite tests and a fix for BZ 29459 (RHEL-55471)