From 78c110a7ea2448404931b7983ed08dccda3a23ba Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 3 Apr 2019 00:01:45 -0700 Subject: [PATCH] dwarves: Revert semantics of member bit/byte hole pahole --reorganize heavily depends on member's bit_hole and hole fields to denote bit/byte holes *after* member. Previous commit "dwarves: use bit sizes and bit/byte hole info in __class__fprintf" changed its meaning to bit/byte hole *before* member to accomodate possible bit/byte holes at the beginning of a struct. This change broke reorganization algorithm, though, which is quite involved and isn't trivially modifiable to accomodate new semantics. This patch reverts the meaning of bit_hole and hole, but also introduces per class pre_bit_hole/pre_hole to record initial bit/byte hole of a struct. This allows to fix reorg code more easily and still handle initial holes cases, if at the expense of being not as elegant. Committer testing: $ time pahole -F btf --packable vmlinux | sort -nr -k4 | head bts_ctx 12288 8192 4096 swsusp_info 4096 432 3664 vc_data 792 496 296 pci_dev 2488 2320 168 rcu_state 3392 3240 152 ptr_ring 192 40 152 xdp_sock 960 840 120 zone 1664 1552 112 rcu_data 576 472 104 rcu_node 576 480 96 real 0m0.038s user 0m0.029s sys 0m0.017s $ Signed-off-by: Andrii Nakryiko Reported-by: Arnaldo Carvalho de Melo Tested-by: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: Yonghong Song Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- dwarves.c | 9 ++++-- dwarves.h | 2 ++ dwarves_fprintf.c | 72 +++++++++++++++++++++++++++++++---------------- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/dwarves.c b/dwarves.c index 619dcb3..efa58a9 100644 --- a/dwarves.c +++ b/dwarves.c @@ -1260,8 +1260,13 @@ void class__find_holes(struct class *class) cur_bitfield_end = bit_end; } - pos->hole = byte_holes; - pos->bit_hole = bit_holes; + if (last) { + last->hole = byte_holes; + last->bit_hole = bit_holes; + } else { + class->pre_hole = byte_holes; + class->pre_bit_hole = bit_holes; + } if (bit_holes) class->nr_bit_holes++; if (byte_holes) diff --git a/dwarves.h b/dwarves.h index e39871f..46083da 100644 --- a/dwarves.h +++ b/dwarves.h @@ -1026,7 +1026,9 @@ struct class { uint16_t nr_vtable_entries; uint8_t nr_holes; uint8_t nr_bit_holes; + uint16_t pre_hole; uint16_t padding; + uint8_t pre_bit_hole; uint8_t bit_padding; bool holes_searched; void *priv; diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c index faae3ba..ef53e2b 100644 --- a/dwarves_fprintf.c +++ b/dwarves_fprintf.c @@ -1292,6 +1292,30 @@ static size_t __class__fprintf(struct class *class, const struct cu *cu, printed += fprintf(fp, " {\n"); + if (class->pre_bit_hole > 0 && !cconf.suppress_comments) { + if (!newline++) { + fputc('\n', fp); + ++printed; + } + printed += fprintf(fp, "%.*s/* XXX %d bit%s hole, " + "try to pack */\n", cconf.indent, tabs, + class->pre_bit_hole, + class->pre_bit_hole != 1 ? "s" : ""); + sum_bit_holes += class->pre_bit_hole; + } + + if (class->pre_hole > 0 && !cconf.suppress_comments) { + if (!newline++) { + fputc('\n', fp); + ++printed; + } + printed += fprintf(fp, "%.*s/* XXX %d byte%s hole, " + "try to pack */\n", + cconf.indent, tabs, class->pre_hole, + class->pre_hole != 1 ? "s" : ""); + sum_holes += class->pre_hole; + } + type__for_each_tag(type, tag_pos) { struct tag *type; const char *accessibility = tag__accessibility(tag_pos); @@ -1361,30 +1385,6 @@ static size_t __class__fprintf(struct class *class, const struct cu *cu, } } - if (pos->bit_hole != 0 && !cconf.suppress_comments) { - if (!newline++) { - fputc('\n', fp); - ++printed; - } - printed += fprintf(fp, "%.*s/* XXX %d bit%s hole, " - "try to pack */\n", cconf.indent, tabs, - pos->bit_hole, - pos->bit_hole != 1 ? "s" : ""); - sum_bit_holes += pos->bit_hole; - } - - if (pos->hole > 0 && !cconf.suppress_comments) { - if (!newline++) { - fputc('\n', fp); - ++printed; - } - printed += fprintf(fp, "%.*s/* XXX %d byte%s hole, " - "try to pack */\n", - cconf.indent, tabs, pos->hole, - pos->hole != 1 ? "s" : ""); - sum_holes += pos->hole; - } - if (newline) { fputc('\n', fp); newline = 0; @@ -1428,6 +1428,30 @@ static size_t __class__fprintf(struct class *class, const struct cu *cu, } } + if (pos->bit_hole != 0 && !cconf.suppress_comments) { + if (!newline++) { + fputc('\n', fp); + ++printed; + } + printed += fprintf(fp, "\n%.*s/* XXX %d bit%s hole, " + "try to pack */", cconf.indent, tabs, + pos->bit_hole, + pos->bit_hole != 1 ? "s" : ""); + sum_bit_holes += pos->bit_hole; + } + + if (pos->hole > 0 && !cconf.suppress_comments) { + if (!newline++) { + fputc('\n', fp); + ++printed; + } + printed += fprintf(fp, "\n%.*s/* XXX %d byte%s hole, " + "try to pack */", + cconf.indent, tabs, pos->hole, + pos->hole != 1 ? "s" : ""); + sum_holes += pos->hole; + } + fputc('\n', fp); ++printed;