[PATCH v5 0/5] tracing: add refcount_final_put tracing
From: Eugene Mavick
Date: Wed Aug 12 2026 - 23:51:27 EST
When debugging use-after-free(UAF) bugs, knowing when the object reaches
0 references and enters final release(final put) can significantly aid the
debugging process.
This patch series adds a tracepoint, refcount_final_put, with
compilation toggleable with CONFIG_REFCOUNT_TRACE_FINAL_PUT.
refcount_final_put fires when a reference
count reaches zero and the object enters its final release path.
refcount_final_put records three fields:
- caller: function that called the refcounting
function(refcount_sub_and_test, percpu_ref_put_many)
- ip: return address of trace wrapper macro call
- obj: refcount object(struct percpu_ref, refcount_t)
bloat-o-meter stats:
CONFIG_REFCOUNT_TRACE_FINAL_PUT=n :
Total: Before=24703933, After=24703933, chg +0.00%
CONFIG_REFCOUNT_TRACE_FINAL_PUT=y :
Total: Before=24703933, After=24764816, chg +0.25%
Alternatives to obtain this information require live reproduction, and
incur a significant performance cost, making them impractical to have
enabled on fuzzers like syzbot.
refcount functions performing final-puts are also inlined, further
complicating alternative dynamic tracing possibilities.
Debugging UAFs without final-put knowledge is possible but is often
significantly harder and requires broad code reading and mapping,
whereas knowing the final-put allows narrowing the scope, thus
decreasing time and effort required.
Local live reproduction and alternative tracing are time, hardware
resource, and manual effort exhaustive. Time-sensitive UAFs which
require many iterations to reproduce further worsen these requirements.
Remote-fuzzer report based UAF debugging is an incredibly frequent
occurence.
Signed-off-by: Eugene Mavick <m@xxxxxxxxxx>
---
Changes in v5:
-rename ref_trace to refcount
-add CONFIG_REFCOUNT_TRACE_FINAL_PUT Kconfig option, due to high footprint
-improve cover letter, add bloat-o-meter statistics
v4: https://lore.kernel.org/r/20260801-refcount-final-put-trace-v4-0-2e58678f0ffd@xxxxxxxxxx
Changes in v4:
ref-trace:
-remove fn
-add ip variable
-change trace wrapper macro respectively, _THIS_IP_ is used for ip variable
-change relevant code respect to fn removal and ip addition
-fix style issues in include/linux/ref_trace.h
-add new macro do_trace_ref_final_put_cond that only calls tracepoint if cond is
true
lib/refcount.c:
-change from do_trace_ref_final_put to *_cond
-remove if statement above since _cond already performs the check
KUnit:
-change relevant code respect to fn removal and ip addition
-check if caller and ip are valid addresses
-change timeout from 10 jiffies to 10 seconds
-move didn't timeout assertion from before to after probe
unregistration, to prevent it from impacting next test
Changes in v3:
include/trace/events/ref_trace.h kernel doc comments:
-caller of refcount function -> return address of refcount function
-ref_trace_final_put->do_ref_trace_final_put
lib/ref_trace.c: add include trace/events/ref_trace.h
kunit:
-change Kconfig depends from FTRACE->TRACEPOINTS
-EXPECT_FALSE->ASSERT_FALSE for calling percpu_ref_init
-add tracepoint_synchronise_unregister to test_exit macro
-added timeout to capture.count waiting
-remove noinline and __always_inline from function attributes
(added for testing, but accidentally submitted)
-add period to the end of Kconfig help text
v2 link:
https://lore.kernel.org/all/20260710-refcount-final-put-trace-v2-0-557cfce860a2@xxxxxxxxxx/
Changes in v2:
-include/linux/ref_trace.h: change macro name, use direct tracepoint
call in macro to avoid double check
-add tracepoint to refcount_dec_if_one
-kunit: make significant improvements to design, fix critical bug, add test case for
refcount_dec_if_one()
-Link to v1: https://lore.kernel.org/r/20260705-refcount-final-put-trace-v1-0-0ae936edb750@xxxxxxxxxx
---
Eugene Mavick (5):
tracing: add refcount_final_put tracepoint
refcount: add refcount_final_put tracepoint
percpu-refcount: add refcount_final_put tracepoint
kunit: add test for refcount_final_put
MAINTAINERS: add entries for refcount_final_put trace
MAINTAINERS | 3 +
include/linux/percpu-refcount.h | 5 +-
include/linux/refcount.h | 2 +
include/linux/refcount_trace.h | 33 +++++++++
include/trace/events/refcount.h | 55 +++++++++++++++
lib/Kconfig | 18 +++++
lib/Makefile | 2 +
lib/refcount.c | 6 +-
lib/refcount_trace.c | 14 ++++
lib/tests/Makefile | 1 +
lib/tests/refcount_trace_kunit.c | 141 +++++++++++++++++++++++++++++++++++++++
11 files changed, 278 insertions(+), 2 deletions(-)
---
base-commit: df685633c3dbc67441cc86f1c3fee58de4652ba2
change-id: 20260624-refcount-final-put-trace-49bd7c39bd5a
Best regards,
--
Eugene Mavick <m@xxxxxxxxxx>