From: Bo Zhang <zhangbo0325@gmail.com>
To: aliceryhl@google.com, gregkh@linuxfoundation.org, cmllamas@google.com
Cc: arve@android.com, tkjos@android.com, christian@brauner.io,
surenb@google.com, baohua@kernel.org, zhanghongru06@gmail.com,
linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH v3 2/2] binder: add install_mutex to serialize page install and shrinker zap
Date: Sat, 5 Sep 2026 00:19:06 +0800 [thread overview]
Message-ID: <20260904161906.67595-1-zhangbo0325@gmail.com> (raw)
In-Reply-To: <20260904110448.23086-3-zhangbo0325@gmail.com>
Thanks for the review. All three are valid; I'll address them together
in v4 by tightening the roles of the two locks: install_mutex only
serializes page install vs shrinker zap, while alloc->lock (spinlock)
exclusively owns pages[] and the LRU. Details per point below.
1) AA self-deadlock via direct reclaim
Sashiko says
"binder_install_single_page() acquires alloc->install_mutex here, then
calls binder_page_insert() which invokes vm_insert_page(). vm_insert_page()
can trigger page table allocations using GFP_KERNEL semantics, which may
enter direct reclaim. If direct reclaim iterates over list_lru shrinkers
and invokes binder_alloc_free_page() for this same allocator on the same
thread, the shrinker callback will unconditionally try to lock the
already-held install_mutex."
Correct. In v4 the shrinker uses mutex_trylock(&install_mutex) and skips
the page (LRU_SKIP) on failure, so a reclaim recursion from the install
side's vm_insert_page() cannot deadlock on the same thread. The original
shrinker already used trylock on alloc->mutex; restoring trylock here also
removes the ABBA concern with mmap_lock, since a trylock does not
participate in a blocking lock cycle.
2) RT task livelock on the -EAGAIN retry
Sashiko says
"a race window exists where the shrinker has isolated a page from the
buffer's range (causing list_lru_del to fail and return -EAGAIN) but is
preempted before acquiring install_mutex. Because the mutex is uncontended,
the allocating thread acquires and drops it instantly, thinks the shrinker
is done, and retries. It will again find the page installed, fail
list_lru_del, and spin in a tight loop."
Correct. The root cause is that the current approach splits the
shrinker's pages[index]=NULL and list_lru_isolate() such that
binder_lru_freelist_del() can observe an inconsistent state. In v4 the
shrinker performs pages[index]=NULL and list_lru_isolate() together under
alloc->lock, so binder_lru_freelist_del() always sees a consistent
pages[]/LRU state and list_lru_del() never fails. This removes the
-EAGAIN retry path entirely, so the livelock cannot occur.
3) Use-after-free from clearing pages[index] outside alloc->lock
Sashiko says
"By moving binder_set_installed_page(alloc, index, NULL) outside the
alloc->lock critical section, a concurrent allocating thread holding
alloc->lock in binder_lru_freelist_del() can read the stale pointer:
page = alloc->pages[index] (which is not yet NULL). ... When the allocating
thread resumes, it will pass the dangling pointer to page_to_lru(page) and
page_to_nid(page), dereferencing the freed page_private."
Correct. In v4 pages[index]=NULL is moved back inside alloc->lock (together
with list_lru_isolate), so binder_lru_freelist_del() reading pages[index]
under alloc->lock can no longer observe a pointer that the shrinker is
about to free.
v4 will carry all three fixes.
Bo
prev parent reply other threads:[~2026-09-04 16:19 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-04 11:04 [RFC PATCH v3 0/2] binder: split alloc->mutex to improve performance Bo Zhang
2026-09-04 11:04 ` [RFC PATCH v3 1/2] binder: switch alloc->mutex to spinlock for buffer metadata Bo Zhang
2026-09-04 11:04 ` [RFC PATCH v3 2/2] binder: add install_mutex to serialize page install and shrinker zap Bo Zhang
2026-09-04 16:19 ` Bo Zhang [this message]
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=20260904161906.67595-1-zhangbo0325@gmail.com \
--to=zhangbo0325@gmail.com \
--cc=aliceryhl@google.com \
--cc=arve@android.com \
--cc=baohua@kernel.org \
--cc=christian@brauner.io \
--cc=cmllamas@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=surenb@google.com \
--cc=tkjos@android.com \
--cc=zhanghongru06@gmail.com \
/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®