From patchwork Mon Aug 27 20:54:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 145218 Delivered-To: patch@linaro.org Received: by 2002:a2e:1648:0:0:0:0:0 with SMTP id 8-v6csp388439ljw; Mon, 27 Aug 2018 13:54:29 -0700 (PDT) X-Google-Smtp-Source: ANB0VdZUkHTameoevzWP8n/QMD88tyIsUOxh8y4ZRtStXFirL9Fm6x8EUO3TCsrOlZXgws+hQ2Jo X-Received: by 2002:a63:2acc:: with SMTP id q195-v6mr13510119pgq.291.1535403268863; Mon, 27 Aug 2018 13:54:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535403268; cv=none; d=google.com; s=arc-20160816; b=iyNj6qK104kuJEcL/+YhlglC7hCxXYp/2EdGwrU3KVUn9k++X0lf7zNmNS44Xqc7KJ HB+sgnxEP8J9limPQk13AIUezBT9bn/3Y6kprVvVxNCr8GXI8Kor2+OT1kTO2U5XGYwA o2iuRglF7eOff3j9I5iUpaKviSfirUcrsNTjwZI8ZvZMUv0wPVlZAcuzFtaCkyeTn2lW y92b56hkBeH667s18ocGLXcTPu6pUcPi7+/hdVtT2k5utHwlauAIF35VxiBc/DTdub87 hb0lgaEYojCq9j6rKOw7spQKZar103qJpetWcasAa2+x6kK5sjo/WwghREp2zhETaKzE fL9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dkim-signature:delivered-to:sender:list-help:list-post :list-archive:list-subscribe:list-unsubscribe:list-id:precedence :mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=eISgaDV/55/MKDczC82gkZkYidvi4cXKBRYnoaVNysQ=; b=kjaKgKBlYx/ZsVL/Ra7SVHHGc4ojE8j3hdOi5Cu2v0TqtN+K4+iSTrFitsPVydQ38I HQcj3h7yms6/wlpCnaeBpxiKcWgytm0U8kCOrHokBO1LTqx+OW4bKmL83VtgYOg2npBw cRC0QAjcQjM/f8SYZTQIjq/cPmfgIMxD9zSuKD6F9A+nVdclj7J/AJrqvaSnZmYILoPq 3MJs7XpfDvNttyjLZj0F28RswL8w2N5neDZLRIm5BQnaw71nm6nh+n0rion0e3Ha4BIJ mNKRr40cM8awcjWw8zUBUG3TWC4uEri/UgevoK2iDAG6O46Bo5+AzREe3cWmQh/nZJJE St5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=ws7AdvIp; dkim=pass header.i=@linaro.org header.s=google header.b=C3AcGv4Q; spf=pass (google.com: domain of libc-alpha-return-95529-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-95529-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id o21-v6si263262pgl.165.2018.08.27.13.54.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Aug 2018 13:54:28 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-95529-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=ws7AdvIp; dkim=pass header.i=@linaro.org header.s=google header.b=C3AcGv4Q; spf=pass (google.com: domain of libc-alpha-return-95529-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-95529-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id :mime-version:content-type:content-transfer-encoding; q=dns; s= default; b=nz4iZcpmbyn9ioNF0q17hU/wSwmURAxd7J2d1E1SPFpJphV4x+Tce DFlV1026qv78TTaNhJD2IZXT/WyiaFTyYt9XMcMOe2fxj/2RtIBZzlG8krWzMu8e cI3Tx7UIdjBsEhYlM+rmeD6ZAG16x31Z6jfrjW9TXYc5+5xAc2m9Vs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id :mime-version:content-type:content-transfer-encoding; s=default; bh=ob+WnikzHsevrg+FNHmNINdAlkY=; b=ws7AdvIpUzB5tTu94+6Gzn+o1D5P MXcQzdPZamHYiyRvOtskCP4LJO1KlHYVGLXueM2TLfV+eYW75Q6dskEfC2WkvOXI Dg7SRLqWOMHKdo9HG6K/EwLUX217jTQ/NOu85bOjrJ0TdZkLqQVv6U8Uh9gDfbMa /sBXLFrbofDa1Sw= Received: (qmail 127409 invoked by alias); 27 Aug 2018 20:54:19 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 127399 invoked by uid 89); 27 Aug 2018 20:54:19 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SEM_URI, SEM_URIRED, SPF_PASS, URIBL_RED autolearn=ham version=3.3.2 spammy=transactions, capable, initiated, issuing X-HELO: mail-qt0-f194.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=eISgaDV/55/MKDczC82gkZkYidvi4cXKBRYnoaVNysQ=; b=C3AcGv4QBe9m5eCHmvf4G8XX9ftp19JicHC2okrgqX1pq1OiVr8nt5kE+12613BuYp KR3MdGUFd8I5od7YwZuGLfACIGXORfqg9Bf4TIfy2AoP7fhMJHrGzjqHGVDTiwqUsKoq sZpdd6SOaglrIiG2wEGe8V3auH6SpoGMxSQFM= Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Breno Leitao Subject: [PATCH] powerpc: Only enable TLE with PPC_FEATURE2_HTM_NOSC Date: Mon, 27 Aug 2018 17:54:07 -0300 Message-Id: <1535403247-27306-1-git-send-email-adhemerval.zanella@linaro.org> MIME-Version: 1.0 Linux from 3.9 through 4.2 does not abort HTM transaction on syscalls, instead it suspend and resume it when leaving the kernel. The side-effects of the syscall will always remain visible, even if the transaction is aborted. This is an issue when transaction is used along with futex syscall, on pthread_cond_wait for instance, where the futex call might succeed but the transaction is rolled back leading the pthread_cond object in an inconsistent state. GLIBC used to prevent it by always aborting a transaction before issuing a syscall. Linux 4.2 also decided to abort active transaction in syscalls which makes the GLIBC workaround superflours. Worse, GLIBC transaction abortion leads to a performance issue on recent kernels where the HTM state is saved/restore lazilyi (v4.9). By aborting a transaction on every syscalls, regardless whether a transaction has being initiated before, GLIBS makes the kernel always save/restore HTM state (it can not even lazily disable it after a certain number of syscall iterations). Because of this shortcoming, Lock Elision is just enabled when it has been explictly set (either by tunables of by a configure switch) and if kernel aborts HTM transactions on syscalls (PPC_FEATURE2_HTM_NOSC). It is reported that using simple benchmark [1], the context-switch is about 5% faster by not issuing a tabort in every syscall in newer kernels. Checked on powerpc64le-linux-gnu with 4.4.0 kernel (Ubuntu 16.04). * sysdeps/powerpc/nptl/tcb-offsets.sym (TM_CAPABLE): Remove. * sysdeps/powerpc/nptl/tls.h (tcbhead_t): Rename tm_capable to __ununsed1. (TLS_INIT_TP, TLS_DEFINE_INIT_TP): Remove tm_capable setup. (THREAD_GET_TM_CAPABLE, THREAD_SET_TM_CAPABLE): Remove macros. * sysdeps/powerpc/powerpc32/sysdep.h, sysdeps/powerpc/powerpc64/sysdep.h (ABORT_TRANSACTION_IMPL, ABORT_TRANSACTION): Remove macros. * sysdeps/powerpc/sysdep.h (ABORT_TRANSACTION): Likewise. * sysdeps/unix/sysv/linux/powerpc/elision-conf.c (elision_init): Set __pthread_force_elision iff PPC_FEATURE2_HTM_NOSC is set. * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h, sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h sysdeps/unix/sysv/linux/powerpc/syscall.S (ABORT_TRANSACTION): Remove usage. Reported-by: Breno Leitão [1] https://github.com/gromero/tabort --- ChangeLog | 18 ++++++++++++++++ sysdeps/powerpc/nptl/tcb-offsets.sym | 1 - sysdeps/powerpc/nptl/tls.h | 13 +----------- sysdeps/powerpc/powerpc32/sysdep.h | 17 --------------- sysdeps/powerpc/powerpc64/sysdep.h | 17 --------------- sysdeps/powerpc/sysdep.h | 20 ------------------ sysdeps/unix/sysv/linux/powerpc/elision-conf.c | 24 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h | 1 - sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h | 1 - sysdeps/unix/sysv/linux/powerpc/syscall.S | 1 - 10 files changed, 43 insertions(+), 70 deletions(-) -- 2.7.4 Acked-by: Gustavo Romero Reported-by: Breno Leitão diff --git a/ChangeLog b/ChangeLog index 157689f..8bf4029 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2018-08-27 Adhemerval Zanella + + * sysdeps/powerpc/nptl/tcb-offsets.sym (TM_CAPABLE): Remove. + * sysdeps/powerpc/nptl/tls.h (tcbhead_t): Rename tm_capable to + __ununsed1. + (TLS_INIT_TP, TLS_DEFINE_INIT_TP): Remove tm_capable setup. + (THREAD_GET_TM_CAPABLE, THREAD_SET_TM_CAPABLE): Remove macros. + * sysdeps/powerpc/powerpc32/sysdep.h, + sysdeps/powerpc/powerpc64/sysdep.h (ABORT_TRANSACTION_IMPL, + ABORT_TRANSACTION): Remove macros. + * sysdeps/powerpc/sysdep.h (ABORT_TRANSACTION): Likewise. + * sysdeps/unix/sysv/linux/powerpc/elision-conf.c (elision_init): Set + __pthread_force_elision iff PPC_FEATURE2_HTM_NOSC is set. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h, + sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h + sysdeps/unix/sysv/linux/powerpc/syscall.S (ABORT_TRANSACTION): Remove + usage. + 2018-08-27 Joseph Myers * sysdeps/generic/math-tests-trap-force.h: New file. diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym index e5bb2b3..4c01615 100644 --- a/sysdeps/powerpc/nptl/tcb-offsets.sym +++ b/sysdeps/powerpc/nptl/tcb-offsets.sym @@ -21,7 +21,6 @@ DSO_SLOT2 (offsetof (tcbhead_t, dso_slot2) - TLS_TCB_OFFSET - sizeof (tcbhead_ #ifdef __powerpc64__ TCB_AT_PLATFORM (offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) #endif -TM_CAPABLE (offsetof (tcbhead_t, tm_capable) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) #ifndef __powerpc64__ TCB_AT_PLATFORM (offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) PADDING (offsetof (tcbhead_t, padding) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h index f88fed5..8db970d 100644 --- a/sysdeps/powerpc/nptl/tls.h +++ b/sysdeps/powerpc/nptl/tls.h @@ -67,8 +67,7 @@ typedef struct uint32_t padding; uint32_t at_platform; #endif - /* Indicate if HTM capable (ISA 2.07). */ - uint32_t tm_capable; + uint32_t __unused1; /* Reservation for AT_PLATFORM data - powerpc64. */ #ifdef __powerpc64__ uint32_t at_platform; @@ -142,7 +141,6 @@ register void *__thread_register __asm__ ("r13"); # define TLS_INIT_TP(tcbp) \ ({ \ __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET; \ - THREAD_SET_TM_CAPABLE (__tcb_hwcap & PPC_FEATURE2_HAS_HTM ? 1 : 0); \ THREAD_SET_HWCAP (__tcb_hwcap); \ THREAD_SET_AT_PLATFORM (__tcb_platform); \ NULL; \ @@ -151,8 +149,6 @@ register void *__thread_register __asm__ ("r13"); /* Value passed to 'clone' for initialization of the thread register. */ # define TLS_DEFINE_INIT_TP(tp, pd) \ void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE; \ - (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].tm_capable) = \ - THREAD_GET_TM_CAPABLE (); \ (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].hwcap) = \ THREAD_GET_HWCAP (); \ (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].at_platform) = \ @@ -210,13 +206,6 @@ register void *__thread_register __asm__ ("r13"); + TLS_PRE_TCB_SIZE))[-1].pointer_guard \ = THREAD_GET_POINTER_GUARD()) -/* tm_capable field in TCB head. */ -# define THREAD_GET_TM_CAPABLE() \ - (((tcbhead_t *) ((char *) __thread_register \ - - TLS_TCB_OFFSET))[-1].tm_capable) -# define THREAD_SET_TM_CAPABLE(value) \ - (THREAD_GET_TM_CAPABLE () = (value)) - /* hwcap field in TCB head. */ # define THREAD_GET_HWCAP() \ (((tcbhead_t *) ((char *) __thread_register \ diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h index 5f1294e..93097c5 100644 --- a/sysdeps/powerpc/powerpc32/sysdep.h +++ b/sysdeps/powerpc/powerpc32/sysdep.h @@ -90,24 +90,7 @@ GOT_LABEL: ; \ cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) -#if !IS_IN(rtld) && !defined(__SPE__) -# define ABORT_TRANSACTION_IMPL \ - cmpwi 2,0; \ - beq 1f; \ - lwz 0,TM_CAPABLE(2); \ - cmpwi 0,0; \ - beq 1f; \ - li 11,_ABORT_SYSCALL; \ - tabort. 11; \ - .align 4; \ -1: -#else -# define ABORT_TRANSACTION_IMPL -#endif -#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL - #define DO_CALL(syscall) \ - ABORT_TRANSACTION \ li 0,syscall; \ sc diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h index 2df1d9b..50e64f9 100644 --- a/sysdeps/powerpc/powerpc64/sysdep.h +++ b/sysdeps/powerpc/powerpc64/sysdep.h @@ -263,24 +263,7 @@ LT_LABELSUFFIX(name,_name_end): ; \ TRACEBACK_MASK(name,mask); \ END_2(name) -#if !IS_IN(rtld) -# define ABORT_TRANSACTION_IMPL \ - cmpdi 13,0; \ - beq 1f; \ - lwz 0,TM_CAPABLE(13); \ - cmpwi 0,0; \ - beq 1f; \ - li 11,_ABORT_SYSCALL; \ - tabort. 11; \ - .p2align 4; \ -1: -#else -# define ABORT_TRANSACTION_IMPL -#endif -#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL - #define DO_CALL(syscall) \ - ABORT_TRANSACTION \ li 0,syscall; \ sc diff --git a/sysdeps/powerpc/sysdep.h b/sysdeps/powerpc/sysdep.h index 8a6d236..c8bf25e 100644 --- a/sysdeps/powerpc/sysdep.h +++ b/sysdeps/powerpc/sysdep.h @@ -21,8 +21,6 @@ */ #define _SYSDEPS_SYSDEP_H 1 #include -#include -#include #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC) @@ -166,22 +164,4 @@ #define ALIGNARG(log2) log2 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name -#else - -/* Linux kernel powerpc documentation [1] states issuing a syscall inside a - transaction is not recommended and may lead to undefined behavior. It - also states syscalls do not abort transactions. To avoid such traps, - we abort transaction just before syscalls. - - [1] Documentation/powerpc/transactional_memory.txt [Syscalls] */ -#if !IS_IN(rtld) && !defined(__SPE__) -# define ABORT_TRANSACTION \ - ({ \ - if (THREAD_GET_TM_CAPABLE ()) \ - __libc_tabort (_ABORT_SYSCALL); \ - }) -#else -# define ABORT_TRANSACTION -#endif - #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c index 906882a..508b917 100644 --- a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +++ b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c @@ -127,6 +127,30 @@ elision_init (int argc __attribute__ ((unused)), TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort)); #endif + /* Linux from 3.9 through 4.2 does not abort HTM transaction on syscalls, + instead it suspend and resume it when leaving the kernel. The + side-effects of the syscall will always remain visible, even if the + transaction is aborted. This is an issue when transaction is used along + with futex syscall, on pthread_cond_wait for instance, where the futex + call might succeed but the transaction is rolled back leading the + pthread_cond object in an inconsistent state. + + GLIBC used to prevent it by always aborting a transaction before issuing + a syscall. Linux 4.2 also decided to abort active transaction in + syscalls which makes the GLIBC workaround superflours. Worse, GLIBC + transaction abortion leads to a performance issue on recent kernels + where the HTM state is saved/restore lazily. By aborting a transaction + on every syscalls, regardless whether a transaction has being initiated + before, glibc make the kernel always save/restore HTM state (it can not + even lazily disable it after a certain number of syscall iterations). + + Because of this shortcoming, Lock Elision is just enabled when it has + been explictly set (either by tunables of by a configure switch) and if + kernel aborts HTM transactions on syscalls (PPC_FEATURE2_HTM_NOSC) */ + + __pthread_force_elision = __pthread_force_elision && + GLRO (dl_hwcap2) & PPC_FEATURE2_HTM_NOSC; + if (!__pthread_force_elision) __elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks. */ } diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index f7277d5..ec5c525 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -109,7 +109,6 @@ register long int r11 __asm__ ("r11"); \ register long int r12 __asm__ ("r12"); \ LOADARGS_##nr(name, args); \ - ABORT_TRANSACTION; \ __asm__ __volatile__ \ ("sc \n\t" \ "mfcr %0" \ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h index 0956cf0..1f17f7b 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h @@ -131,7 +131,6 @@ register long int r7 __asm__ ("r7"); \ register long int r8 __asm__ ("r8"); \ LOADARGS_##nr (name, ##args); \ - ABORT_TRANSACTION; \ __asm__ __volatile__ \ ("sc\n\t" \ "mfcr %0\n\t" \ diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S index 2da9172..bbab613 100644 --- a/sysdeps/unix/sysv/linux/powerpc/syscall.S +++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S @@ -18,7 +18,6 @@ #include ENTRY (syscall) - ABORT_TRANSACTION mr r0,r3 mr r3,r4 mr r4,r5