Messages in this thread | | | Date | Wed, 27 Mar 2013 04:22:23 -0700 | Subject | Re: [PATCH -mm -next] ipc,sem: fix lockdep false positive | From | Michel Lespinasse <> |
| |
On Wed, Mar 27, 2013 at 1:42 AM, Peter Zijlstra <peterz@infradead.org> wrote: > On Tue, 2013-03-26 at 11:19 -0400, Rik van Riel wrote: >> > Maybe something like: >> > >> > void sma_lock(struct sem_array *sma) /* global */ >> > { >> > int i; >> > >> > sma->global_locked = 1; >> > smp_wmb(); /* can we merge with the LOCK ? */ >> > spin_lock(&sma->global_lock); >> > >> > /* wait for all local locks to go away */ >> > for (i = 0; i < sma->sem_nsems; i++) >> > spin_unlock_wait(&sem->sem_base[i]->lock); >> > } >> > >> > void sma_lock_one(struct sem_array *sma, int nr) /* local */ >> > { >> > smp_rmb(); /* pairs with wmb in sma_lock() */ >> > if (unlikely(sma->global_locked)) { /* wait for global lock */ >> > while (sma->global_locked) >> > spin_unlock_wait(&sma->global_lock); >> > } >> > spin_lock(&sma->sem_base[nr]->lock); >> > } > > I since realized there's an ordering problem with ->global_locked, we > need to use spin_is_locked() or somesuch. > > Two competing sma_lock() operations will screw over the separate > variable. > >> >> > This still has the problem of a non-preemptible section of >> O(sem_nsems) >> > (with the avg wait-time on the local lock). Could we make the global >> > lock a sleeping lock? >> >> Not without breaking your scheme above :) > > How would making sma->global_lock a mutex wreck anything?
I don't remember the details (rik probably will), but rcu is also already involved, so there is a non trivial chance that it would...
-- Michel "Walken" Lespinasse A program is never fully debugged until the last user dies.
| |