On 05/12, Peter Zijlstra wrote: > > +static inline void rw_mutex_readers_dec(struct rw_mutex *rw_mutex) > +{ > + percpu_counter_dec(&rw_mutex->readers); > + smp_wmb(); > +} > > +void rw_mutex_read_unlock(struct rw_mutex *rw_mutex) > +{ > + rw_mutex_readers_dec(rw_mutex); > + /* > + * on the slow path; > + * nudge the writer waiting for the last reader to go away > + */ > + if (unlikely(rw_mutex_reader_slow(rw_mutex))) > + rw_mutex_writer_wake(rw_mutex); > +} > > +void rw_mutex_write_lock_nested(struct rw_mutex *rw_mutex, int subclass) > +{ > + mutex_lock_nested(&rw_mutex->write_mutex, subclass); > + > + /* > + * block new readers > + */ > + mutex_lock_nested(&rw_mutex->read_mutex, subclass); > + rw_mutex_status_set(rw_mutex, RW_MUTEX_READER_SLOW); > + /* > + * and wait for all current readers to go away > + */ > + rw_mutex_writer_wait(rw_mutex, (rw_mutex_readers(rw_mutex) == 0)); > +}
I think this is still not right, but when it comes to barriers we need a true expert (Paul cc-ed). this code roughly does (the only reader does unlock) READER WRITER readers = 0; state = 1; wmb(); wmb(); CHECK(state != 0) CHECK(readers == 0) We need to ensure that we can't miss both CHECKs. Either reader should see RW_MUTEX_READER_SLOW, o writer sees "readers == 0" and does not sleep. In that case both barriers should be converted to smp_mb(). There was a _long_ discussion about STORE-MB-LOAD behaviour, and experts seem to believe everething is ok. Another question. Isn't it possible to kill rw_mutex->status ? I have a vague feeling you can change the code so that rw_mutex_reader_slow() <=> "->waiter != NULL" , but I am not sure. Oleg. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/