From: Matthew Wilcox <willy@infradead.org>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>, Will Deacon <will@kernel.org>,
Waiman Long <longman@redhat.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
linux-kernel@vger.kernel.org
Subject: Wait for mutex to become unlocked
Date: Wed, 4 May 2022 22:44:12 +0100 [thread overview]
Message-ID: <YnLzrGlBNCmCPLmS@casper.infradead.org> (raw)
Paul, Liam and I were talking about some code we intend to write soon
and realised there's a missing function in the mutex & rwsem API.
We're intending to use it for an rwsem, but I think it applies equally
to mutexes.
The customer has a low priority task which wants to read /proc/pid/smaps
of a higher priority task. Today, everything is awful; smaps acquires
mmap_sem read-only, is preempted, then the high-pri task calls mmap()
and the down_write(mmap_sem) blocks on the low-pri task. Then all the
other threads in the high-pri task block on the mmap_sem as they take
page faults because we don't want writers to starve.
The approach we're looking at is to allow RCU lookup of VMAs, and then
take a per-VMA rwsem for read. Because we're under RCU protection,
that looks a bit like this:
rcu_read_lock();
vma = vma_lookup();
if (down_read_trylock(&vma->sem)) {
rcu_read_unlock();
} else {
rcu_read_unlock();
down_read(&mm->mmap_sem);
vma = vma_lookup();
down_read(&vma->sem);
up_read(&mm->mmap_sem);
}
(for clarity, I've skipped the !vma checks; don't take this too literally)
So this is Good. For the vast majority of cases, we avoid taking the
mmap read lock and the problem will appear much less often. But we can
do Better with a new API. You see, for this case, we don't actually
want to acquire the mmap_sem; we're happy to spin a bit, but there's no
point in spinning waiting for the writer to finish when we can sleep.
I'd like to write this code:
again:
rcu_read_lock();
vma = vma_lookup();
if (down_read_trylock(&vma->sem)) {
rcu_read_unlock();
} else {
rcu_read_unlock();
rwsem_wait_read(&mm->mmap_sem);
goto again;
}
That is, rwsem_wait_read() puts the thread on the rwsem's wait queue,
and wakes it up without giving it the lock. Now this thread will never
be able to block any thread that tries to acquire mmap_sem for write.
Similarly, it may make sense to add rwsem_wait_write() and mutex_wait().
Perhaps also mutex_wait_killable() and mutex_wait_interruptible()
(the combinatoric explosion is a bit messy; I don't know that it makes
sense to do the _nested, _io variants).
Does any of this make sense?
next reply other threads:[~2022-05-04 21:44 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-04 21:44 Matthew Wilcox [this message]
2022-05-05 0:22 ` Thomas Gleixner
2022-05-05 0:38 ` Matthew Wilcox
2022-05-05 1:14 ` Thomas Gleixner
2022-05-05 5:04 ` Paul E. McKenney
2022-05-05 5:21 ` Paul E. McKenney
2022-05-05 1:11 ` Waiman Long
[not found] ` <20220505015223.5132-1-hdanton@sina.com>
2022-05-05 4:12 ` Matthew Wilcox
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=YnLzrGlBNCmCPLmS@casper.infradead.org \
--to=willy@infradead.org \
--cc=Liam.Howlett@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mingo@redhat.com \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=will@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®