Blame SOURCES/glibc-rh1401665-5.patch

147e83
commit 5920a4a624b1f4db310d1c44997b640e2a4653e5
147e83
Author: Carlos O'Donell <carlos@redhat.com>
147e83
Date:   Sat Jul 29 00:02:03 2017 -0400
147e83
147e83
    mutex: Fix robust mutex lock acquire (Bug 21778)
147e83
    
147e83
    65810f0ef05e8c9e333f17a44e77808b163ca298 fixed a robust mutex bug but
147e83
    introduced BZ 21778: if the CAS used to try to acquire a lock fails, the
147e83
    expected value is not updated, which breaks other cases in the loce
147e83
    acquisition loop.  The fix is to simply update the expected value with
147e83
    the value returned by the CAS, which ensures that behavior is as if the
147e83
    first case with the CAS never happened (if the CAS fails).
147e83
    
147e83
    This is a regression introduced in the last release.
147e83
    
147e83
    Tested on x86_64, i686, ppc64, ppc64le, s390x, aarch64, armv7hl.
147e83
147e83
Index: glibc-2.17-c758a686/nptl/Makefile
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/nptl/Makefile
147e83
+++ glibc-2.17-c758a686/nptl/Makefile
147e83
@@ -204,7 +204,7 @@ CFLAGS-tst-thread-exit-clobber.o = -std=
147e83
 tests = tst-typesizes \
147e83
 	tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
147e83
 	tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
147e83
-	tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \
147e83
+	tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a tst-mutex7robust \
147e83
 	tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
147e83
 	tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
147e83
 	tst-mutexpi9 \
147e83
Index: glibc-2.17-c758a686/nptl/pthread_mutex_lock.c
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_lock.c
147e83
+++ glibc-2.17-c758a686/nptl/pthread_mutex_lock.c
147e83
@@ -198,11 +198,14 @@ __pthread_mutex_lock_full (pthread_mutex
147e83
 	{
147e83
 	  /* Try to acquire the lock through a CAS from 0 (not acquired) to
147e83
 	     our TID | assume_other_futex_waiters.  */
147e83
-	  if (__glibc_likely ((oldval == 0)
147e83
-			      && (atomic_compare_and_exchange_bool_acq
147e83
-				  (&mutex->__data.__lock,
147e83
-				   id | assume_other_futex_waiters, 0) == 0)))
147e83
-	      break;
147e83
+	  if (__glibc_likely (oldval == 0))
147e83
+	    {
147e83
+	      oldval
147e83
+	        = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
147e83
+	            id | assume_other_futex_waiters, 0);
147e83
+	      if (__glibc_likely (oldval == 0))
147e83
+		break;
147e83
+	    }
147e83
 
147e83
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
147e83
 	    {
147e83
Index: glibc-2.17-c758a686/nptl/pthread_mutex_timedlock.c
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_timedlock.c
147e83
+++ glibc-2.17-c758a686/nptl/pthread_mutex_timedlock.c
147e83
@@ -154,11 +154,14 @@ pthread_mutex_timedlock (pthread_mutex_t
147e83
 	{
147e83
 	  /* Try to acquire the lock through a CAS from 0 (not acquired) to
147e83
 	     our TID | assume_other_futex_waiters.  */
147e83
-	  if (__glibc_likely ((oldval == 0)
147e83
-			      && (atomic_compare_and_exchange_bool_acq
147e83
-				  (&mutex->__data.__lock,
147e83
-				   id | assume_other_futex_waiters, 0) == 0)))
147e83
-	      break;
147e83
+	  if (__glibc_likely (oldval == 0))
147e83
+	    {
147e83
+	      oldval
147e83
+	        = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
147e83
+	            id | assume_other_futex_waiters, 0);
147e83
+	      if (__glibc_likely (oldval == 0))
147e83
+		break;
147e83
+	    }
147e83
 
147e83
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
147e83
 	    {
147e83
Index: glibc-2.17-c758a686/nptl/tst-mutex7.c
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/nptl/tst-mutex7.c
147e83
+++ glibc-2.17-c758a686/nptl/tst-mutex7.c
147e83
@@ -22,25 +22,41 @@
147e83
 #include <stdlib.h>
147e83
 #include <time.h>
147e83
 
147e83
-
147e83
+/* This test is a template for other tests to use.  Other tests define
147e83
+   the following macros to change the behaviour of the template test.
147e83
+   The test is very simple, it configures N threads given the parameters
147e83
+   below and then proceeds to go through mutex lock and unlock
147e83
+   operations in each thread as described before for the thread
147e83
+   function.  */
147e83
 #ifndef TYPE
147e83
 # define TYPE PTHREAD_MUTEX_DEFAULT
147e83
 #endif
147e83
-
147e83
+#ifndef ROBUST
147e83
+# define ROBUST PTHREAD_MUTEX_STALLED
147e83
+#endif
147e83
+#ifndef DELAY_NSEC
147e83
+# define DELAY_NSEC 11000
147e83
+#endif
147e83
+#ifndef ROUNDS
147e83
+# define ROUNDS 1000
147e83
+#endif
147e83
+#ifndef N
147e83
+# define N 100
147e83
+#endif
147e83
 
147e83
 static pthread_mutex_t lock;
147e83
 
147e83
-
147e83
-#define ROUNDS 1000
147e83
-#define N 100
147e83
-
147e83
-
147e83
+/* Each thread locks and the subsequently unlocks the lock, yielding
147e83
+   the smallest critical section possible.  After the unlock the thread
147e83
+   waits DELAY_NSEC nanoseconds before doing the lock and unlock again.
147e83
+   Every thread does this ROUNDS times.  The lock and unlock are
147e83
+   checked for errors.  */
147e83
 static void *
147e83
 tf (void *arg)
147e83
 {
147e83
   int nr = (long int) arg;
147e83
   int cnt;
147e83
-  struct timespec ts = { .tv_sec = 0, .tv_nsec = 11000 };
147e83
+  struct timespec ts = { .tv_sec = 0, .tv_nsec = DELAY_NSEC };
147e83
 
147e83
   for (cnt = 0; cnt < ROUNDS; ++cnt)
147e83
     {
147e83
@@ -56,13 +72,16 @@ tf (void *arg)
147e83
 	  return (void *) 1l;
147e83
 	}
147e83
 
147e83
-      nanosleep (&ts, NULL);
147e83
+      if ((ts.tv_sec > 0) || (ts.tv_nsec > 0))
147e83
+	nanosleep (&ts, NULL);
147e83
     }
147e83
 
147e83
   return NULL;
147e83
 }
147e83
 
147e83
-
147e83
+/* Setup and run N threads, where each thread does as described
147e83
+   in the above thread function.  The threads are given a minimal 1MiB
147e83
+   stack since they don't do anything between the lock and unlock.  */
147e83
 static int
147e83
 do_test (void)
147e83
 {
147e83
@@ -80,6 +99,12 @@ do_test (void)
147e83
       exit (1);
147e83
     }
147e83
 
147e83
+  if (pthread_mutexattr_setrobust (&a, ROBUST) != 0)
147e83
+    {
147e83
+      puts ("mutexattr_setrobust failed");
147e83
+      exit (1);
147e83
+    }
147e83
+
147e83
 #ifdef ENABLE_PI
147e83
   if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
147e83
     {
147e83
Index: glibc-2.17-c758a686/nptl/tst-mutex7robust.c
147e83
===================================================================
147e83
--- /dev/null
147e83
+++ glibc-2.17-c758a686/nptl/tst-mutex7robust.c
147e83
@@ -0,0 +1,7 @@
147e83
+/* Bug 21778: Fix oversight in robust mutex lock acquisition.  */
147e83
+#define TYPE PTHREAD_MUTEX_NORMAL
147e83
+#define ROBUST PTHREAD_MUTEX_ROBUST
147e83
+#define DELAY_NSEC 0
147e83
+#define ROUNDS 1000
147e83
+#define N 32
147e83
+#include "tst-mutex7.c"