Since 6.13 the list_lru walker reacquires the lock itself after
LRU_REMOVED_RETRY. Taking it in the callback makes the next
lock_list_lru_of_memcg() spin forever, leaving kswapd at 100% CPU
in binder_shrink_scan().
Since Linux 6.13 the list_lru walk callback no longer receives the lru
lock; it lives in struct list_lru_one. binder_alloc_free_page_no_lock()
passes NULL as the lock, so binder_alloc_free_page() ends up calling
spin_unlock(NULL) as soon as kswapd runs the binder shrinker:
BUG: kernel NULL pointer dereference, address: 0000000000000000
RIP: 0010:_raw_spin_unlock+0x9/0x40
Call Trace:
binder_alloc_free_page+0xe1/0x360 [binder_linux]
__list_lru_walk_one+0xdf/0x230
list_lru_walk_node+0x52/0x230
binder_shrink_scan+0xa7/0x100 [binder_linux]
do_shrink_slab+0x154/0x3a0
...
kswapd+0x1e2/0x360
The machine then hangs, typically under memory pressure, right after
resuming from suspend, or while writing a hibernation image.
Fall back to &lru->lock when no lock is passed, as upstream binder does.
deps.c implements zap_page_range_single() as a runtime compat shim
(resolved via kallsyms_lookup_name), but deps.h never declared its
prototype, and binder_alloc.c did not include deps.h. Newer compilers
(Clang, building with -std=gnu11 and later defaults) treat an
implicit function declaration as a hard error rather than a warning,
so the module fails to build:
binder_alloc.c:1029:3: error: call to undeclared function
'zap_page_range_single'; ISO C99 and later do not support implicit
function declarations [-Wimplicit-function-declaration]
Declare the prototype in deps.h and include it from binder_alloc.c.
Verified the module builds and links cleanly (binder_linux.ko) against
kernel 7.1.1 with the fix applied; previously failed with the error
above.
* Use shrinker pointer instead of shrink struct for 6.7+, due to the `shrinker_alloc` function always return the pointer.
* Most of the codes are stolen from drivers/android/binder_alloc.c
Over the last years, many fixes and changes have been applied to
Binder in the Linux kernel, but these fixes were never backported
to anbox-modules. The meant that the version of Binder in anbox-modules
was very outdated.
With this commit, Binder has been update to the latest state from
the Linux kernel. This should also fix the compile on kernel 5.12
and later.