From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030753AbbD1ReP (ORCPT ); Tue, 28 Apr 2015 13:34:15 -0400 Received: from mail-am1on0096.outbound.protection.outlook.com ([157.56.112.96]:5632 "EHLO emea01-am1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1030479AbbD1ReM (ORCPT ); Tue, 28 Apr 2015 13:34:12 -0400 Authentication-Results: spf=fail (sender IP is 12.216.194.146) smtp.mailfrom=ezchip.com; redhat.com; dkim=none (message not signed) header.d=none; From: Chris Metcalf To: Peter Zijlstra CC: Chris Metcalf , "Paul E. McKenney" , Manfred Spraul , "Oleg Nesterov" , Kirill Tkhai , , Ingo Molnar , "Josh Poimboeuf" Subject: [PATCH 1/2] tile: modify arch_spin_unlock_wait() semantics Date: Tue, 28 Apr 2015 13:33:56 -0400 Message-ID: <1430242437-19938-1-git-send-email-cmetcalf@ezchip.com> X-Mailer: git-send-email 2.1.2 In-Reply-To: <20150428162458.GI5029@twins.programming.kicks-ass.net> X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:12.216.194.146;CTRY:US;IPV:NLI;EFV:NLI;BMV:1;SFV:NSPM;SFS:(10009020)(6009001)(339900001)(199003)(189002)(77156002)(62966003)(104016003)(47776003)(105606002)(33646002)(50466002)(19580395003)(229853001)(50986999)(106466001)(6806004)(19580405001)(42186005)(46102003)(36756003)(110136001)(92566002)(2950100001)(85426001)(86362001)(87936001)(50226001)(48376002);DIR:OUT;SFP:1101;SCL:1;SRVR:HE1PR02MB0777;H:ld-1.internal.tilera.com;FPR:;SPF:Fail;MLV:sfv;A:1;MX:1;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HE1PR02MB0777; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(5002010)(5005006)(3002001);SRVR:HE1PR02MB0777;BCL:0;PCL:0;RULEID:;SRVR:HE1PR02MB0777; X-Forefront-PRVS: 0560A2214D X-OriginatorOrg: ezchip.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Apr 2015 17:34:07.0182 (UTC) X-MS-Exchange-CrossTenant-Id: 0fc16e0a-3cd3-4092-8b2f-0a42cff122c3 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0fc16e0a-3cd3-4092-8b2f-0a42cff122c3;Ip=[12.216.194.146];Helo=[ld-1.internal.tilera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR02MB0777 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Rather than trying to wait until all possible lockers have unlocked the lock, we now only wait until the current locker (if any) has released the lock. The old code was correct, but the new code works more like the x86 code and thus hopefully is more appropriate under contention. See commit 78bff1c8684f ("x86/ticketlock: Fix spin_unlock_wait() livelock") for x86. Signed-off-by: Chris Metcalf --- arch/tile/lib/spinlock_32.c | 11 ++++++++++- arch/tile/lib/spinlock_64.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/tile/lib/spinlock_32.c b/arch/tile/lib/spinlock_32.c index b34f79aada48..c3df3c237496 100644 --- a/arch/tile/lib/spinlock_32.c +++ b/arch/tile/lib/spinlock_32.c @@ -65,8 +65,17 @@ EXPORT_SYMBOL(arch_spin_trylock); void arch_spin_unlock_wait(arch_spinlock_t *lock) { u32 iterations = 0; - while (arch_spin_is_locked(lock)) + int current = READ_ONCE(lock->current_ticket); + int next = READ_ONCE(lock->next_ticket); + + /* Return immediately if unlocked. */ + if (next == current) + return; + + /* Wait until the current locker has released the lock. */ + do { delay_backoff(iterations++); + } while (READ_ONCE(lock->current_ticket) == current) } EXPORT_SYMBOL(arch_spin_unlock_wait); diff --git a/arch/tile/lib/spinlock_64.c b/arch/tile/lib/spinlock_64.c index d6fb9581e980..aaf12813d4db 100644 --- a/arch/tile/lib/spinlock_64.c +++ b/arch/tile/lib/spinlock_64.c @@ -65,8 +65,17 @@ EXPORT_SYMBOL(arch_spin_trylock); void arch_spin_unlock_wait(arch_spinlock_t *lock) { u32 iterations = 0; - while (arch_spin_is_locked(lock)) + u32 val = READ_ONCE(lock->lock); + u32 current = arch_spin_current(val); + + /* Return immediately if unlocked. */ + if (arch_spin_next(val) == current) + return; + + /* Wait until the current locker has released the lock. */ + do { delay_backoff(iterations++); + } while (arch_spin_current(READ_ONCE(lock->lock)) == current); } EXPORT_SYMBOL(arch_spin_unlock_wait); -- 2.1.2