Re: [PATCH v2 12/18] perf rwsem: Add down_read_trylock() and down_write_trylock()
From: Alireza Haghdoost
Date: Fri Oct 30 2026 - 09:40:27 EST
On Tue, Oct 27, 2026 at 4:15 PM Ian Rogers <irogers@xxxxxxxxxx> wrote:
> symbols->lock, dsos->lock, or machines->lock). Non-blocking trylock
> primitives are needed so shrinking paths can safely skip any locked
> container without deadlocking.
[...]
> + return perf_singlethreaded ? true : pthread_rwlock_trywrlock(&sem->lock) == 0;
Could the single-threaded trylock path detect when the current thread
already holds the lock, rather than unconditionally succeeding? One
option would be to track lock ownership or nesting depth. Otherwise,
the shrink path needs to avoid any container that is currently being
changed. In the full series, the unconditional success can make
shrinking free an array that its caller is about to pass back to
realloc().
perf_singlethreaded remains true in perf report, perf script, and most
commands. perf top, multi-threaded synthesis in perf record, and perf
bench synthesize explicitly switch it. In report and script these
trylocks therefore always succeed, even on a lock the current thread
already holds. The shrink paths can't skip a locked container there.
The case I hit: __symbols__insert_sorted(), reached through
dso__insert_symbol() outside dso__load() (for example from
db_ids_from_al()), holds symbols->lock for writing and calls
perf_session__realloc(session, symbols->symbols, ...)
This path combines 12/18 with the shrink and allocator plumbing in
15-17/18.
If that realloc fails, perf_session__shrink() reaches symbols__shrink()
on the same container. The write trylock succeeds and, with every
symbol at refcount 1, it frees symbols->symbols (or reallocs it
smaller). perf_session__realloc() then retries realloc() with the old
pointer. With an LD_PRELOAD shim that fails one realloc, ASan reports
realloc() on freed memory from perf_session__realloc() <-
__symbols__insert_sorted() <- dso__insert_symbol(). After
perf_set_multithreaded() the trylock fails and the insert returns
-ENOMEM, as intended.
Thanks,
Alireza