Add sched_setattr, sched_getattr, pthread_gettid_np (RHEL-56627)

To avoid ABI stability issues, the functions are added to
libc_nonshared.a.

Resolves: RHEL-56627
Resolves: RHEL-61562
Resolves: RHEL-83017
This commit is contained in:
Florian Weimer 2025-03-12 13:27:23 +01:00
parent 6dd6a815e9
commit 2d30216b53
9 changed files with 1139 additions and 1 deletions

451
glibc-RHEL-56627-1.patch Normal file
View File

@ -0,0 +1,451 @@
Partial backport (without ABI changes, using libc_nonshared.a instead)
of:
commit 21571ca0d70302909cf72707b2a7736cf12190a0
Author: Florian Weimer <fweimer@redhat.com>
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 <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.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
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 <sysdep.h>,
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 <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. */
@@ -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
+ <https://www.gnu.org/licenses/>. */
+
+#include <sched.h>
+#include <sysdep.h>
+#include <unistd.h>
+
+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
+ <https://www.gnu.org/licenses/>. */
+
+#include <sched.h>
+#include <sysdep.h>
+#include <unistd.h>
+
+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
+ <https://www.gnu.org/licenses/>. */
+
+#include <sched.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <support/check.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+/* Padding struct to detect unexpected writes. */
+union
+{
+ struct sched_attr attr;
+ /* Hopefully the kernel will never need as much. */
+ unsigned char padding[4096];
+} u;
+
+static void
+check_unused (void)
+{
+ TEST_VERIFY (u.attr.size < sizeof (u));
+ for (unsigned int i = u.attr.size; i < sizeof (u); ++i)
+ TEST_COMPARE (u.padding[i], 0xcc);
+}
+
+static int
+do_test (void)
+{
+ TEST_VERIFY (sizeof (struct sched_attr) < sizeof (u));
+
+ /* Check that reading and re-applying the current policy works. */
+ memset (&u, 0xcc, sizeof (u));
+ /* Compiler barrier to bypass write access attribute. */
+ volatile unsigned int size = sizeof (u);
+ TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
+ check_unused ();
+ TEST_COMPARE (sched_setattr (0, &u.attr, 0), 0); /* Apply unchanged. */
+
+ /* Try to switch to the SCHED_OTHER policy. */
+ memset (&u, 0, sizeof (u));
+ u.attr.size = sizeof (u); /* With padding, kernel should accept zeroes. */
+ u.attr.sched_policy = SCHED_OTHER; /* Should be the default. */
+ {
+ errno = 0;
+ int prio = getpriority (PRIO_PROCESS, 0);
+ if (errno != 0)
+ prio = 0;
+ u.attr.sched_nice = prio;
+ }
+ TEST_COMPARE (sched_setattr (0, &u.attr, 0), 0);
+
+ /* Non-zero values not known to the kernel result in an E2BIG error. */
+ memset (&u, 0, sizeof (u));
+ TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
+ u.padding[u.attr.size] = 0xcc;
+ u.attr.size = sizeof (u);
+ errno = 0;
+ TEST_COMPARE (sched_setattr (0, &u.attr, 0), -1);
+ TEST_COMPARE (errno, E2BIG);
+
+ memset (&u, 0xcc, sizeof (u));
+ TEST_COMPARE (sched_getattr (0, (struct sched_attr *) &u, size, 0), 0);
+ TEST_COMPARE (u.attr.sched_policy, SCHED_OTHER);
+ check_unused ();
+
+ /* Raise the niceless level to 19 and observe its effect. */
+ TEST_COMPARE (nice (19), 19);
+ TEST_COMPARE (sched_getattr (0, &u.attr, sizeof (u.attr), 0), 0);
+ TEST_COMPARE (u.attr.sched_policy, SCHED_OTHER);
+ TEST_COMPARE (u.attr.sched_nice, 19);
+ check_unused ();
+
+ /* Invalid buffer arguments result in EINVAL (not EFAULT). */
+ {
+ errno = 0;
+ void *volatile null_pointer = NULL; /* compiler barrier. */
+ TEST_COMPARE (sched_setattr (0, null_pointer, 0), -1);
+ TEST_COMPARE (errno, EINVAL);
+ errno = 0;
+ TEST_COMPARE (sched_getattr (0, null_pointer, size, 0), -1);
+ TEST_COMPARE (errno, EINVAL);
+ }
+
+ return 0;
+}
+
+#include <support/test-driver.c>

143
glibc-RHEL-56627-2.patch Normal file
View File

@ -0,0 +1,143 @@
commit c444cc1d8335243c5c4e636d6a26c472df85522c
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Sep 11 10:05:08 2024 +0200
Linux: Add missing scheduler constants to <sched.h>
And add a test, misc/tst-sched-consts, that checks
consistency with <sched.h>.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
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
+# <https://www.gnu.org/licenses/>.
+
+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 <sched.h>\n',
+ '#define _GNU_SOURCE 1\n'
+ '#include <linux/sched.h>\n'
+ '#include <linux/sched/types.h>\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. */

73
glibc-RHEL-56627-3.patch Normal file
View File

@ -0,0 +1,73 @@
commit b3a6bd625ce96bcec0e5d41b9835b1367d97e548
Author: Florian Weimer <fweimer@redhat.com>
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 <xry111@xry111.site>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
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). */
{

47
glibc-RHEL-56627-4.patch Normal file
View File

@ -0,0 +1,47 @@
commit 517846c85dfc48aa231e28e95e8f90a6d8a8efde
Author: Florian Weimer <fweimer@redhat.com>
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 <josmyers@redhat.com>
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

223
glibc-RHEL-56627-5.patch Normal file
View File

@ -0,0 +1,223 @@
Partial backport (without ABI changes, using libc_nonshared.a instead)
of:
commit 74d463c50bb1096efef47022405c7db33f83fb5a
Author: Florian Weimer <fweimer@redhat.com>
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 <josmyers@redhat.com>
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 <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <pthreadP.h>
+
+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 <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <pthread.h>
+#include <sched.h>
+#include <signal.h>
+#include <support/check.h>
+#include <support/xthread.h>
+#include <unistd.h>
+
+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 <support/test-driver.c>
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

20
glibc-RHEL-56627-6.patch Normal file
View File

@ -0,0 +1,20 @@
commit 6e30efe570f1ba135747c6d8f4004e78cd24c49c
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Mar 12 11:10:14 2025 +0100
nptl: Include <stdbool.h> 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 <pthread.h>
#include <sched.h>
#include <signal.h>
+#include <stdbool.h>
#include <support/check.h>
#include <support/xthread.h>
#include <unistd.h>

21
glibc-RHEL-56627-7.patch Normal file
View File

@ -0,0 +1,21 @@
commit 74c68fa61b5ebf4c64605a3cc5e47154a66671ce
Author: Florian Weimer <fweimer@redhat.com>
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

149
glibc-RHEL-56627-8.patch Normal file
View File

@ -0,0 +1,149 @@
commit 1ec411f7aec1bb7fb0992c8e23a42cea306305aa
Author: Florian Weimer <fweimer@redhat.com>
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 <josmyers@redhat.com>
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
+ <https://www.gnu.org/licenses/>. */
+
+#include <sched.h>
+
+#include <stddef.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <support/xthread.h>
+#include <unistd.h>
+
+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 <support/test-driver.c>

View File

@ -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 <fweimer@redhat.com> - 2.34-176
- Add sched_setattr, sched_getattr, pthread_gettid_np (RHEL-56627, RHEL-83017)
* Mon Mar 10 2025 Tulio Magno Quites Machado Filho <tuliom@redhat.com> - 2.34-175
- Backport fwrite tests and a fix for BZ 29459 (RHEL-55471)