[COMMITTED,2.22] powerpc: Fix usage of elision transient failure adapt param
Commit Message
From: Paul Murphy <murphyp@linux.vnet.ibm.com>
The skip_lock_out_of_tbegin_retries adaptive parameter was
not being used correctly, nor as described. This prevents
a fallback for all users of the lock if a transient abort
occurs within the accepted number of retries.
[BZ #19174]
* sysdeps/powerpc/nptl/elide.h (__elide_lock): Fix usage of
.skip_lock_out_of_tbegin_retries.
* sysdeps/unix/sysv/linux/powerpc/elision-lock.c
(__lll_lock_elision): Likewise, and respect a value of
try_tbegin <= 0.
(cherry picked from commit 72f1463df85a522bfd1568e47bd81371522ee358)
Conflicts:
NEWS
---
ChangeLog | 9 +++++++++
NEWS | 2 +-
sysdeps/powerpc/nptl/elide.h | 6 +++---
sysdeps/unix/sysv/linux/powerpc/elision-lock.c | 15 ++++++---------
4 files changed, 19 insertions(+), 13 deletions(-)
@@ -1,3 +1,12 @@
+2015-12-17 Paul E. Murphy <murphyp@linux.vnet.ibm.com>
+
+ [BZ #19174]
+ * sysdeps/powerpc/nptl/elide.h (__elide_lock): Fix usage of
+ .skip_lock_out_of_tbegin_retries.
+ * sysdeps/unix/sysv/linux/powerpc/elision-lock.c
+ (__lll_lock_elision): Likewise, and respect a value of
+ try_tbegin <= 0.
+
2015-12-03 Andrew Senkevich <andrew.senkevich@intel.com>
* math/Makefile ($(inst_libdir)/libm.so): Corrected path to
@@ -10,7 +10,7 @@ Version 2.22.1
* The following bugs are resolved with this release:
18589, 18743, 18778, 18781, 18787, 18796, 18870, 18887, 18921, 18928,
- 18969, 19018, 19058, 19178.
+ 18969, 19018, 19058, 19174, 19178.
* The LD_POINTER_GUARD environment variable can no longer be used to
disable the pointer guard feature. It is always enabled.
@@ -27,7 +27,7 @@
configurations. Returns true if the system should retry again or false
otherwise. */
static inline bool
-__get_new_count (uint8_t *adapt_count)
+__get_new_count (uint8_t *adapt_count, int attempt)
{
/* A persistent failure indicates that a retry will probably
result in another failure. Use normal locking now and
@@ -40,7 +40,7 @@ __get_new_count (uint8_t *adapt_count)
}
/* Same logic as above, but for a number of temporary failures in a
a row. */
- else if (__elision_aconf.skip_lock_out_of_tbegin_retries > 0
+ else if (attempt <= 1 && __elision_aconf.skip_lock_out_of_tbegin_retries > 0
&& __elision_aconf.try_tbegin > 0)
*adapt_count = __elision_aconf.skip_lock_out_of_tbegin_retries;
return true;
@@ -78,7 +78,7 @@ __get_new_count (uint8_t *adapt_count)
__builtin_tabort (_ABORT_LOCK_BUSY); \
} \
else \
- if (!__get_new_count(&adapt_count)) \
+ if (!__get_new_count (&adapt_count,i)) \
break; \
} \
ret; \
@@ -72,8 +72,7 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
goto use_lock;
}
- int try_begin = aconf.try_tbegin;
- while (1)
+ for (int i = aconf.try_tbegin; i > 0; i--)
{
if (__builtin_tbegin (0))
{
@@ -87,21 +86,19 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
/* A persistent failure indicates that a retry will probably
result in another failure. Use normal locking now and
for the next couple of calls. */
- if (try_begin-- <= 0
- || _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
+ if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
{
if (aconf.skip_lock_internal_abort > 0)
*adapt_count = aconf.skip_lock_internal_abort;
goto use_lock;
}
- /* Same logic as above, but for for a number of temporary failures
- in a row. */
- else if (aconf.skip_lock_out_of_tbegin_retries > 0
- && aconf.try_tbegin > 0)
- *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
}
}
+ /* Fall back to locks for a bit if retries have been exhausted */
+ if (aconf.try_tbegin > 0 && aconf.skip_lock_out_of_tbegin_retries > 0)
+ *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
+
use_lock:
return LLL_LOCK ((*lock), pshared);
}