diff --git a/srcpkgs/glibc/patches/glibc-upstream-20.patch b/srcpkgs/glibc/patches/glibc-upstream-20.patch index 559f7fb2026..b30b798481a 100644 --- a/srcpkgs/glibc/patches/glibc-upstream-20.patch +++ b/srcpkgs/glibc/patches/glibc-upstream-20.patch @@ -237,3 +237,4 @@ index 42da321149..17ea905aa6 100644 return result; #endif /* Trying to emulate the pwritev2 syscall flags is troublesome: + diff --git a/srcpkgs/glibc/patches/glibc-upstream-21.patch b/srcpkgs/glibc/patches/glibc-upstream-21.patch new file mode 100644 index 00000000000..14b2f7c8c50 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-21.patch @@ -0,0 +1,69 @@ +From 5473739a7b44f27965b70d1acf480f5f72603e78 Mon Sep 17 00:00:00 2001 +From: Rafal Luzynski +Date: Tue, 2 Oct 2018 23:34:18 +0200 +Subject: [PATCH 21] kl_GL: Fix spelling of Sunday, should be "sapaat" (bug + 20209). + +Although CLDR says otherwise, it is confirmed by Oqaasileriffik, the +official Greenlandic language regulator, that this change is correct. + + [BZ #20209] + * localedata/locales/kl_GL: (abday): Fix spelling of Sun (Sunday), + should be "sap" rather than "sab". + (day): Fix spelling of Sunday, should be "sapaat" rather than + "sabaat". + +(cherry picked from commit dae3ed958c3d0090838e49ff4f78c201262b1cf0) +--- + ChangeLog | 8 ++++++++ + NEWS | 1 + + localedata/locales/kl_GL | 4 ++-- + 3 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 11a9b8d98e..32b9cbfbe2 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,11 @@ ++2018-10-09 Rafal Luzynski ++ ++ [BZ #20209] ++ * localedata/locales/kl_GL: (abday): Fix spelling of Sun (Sunday), ++ should be "sap" rather than "sab". ++ (day): Fix spelling of Sunday, should be "sapaat" rather than ++ "sabaat". ++ + 2018-09-28 Adhemerval Zanella + + [BZ #23579] +diff --git a/NEWS b/NEWS +index fd14941128..594cecfc75 100644 +--- a/NEWS ++++ b/NEWS +@@ -9,6 +9,7 @@ Version 2.28.1 + + The following bugs are resolved with this release: + ++ [20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL + [23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream + [23521] nss_files aliases database file stream leak + [23538] pthread_cond_broadcast: Fix waiters-after-spinning case +diff --git a/localedata/locales/kl_GL b/localedata/locales/kl_GL +index 5ab14a31aa..5723ce7dcf 100644 +--- a/localedata/locales/kl_GL ++++ b/localedata/locales/kl_GL +@@ -70,11 +70,11 @@ copy "da_DK" + END LC_NUMERIC + + LC_TIME +-abday "sab";"ata";/ ++abday "sap";"ata";/ + "mar";"pin";/ + "sis";"tal";/ + "arf" +-day "sabaat";/ ++day "sapaat";/ + "ataasinngorneq";/ + "marlunngorneq";/ + "pingasunngorneq";/ + diff --git a/srcpkgs/glibc/patches/glibc-upstream-22.patch b/srcpkgs/glibc/patches/glibc-upstream-22.patch new file mode 100644 index 00000000000..6a9141c24d2 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-22.patch @@ -0,0 +1,161 @@ +From 5a74abda201907cafbdabd1debf98890313ff71e Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Fri, 28 Sep 2018 13:31:19 -0700 +Subject: [PATCH 22] i386: Use _dl_runtime_[resolve|profile]_shstk for SHSTK + [BZ #23716] + +When elf_machine_runtime_setup is called to set up resolver, it should +use _dl_runtime_resolve_shstk or _dl_runtime_profile_shstk if SHSTK is +enabled by kernel. + +Tested on i686 with and without --enable-cet as well as on CET emulator +with --enable-cet. + + [BZ #23716] + * sysdeps/i386/dl-cet.c: Removed. + * sysdeps/i386/dl-machine.h (_dl_runtime_resolve_shstk): New + prototype. + (_dl_runtime_profile_shstk): Likewise. + (elf_machine_runtime_setup): Use _dl_runtime_profile_shstk or + _dl_runtime_resolve_shstk if SHSTK is enabled by kernel. + +Signed-off-by: H.J. Lu + +(cherry picked from commit 7b1f9406761331cf35fe521fbdb592beecf68a2c) +--- + ChangeLog | 10 ++++++ + sysdeps/i386/dl-cet.c | 67 --------------------------------------- + sysdeps/i386/dl-machine.h | 13 ++++++-- + 3 files changed, 21 insertions(+), 69 deletions(-) + delete mode 100644 sysdeps/i386/dl-cet.c + +diff --git a/ChangeLog b/ChangeLog +index 32b9cbfbe2..7f4c6a48bc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,13 @@ ++2018-10-09 H.J. Lu ++ ++ [BZ #23716] ++ * sysdeps/i386/dl-cet.c: Removed. ++ * sysdeps/i386/dl-machine.h (_dl_runtime_resolve_shstk): New ++ prototype. ++ (_dl_runtime_profile_shstk): Likewise. ++ (elf_machine_runtime_setup): Use _dl_runtime_profile_shstk or ++ _dl_runtime_resolve_shstk if SHSTK is enabled by kernel. ++ + 2018-10-09 Rafal Luzynski + + [BZ #20209] +diff --git a/sysdeps/i386/dl-cet.c b/sysdeps/i386/dl-cet.c +deleted file mode 100644 +index 5d9a4e8d51..0000000000 +--- a/sysdeps/i386/dl-cet.c ++++ /dev/null +@@ -1,67 +0,0 @@ +-/* Linux/i386 CET initializers function. +- Copyright (C) 2018 Free Software Foundation, Inc. +- +- 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 +- . */ +- +- +-#define LINKAGE static inline +-#define _dl_cet_check cet_check +-#include +-#undef _dl_cet_check +- +-#ifdef SHARED +-void +-_dl_cet_check (struct link_map *main_map, const char *program) +-{ +- cet_check (main_map, program); +- +- if ((GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) +- { +- /* Replace _dl_runtime_resolve and _dl_runtime_profile with +- _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk, +- respectively if SHSTK is enabled. */ +- extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; +- extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden; +- extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; +- extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden; +- unsigned int i; +- struct link_map *l; +- Elf32_Addr *got; +- +- if (main_map->l_info[DT_JMPREL]) +- { +- got = (Elf32_Addr *) D_PTR (main_map, l_info[DT_PLTGOT]); +- if (got[2] == (Elf32_Addr) &_dl_runtime_resolve) +- got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk; +- else if (got[2] == (Elf32_Addr) &_dl_runtime_profile) +- got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk; +- } +- +- i = main_map->l_searchlist.r_nlist; +- while (i-- > 0) +- { +- l = main_map->l_initfini[i]; +- if (l->l_info[DT_JMPREL]) +- { +- got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]); +- if (got[2] == (Elf32_Addr) &_dl_runtime_resolve) +- got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk; +- else if (got[2] == (Elf32_Addr) &_dl_runtime_profile) +- got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk; +- } +- } +- } +-} +-#endif +diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h +index 1afdcbd9ea..f6cfb90e21 100644 +--- a/sysdeps/i386/dl-machine.h ++++ b/sysdeps/i386/dl-machine.h +@@ -67,6 +67,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + Elf32_Addr *got; + extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; + extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; ++ extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden; ++ extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden; ++ /* Check if SHSTK is enabled by kernel. */ ++ bool shstk_enabled ++ = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0; + + if (l->l_info[DT_JMPREL] && lazy) + { +@@ -93,7 +98,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + end in this function. */ + if (__glibc_unlikely (profile)) + { +- got[2] = (Elf32_Addr) &_dl_runtime_profile; ++ got[2] = (shstk_enabled ++ ? (Elf32_Addr) &_dl_runtime_profile_shstk ++ : (Elf32_Addr) &_dl_runtime_profile); + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) +@@ -104,7 +111,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + else + /* This function will get called to fix up the GOT entry indicated by + the offset on the stack, and then jump to the resolved address. */ +- got[2] = (Elf32_Addr) &_dl_runtime_resolve; ++ got[2] = (shstk_enabled ++ ? (Elf32_Addr) &_dl_runtime_resolve_shstk ++ : (Elf32_Addr) &_dl_runtime_resolve); + } + + return lazy; + diff --git a/srcpkgs/glibc/patches/glibc-upstream-23.patch b/srcpkgs/glibc/patches/glibc-upstream-23.patch new file mode 100644 index 00000000000..00f1f9db305 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-23.patch @@ -0,0 +1,800 @@ +From 314e181dc90cb290942d8b2b57823306ae956696 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Wed, 17 Oct 2018 12:23:04 +0200 +Subject: [PATCH 23] Fix race in pthread_mutex_lock while promoting to + PTHREAD_MUTEX_ELISION_NP [BZ #23275] + +The race leads either to pthread_mutex_destroy returning EBUSY +or triggering an assertion (See description in bugzilla). + +This patch is fixing the race by ensuring that the elision path is +used in all cases if elision is enabled by the GLIBC_TUNABLES framework. + +The __kind variable in struct __pthread_mutex_s is accessed concurrently. +Therefore we are now using the atomic macros. + +The new testcase tst-mutex10 is triggering the race on s390x and intel. +Presumably also on power, but I don't have access to a power machine +with lock-elision. At least the code for power is the same as on the other +two architectures. + +ChangeLog: + + [BZ #23275] + * nptl/tst-mutex10.c: New File. + * nptl/Makefile (tests): Add tst-mutex10. + (tst-mutex10-ENV): New variable. + * sysdeps/unix/sysv/linux/s390/force-elision.h: (FORCE_ELISION): + Ensure that elision path is used if elision is available. + * sysdeps/unix/sysv/linux/powerpc/force-elision.h (FORCE_ELISION): + Likewise. + * sysdeps/unix/sysv/linux/x86/force-elision.h: (FORCE_ELISION): + Likewise. + * nptl/pthreadP.h (PTHREAD_MUTEX_TYPE, PTHREAD_MUTEX_TYPE_ELISION) + (PTHREAD_MUTEX_PSHARED): Use atomic_load_relaxed. + * nptl/pthread_mutex_consistent.c (pthread_mutex_consistent): Likewise. + * nptl/pthread_mutex_getprioceiling.c (pthread_mutex_getprioceiling): + Likewise. + * nptl/pthread_mutex_lock.c (__pthread_mutex_lock_full) + (__pthread_mutex_cond_lock_adjust): Likewise. + * nptl/pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling): + Likewise. + * nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Likewise. + * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise. + * nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise. + * sysdeps/nptl/bits/thread-shared-types.h (struct __pthread_mutex_s): + Add comments. + * nptl/pthread_mutex_destroy.c (__pthread_mutex_destroy): + Use atomic_load_relaxed and atomic_store_relaxed. + * nptl/pthread_mutex_init.c (__pthread_mutex_init): + Use atomic_store_relaxed. + +(cherry picked from commit 403b4feb22dcbc85ace72a361d2a951380372471) +--- + ChangeLog | 31 +++++ + nptl/Makefile | 8 +- + nptl/pthreadP.h | 12 +- + nptl/pthread_mutex_consistent.c | 7 +- + nptl/pthread_mutex_destroy.c | 11 +- + nptl/pthread_mutex_getprioceiling.c | 4 +- + nptl/pthread_mutex_init.c | 14 ++- + nptl/pthread_mutex_lock.c | 28 +++-- + nptl/pthread_mutex_setprioceiling.c | 7 +- + nptl/pthread_mutex_timedlock.c | 17 ++- + nptl/pthread_mutex_trylock.c | 17 ++- + nptl/pthread_mutex_unlock.c | 17 ++- + nptl/tst-mutex10.c | 109 ++++++++++++++++++ + sysdeps/nptl/bits/thread-shared-types.h | 22 +++- + .../unix/sysv/linux/powerpc/force-elision.h | 44 ++++++- + sysdeps/unix/sysv/linux/s390/force-elision.h | 44 ++++++- + sysdeps/unix/sysv/linux/x86/force-elision.h | 44 ++++++- + 17 files changed, 386 insertions(+), 50 deletions(-) + create mode 100644 nptl/tst-mutex10.c + +diff --git a/ChangeLog b/ChangeLog +index 7f4c6a48bc..5b743f2fdb 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,34 @@ ++2018-10-17 Stefan Liebler ++ ++ [BZ #23275] ++ * nptl/tst-mutex10.c: New File. ++ * nptl/Makefile (tests): Add tst-mutex10. ++ (tst-mutex10-ENV): New variable. ++ * sysdeps/unix/sysv/linux/s390/force-elision.h: (FORCE_ELISION): ++ Ensure that elision path is used if elision is available. ++ * sysdeps/unix/sysv/linux/powerpc/force-elision.h (FORCE_ELISION): ++ Likewise. ++ * sysdeps/unix/sysv/linux/x86/force-elision.h: (FORCE_ELISION): ++ Likewise. ++ * nptl/pthreadP.h (PTHREAD_MUTEX_TYPE, PTHREAD_MUTEX_TYPE_ELISION) ++ (PTHREAD_MUTEX_PSHARED): Use atomic_load_relaxed. ++ * nptl/pthread_mutex_consistent.c (pthread_mutex_consistent): Likewise. ++ * nptl/pthread_mutex_getprioceiling.c (pthread_mutex_getprioceiling): ++ Likewise. ++ * nptl/pthread_mutex_lock.c (__pthread_mutex_lock_full) ++ (__pthread_mutex_cond_lock_adjust): Likewise. ++ * nptl/pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling): ++ Likewise. ++ * nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Likewise. ++ * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise. ++ * nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise. ++ * sysdeps/nptl/bits/thread-shared-types.h (struct __pthread_mutex_s): ++ Add comments. ++ * nptl/pthread_mutex_destroy.c (__pthread_mutex_destroy): ++ Use atomic_load_relaxed and atomic_store_relaxed. ++ * nptl/pthread_mutex_init.c (__pthread_mutex_init): ++ Use atomic_store_relaxed. ++ + 2018-10-09 H.J. Lu + + [BZ #23716] +diff --git a/nptl/Makefile b/nptl/Makefile +index be8066524c..49b6faa330 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -241,9 +241,9 @@ LDLIBS-tst-minstack-throw = -lstdc++ + + tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ +- tst-mutex7 tst-mutex9 tst-mutex5a tst-mutex7a tst-mutex7robust \ +- tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \ +- tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ ++ tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex5a tst-mutex7a \ ++ tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \ ++ tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ + tst-mutexpi9 \ + tst-spin1 tst-spin2 tst-spin3 tst-spin4 \ + tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ +@@ -709,6 +709,8 @@ endif + + $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so + ++tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1 ++ + # The tests here better do not run in parallel + ifneq ($(filter %tests,$(MAKECMDGOALS)),) + .NOTPARALLEL: +diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h +index 13bdb11133..19efe1e35f 100644 +--- a/nptl/pthreadP.h ++++ b/nptl/pthreadP.h +@@ -110,19 +110,23 @@ enum + }; + #define PTHREAD_MUTEX_PSHARED_BIT 128 + ++/* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ + #define PTHREAD_MUTEX_TYPE(m) \ +- ((m)->__data.__kind & 127) ++ (atomic_load_relaxed (&((m)->__data.__kind)) & 127) + /* Don't include NO_ELISION, as that type is always the same + as the underlying lock type. */ + #define PTHREAD_MUTEX_TYPE_ELISION(m) \ +- ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_NP)) ++ (atomic_load_relaxed (&((m)->__data.__kind)) \ ++ & (127 | PTHREAD_MUTEX_ELISION_NP)) + + #if LLL_PRIVATE == 0 && LLL_SHARED == 128 + # define PTHREAD_MUTEX_PSHARED(m) \ +- ((m)->__data.__kind & 128) ++ (atomic_load_relaxed (&((m)->__data.__kind)) & 128) + #else + # define PTHREAD_MUTEX_PSHARED(m) \ +- (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE) ++ ((atomic_load_relaxed (&((m)->__data.__kind)) & 128) \ ++ ? LLL_SHARED : LLL_PRIVATE) + #endif + + /* The kernel when waking robust mutexes on exit never uses +diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c +index 85b8e1a6cb..4fbd875430 100644 +--- a/nptl/pthread_mutex_consistent.c ++++ b/nptl/pthread_mutex_consistent.c +@@ -23,8 +23,11 @@ + int + pthread_mutex_consistent (pthread_mutex_t *mutex) + { +- /* Test whether this is a robust mutex with a dead owner. */ +- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 ++ /* Test whether this is a robust mutex with a dead owner. ++ See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 + || mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT) + return EINVAL; + +diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c +index 5a22611541..713ea68496 100644 +--- a/nptl/pthread_mutex_destroy.c ++++ b/nptl/pthread_mutex_destroy.c +@@ -27,12 +27,17 @@ __pthread_mutex_destroy (pthread_mutex_t *mutex) + { + LIBC_PROBE (mutex_destroy, 1, mutex); + +- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0 + && mutex->__data.__nusers != 0) + return EBUSY; + +- /* Set to an invalid value. */ +- mutex->__data.__kind = -1; ++ /* Set to an invalid value. Relaxed MO is enough as it is undefined behavior ++ if the mutex is used after it has been destroyed. But you can reinitialize ++ it with pthread_mutex_init. */ ++ atomic_store_relaxed (&(mutex->__data.__kind), -1); + + return 0; + } +diff --git a/nptl/pthread_mutex_getprioceiling.c b/nptl/pthread_mutex_getprioceiling.c +index efa37b0d99..ee85949578 100644 +--- a/nptl/pthread_mutex_getprioceiling.c ++++ b/nptl/pthread_mutex_getprioceiling.c +@@ -24,7 +24,9 @@ + int + pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, int *prioceiling) + { +- if (__builtin_expect ((mutex->__data.__kind ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if (__builtin_expect ((atomic_load_relaxed (&(mutex->__data.__kind)) + & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0, 0)) + return EINVAL; + +diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c +index d8fe473728..5cf290c272 100644 +--- a/nptl/pthread_mutex_init.c ++++ b/nptl/pthread_mutex_init.c +@@ -101,7 +101,7 @@ __pthread_mutex_init (pthread_mutex_t *mutex, + memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T); + + /* Copy the values from the attribute. */ +- mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS; ++ int mutex_kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS; + + if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0) + { +@@ -111,17 +111,17 @@ __pthread_mutex_init (pthread_mutex_t *mutex, + return ENOTSUP; + #endif + +- mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ mutex_kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP; + } + + switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK) + { + case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: +- mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP; ++ mutex_kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP; + break; + + case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: +- mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP; ++ mutex_kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP; + + int ceiling = (imutexattr->mutexkind + & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK) +@@ -145,7 +145,11 @@ __pthread_mutex_init (pthread_mutex_t *mutex, + FUTEX_PRIVATE_FLAG FUTEX_WAKE. */ + if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED + | PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0) +- mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT; ++ mutex_kind |= PTHREAD_MUTEX_PSHARED_BIT; ++ ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ atomic_store_relaxed (&(mutex->__data.__kind), mutex_kind); + + /* Default values: mutex not used yet. */ + // mutex->__count = 0; already done by memset +diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c +index 1519c142bd..29cc143e6c 100644 +--- a/nptl/pthread_mutex_lock.c ++++ b/nptl/pthread_mutex_lock.c +@@ -62,6 +62,8 @@ static int __pthread_mutex_lock_full (pthread_mutex_t *mutex) + int + __pthread_mutex_lock (pthread_mutex_t *mutex) + { ++ /* See concurrency notes regarding mutex type which is loaded from __kind ++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ + unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); + + LIBC_PROBE (mutex_entry, 1, mutex); +@@ -350,8 +352,14 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; +- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ int kind, robust; ++ { ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); ++ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ } + + if (robust) + { +@@ -502,7 +510,10 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_PP_NORMAL_NP: + case PTHREAD_MUTEX_PP_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int kind = atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_KIND_MASK_NP; + + oldval = mutex->__data.__lock; + +@@ -607,15 +618,18 @@ hidden_def (__pthread_mutex_lock) + void + __pthread_mutex_cond_lock_adjust (pthread_mutex_t *mutex) + { +- assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0); +- assert ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0); +- assert ((mutex->__data.__kind & PTHREAD_MUTEX_PSHARED_BIT) == 0); ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); ++ assert ((mutex_kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0); ++ assert ((mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0); ++ assert ((mutex_kind & PTHREAD_MUTEX_PSHARED_BIT) == 0); + + /* Record the ownership. */ + pid_t id = THREAD_GETMEM (THREAD_SELF, tid); + mutex->__data.__owner = id; + +- if (mutex->__data.__kind == PTHREAD_MUTEX_PI_RECURSIVE_NP) ++ if (mutex_kind == PTHREAD_MUTEX_PI_RECURSIVE_NP) + ++mutex->__data.__count; + } + #endif +diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c +index 8594874f85..8306cabcf4 100644 +--- a/nptl/pthread_mutex_setprioceiling.c ++++ b/nptl/pthread_mutex_setprioceiling.c +@@ -27,9 +27,10 @@ int + pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling, + int *old_ceiling) + { +- /* The low bits of __kind aren't ever changed after pthread_mutex_init, +- so we don't need a lock yet. */ +- if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0) ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0) + return EINVAL; + + /* See __init_sched_fifo_prio. */ +diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c +index 28237b0e58..888c12fe28 100644 +--- a/nptl/pthread_mutex_timedlock.c ++++ b/nptl/pthread_mutex_timedlock.c +@@ -53,6 +53,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, + /* We must not check ABSTIME here. If the thread does not block + abstime must not be checked for a valid value. */ + ++ /* See concurrency notes regarding mutex type which is loaded from __kind ++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ + switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), + PTHREAD_MUTEX_TIMED_NP)) + { +@@ -338,8 +340,14 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, + case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; +- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ int kind, robust; ++ { ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); ++ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ } + + if (robust) + { +@@ -509,7 +517,10 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex, + case PTHREAD_MUTEX_PP_NORMAL_NP: + case PTHREAD_MUTEX_PP_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int kind = atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_KIND_MASK_NP; + + oldval = mutex->__data.__lock; + +diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c +index 7de61f4f68..fa90c1d1e6 100644 +--- a/nptl/pthread_mutex_trylock.c ++++ b/nptl/pthread_mutex_trylock.c +@@ -36,6 +36,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + int oldval; + pid_t id = THREAD_GETMEM (THREAD_SELF, tid); + ++ /* See concurrency notes regarding mutex type which is loaded from __kind ++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ + switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), + PTHREAD_MUTEX_TIMED_NP)) + { +@@ -199,8 +201,14 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: + case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; +- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ int kind, robust; ++ { ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind)); ++ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ } + + if (robust) + /* Note: robust PI futexes are signaled by setting bit 0. */ +@@ -325,7 +333,10 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) + case PTHREAD_MUTEX_PP_NORMAL_NP: + case PTHREAD_MUTEX_PP_ADAPTIVE_NP: + { +- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP; ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int kind = atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_KIND_MASK_NP; + + oldval = mutex->__data.__lock; + +diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c +index 9ea62943b7..68d04d5395 100644 +--- a/nptl/pthread_mutex_unlock.c ++++ b/nptl/pthread_mutex_unlock.c +@@ -35,6 +35,8 @@ int + attribute_hidden + __pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr) + { ++ /* See concurrency notes regarding mutex type which is loaded from __kind ++ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */ + int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); + if (__builtin_expect (type & + ~(PTHREAD_MUTEX_KIND_MASK_NP|PTHREAD_MUTEX_ELISION_FLAGS_NP), 0)) +@@ -222,13 +224,19 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr) + /* If the previous owner died and the caller did not succeed in + making the state consistent, mark the mutex as unrecoverable + and make all waiters. */ +- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0 ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0 + && __builtin_expect (mutex->__data.__owner + == PTHREAD_MUTEX_INCONSISTENT, 0)) + pi_notrecoverable: + newowner = PTHREAD_MUTEX_NOTRECOVERABLE; + +- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0) ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ if ((atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0) + { + continue_pi_robust: + /* Remove mutex from the list. +@@ -251,7 +259,10 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr) + /* Unlock. Load all necessary mutex data before releasing the mutex + to not violate the mutex destruction requirements (see + lll_unlock). */ +- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP; ++ /* See concurrency notes regarding __kind in struct __pthread_mutex_s ++ in sysdeps/nptl/bits/thread-shared-types.h. */ ++ int robust = atomic_load_relaxed (&(mutex->__data.__kind)) ++ & PTHREAD_MUTEX_ROBUST_NORMAL_NP; + private = (robust + ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex) + : PTHREAD_MUTEX_PSHARED (mutex)); +diff --git a/nptl/tst-mutex10.c b/nptl/tst-mutex10.c +new file mode 100644 +index 0000000000..e1113ca60a +--- /dev/null ++++ b/nptl/tst-mutex10.c +@@ -0,0 +1,109 @@ ++/* Testing race while enabling lock elision. ++ Copyright (C) 2018 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 ++#include ++ ++static pthread_barrier_t barrier; ++static pthread_mutex_t mutex; ++static long long int iteration_count = 1000000; ++static unsigned int thread_count = 3; ++ ++static void * ++thr_func (void *arg) ++{ ++ long long int i; ++ for (i = 0; i < iteration_count; i++) ++ { ++ if ((uintptr_t) arg == 0) ++ { ++ xpthread_mutex_destroy (&mutex); ++ xpthread_mutex_init (&mutex, NULL); ++ } ++ ++ xpthread_barrier_wait (&barrier); ++ ++ /* Test if enabling lock elision works if it is enabled concurrently. ++ There was a race in FORCE_ELISION macro which leads to either ++ pthread_mutex_destroy returning EBUSY as the owner was recorded ++ by pthread_mutex_lock - in "normal mutex" code path - but was not ++ resetted in pthread_mutex_unlock - in "elision" code path. ++ Or it leads to the assertion in nptl/pthread_mutex_lock.c: ++ assert (mutex->__data.__owner == 0); ++ Please ensure that the test is run with lock elision: ++ export GLIBC_TUNABLES=glibc.elision.enable=1 */ ++ xpthread_mutex_lock (&mutex); ++ xpthread_mutex_unlock (&mutex); ++ ++ xpthread_barrier_wait (&barrier); ++ } ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ unsigned int i; ++ printf ("Starting %d threads to run %lld iterations.\n", ++ thread_count, iteration_count); ++ ++ pthread_t *threads = xmalloc (thread_count * sizeof (pthread_t)); ++ xpthread_barrier_init (&barrier, NULL, thread_count); ++ xpthread_mutex_init (&mutex, NULL); ++ ++ for (i = 0; i < thread_count; i++) ++ threads[i] = xpthread_create (NULL, thr_func, (void *) (uintptr_t) i); ++ ++ for (i = 0; i < thread_count; i++) ++ xpthread_join (threads[i]); ++ ++ xpthread_barrier_destroy (&barrier); ++ free (threads); ++ ++ return EXIT_SUCCESS; ++} ++ ++#define OPT_ITERATIONS 10000 ++#define OPT_THREADS 10001 ++#define CMDLINE_OPTIONS \ ++ { "iterations", required_argument, NULL, OPT_ITERATIONS }, \ ++ { "threads", required_argument, NULL, OPT_THREADS }, ++static void ++cmdline_process (int c) ++{ ++ long long int arg = strtoll (optarg, NULL, 0); ++ switch (c) ++ { ++ case OPT_ITERATIONS: ++ if (arg > 0) ++ iteration_count = arg; ++ break; ++ case OPT_THREADS: ++ if (arg > 0 && arg < 100) ++ thread_count = arg; ++ break; ++ } ++} ++#define CMDLINE_PROCESS cmdline_process ++#define TIMEOUT 50 ++#include +diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h +index 1e2092a05d..05c94e7a71 100644 +--- a/sysdeps/nptl/bits/thread-shared-types.h ++++ b/sysdeps/nptl/bits/thread-shared-types.h +@@ -124,7 +124,27 @@ struct __pthread_mutex_s + unsigned int __nusers; + #endif + /* KIND must stay at this position in the structure to maintain +- binary compatibility with static initializers. */ ++ binary compatibility with static initializers. ++ ++ Concurrency notes: ++ The __kind of a mutex is initialized either by the static ++ PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init. ++ ++ After a mutex has been initialized, the __kind of a mutex is usually not ++ changed. BUT it can be set to -1 in pthread_mutex_destroy or elision can ++ be enabled. This is done concurrently in the pthread_mutex_*lock functions ++ by using the macro FORCE_ELISION. This macro is only defined for ++ architectures which supports lock elision. ++ ++ For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and ++ PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set ++ type of a mutex. ++ Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set ++ with pthread_mutexattr_settype. ++ After a mutex has been initialized, the functions pthread_mutex_*lock can ++ enable elision - if the mutex-type and the machine supports it - by setting ++ the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards ++ the lock / unlock functions are using specific elision code-paths. */ + int __kind; + __PTHREAD_COMPAT_PADDING_MID + #if __PTHREAD_MUTEX_NUSERS_AFTER_KIND +diff --git a/sysdeps/unix/sysv/linux/powerpc/force-elision.h b/sysdeps/unix/sysv/linux/powerpc/force-elision.h +index fe5d6ceade..d8f5a4b1c7 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/force-elision.h ++++ b/sysdeps/unix/sysv/linux/powerpc/force-elision.h +@@ -18,9 +18,45 @@ + + /* Automatically enable elision for existing user lock kinds. */ + #define FORCE_ELISION(m, s) \ +- if (__pthread_force_elision \ +- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ if (__pthread_force_elision) \ + { \ +- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ +- s; \ ++ /* See concurrency notes regarding __kind in \ ++ struct __pthread_mutex_s in \ ++ sysdeps/nptl/bits/thread-shared-types.h. \ ++ \ ++ There are the following cases for the kind of a mutex \ ++ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ ++ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ ++ only one of both flags can be set): \ ++ - both flags are not set: \ ++ This is the first lock operation for this mutex. Enable \ ++ elision as it is not enabled so far. \ ++ Note: It can happen that multiple threads are calling e.g. \ ++ pthread_mutex_lock at the same time as the first lock \ ++ operation for this mutex. Then elision is enabled for this \ ++ mutex by multiple threads. Storing with relaxed MO is enough \ ++ as all threads will store the same new value for the kind of \ ++ the mutex. But we have to ensure that we always use the \ ++ elision path regardless if this thread has enabled elision or \ ++ another one. \ ++ \ ++ - PTHREAD_MUTEX_ELISION_NP flag is set: \ ++ Elision was already enabled for this mutex by a previous lock \ ++ operation. See case above. Just use the elision path. \ ++ \ ++ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ ++ Elision was explicitly disabled by pthread_mutexattr_settype. \ ++ Do not use the elision path. \ ++ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ ++ changed after mutex initialization. */ \ ++ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ { \ ++ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ ++ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ ++ } \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ ++ { \ ++ s; \ ++ } \ + } +diff --git a/sysdeps/unix/sysv/linux/s390/force-elision.h b/sysdeps/unix/sysv/linux/s390/force-elision.h +index d8a1b9972f..71f32367dd 100644 +--- a/sysdeps/unix/sysv/linux/s390/force-elision.h ++++ b/sysdeps/unix/sysv/linux/s390/force-elision.h +@@ -18,9 +18,45 @@ + + /* Automatically enable elision for existing user lock kinds. */ + #define FORCE_ELISION(m, s) \ +- if (__pthread_force_elision \ +- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ if (__pthread_force_elision) \ + { \ +- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ +- s; \ ++ /* See concurrency notes regarding __kind in \ ++ struct __pthread_mutex_s in \ ++ sysdeps/nptl/bits/thread-shared-types.h. \ ++ \ ++ There are the following cases for the kind of a mutex \ ++ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ ++ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ ++ only one of both flags can be set): \ ++ - both flags are not set: \ ++ This is the first lock operation for this mutex. Enable \ ++ elision as it is not enabled so far. \ ++ Note: It can happen that multiple threads are calling e.g. \ ++ pthread_mutex_lock at the same time as the first lock \ ++ operation for this mutex. Then elision is enabled for this \ ++ mutex by multiple threads. Storing with relaxed MO is enough \ ++ as all threads will store the same new value for the kind of \ ++ the mutex. But we have to ensure that we always use the \ ++ elision path regardless if this thread has enabled elision or \ ++ another one. \ ++ \ ++ - PTHREAD_MUTEX_ELISION_NP flag is set: \ ++ Elision was already enabled for this mutex by a previous lock \ ++ operation. See case above. Just use the elision path. \ ++ \ ++ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ ++ Elision was explicitly disabled by pthread_mutexattr_settype. \ ++ Do not use the elision path. \ ++ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ ++ changed after mutex initialization. */ \ ++ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ { \ ++ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ ++ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ ++ } \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ ++ { \ ++ s; \ ++ } \ + } +diff --git a/sysdeps/unix/sysv/linux/x86/force-elision.h b/sysdeps/unix/sysv/linux/x86/force-elision.h +index dd659c908f..61282d6678 100644 +--- a/sysdeps/unix/sysv/linux/x86/force-elision.h ++++ b/sysdeps/unix/sysv/linux/x86/force-elision.h +@@ -18,9 +18,45 @@ + + /* Automatically enable elision for existing user lock kinds. */ + #define FORCE_ELISION(m, s) \ +- if (__pthread_force_elision \ +- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ if (__pthread_force_elision) \ + { \ +- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ +- s; \ ++ /* See concurrency notes regarding __kind in \ ++ struct __pthread_mutex_s in \ ++ sysdeps/nptl/bits/thread-shared-types.h. \ ++ \ ++ There are the following cases for the kind of a mutex \ ++ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \ ++ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \ ++ only one of both flags can be set): \ ++ - both flags are not set: \ ++ This is the first lock operation for this mutex. Enable \ ++ elision as it is not enabled so far. \ ++ Note: It can happen that multiple threads are calling e.g. \ ++ pthread_mutex_lock at the same time as the first lock \ ++ operation for this mutex. Then elision is enabled for this \ ++ mutex by multiple threads. Storing with relaxed MO is enough \ ++ as all threads will store the same new value for the kind of \ ++ the mutex. But we have to ensure that we always use the \ ++ elision path regardless if this thread has enabled elision or \ ++ another one. \ ++ \ ++ - PTHREAD_MUTEX_ELISION_NP flag is set: \ ++ Elision was already enabled for this mutex by a previous lock \ ++ operation. See case above. Just use the elision path. \ ++ \ ++ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \ ++ Elision was explicitly disabled by pthread_mutexattr_settype. \ ++ Do not use the elision path. \ ++ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \ ++ changed after mutex initialization. */ \ ++ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ { \ ++ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \ ++ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \ ++ } \ ++ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \ ++ { \ ++ s; \ ++ } \ + } + diff --git a/srcpkgs/glibc/patches/glibc-upstream-24.patch b/srcpkgs/glibc/patches/glibc-upstream-24.patch new file mode 100644 index 00000000000..a55dd72df1f --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-24.patch @@ -0,0 +1,53 @@ +From 69d1e73d99c6ad3f65fc16b6325d6ae289950d03 Mon Sep 17 00:00:00 2001 +From: "Ilya Yu. Malakhov" +Date: Mon, 22 Oct 2018 13:03:57 +0200 +Subject: [PATCH 24] signal: Use correct type for si_band in siginfo_t [BZ + #23562] + +(cherry picked from commit f997b4be18f7e57d757d39e42f7715db26528aa0) +--- + ChangeLog | 6 ++++++ + NEWS | 1 + + sysdeps/unix/sysv/linux/bits/types/siginfo_t.h | 2 +- + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 5b743f2fdb..7726438658 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2018-10-19 Ilya Yu. Malakhov ++ ++ [BZ #23562] ++ * sysdeps/unix/sysv/linux/bits/types/siginfo_t.h ++ (struct siginfo_t): Use correct type for si_band. ++ + 2018-10-17 Stefan Liebler + + [BZ #23275] +diff --git a/NEWS b/NEWS +index 594cecfc75..e95a0ea159 100644 +--- a/NEWS ++++ b/NEWS +@@ -13,6 +13,7 @@ The following bugs are resolved with this release: + [23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream + [23521] nss_files aliases database file stream leak + [23538] pthread_cond_broadcast: Fix waiters-after-spinning case ++ [23562] signal: Use correct type for si_band in siginfo_t + [23578] regex: Fix memory overread in re_compile_pattern + [23579] libc: Errors misreported in preadv2 + [23606] Missing ENDBR32 in sysdeps/i386/start.S +diff --git a/sysdeps/unix/sysv/linux/bits/types/siginfo_t.h b/sysdeps/unix/sysv/linux/bits/types/siginfo_t.h +index 33766d1813..43c4e009a4 100644 +--- a/sysdeps/unix/sysv/linux/bits/types/siginfo_t.h ++++ b/sysdeps/unix/sysv/linux/bits/types/siginfo_t.h +@@ -107,7 +107,7 @@ typedef struct + /* SIGPOLL. */ + struct + { +- long int si_band; /* Band event for SIGPOLL. */ ++ __SI_BAND_TYPE si_band; /* Band event for SIGPOLL. */ + int si_fd; + } _sigpoll; + + diff --git a/srcpkgs/glibc/patches/glibc-upstream-25.patch b/srcpkgs/glibc/patches/glibc-upstream-25.patch new file mode 100644 index 00000000000..ebc6316cf37 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-25.patch @@ -0,0 +1,111 @@ +From aff9b377121f9cfabe5d45f3226acf99c73928a7 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Fri, 26 Oct 2018 09:19:40 +0200 +Subject: [PATCH 25] conform: XFAIL siginfo_t si_band test on sparc64 + +We can use long int on sparcv9, but on sparc64, we must match the int +type used by the kernel (and not long int, as in POSIX). + +(cherry picked from commit 7c5e34d7f1b8f8f5acd94c2b885ae13b85414dcd) +--- + ChangeLog | 13 +++++++++++++ + NEWS | 1 + + conform/data/signal.h-data | 3 ++- + conform/data/sys/wait.h-data | 3 ++- + sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h | 7 ++++++- + sysdeps/unix/sysv/linux/sparc/sparc64/Makefile | 5 +++++ + 6 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7726438658..6debca5f83 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,16 @@ ++2018-10-25 Florian Weimer ++ ++ [BZ #23562] ++ [BZ #23821] ++ XFAIL siginfo_t si_band conform test on sparc64. ++ * sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h ++ (__SI_BAND_TYPE): Only override long int default type on sparc64. ++ * sysdeps/unix/sysv/linux/sparc/sparc64/Makefile ++ (conformtest-xfail-conds): Add sparc64-linux. ++ * conform/data/signal.h-data (siginfo_t): XFAIL si_band test on ++ sparc64. ++ * conform/data/sys/wait.h-data (siginfo_t): Likewise. ++ + 2018-10-19 Ilya Yu. Malakhov + + [BZ #23562] +diff --git a/NEWS b/NEWS +index e95a0ea159..fda6788519 100644 +--- a/NEWS ++++ b/NEWS +@@ -19,6 +19,7 @@ The following bugs are resolved with this release: + [23606] Missing ENDBR32 in sysdeps/i386/start.S + [23679] gethostid: Missing NULL check for gethostbyname_r result + [23717] Fix stack overflow in stdlib/tst-setcontext9 ++ [23821] si_band in siginfo_t has wrong type long int on sparc64 + + + Version 2.28 +diff --git a/conform/data/signal.h-data b/conform/data/signal.h-data +index 11e54adb04..674e5793db 100644 +--- a/conform/data/signal.h-data ++++ b/conform/data/signal.h-data +@@ -172,7 +172,8 @@ element siginfo_t pid_t si_pid + element siginfo_t uid_t si_uid + element siginfo_t {void*} si_addr + element siginfo_t int si_status +-element siginfo_t long si_band ++// Bug 23821: si_band has type int on sparc64. ++xfail[sparc64-linux]-element siginfo_t long si_band + # endif + # ifndef XPG42 + element siginfo_t {union sigval} si_value +diff --git a/conform/data/sys/wait.h-data b/conform/data/sys/wait.h-data +index ed3869b34f..c0761424da 100644 +--- a/conform/data/sys/wait.h-data ++++ b/conform/data/sys/wait.h-data +@@ -46,7 +46,8 @@ element siginfo_t pid_t si_pid + element siginfo_t uid_t si_uid + element siginfo_t {void*} si_addr + element siginfo_t int si_status +-element siginfo_t long si_band ++// Bug 23821: si_band has type int on sparc64. ++xfail[sparc64-linux]-element siginfo_t long si_band + # ifndef XPG42 + element siginfo_t {union sigval} si_value + # endif +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h b/sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h +index 9f79715ebe..4dd35237f6 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h +@@ -2,7 +2,12 @@ + #ifndef _BITS_SIGINFO_ARCH_H + #define _BITS_SIGINFO_ARCH_H 1 + +-#define __SI_BAND_TYPE int ++/* The kernel uses int instead of long int (as in POSIX). In 32-bit ++ mode, we can still use long int, but in 64-bit mode, we need to ++ deviate from POSIX. */ ++#if __WORDSIZE == 64 ++# define __SI_BAND_TYPE int ++#endif + + #define __SI_SIGFAULT_ADDL \ + int _si_trapno; +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile +index 715af3df7b..218c246f16 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile +@@ -7,3 +7,8 @@ LD += -melf64_sparc + ifeq ($(subdir),stdlib) + sysdep_routines += __start_context + endif ++ ++ifeq ($(subdir),conform) ++# For bug 23821 (incorrect type of si_band). ++conformtest-xfail-conds += sparc64-linux ++endif + diff --git a/srcpkgs/glibc/patches/glibc-upstream-26.patch b/srcpkgs/glibc/patches/glibc-upstream-26.patch new file mode 100644 index 00000000000..f4f096b3a67 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-26.patch @@ -0,0 +1,139 @@ +From 5256ffc51e4188a70fa0173cb6b6c94adde03fcb Mon Sep 17 00:00:00 2001 +From: Szabolcs Nagy +Date: Fri, 26 Oct 2018 14:39:42 +0100 +Subject: [PATCH 26] i64: fix missing exp2f, log2f and powf symbols in + libm.a [BZ #23822] + +When new symbol versions were introduced without SVID compatible +error handling the exp2f, log2f and powf symbols were accidentally +removed from the ia64 lim.a. The regression was introduced by +the commits + +f5f0f5265162fe6f4f238abcd3086985f7c38d6d +New expf and exp2f version without SVID compat wrapper + +72d3d281080be9f674982067d72874fd6cdb4b64 +New symbol version for logf, log2f and powf without SVID compat + +With WEAK_LIBM_ENTRY(foo), there is a hidden __foo and weak foo +symbol definition in both SHARED and !SHARED build. + + [BZ #23822] + * sysdeps/ia64/fpu/e_exp2f.S (exp2f): Use WEAK_LIBM_ENTRY. + * sysdeps/ia64/fpu/e_log2f.S (log2f): Likewise. + * sysdeps/ia64/fpu/e_exp2f.S (powf): Likewise. + +(cherry picked from commit ba5b14c7613980dfefcad6b6e88f913e5f596c59) +--- + ChangeLog | 7 +++++++ + NEWS | 1 + + sysdeps/ia64/fpu/e_exp2f.S | 6 +++--- + sysdeps/ia64/fpu/e_log2f.S | 6 +++--- + sysdeps/ia64/fpu/e_powf.S | 6 +++--- + 5 files changed, 17 insertions(+), 9 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 6debca5f83..73d5c57f0d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2018-10-26 Szabolcs Nagy ++ ++ [BZ #23822] ++ * sysdeps/ia64/fpu/e_exp2f.S (exp2f): Use WEAK_LIBM_ENTRY. ++ * sysdeps/ia64/fpu/e_log2f.S (log2f): Likewise. ++ * sysdeps/ia64/fpu/e_exp2f.S (powf): Likewise. ++ + 2018-10-25 Florian Weimer + + [BZ #23562] +diff --git a/NEWS b/NEWS +index fda6788519..f4d9885819 100644 +--- a/NEWS ++++ b/NEWS +@@ -20,6 +20,7 @@ The following bugs are resolved with this release: + [23679] gethostid: Missing NULL check for gethostbyname_r result + [23717] Fix stack overflow in stdlib/tst-setcontext9 + [23821] si_band in siginfo_t has wrong type long int on sparc64 ++ [23822] ia64 static libm.a is missing exp2f, log2f and powf symbols + + + Version 2.28 +diff --git a/sysdeps/ia64/fpu/e_exp2f.S b/sysdeps/ia64/fpu/e_exp2f.S +index 77bc6ea686..3010a95a2d 100644 +--- a/sysdeps/ia64/fpu/e_exp2f.S ++++ b/sysdeps/ia64/fpu/e_exp2f.S +@@ -221,7 +221,7 @@ LOCAL_OBJECT_END(T_table) + + + .section .text +-GLOBAL_LIBM_ENTRY(__exp2f) ++WEAK_LIBM_ENTRY(exp2f) + + + {.mfi +@@ -468,10 +468,10 @@ OUT_RANGE_exp2: + } + ;; + +-GLOBAL_LIBM_END(__exp2f) ++WEAK_LIBM_END(exp2f) + libm_alias_float_other (__exp2, exp2) + #ifdef SHARED +-.symver __exp2f,exp2f@@GLIBC_2.27 ++.symver exp2f,exp2f@@GLIBC_2.27 + .weak __exp2f_compat + .set __exp2f_compat,__exp2f + .symver __exp2f_compat,exp2f@GLIBC_2.2 +diff --git a/sysdeps/ia64/fpu/e_log2f.S b/sysdeps/ia64/fpu/e_log2f.S +index 5ca3bd61ea..e4ea094344 100644 +--- a/sysdeps/ia64/fpu/e_log2f.S ++++ b/sysdeps/ia64/fpu/e_log2f.S +@@ -252,7 +252,7 @@ LOCAL_OBJECT_END(T_table) + + + .section .text +-GLOBAL_LIBM_ENTRY(__log2f) ++WEAK_LIBM_ENTRY(log2f) + + { .mfi + alloc r32=ar.pfs,1,4,4,0 +@@ -491,10 +491,10 @@ SPECIAL_log2f: + br.ret.sptk b0;; + } + +-GLOBAL_LIBM_END(__log2f) ++WEAK_LIBM_END(log2f) + libm_alias_float_other (__log2, log2) + #ifdef SHARED +-.symver __log2f,log2f@@GLIBC_2.27 ++.symver log2f,log2f@@GLIBC_2.27 + .weak __log2f_compat + .set __log2f_compat,__log2f + .symver __log2f_compat,log2f@GLIBC_2.2 +diff --git a/sysdeps/ia64/fpu/e_powf.S b/sysdeps/ia64/fpu/e_powf.S +index 7449f8c7d5..945d5cdf28 100644 +--- a/sysdeps/ia64/fpu/e_powf.S ++++ b/sysdeps/ia64/fpu/e_powf.S +@@ -868,7 +868,7 @@ data8 0xEAC0C6E7DD24392F , 0x00003FFF + LOCAL_OBJECT_END(pow_tbl2) + + .section .text +-GLOBAL_LIBM_ENTRY(__powf) ++WEAK_LIBM_ENTRY(powf) + + // Get exponent of x. Will be used to calculate K. + { .mfi +@@ -2002,10 +2002,10 @@ POW_OVER_UNDER_ERROR: + } + ;; + +-GLOBAL_LIBM_END(__powf) ++WEAK_LIBM_END(powf) + libm_alias_float_other (__pow, pow) + #ifdef SHARED +-.symver __powf,powf@@GLIBC_2.27 ++.symver powf,powf@@GLIBC_2.27 + .weak __powf_compat + .set __powf_compat,__powf + .symver __powf_compat,powf@GLIBC_2.2 diff --git a/srcpkgs/glibc/template b/srcpkgs/glibc/template index d05ef598a42..e97a13077f9 100644 --- a/srcpkgs/glibc/template +++ b/srcpkgs/glibc/template @@ -1,7 +1,7 @@ # Template file for 'glibc' pkgname=glibc version=2.28 -revision=2 +revision=3 bootstrap=yes short_desc="The GNU C library" maintainer="Juan RP "