On Mon, Nov 11, 2024 at 8:58 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > On Mon, Nov 11, 2024 at 12:55:05PM -0800, Suren Baghdasaryan wrote: > > When a reader takes read lock, it increments the atomic, unless the > > top two bits are set indicating a writer is present. > > When writer takes write lock, it sets VMA_LOCK_WR_LOCKED bit if there > > are no readers or VMA_LOCK_WR_WAIT bit if readers are holding the lock > > and puts itself onto newly introduced mm.vma_writer_wait. Since all > > writers take mmap_lock in write mode first, there can be only one writer > > at a time. The last reader to release the lock will signal the writer > > to wake up. > > I don't think you need two bits. You can do it this way: > > 0x8000'0000 - No readers, no writers > 0x1-7fff'ffff - Some number of readers > 0x0 - Writer held > 0x8000'0001-0xffff'ffff - Reader held, writer waiting > > A prospective writer subtracts 0x8000'0000. If the result is 0, it got > the lock, otherwise it sleeps until it is 0. > > A writer unlocks by adding 0x8000'0000 (not by setting the value to > 0x8000'0000). > > A reader unlocks by adding 1. If the result is 0, it wakes the writer. > > A prospective reader subtracts 1. If the result is positive, it got the > lock, otherwise it does the unlock above (this might be the one which > wakes the writer). > > And ... that's it. See how we use the CPU arithmetic flags to tell us > everything we need to know without doing arithmetic separately? Yes, this is neat! You are using the fact that write-locked == no readers to eliminate unnecessary state. I'll give that a try. Thanks! >