Re: [PATCH pahole] pahole: use 32-bit integers for iterations within CU

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Mar 11, 2019 at 7:53 AM Arnaldo Carvalho de Melo
<arnaldo.melo@xxxxxxxxx> wrote:
>
> Em Sun, Mar 10, 2019 at 09:31:51PM -0700, Andrii Nakryiko escreveu:
> > On Fri, Mar 8, 2019 at 11:42 AM Andrii Nakryiko
> > <andrii.nakryiko@xxxxxxxxx> wrote:
> > >
> > > On Fri, Mar 8, 2019 at 10:45 AM Arnaldo Carvalho de Melo
> > > <arnaldo.melo@xxxxxxxxx> wrote:
> > > >
> > > > Em Thu, Mar 07, 2019 at 09:26:37PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > > Several looks similar and the low hanging fruit to investigate, seems to
> > > > > be enum bitfields, and the others may as well end up being the same, in
> > > > > miscalculated stats for structs embedded in other structs:
> > > >
> > > > I had little time to further look into this, but from what I've seen the
> > > > good news is that it seems the problem is with the DWARF loader, the BTF
> > > > one producing the right results 8-) I'll take a look at a fix you made
> > > > for packed enums and probably use the same thing on the DWARF loader.
> > >
> > > Yeah, I suspected it might be related to base_type__name_to_size()
> > > logic I removed for btf_loader. Ideally we should take the size from
> > > DWARF data itself (assuming it's there) and remove
> > > base_type__name_to_size() and related parts.
> >
> > So I got a chance today to verify your changes from
> > tmp.type_id_t-as-uint32_t branch. They look good to me. I've tested
> > old and new version of pahole on few of my kernel images, both typical
> > one and allyesconfig one. They both produced identical binaries after
> > BTF encoding and deduplication, which seems to be good indication that
> > nothing is broken. I hope you can push those changes into master soon.
> >
> > I've also took a brief look at btfdiff differences for allyesconfig.
> > There are not that many of them: just 16k of output text, which given
> > 200k types is not a lot.
> >
> > I've noticed that there are problems for packed enum fields, which are
> > not handled properly neither in DWARF, nor in BTF.
> >
> > Here's one example:
> >
> >  struct myrb_dcdb {
> >         unsigned int               target:4;             /*     0:28  4 */
> >         unsigned int               channel:4;            /*     0:24  4 */
> >
> > -       /* Bitfield combined with next fields */
> > +       /* XXX 24 bits hole, try to pack */
> >
> >         enum {
> >                 MYRB_DCDB_XFER_NONE = 0,
> >                 MYRB_DCDB_XFER_DEVICE_TO_SYSTEM = 1,
> >                 MYRB_DCDB_XFER_SYSTEM_TO_DEVICE = 2,
> >                 MYRB_DCDB_XFER_ILLEGAL = 3,
> > -       } data_xfer:2;                                     /*     1     4 */
> > +       } data_xfer:2;                                     /*     4     1 */
> >
> >         /* Bitfield combined with previous fields */
> >
> >         unsigned int               early_status:1;       /*     0:21  4 */
> >         unsigned int               rsvd1:1;              /*     0:20  4 */
> >
> > -       /* XXX 4 bits hole, try to pack */
> > -       /* Bitfield combined with next fields */
> > +       /* XXX 28 bits hole, try to pack */
> >
> >         enum {
> >                 MYRB_DCDB_TMO_24_HRS = 0,
> >                 MYRB_DCDB_TMO_10_SECS = 1,
> >                 MYRB_DCDB_TMO_60_SECS = 2,
> >                 MYRB_DCDB_TMO_10_MINS = 3,
> > -       } timeout:2;                                       /*     1     4 */
> > +       } timeout:2;                                       /*     4     1 */
> >
> >         /* Bitfield combined with previous fields */
> >
> > @@ -324624,10 +324641,10 @@ struct myrb_dcdb {
> >         unsigned char              rsvd2;                /*    87     1 */
> >
> >         /* size: 88, cachelines: 2, members: 17 */
> > -       /* bit holes: 2, sum bit holes: 16 bits */
> > +       /* bit holes: 3, sum bit holes: 64 bits */
> >         /* last cacheline: 24 bytes */
> >
> > -       /* BRAIN FART ALERT! 88 != 83 + 0(holes), diff = 5 */
> > +       /* BRAIN FART ALERT! 88 != 86 + 0(holes), diff = 2 */
> >  };
> >
> >
> > Both DWARF and BTF output emits BRAIN FART ALERT and both can't handle
> > 2-bit enums.
> >
> > Here's source code definition of that struct:
> >
> > struct myrb_dcdb {
> >         unsigned target:4;                               /* Byte 0 Bits 0-3 */
> >         unsigned channel:4;                              /* Byte 0 Bits 4-7 */
> >         enum {
> >                 MYRB_DCDB_XFER_NONE =           0,
> >                 MYRB_DCDB_XFER_DEVICE_TO_SYSTEM = 1,
> >                 MYRB_DCDB_XFER_SYSTEM_TO_DEVICE = 2,
> >                 MYRB_DCDB_XFER_ILLEGAL =        3
> >         } __packed data_xfer:2;                         /* Byte 1 Bits 0-1 */
> >         unsigned early_status:1;                        /* Byte 1 Bit 2 */
> >         unsigned rsvd1:1;                               /* Byte 1 Bit 3 */
> >         enum {
> >                 MYRB_DCDB_TMO_24_HRS =  0,
> >                 MYRB_DCDB_TMO_10_SECS = 1,
> >                 MYRB_DCDB_TMO_60_SECS = 2,
> >                 MYRB_DCDB_TMO_10_MINS = 3
> >         } __packed timeout:2;                           /* Byte 1 Bits 4-5 */
> >         unsigned no_autosense:1;                        /* Byte 1 Bit 6 */
> >         unsigned allow_disconnect:1;                    /* Byte 1 Bit 7 */
> >         unsigned short xfer_len_lo;                     /* Bytes 2-3 */
> >         u32 dma_addr;                                   /* Bytes 4-7 */
> >         unsigned char cdb_len:4;                        /* Byte 8 Bits 0-3 */
> >         unsigned char xfer_len_hi4:4;                   /* Byte 8 Bits 4-7 */
> >         unsigned char sense_len;                        /* Byte 9 */
> >         unsigned char cdb[12];                          /* Bytes 10-21 */
> >         unsigned char sense[64];                        /* Bytes 22-85 */
> >         unsigned char status;                           /* Byte 86 */
> >         unsigned char rsvd2;                            /* Byte 87 */
> > };
> >
> > I've checked raw BTF data for that struct:
> >
> > [12835109] <STRUCT> 'myrb_dcdb' (17 members)
> >     #00 target (off=0, sz=4) --> [12832925]
> >     #01 channel (off=4, sz=4) --> [12832925]
> >     #02 data_xfer (off=32, sz=2) --> [12835107]
> >     #03 early_status (off=10, sz=1) --> [12832925]
> >     #04 rsvd1 (off=11, sz=1) --> [12832925]
> >     #05 timeout (off=36, sz=2) --> [12835108]
> >     #06 no_autosense (off=14, sz=1) --> [12832925]
> >     #07 allow_disconnect (off=15, sz=1) --> [12832925]
> >     #08 xfer_len_lo (off=16, sz=0) --> [12832933]
> >     #09 dma_addr (off=32, sz=0) --> [12832946]
> >     #10 cdb_len (off=64, sz=4) --> [12832929]
> >     #11 xfer_len_hi4 (off=68, sz=4) --> [12832929]
> >     #12 sense_len (off=72, sz=0) --> [12832929]
> >     #13 cdb (off=80, sz=0) --> [12835084]
> >     #14 sense (off=176, sz=0) --> [12835110]
> >     #15 status (off=688, sz=0) --> [12832929]
> >     #16 rsvd2 (off=696, sz=0) --> [12832929]
> >
> > off is a bit field offset, sz is bitfield size (0 if not bitfield).
> >
> > Notice how data_xfer has correct sz=2, but off=32 is totally wrong and
> > should be 8. Similar issue with timeout with sz=2 and off=36 (should
> > be 12). So there seem to be some problem when doing DWARF to BTF
> > conversion. I haven't had chance to dig deeper, I'll try to create a
> > small repro and dig deeper when I get time (it's really hard to work
> > with allyesconfig anything due to humongous sizes of data/log/output).
>
> Right, what I'm doing now is to pick the structs that and having things
> like:
>
> [acme@quaco pahole]$ size examples/DAC960.o
>    text    data     bss     dec     hex filename
>       0       0       0       0       0 examples/DAC960.o
> [acme@quaco pahole]$ ls -la examples/DAC960.o
> -rwxrwxr-x. 1 acme acme 10736 Mar  8 11:07 examples/DAC960.o
> [acme@quaco pahole]$ ls -la examples/DAC960.c
> -rw-rw-r--. 1 acme acme 4480 Mar  8 11:04 examples/DAC960.c
> [acme@quaco pahole]$ pahole --sizes examples/DAC960.o
> myrb_enquiry2   128     0
> [acme@quaco pahole]
> [acme@quaco pahole]$ btfdiff examples/DAC960.o
> --- /tmp/btfdiff.dwarf.VMTvcw   2019-03-11 11:51:07.858695537 -0300
> +++ /tmp/btfdiff.btf.f75DjU     2019-03-11 11:51:07.860695576 -0300
> @@ -52,18 +52,18 @@ struct myrb_enquiry2 {
>                         MYRB_RAM_TYPE_EDO = 1,
>                         MYRB_RAM_TYPE_SDRAM = 2,
>                         MYRB_RAM_TYPE_Last = 7,
> -               } ram:3;                                   /*    40     4 */
> +               } ram:3;                                   /*    43     1 */
>                 enum {
>                         MYRB_ERR_CORR_None = 0,
>                         MYRB_ERR_CORR_Parity = 1,
>                         MYRB_ERR_CORR_ECC = 2,
>                         MYRB_ERR_CORR_Last = 7,
> -               } ec:3;                                    /*    40     4 */
> -               unsigned char      fast_page:1;          /*    40: 1  1 */
> -               unsigned char      low_power:1;          /*    40: 0  1 */
> +               } ec:3;                                    /*    43     1 */
>
> -               /* Bitfield combined with next fields */
> +               /* Bitfield combined with previous fields */
>
> +               unsigned char      fast_page:1;          /*    40: 1  1 */
> +               unsigned char      low_power:1;          /*    40: 0  1 */
>                 unsigned char      rsvd4;                /*    41     1 */
>         } mem_type;                                      /*    40     2 */
>         short unsigned int         clock_speed;          /*    42     2 */
> @@ -94,18 +94,18 @@ struct myrb_enquiry2 {
>                         MYRB_WIDTH_NARROW_8BIT = 0,
>                         MYRB_WIDTH_WIDE_16BIT = 1,
>                         MYRB_WIDTH_WIDE_32BIT = 2,
> -               } bus_width:2;                             /*   106     4 */
> +               } bus_width:2;                             /*   109     1 */
>                 enum {
>                         MYRB_SCSI_SPEED_FAST = 0,
>                         MYRB_SCSI_SPEED_ULTRA = 1,
>                         MYRB_SCSI_SPEED_ULTRA2 = 2,
> -               } bus_speed:2;                             /*   106     4 */
> +               } bus_speed:2;                             /*   109     1 */
> +
> +               /* Bitfield combined with previous fields */
> +
>                 unsigned char      differential:1;       /*   106: 3  1 */
>                 unsigned char      rsvd10:3;             /*   106: 0  1 */
>         } scsi_cap;                                      /*   106     1 */
> -
> -       /* XXX last struct has 65533 bytes of padding */
> -
>         unsigned char              rsvd11[5];            /*   107     5 */
>         short unsigned int         fw_build;             /*   112     2 */
>         enum {
> @@ -127,5 +127,4 @@ struct myrb_enquiry2 {
>         unsigned char              rsvd14[8];            /*   120     8 */
>
>         /* size: 128, cachelines: 2, members: 46 */
> -       /* paddings: 1, sum paddings: 65533 */
>  };
> [acme@quaco pahole]$
>
> > In any case, what was your plan w.r.t. new release of pahole? Do you
> > want to iron out these obscure bitfield problems first and add
> > --progress before new version?
>
> --progress can wait, what I would like would be to have btfdiff clean
> for that allyesconfig kernel, fixing these last odd cases. Getting the
> exact same output (modulo flat arrays and the show_private_classes used
> in btfdiff) would inspire more confidence in the whole thing, I think.

Yep, makes sense.

>
> I've added your Tested-by to the csets changing uint16_t to uint32_t and
> pushing to master now. Will try to spend some time fixing these last
> issues.

Sounds good!

>
> - Arnaldo



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux