Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756257AbbBJO0h (ORCPT ); Tue, 10 Feb 2015 09:26:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52496 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754798AbbBJO0g (ORCPT ); Tue, 10 Feb 2015 09:26:36 -0500 Date: Tue, 10 Feb 2015 15:24:17 +0100 From: Oleg Nesterov To: Denys Vlasenko Cc: Raghavendra K T , Linus Torvalds , Jeremy Fitzhardinge , Sasha Levin , Davidlohr Bueso , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Peter Anvin , Konrad Rzeszutek Wilk , Paolo Bonzini , Paul McKenney , Waiman Long , Dave Jones , the arch/x86 maintainers , Paul Gortmaker , Andi Kleen , Jason Wang , Linux Kernel Mailing List , KVM list , virtualization , xen-devel@lists.xenproject.org, Rik van Riel , Christian Borntraeger , Andrew Morton , Andrey Ryabinin Subject: Re: [PATCH] x86 spinlock: Fix memory corruption on completing completions Message-ID: <20150210142417.GA1449@redhat.com> References: <1423234148-13886-1-git-send-email-raghavendra.kt@linux.vnet.ibm.com> <54D7D19B.1000103@goop.org> <54D87F1E.9060307@linux.vnet.ibm.com> <20150209120227.GT21418@twins.programming.kicks-ass.net> <54D9CFC7.5020007@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.18 (2008-05-17) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1664 Lines: 57 On 02/10, Denys Vlasenko wrote: > > # define HEAD_MASK (TICKET_SLOWPATH_FLAG-1) > > ... > unlock_again: > > val = xadd((&lock->ticket.head_tail, TICKET_LOCK_INC); > if (unlikely(!(val & HEAD_MASK))) { > /* overflow. we inadvertently incremented the tail word. > * tail's lsb is TICKET_SLOWPATH_FLAG. > * Increment inverted this bit, fix it up. > * (inc _may_ have messed up tail counter too, > * will deal with it after kick.) > */ > val ^= TICKET_SLOWPATH_FLAG; > } > > if (unlikely(val & TICKET_SLOWPATH_FLAG)) { > ...kick the waiting task... > > val -= TICKET_SLOWPATH_FLAG; > if (unlikely(!(val & HEAD_MASK))) { > /* overflow. we inadvertently incremented tail word, *and* > * TICKET_SLOWPATH_FLAG was set, increment overflowed > * that bit too and incremented tail counter. > * This means we (inadvertently) taking the lock again! > * Oh well. Take it, and unlock it again... > */ > while (1) { > if (READ_ONCE(lock->tickets.head) != TICKET_TAIL(val)) > cpu_relax(); > } > goto unlock_again; > } > > > Granted, this looks ugly. complicated ;) But "Take it, and unlock it again" simply can't work, this can deadlock. Note that unlock() can be called after successful try_lock(). And other problems with lock-ordering, like lock(X); lock(Y); unlock(X); Oleg. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/