tracing: Fix memory leak in fgraph storage selftest
Masami Hiramatsu (Google)
maintainerPATCH 1/1 tracing: Fix memory leak in fgraph storage selftest
From: Masami Hiramatsu (Google) <[email protected]>
With ftrace boot-time selftest, kmemleak reported some memory leaks in the new test case for function graph storage for multiple tracers.
unreferenced object 0xffff888005060080 (size 32):
comm "swapper/0", pid 1, jiffies 4294676440
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 20 10 06 05 80 88 ff ff ........ .......
54 0c 1e 81 ff ff ff ff 00 00 00 00 00 00 00 00 T...............
backtrace (crc 7c93416c):
[<000000000238ee6f>] __kmalloc_cache_noprof+0x11f/0x2a0
[<0000000033d2b6c5>] enter_record+0xe8/0x150
[<0000000054c38424>] match_records+0x1cd/0x230
[<00000000c775b63d>] ftrace_set_hash+0xff/0x380
[<000000007bf7208c>] ftrace_set_filter+0x70/0x90
[<00000000a5c08dda>] test_graph_storage_multi+0x2e/0xf0
[<000000006ba028ca>] trace_selftest_startup_function_graph+0x1e8/0x260
[<00000000a715d3eb>] run_tracer_selftest+0x111/0x190
[<00000000395cbf90>] register_tracer+0xdf/0x1f0
[<0000000093e67f7b>] do_one_initcall+0x141/0x3b0
[<00000000c591b682>] do_initcall_level+0x82/0xa0
[<000000004e4c6600>] do_initcalls+0x43/0x70
[<0000000034f3c4e4>] kernel_init_freeable+0x170/0x1f0
[<00000000c7a5dab2>] kernel_init+0x1a/0x1a0
[<00000000ea105947>] ret_from_fork+0x3a/0x50
[<00000000a1932e84>] ret_from_fork_asm+0x1a/0x30...
This means filter hash allocated for the fixtures are not correctly released after the test.
Free those hash lists after tests are done and split the loop for initialize fixture and register fixture for rollback.
Fixes dd120af2d5f8 ("ftrace: Add multiple fgraph storage selftest")
Signed-off-by Masami Hiramatsu (Google) <[email protected]>
--- kernel/trace/trace_selftest.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
kernel/trace/trace_selftest.c +18 -5
@@ -942,7 +942,7 @@ static __init int test_graph_storage_multi(void) {struct fgraph_fixture *fixture;bool printed = false; -int i, ret; +int i, j, ret;pr_cont ("PASSED\n" );pr_info ("Testing multiple fgraph storage on a function: " );
@@ -953,22 +953,35 @@ static __init int test_graph_storage_multi(void)if (ret && ret != -ENODEV ) {pr_cont ("*Could not set filter* " ); printed = true; - goto out; + goto out2; } + } +for (j =0 ; j <ARRAY_SIZE (store_bytes); j++) { + fixture = &store_bytes[j]; ret =register_ftrace_graph (&fixture->gops);if (ret) {pr_warn ("Failed to init store_bytes fgraph tracing\n" ); printed = true; - goto out; + goto out1; } }DYN_FTRACE_TEST_NAME (); -out: +out1: +while (--j >=0 ) { + fixture = &store_bytes[j]; +unregister_ftrace_graph (&fixture->gops); + +if (fixture->error_str && !printed) { +pr_cont ("*** %s ***" , fixture->error_str); + printed = true; + } + } +out2:while (--i >=0 ) { fixture = &store_bytes[i]; -unregister_ftrace_graph (&fixture->gops); +ftrace_free_filter (&fixture->gops.ops);if (fixture->error_str && !printed) {pr_cont ("*** %s ***" , fixture->error_str);