From patchwork Wed Apr 25 11:27:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Liebler X-Patchwork-Id: 904139 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-91812-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="A52iCDBp"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40WHxJ4C1Hz9s0t for ; Wed, 25 Apr 2018 21:27:48 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:from:subject:date:mime-version:content-type :message-id; q=dns; s=default; b=qudG8dRLcEIGMLae/9eVJbSwMzVMrxo 2s9pxEPpKVbczCJmLxL38/8OcZz5fgey4H3OH6JNLu3jJm4olXmd9XvbgE9cN9pN MMHjK3Uzfkd2TKRCG7aymu3igb2t4pAZK2gvxCDfOkomOzRBiugNYoX8Tq3NLJfB MwnlqC4IfeuQ= 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:to:from:subject:date:mime-version:content-type :message-id; s=default; bh=e6qHr1cX0E2WXtaBGiRHy084/6M=; b=A52iC DBpdeSCbtx+VTDNJgo7Eux4AzyosSpog20SwjRqB3uO/fp4ydPCyVABPXSwUHQgJ B71YsFTc6f65JVMQQarRnrJHWttZk8tdeNTc9iWkuRLieLh/YnV6ir1zCxT52gJo fr/HLpbFU17zbJvdGPnpceWBc3UifmU2QLMFyc= Received: (qmail 90188 invoked by alias); 25 Apr 2018 11:27:16 -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 90013 invoked by uid 89); 25 Apr 2018 11:27:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=Stefan X-HELO: mx0a-001b2d01.pphosted.com To: GNU C Library From: Stefan Liebler Subject: [PATCH]: Fix blocking pthread_join. Date: Wed, 25 Apr 2018 13:27:07 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 18042511-0008-0000-0000-000004EEFC74 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18042511-0009-0000-0000-00001E832EFF Message-Id: <8aeb7b8b-6b1e-9a60-e961-75cde1aa463b@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-04-25_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1804250109 Hi, On s390 (31bit) if glibc is build with -Os, pthread_join sometimes blocks indefinitely. This is e.g. observable with testcase intl/tst-gettext6. pthread_join is calling lll_wait_tid(tid), which performs the futex-wait syscall in a loop as long as tid != 0 (thread is alive). On s390 (and build with -Os), tid is loaded from memory before comparing against zero and then the tid is loaded a second time in order to pass it to the futex-wait-syscall. If the thread exits in between, then the futex-wait-syscall is called with the value zero and it waits until a futex-wake occurs. As the thread is already exited, there won't be a futex-wake. In lll_wait_tid, the tid is stored to the local variable __tid, which is then used as argument for the futex-wait-syscall. But unfortunately the compiler is allowed to reload the value from memory. With this patch, the tid is loaded by dereferencing a volatile pointer. Then the compiler is not allowed to reload the value for __tid from memory. Okay to commit? Bye Stefan Reviewed-by: Carlos O'Donell --- ChangeLog: * sysdeps/nptl/lowlevellock.h (lll_wait_tid): Use a volatile pointer to load __tid. commit be2e80e32fa4d0c7f7d021f550d21ab102aa8c42 Author: Stefan Liebler Date: Wed Apr 25 12:51:27 2018 +0200 Fix blocking pthread_join. On s390 (31bit) if glibc is build with -Os, pthread_join sometimes blocks indefinitely. This is e.g. observable with testcase intl/tst-gettext6. pthread_join is calling lll_wait_tid(tid), which performs the futex-wait syscall in a loop as long as tid != 0 (thread is alive). On s390 (and build with -Os), tid is loaded from memory before comparing against zero and then the tid is loaded a second time in order to pass it to the futex-wait-syscall. If the thread exits in between, then the futex-wait-syscall is called with the value zero and it waits until a futex-wake occurs. As the thread is already exited, there won't be a futex-wake. In lll_wait_tid, the tid is stored to the local variable __tid, which is then used as argument for the futex-wait-syscall. But unfortunately the compiler is allowed to reload the value from memory. With this patch, the tid is loaded by dereferencing a volatile pointer. Then the compiler is not allowed to reload the value for __tid from memory. ChangeLog: * sysdeps/nptl/lowlevellock.h (lll_wait_tid): Use a volatile pointer to load __tid. diff --git a/sysdeps/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h index 8326e2805c..6e06e8498a 100644 --- a/sysdeps/nptl/lowlevellock.h +++ b/sysdeps/nptl/lowlevellock.h @@ -184,7 +184,7 @@ extern int __lll_timedlock_wait (int *futex, const struct timespec *, #define lll_wait_tid(tid) \ do { \ __typeof (tid) __tid; \ - while ((__tid = (tid)) != 0) \ + while ((__tid = *(volatile __typeof(tid) *) &(tid)) != 0) \ lll_futex_wait (&(tid), __tid, LLL_SHARED);\ } while (0)