History

tracing: Fix memory leak in fgraph storage selftest

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.

Masami Hiramatsu (Google) committed 2 years ago

Commit bc754cc1 parent a069a221 file · +18 −5Browse files

Showing the changes to kernel (1 of 1 file). Show all

Unified · Split

kernel/trace/trace_selftest.c+18−5
@@ -942,7 +942,7 @@ static __init int test_graph_storage_multi(void) · 941 unmodified lines
942942 {
943943 struct fgraph_fixture *fixture;
944944 bool printed = false;
945− int i, ret;
945+ int i, j, ret;
946946
947947 pr_cont("PASSED\n");
948948 pr_info("Testing multiple fgraph storage on a function: ");
@@ -953,22 +953,35 @@ static __init int test_graph_storage_multi(void) · 4 unmodified lines
953953 if (ret && ret != -ENODEV) {
954954 pr_cont("*Could not set filter* ");
955955 printed = true;
956− goto out;
956+ goto out2;
957957 }
958+ }
958959
960+ for (j = 0; j < ARRAY_SIZE(store_bytes); j++) {
961+ fixture = &store_bytes[j];
959962 ret = register_ftrace_graph(&fixture->gops);
960963 if (ret) {
961964 pr_warn("Failed to init store_bytes fgraph tracing\n");
962965 printed = true;
963− goto out;
966+ goto out1;
964967 }
965968 }
966969
967970 DYN_FTRACE_TEST_NAME();
968−out:
971+out1:
972+ while (--j >= 0) {
973+ fixture = &store_bytes[j];
974+ unregister_ftrace_graph(&fixture->gops);
975+
976+ if (fixture->error_str && !printed) {
977+ pr_cont("*** %s ***", fixture->error_str);
978+ printed = true;
979+ }
980+ }
981+out2:
969982 while (--i >= 0) {
970983 fixture = &store_bytes[i];
971− unregister_ftrace_graph(&fixture->gops);
984+ ftrace_free_filter(&fixture->gops.ops);
972985
973986 if (fixture->error_str && !printed) {
974987 pr_cont("*** %s ***", fixture->error_str);