This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [RFC][PATCH] tunables: Add elision tunable
On 09/13/2017 03:42 PM, Gabriel F. T. Gomes wrote:
On 12 Sep 2017, Stefan Liebler wrote:
I've also used a small s390 specific test program to check wether a
mutex was elided or not:
./prog
Lock was a normal lock!
GLIBC_TUNABLES=glibc.elision.enable=0 ./prog
Lock was a normal lock!
GLIBC_TUNABLES=glibc.elision.enable=1 ./prog
Lock was elided via a transaction! (nesting-depth=1)
GLIBC_TUNABLES=glibc.elision.enable=1 ./prog_secure
Lock was a normal lock!
Would you be willing to share this test program (and your build
configurations)? I understand that it is s390-specific, but it could help
anyway (at least for my education, it will).
Yes sure, please see the notes in the attached file.
Bye
Stefan
//CFLAGS=-march=zEC12 -mzarch
/* We need at least zEC12 and zarch (on 31bit) for transaction instructions! */
//LDFLAGS=-lpthread
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <htmintrin.h> //for builtin_tx_nesting_depth
//https://gcc.gnu.org/onlinedocs/gcc/S_002f390-System-z-Built-in-Functions.html#S_002f390-System-z-Built-in-Functions
#include <sys/auxv.h>
#include <unistd.h>
#include <sys/types.h>
/* Note:
You have to use configure flag --enable-lock-elision.
Then transactions are always used (before the tunables patch).
stli@xyz:# GLIBC_TUNABLES=glibc.elision.enable=1 ./isintransaction-s390x.new
uid=12345; euid=12345
Lock was elided via a transaction!
Testing setuid:
root@xyz:# cp isintransaction-s390x isintransaction-s390x_suid
root@xyz:# chown root:root isintransaction-s390x_suid
root@xyz:# chmod +s isintransaction-s390x_suid
root@:# ls -lah
-rwxrwxr-x 1 stli stli 142K Mar 31 09:33 isintransaction-s390x
-rwsrwsr-x 1 root root 142K Mar 31 09:34 isintransaction-s390x_suid
=> Run isintransaction-s390x_suid as e.g. user stli and no transactions
should be used even if you enabled it!
stli@xyz:# GLIBC_TUNABLES=glibc.elision.enable=1 ./isintransaction-s390x_suid
uid=12345; euid=0
Lock was a normal lock!
*/
#define GETNESTINGDEPTH(var) \
({ \
__asm__ (".machine push \n\t" \
".machine \"all\""); \
var = __builtin_tx_nesting_depth (); \
__asm__ (".machine pop"); \
})
int
main (void)
{
uid_t uid = getuid ();
uid_t euid = geteuid ();
printf ("uid=%d; euid=%d\n", (int) uid, (int) euid);
int have_te = (getauxval (AT_HWCAP) & HWCAP_S390_TE) ? 1 : 0;
if (have_te == 0)
puts ("This machine do not support transactional execution!\n"
"You need a >= zEC12 lpar or z/VM >= 6.4!\n");
pthread_mutex_t testlock;
if (pthread_mutex_init (&testlock, NULL) != 0)
{
printf("mutex init failed: %m \n");
return EXIT_FAILURE;
}
int nestdepthInLock = -1;
if (pthread_mutex_lock (&testlock))
{
printf ("LOCK failed: %m\n");
return EXIT_FAILURE;
}
if (have_te)
GETNESTINGDEPTH (nestdepthInLock);
if (pthread_mutex_unlock (&testlock))
{
printf ("UNLOCK failed %m\n");
return EXIT_FAILURE;
}
/* Note: a transaction can also be aborted even if lock-elision is available.
If the lock should be elided but was not, then try again and set a debug
the transaction fallback path. */
if (nestdepthInLock > 0)
printf ("Lock was elided via a transaction! (nesting-depth=%d)\n",
nestdepthInLock);
else if (nestdepthInLock < 0)
puts ("Nesting-depth could not be determined!");
else
puts ("Lock was a normal lock!");
if (pthread_mutex_destroy (&testlock))
{
printf("mutex destroy failed: %m \n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}