Re: encoding BTF on glibc was: Re: [PATCH pahole 0/3] fix handling of bitfields in btf_loader

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

 




On 2/25/19 9:45 PM, Andrii Nakryiko wrote:
> On Mon, Feb 25, 2019 at 9:38 PM Yonghong Song <yhs@xxxxxx> wrote:
>>
>>
>>
>> On 2/25/19 1:36 PM, Andrii Nakryiko wrote:
>>> On Mon, Feb 25, 2019 at 12:51 PM Andrii Nakryiko
>>> <andrii.nakryiko@xxxxxxxxx> wrote:
>>>>
>>>> On Mon, Feb 25, 2019 at 12:08 PM Arnaldo Carvalho de Melo
>>>> <arnaldo.melo@xxxxxxxxx> wrote:
>>>>>
>>>>> Em Mon, Feb 25, 2019 at 11:42:29AM -0800, Andrii Nakryiko escreveu:
>>>>>> On Mon, Feb 25, 2019 at 11:00 AM Arnaldo Carvalho de Melo> <arnaldo.melo@xxxxxxxxx> wrote:
>>>>>
>>>>>>> Em Mon, Feb 25, 2019 at 01:02:39PM -0300, Arnaldo Carvalho de Melo escreveu:
>>>>>>>> So yeah, the BTF encoder/decoder is working just fine, the problem is in
>>>>>>>> pahole's DWARF code, lemme see...
>>>>>>>
>>>>>>> Please try the patch below, for me btfdiff continues to show no diff for
>>>>>>> all types in my vmlinux and now it also produces the same output for
>>>>>>> when the first element of a bitfield has its bit_size equal to its
>>>>>>> byte_size * 8:
>>>>>>
>>>>>> Yes, this fixes all the issues I've seen. btfdiff output is now empty
>>>>>> for my kernel image. Thanks for quick fix!
>>>>>>
>>>>>> Reviewed-by: Andrii Nakryiko <andriin@xxxxxx>
>>>>>
>>>>> Thanks, just for some extra testing I tried encoding BTF for glibc 2.28:
>>>>>
>>>>> [acme@quaco pahole]$ pahole -JV libc-2.28.so.debug
>>>>> <BIG snip>
>>>>
>>>> <snip>
>>>>
>>>>> [386075] INT long unsigned int size=8 bit_offset=0 nr_bits=64 encoding=(none)
>>>>> Cannot open libc-2.28.so.debug
>>>>> Failed to encode BTF
>>>>
>>>> I've tried the same on libc-2.26.so.debug and it worked.
>>>>
>>>> It failes after BTF encoding and deduping is done, exactly when it
>>>> tries to re-open libc-2.28.so.debug to write out new contents. Not
>>>> sure why it would fail, as it seems to be just plain open() call, but
>>>> the fact that we both can repro this means there is something there.
>>>>
>>>> It also seems that libc-2.28.so.debug is corrupted:
>>>>
>>>> $ readelf -n /home/andriin/local/btf/libc-2.26.so.debug | grep
>>>> 'Unknown note type' | wc -l
>>>> 0
>>>> $ readelf -n /home/andriin/local/btf/libc-2.28.so.debug | grep
>>>> 'Unknown note type' | wc -l
>>>> 17953
>>>>
>>>
>>> Ignore everything I've said (though 'Unknown note type' issue is
>>> strange), for me it was just permissions issues.
>>>
>>> $ chmod +rw /home/andriin/local/btf/libc-2.28.so.debug
>>>
>>> $ ~/local/pahole/build/pahole -J ~/local/btf/libc-2.28.so.debug
>>>
>>> $ PAHOLE=~/local/pahole/build/pahole ./btfdiff ~/local/btf/libc-2.28.so.debug
>>> base_type__name_to_size: base_type _Float128
>>> class__fixup_btf_bitfields: unknown base type name "_Float128"!
>>> base_type__name_to_size: base_type _Float128
>>> class__fixup_btf_bitfields: unknown base type name "_Float128"!
>>> base_type__name_to_size: base_type _Float128
>>> class__fixup_btf_bitfields: unknown base type name "_Float128"!
>>> base_type__name_to_size: base_type _Float128
>>> class__fixup_btf_bitfields: unknown base type name "_Float128"!
>>> base_type__name_to_size: base_type _Float128
>>> class__fixup_btf_bitfields: unknown base type name "_Float128"!
>>> base_type__name_to_size: base_type _Float128
>>> class__fixup_btf_bitfields: unknown base type name "_Float128"!
>>> --- /tmp/btfdiff.dwarf.aV4wSL   2019-02-25 13:31:54.787923673 -0800
>>> +++ /tmp/btfdiff.btf.22NQmJ     2019-02-25 13:31:54.802923668 -0800
>>> @@ -461,9 +461,15 @@ struct La_x86_64_retval {
>>>           uint64_t                   lrv_rdx;              /*     8     8 */
>>>           La_x86_64_xmm              lrv_xmm0;             /*    16    16 */
>>>           La_x86_64_xmm              lrv_xmm1;             /*    32    16 */
>>> -       long double                lrv_st0;              /*    48    16 */
>>> +       long double                lrv_st0;              /*    48     8 */
>>> +
>>> +       /* XXX 8 bytes hole, try to pack */
>>> +
>>>           /* --- cacheline 1 boundary (64 bytes) --- */
>>> -       long double                lrv_st1;              /*    64    16 */
>>> +       long double                lrv_st1;              /*    64     8 */
>>> +
>>> +       /* XXX 8 bytes hole, try to pack */
>>> +
>>>           La_x86_64_vector           lrv_vector0;          /*    80    64 */
>>>           /* --- cacheline 2 boundary (128 bytes) was 16 bytes ago --- */
>>>           La_x86_64_vector           lrv_vector1;          /*   144    64 */
>>> @@ -472,6 +478,7 @@ struct La_x86_64_retval {
>>>           __int128                   lrv_bnd1;             /*   224    16 */
>>>
>>>           /* size: 240, cachelines: 4, members: 10 */
>>> +       /* sum members: 224, holes: 2, sum holes: 16 */
>>>           /* last cacheline: 48 bytes */
>>>    };
>>>    struct r_debug {
>>> @@ -2044,7 +2051,7 @@ union ieee754_float {
>>>           } ieee_nan;                                    /*     0     4 */
>>>    };
>>>    union ieee854_long_double {
>>> -       long double                d;                  /*     0    16 */
>>> +       long double                d;                  /*     0     8 */
>>>           struct {
>>>                   unsigned int       mantissa1:32;       /*     0: 0  4 */
>>>                   unsigned int       mantissa0:32;       /*     4: 0  4 */
>>> @@ -2141,7 +2148,7 @@ struct ucontext_t {
>>>           /* last cacheline: 8 bytes */
>>>    };
>>>    union ieee854_float128 {
>>> -       _Float128                  d;                  /*     0    16 */
>>> +       _Float128                  d;                  /*     0     0 */
>>>           struct {
>>>                   unsigned int       mantissa3:32;       /*     0: 0  4 */
>>>                   unsigned int       mantissa2:32;       /*     4: 0  4 */
>>> @@ -2219,7 +2226,7 @@ union printf_arg {
>>>           long unsigned int          pa_u_long_int;      /*     0     8 */
>>>           long long unsigned int     pa_u_long_long_int; /*     0     8 */
>>>           double                     pa_double;          /*     0     8 */
>>> -       long double                pa_long_double;     /*     0    16 */
>>> +       long double                pa_long_double;     /*     0     8 */
>>>           const char  *              pa_string;          /*     0     8 */
>>>           const wchar_t  *           pa_wstring;         /*     0     8 */
>>>           void *                     pa_pointer;         /*     0     8 */
>>>
>>> Seems like "long double" size is invalid for BTF. And we should
>>> probably add "_Float128" as another "well known" base type name?
>>
>> BPF does not support floating point instructions. As the result,
>> BTF design does not contain floating point types.
>>
>> Looks like kernel also uses float types (in certain drivers and arch's),
>> but types referred by bpf program mostly will not contain float types.
>>
>> Currently, both llvm and pahole will ignore floating types, so
>> from type comparison point of view, we will be fine.
>> The issue may come up with people using vmlinux BTF inside the
>> kernel for different purpose where a float type needs to be
>> specified, e.g., for a floating point function argument in ftrace.
>> But this is rare too.
>>
>> I am not 100% sure whether pahole dwarf/btf parity is considered
>> as a strong reason to add floating point type support in BTF or not.
> 
> Isn't float and double just another base type with corresponding name?
> Fundamentally, how is it different from int or long? It's still just a
> collection of bits in 32-bit, 64-bit, etc number, except interpreted
> differently. Do you mean that for BTF to properly support floats,
> we'll need to extends set of possible encodings in INT type (in
> addition to today's CHAR, SIGNED and UNSIGNED)?

Probably another kind like BTF_KIND_FLOAT with additional u32 (in 
addition to btf_type) indicating the size (4 bytes, 8 bytes and 16 bytes).

> 
>>
>>>
>>> Though for the latter, it probably would be better to resolve base
>>> type size using BTF data itself.
>>>
>>>>> [acme@quaco pahole]$




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

  Powered by Linux