glibc: update upstream patches

This commit is contained in:
maxice8 2018-10-30 15:57:51 -03:00 committed by maxice8
parent bf1e08a93b
commit 6150038d3a
8 changed files with 1335 additions and 1 deletions

View File

@ -237,3 +237,4 @@ index 42da321149..17ea905aa6 100644
return result;
#endif
/* Trying to emulate the pwritev2 syscall flags is troublesome:

View File

@ -0,0 +1,69 @@
From 5473739a7b44f27965b70d1acf480f5f72603e78 Mon Sep 17 00:00:00 2001
From: Rafal Luzynski <digitalfreak@lingonborough.com>
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 <digitalfreak@lingonborough.com>
+
+ [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 <adhemerval.zanella@linaro.org>
[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";/

View File

@ -0,0 +1,161 @@
From 5a74abda201907cafbdabd1debf98890313ff71e Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
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 <hjl.tools@gmail.com>
(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 <hongjiu.lu@intel.com>
+
+ [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 <digitalfreak@lingonborough.com>
[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
- <http://www.gnu.org/licenses/>. */
-
-
-#define LINKAGE static inline
-#define _dl_cet_check cet_check
-#include <sysdeps/x86/dl-cet.c>
-#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;

View File

@ -0,0 +1,800 @@
From 314e181dc90cb290942d8b2b57823306ae956696 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.ibm.com>
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 <stli@linux.ibm.com>
+
+ [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 <hongjiu.lu@intel.com>
[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
+ <http://www.gnu.org/licenses/>. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <support/support.h>
+#include <support/xthread.h>
+
+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 <support/test-driver.c>
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; \
+ } \
}

View File

@ -0,0 +1,53 @@
From 69d1e73d99c6ad3f65fc16b6325d6ae289950d03 Mon Sep 17 00:00:00 2001
From: "Ilya Yu. Malakhov" <malakhov@mcst.ru>
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 <malakhov@mcst.ru>
+
+ [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 <stli@linux.ibm.com>
[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;

View File

@ -0,0 +1,111 @@
From aff9b377121f9cfabe5d45f3226acf99c73928a7 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
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 <fweimer@redhat.com>
+
+ [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 <malakhov@mcst.ru>
[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

View File

@ -0,0 +1,139 @@
From 5256ffc51e4188a70fa0173cb6b6c94adde03fcb Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
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 <szabolcs.nagy@arm.com>
+
+ [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 <fweimer@redhat.com>
[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

View File

@ -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 <xtraeme@voidlinux.eu>"