From 815041d6dc4d62bfe7267576a8acb65e774fc94f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 6 Aug 2021 16:46:25 -0300 Subject: [PATCH] pahole: Improve the type sorting routine to consider multiple types with same name Out of these different Linux kernel types with the same name (in different object files): $ pahole --sizes | sed -r 's/([^\t]+)\t.*/\1/g' | sort | uniq -c | grep -v ' 1 ' 2 chksum_desc_ctx 2 controller 2 debug_buffer 2 dir_entry 2 disklabel 2 dma_chan 2 dma_heap_attachment 2 d_partition 2 elf_thread_core_info 2 intel_community_context 2 intel_pad_context 3 irq_info 2 irte 2 map_info 2 mm_slot 2 netlbl_domhsh_walk_arg 2 node 2 pci_root_info 2 perf_aux_event 2 pmc_dev 2 pmc_reg_map 2 remap_data 2 slot 2 sw842_param 2 syscall_tp_t 3 urb_priv 2 walk_control 3 workspace $ Only this one needs a more involved type comparision: $ btfdiff vmlinux --- /tmp/btfdiff.dwarf.Pksrlr 2021-08-06 16:42:34.823259365 -0300 +++ /tmp/btfdiff.btf.KOAuwd 2021-08-06 16:42:35.032264038 -0300 @@ -31035,7 +31035,7 @@ struct elf_note_info { struct memelfnote auxv; /* 56 24 */ /* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */ struct memelfnote files; /* 80 24 */ - compat_siginfo_t csigdata; /* 104 128 */ + siginfo_t csigdata; /* 104 128 */ /* --- cacheline 3 boundary (192 bytes) was 40 bytes ago --- */ size_t size; /* 232 8 */ int thread_notes; /* 240 4 */ $ It has the same size, number of members. And this is not always, it all depends on the order in which the btf encoder gets it from one of the DWARF loading threads: $ pahole -j12 --btf_encode vmlinux $ btfdiff vmlinux $ No changes, but then: $ btfdiff vmlinux $ perf stat pahole -j12 --btf_encode vmlinux Performance counter stats for 'pahole -j12 --btf_encode vmlinux': 17,920.75 msec task-clock:u # 2.995 CPUs utilized 0 context-switches:u # 0.000 /sec 0 cpu-migrations:u # 0.000 /sec 78,004 page-faults:u # 4.353 K/sec 42,677,746,170 cycles:u # 2.381 GHz (83.37%) 480,920,924 stalled-cycles-frontend:u # 1.13% frontend cycles idle (83.33%) 6,470,001,379 stalled-cycles-backend:u # 15.16% backend cycles idle (83.39%) 96,468,468,147 instructions:u # 2.26 insn per cycle # 0.07 stalled cycles per insn (83.33%) 19,757,801,968 branches:u # 1.103 G/sec (83.27%) 143,118,731 branch-misses:u # 0.72% of all branches (83.32%) 5.984348164 seconds time elapsed 17.234929000 seconds user 0.398715000 seconds sys $ btfdiff vmlinux --- /tmp/btfdiff.dwarf.b9FEZI 2021-08-06 16:46:08.810043718 -0300 +++ /tmp/btfdiff.btf.IawvDY 2021-08-06 16:46:09.026048548 -0300 @@ -31035,7 +31035,7 @@ struct elf_note_info { struct memelfnote auxv; /* 56 24 */ /* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */ struct memelfnote files; /* 80 24 */ - compat_siginfo_t csigdata; /* 104 128 */ + siginfo_t csigdata; /* 104 128 */ /* --- cacheline 3 boundary (192 bytes) was 40 bytes ago --- */ size_t size; /* 232 8 */ int thread_notes; /* 240 4 */ $ Next cset will take that into account by traversing both types looking for differences in the type for a field. Signed-off-by: Arnaldo Carvalho de Melo --- pahole.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/pahole.c b/pahole.c index 32eb287..e3e6d66 100644 --- a/pahole.c +++ b/pahole.c @@ -123,19 +123,36 @@ static struct rb_root structures__tree = RB_ROOT; static LIST_HEAD(structures__list); static pthread_mutex_t structures_lock = PTHREAD_MUTEX_INITIALIZER; +static int type__compare(struct type *a, struct type *b) +{ + int ret = strcmp(type__name(a), type__name(b)); + + if (ret) + goto found; + + ret = (int)a->size - (int)b->size; + if (ret) + goto found; + + ret = (int)a->nr_members - (int)b->nr_members; + if (ret) + goto found; +found: + return ret; +} + static struct structure *__structures__add(struct class *class, struct cu *cu, uint32_t id, bool *existing_entry) { struct rb_node **p = &structures__tree.rb_node; struct rb_node *parent = NULL; struct structure *str; - const char *new_class_name = class__name(class); while (*p != NULL) { int rc; parent = *p; str = rb_entry(parent, struct structure, rb_node); - rc = strcmp(class__name(str->class), new_class_name); + rc = type__compare(&str->class->type, &class->type); if (rc > 0) p = &(*p)->rb_left;