From: Peter Zijlstra <peterz@infradead.org>
To: Suren Baghdasaryan <surenb@google.com>
Cc: Matthew Wilcox <willy@infradead.org>,
akpm@linux-foundation.org, liam.howlett@oracle.com,
lorenzo.stoakes@oracle.com, mhocko@suse.com, vbabka@suse.cz,
hannes@cmpxchg.org, mjguzik@gmail.com, oliver.sang@intel.com,
mgorman@techsingularity.net, david@redhat.com, peterx@redhat.com,
oleg@redhat.com, dave@stgolabs.net, paulmck@kernel.org,
brauner@kernel.org, dhowells@redhat.com, hdanton@sina.com,
hughd@google.com, minchan@google.com, jannh@google.com,
shakeel.butt@linux.dev, souravpanda@google.com,
pasha.tatashin@soleen.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, kernel-team@android.com
Subject: Re: [PATCH 3/4] mm: replace rw_semaphore with atomic_t in vma_lock
Date: Tue, 10 Dec 2024 23:38:50 +0100 [thread overview]
Message-ID: <20241210223850.GA2484@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <CAJuCfpHpGSpix8+mB76Virb+HAMrOqB3wG8E4EXPrRCnBoBGeA@mail.gmail.com>
On Tue, Nov 12, 2024 at 07:18:45AM -0800, Suren Baghdasaryan wrote:
> On Mon, Nov 11, 2024 at 8:58 PM Matthew Wilcox <willy@infradead.org> 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!
The reason I got here is that Vlastimil poked me about the whole
TYPESAFE_BY_RCU thing.
So the normal way those things work is with a refcount, if the refcount
is non-zero, the identifying fields should be stable and you can
determine if you have the right object, otherwise tough luck.
And I was thinking that since you abuse this rwsem you have, you might
as well turn that into a refcount with some extra.
So I would propose a slightly different solution.
Replace vm_lock with vm_refcnt. Replace vm_detached with vm_refcnt == 0
-- that is, attach sets refcount to 1 to indicate it is part of the mas,
detached is the final 'put'.
RCU lookup does the inc_not_zero thing, when increment succeeds, compare
mm/addr to validate.
vma_start_write() already relies on mmap_lock being held for writing,
and thus does not have to worry about writer-vs-writer contention, that
is fully resolved by mmap_sem. This means we only need to wait for
readers to drop out.
vma_start_write()
add(0x8000'0001); // could fetch_add and double check the high
// bit wasn't already set.
wait-until(refcnt == 0x8000'0002); // mas + writer ref
WRITE_ONCE(vma->vm_lock_seq, mm_lock_seq);
sub(0x8000'0000);
vma_end_write()
put();
vma_start_read() then becomes something like:
if (vm_lock_seq == mm_lock_seq)
return false;
cnt = fetch_inc(1);
if (cnt & msb || vm_lock_seq == mm_lock_seq) {
put();
return false;
}
return true;
vma_end_read() then becomes:
put();
and the down_read() from uffffffd requires mmap_read_lock() and thus
does not have to worry about writers, it can simpy be inc() and put(),
no?
next prev parent reply other threads:[~2024-12-10 22:39 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-11 20:55 [PATCH 0/4] move per-vma lock into vm_area_struct Suren Baghdasaryan
2024-11-11 20:55 ` [PATCH 1/4] mm: introduce vma_start_read_locked{_nested} helpers Suren Baghdasaryan
2024-11-11 20:55 ` [PATCH 2/4] mm: move per-vma lock into vm_area_struct Suren Baghdasaryan
2024-11-12 9:36 ` kernel test robot
2024-11-12 9:47 ` kernel test robot
2024-11-12 10:18 ` kernel test robot
2024-11-12 15:57 ` Vlastimil Babka
2024-11-12 16:08 ` Suren Baghdasaryan
2024-11-12 16:58 ` Suren Baghdasaryan
2024-11-11 20:55 ` [PATCH 3/4] mm: replace rw_semaphore with atomic_t in vma_lock Suren Baghdasaryan
2024-11-12 0:06 ` Andrew Morton
2024-11-12 0:52 ` Suren Baghdasaryan
2024-11-12 0:35 ` Davidlohr Bueso
2024-11-12 0:59 ` Suren Baghdasaryan
2024-11-12 4:58 ` Matthew Wilcox
2024-11-12 15:18 ` Suren Baghdasaryan
2024-12-10 22:38 ` Peter Zijlstra [this message]
2024-12-10 23:37 ` Suren Baghdasaryan
2024-12-11 8:25 ` Peter Zijlstra
2024-12-11 15:20 ` Suren Baghdasaryan
2024-12-12 3:01 ` Suren Baghdasaryan
2024-12-12 9:16 ` Peter Zijlstra
2024-12-12 14:17 ` Suren Baghdasaryan
2024-12-12 14:19 ` Suren Baghdasaryan
2024-12-13 4:48 ` Suren Baghdasaryan
2024-12-13 9:57 ` Peter Zijlstra
2024-12-13 17:45 ` Suren Baghdasaryan
2024-12-13 18:19 ` Matthew Wilcox
2024-12-13 18:35 ` Peter Zijlstra
2024-12-13 18:37 ` Suren Baghdasaryan
2024-12-16 19:32 ` Suren Baghdasaryan
2024-12-13 9:22 ` Peter Zijlstra
2024-12-13 17:41 ` Suren Baghdasaryan
2024-11-11 20:55 ` [PATCH 4/4] mm: move lesser used vma_area_struct members into the last cacheline Suren Baghdasaryan
2024-11-12 10:07 ` Vlastimil Babka
2024-11-12 15:45 ` Suren Baghdasaryan
2024-11-11 21:41 ` [PATCH 0/4] move per-vma lock into vm_area_struct Suren Baghdasaryan
2024-11-12 2:48 ` Liam R. Howlett
2024-11-12 3:27 ` Suren Baghdasaryan
2024-11-11 22:18 ` Davidlohr Bueso
2024-11-11 23:19 ` Suren Baghdasaryan
2024-11-12 0:03 ` Davidlohr Bueso
2024-11-12 0:43 ` Suren Baghdasaryan
2024-11-12 0:11 ` Andrew Morton
2024-11-12 0:48 ` Suren Baghdasaryan
2024-11-12 2:35 ` Liam R. Howlett
2024-11-12 3:23 ` Suren Baghdasaryan
2024-11-12 9:39 ` Lorenzo Stoakes
2024-11-12 15:38 ` Suren Baghdasaryan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241210223850.GA2484@noisy.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=akpm@linux-foundation.org \
--cc=brauner@kernel.org \
--cc=dave@stgolabs.net \
--cc=david@redhat.com \
--cc=dhowells@redhat.com \
--cc=hannes@cmpxchg.org \
--cc=hdanton@sina.com \
--cc=hughd@google.com \
--cc=jannh@google.com \
--cc=kernel-team@android.com \
--cc=liam.howlett@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=mgorman@techsingularity.net \
--cc=mhocko@suse.com \
--cc=minchan@google.com \
--cc=mjguzik@gmail.com \
--cc=oleg@redhat.com \
--cc=oliver.sang@intel.com \
--cc=pasha.tatashin@soleen.com \
--cc=paulmck@kernel.org \
--cc=peterx@redhat.com \
--cc=shakeel.butt@linux.dev \
--cc=souravpanda@google.com \
--cc=surenb@google.com \
--cc=vbabka@suse.cz \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.