[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] x86 spinlock: Fix memory corruption on completing completions
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. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |