* Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx> wrote: > We want to add optimistic spinning to rwsems because > the writer rwsem does not perform as well as mutexes. Tim noticed that > for exim (mail server) workloads, when reverting commit 4fc3f1d6 and > Davidlohr noticed it when converting the i_mmap_mutex to a rwsem in some > aim7 workloads. We've noticed that the biggest difference > is when we fail to acquire a mutex in the fastpath, optimistic spinning > comes in to play and we can avoid a large amount of unnecessary sleeping > and overhead of moving tasks in and out of wait queue. > > Allowing optimistic spinning before putting the writer on the wait queue > reduces wait queue contention and provided greater chance for the rwsem > to get acquired. With these changes, rwsem is on par with mutex. > > Reviewed-by: Ingo Molnar <mingo@xxxxxxx> > Reviewed-by: Peter Zijlstra <peterz@xxxxxxxxxxxxx> > Reviewed-by: Peter Hurley <peter@xxxxxxxxxxxxxxxxxx> > Signed-off-by: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx> > Signed-off-by: Davidlohr Bueso <davidlohr@xxxxxx> > --- > include/linux/rwsem.h | 6 +- > kernel/rwsem.c | 19 +++++- > lib/rwsem.c | 203 ++++++++++++++++++++++++++++++++++++++++++++----- > 3 files changed, 207 insertions(+), 21 deletions(-) > > diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h > index 0616ffe..ef5a83a 100644 > --- a/include/linux/rwsem.h > +++ b/include/linux/rwsem.h > @@ -26,6 +26,8 @@ struct rw_semaphore { > long count; > raw_spinlock_t wait_lock; > struct list_head wait_list; > + struct task_struct *owner; /* write owner */ > + void *spin_mlock; > +#define MLOCK(rwsem) ((struct mcs_spin_node **)&((rwsem)->spin_mlock)) > + mcs_spin_lock(MLOCK(sem), &node); > + mcs_spin_unlock(MLOCK(sem), &node); > + mcs_spin_unlock(MLOCK(sem), &node); > + mcs_spin_unlock(MLOCK(sem), &node); That forced type casting is ugly and fragile. To avoid having to include mcslock.h into rwsem.h just add a forward struct declaration, before the struct rw_semaphore definition: struct mcs_spin_node; Then define spin_mlock with the right type: struct mcs_spin_node *spin_mlock; I'd also suggest renaming 'spin_mlock', to reduce unnecessary variants. If the lock type name is 'struct mcs_spin_node' then 'mcs_lock' would be a perfect field name, right? While at it, renaming mcs_spin_node to mcs_spinlock might be wise as well, and the include file would be named mcs_spinlock.h. Thanks, Ingo -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>