Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libperf rc_check: Add RC_CHK_EQUAL

Comparing pointers with reference count checking is tricky to avoid a
SEGV. Add a convenience macro to simplify and use.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: German Gomez <german.gomez@arm.com>
Cc: James Clark <james.clark@arm.com>
Cc: Nick Terrell <terrelln@fb.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: liuwenyu <liuwenyu7@huawei.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Song Liu <song@kernel.org>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Yanteng Si <siyanteng@loongson.cn>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20231024222353.3024098-5-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
78c32f4c 75265320

+21 -15
+7
tools/lib/perf/include/internal/rc_check.h
··· 54 54 /* A put operation removing the indirection layer. */ 55 55 #define RC_CHK_PUT(object) {} 56 56 57 + /* Pointer equality when the indirection may or may not be there. */ 58 + #define RC_CHK_EQUAL(object1, object2) (object1 == object2) 59 + 57 60 #else 58 61 59 62 /* Replaces "struct foo" so that the pointer may be interposed. */ ··· 103 100 free(object); \ 104 101 } \ 105 102 } while(0) 103 + 104 + /* Pointer equality when the indirection may or may not be there. */ 105 + #define RC_CHK_EQUAL(object1, object2) (object1 == object2 || \ 106 + (object1 && object2 && object1->orig == object2->orig)) 106 107 107 108 #endif 108 109
+1 -1
tools/perf/builtin-sched.c
··· 1385 1385 { 1386 1386 pid_t l_tid, r_tid; 1387 1387 1388 - if (RC_CHK_ACCESS(l->thread) == RC_CHK_ACCESS(r->thread)) 1388 + if (RC_CHK_EQUAL(l->thread, r->thread)) 1389 1389 return 0; 1390 1390 l_tid = thread__tid(l->thread); 1391 1391 r_tid = thread__tid(r->thread);
+2 -2
tools/perf/tests/hists_link.c
··· 148 148 struct thread *t, struct map *m, struct symbol *s) 149 149 { 150 150 while (nr_samples--) { 151 - if (RC_CHK_ACCESS(samples->thread) == RC_CHK_ACCESS(t) && 152 - RC_CHK_ACCESS(samples->map) == RC_CHK_ACCESS(m) && 151 + if (RC_CHK_EQUAL(samples->thread, t) && 152 + RC_CHK_EQUAL(samples->map, m) && 153 153 samples->sym == s) 154 154 return 1; 155 155 samples++;
+4 -5
tools/perf/tests/thread-maps-share.c
··· 46 46 TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 4); 47 47 48 48 /* test the maps pointer is shared */ 49 - TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) == RC_CHK_ACCESS(thread__maps(t1))); 50 - TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) == RC_CHK_ACCESS(thread__maps(t2))); 51 - TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) == RC_CHK_ACCESS(thread__maps(t3))); 49 + TEST_ASSERT_VAL("maps don't match", RC_CHK_EQUAL(maps, thread__maps(t1))); 50 + TEST_ASSERT_VAL("maps don't match", RC_CHK_EQUAL(maps, thread__maps(t2))); 51 + TEST_ASSERT_VAL("maps don't match", RC_CHK_EQUAL(maps, thread__maps(t3))); 52 52 53 53 /* 54 54 * Verify the other leader was created by previous call. ··· 73 73 other_maps = thread__maps(other); 74 74 TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(other_maps)), 2); 75 75 76 - TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(other_maps) == 77 - RC_CHK_ACCESS(thread__maps(other_leader))); 76 + TEST_ASSERT_VAL("maps don't match", RC_CHK_EQUAL(other_maps, thread__maps(other_leader))); 78 77 79 78 /* release thread group */ 80 79 thread__put(t3);
+1 -1
tools/perf/util/callchain.c
··· 1142 1142 if (al->map == NULL) 1143 1143 goto out; 1144 1144 } 1145 - if (RC_CHK_ACCESS(al->maps) == RC_CHK_ACCESS(machine__kernel_maps(machine))) { 1145 + if (RC_CHK_EQUAL(al->maps, machine__kernel_maps(machine))) { 1146 1146 if (machine__is_host(machine)) { 1147 1147 al->cpumode = PERF_RECORD_MISC_KERNEL; 1148 1148 al->level = 'k';
+1 -1
tools/perf/util/hist.c
··· 2142 2142 struct hist_entry *he) 2143 2143 { 2144 2144 if (hists->thread_filter != NULL && 2145 - RC_CHK_ACCESS(he->thread) != RC_CHK_ACCESS(hists->thread_filter)) { 2145 + !RC_CHK_EQUAL(he->thread, hists->thread_filter)) { 2146 2146 he->filtered |= (1 << HIST_FILTER__THREAD); 2147 2147 return true; 2148 2148 }
+2 -2
tools/perf/util/machine.c
··· 969 969 if (!map) 970 970 return 0; 971 971 972 - if (RC_CHK_ACCESS(map) != RC_CHK_ACCESS(machine->vmlinux_map)) 972 + if (!RC_CHK_EQUAL(map, machine->vmlinux_map)) 973 973 maps__remove(machine__kernel_maps(machine), map); 974 974 else { 975 975 struct dso *dso = map__dso(map); ··· 2058 2058 if (!nd) 2059 2059 nd = thread_rb_node__find(th, &threads->entries.rb_root); 2060 2060 2061 - if (threads->last_match && RC_CHK_ACCESS(threads->last_match) == RC_CHK_ACCESS(th)) 2061 + if (threads->last_match && RC_CHK_EQUAL(threads->last_match, th)) 2062 2062 threads__set_last_match(threads, NULL); 2063 2063 2064 2064 if (lock)
+1 -1
tools/perf/util/sort.c
··· 128 128 if (type != HIST_FILTER__THREAD) 129 129 return -1; 130 130 131 - return th && RC_CHK_ACCESS(he->thread) != RC_CHK_ACCESS(th); 131 + return th && !RC_CHK_EQUAL(he->thread, th); 132 132 } 133 133 134 134 struct sort_entry sort_thread = {
+2 -2
tools/perf/util/symbol.c
··· 877 877 *module++ = '\0'; 878 878 curr_map_dso = map__dso(curr_map); 879 879 if (strcmp(curr_map_dso->short_name, module)) { 880 - if (RC_CHK_ACCESS(curr_map) != RC_CHK_ACCESS(initial_map) && 880 + if (!RC_CHK_EQUAL(curr_map, initial_map) && 881 881 dso->kernel == DSO_SPACE__KERNEL_GUEST && 882 882 machine__is_default_guest(machine)) { 883 883 /* ··· 1469 1469 1470 1470 list_del_init(&new_node->node); 1471 1471 1472 - if (RC_CHK_ACCESS(new_map) == RC_CHK_ACCESS(replacement_map)) { 1472 + if (RC_CHK_EQUAL(new_map, replacement_map)) { 1473 1473 struct map *map_ref; 1474 1474 1475 1475 map__set_start(map, map__start(new_map));