btf: support ints larger than 128 bits
Subsystems (8)
v3 cover btf: support ints larger than 128 bits
clang supports arbitrary length ints using the _ExtInt extension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.
Larger types (e.g. 1024 bits) are possible but I am unaware of a use case for these.
This requires the _ExtInt extension enabled in clang, which is under review.
changes since v2:
- split patches into 4 distinct patches
changes since v1:
- added tests as suggested by Yonghong Song
- added kernel pretty-printer
Sean Young (4):
btf: add support for ints larger than 128 bits
libbpf: add support for ints larger than 128 bits
bpftool: add support for ints larger than 128 bits
bpf: add tests for ints larger than 128 bits
Documentation/bpf/btf.rst | 4 +- include/uapi/linux/btf.h | 2 +- kernel/bpf/btf.c | 54 +- tools/bpf/bpftool/btf_dumper.c | 40 ++ tools/include/uapi/linux/btf.h | 2 +- tools/lib/bpf/btf.c | 2 +- tools/testing/selftests/bpf/Makefile | 3 +- tools/testing/selftests/bpf/prog_tests/btf.c | 3 +- .../selftests/bpf/progs/test_btf_extint.c | 50 ++ tools/testing/selftests/bpf/test_extint.py | 535 ++++++++++++++++++ 10 files changed, 679 insertions(+), 16 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/test_btf_extint.c create mode 100755 tools/testing/selftests/bpf/test_extint.py
Signature · 1 line
2.29.2
PATCH v3 1/4 btf: add support for ints larger than 128 bits
clang supports arbitrary length ints using the _ExtInt extension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.
Larger types (e.g. 1024 bits) are possible but I am unaware of a use case for these.
This requires the _ExtInt extension enabled in clang, which is under review.
--- Documentation/bpf/btf.rst | 4 +-- include/uapi/linux/btf.h | 2 +- kernel/bpf/btf.c | 54 ++++++++++++++++++++++++++++------ tools/include/uapi/linux/btf.h | 2 +- 4 files changed, 49 insertions(+), 13 deletions(-)
Documentation/bpf/btf.rst +2 -2
@@ -132,7 +132,7 @@ The following sections detail encoding of each kind. #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) #define BTF_INT_OFFSET(VAL) (((VAL) & 0x00ff0000) >> 16) - #define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff) + #define BTF_INT_BITS(VAL) ((VAL) & 0x000003ff) The ``BTF_INT_ENCODING`` has the following attributes::
@@ -147,7 +147,7 @@ pretty print. At most one encoding can be specified for the int type. The ``BTF_INT_BITS()`` specifies the number of actual bits held by this int type. For example, a 4-bit bitfield encodes ``BTF_INT_BITS()`` equals to 4. The ``btf_type.size * 8`` must be equal to or greater than ``BTF_INT_BITS()`` -for the type. The maximum value of ``BTF_INT_BITS()`` is 128. +for the type. The maximum value of ``BTF_INT_BITS()`` is 512. The ``BTF_INT_OFFSET()`` specifies the starting bit offset to calculate values for this int. For example, a bitfield struct member has:
include/uapi/linux/btf.h +1 -1
@@ -84,7 +84,7 @@ struct btf_type {*/ #define BTF_INT_ENCODING (VAL ) (((VAL) & 0x0f000000) >> 24)#define BTF_INT_OFFSET (VAL ) (((VAL) & 0x00ff0000) >> 16) -#define BTF_INT_BITS (VAL ) ((VAL) & 0x000000ff) +#define BTF_INT_BITS (VAL ) ((VAL) & 0x000003ff)/* Attributes stored in the BTF_INT_ENCODING */ #define BTF_INT_SIGNED (1 << 0)
kernel/bpf/btf.c +45 -9
98 lines not on this page · raw message
tools/include/uapi/linux/btf.h +1 -1
@@ -84,7 +84,7 @@ struct btf_type {*/ #define BTF_INT_ENCODING (VAL ) (((VAL) & 0x0f000000) >> 24)#define BTF_INT_OFFSET (VAL ) (((VAL) & 0x00ff0000) >> 16) -#define BTF_INT_BITS (VAL ) ((VAL) & 0x000000ff) +#define BTF_INT_BITS (VAL ) ((VAL) & 0x000003ff)/* Attributes stored in the BTF_INT_ENCODING */ #define BTF_INT_SIGNED (1 << 0)
Signature · 1 line
2.29.2
Re: [PATCH v3 1/4] btf: add support for ints larger than 128 bits
Quoted 124 lines · Sean Young
clang supports arbitrary length ints using the
_ExtIntextension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.Larger types (e.g. 1024 bits) are possible but I am unaware of a use case for these.
This requires the
_ExtIntextension enabled in clang, which is under review.Signed-off-by Sean Young <[email protected]>--- Documentation/bpf/btf.rst | 4 +-- include/uapi/linux/btf.h | 2 +- kernel/bpf/btf.c | 54 ++++++++++++++++++++++++++++------ tools/include/uapi/linux/btf.h | 2 +- 4 files changed, 49 insertions(+), 13 deletions(-)Documentation/bpf/btf.rst +2
-2@@ -132,7 +132,7 @@ The following sections detail encoding of each kind. #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) #define BTF_INT_OFFSET(VAL) (((VAL) & 0x00ff0000) >> 16) - #define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff) + #define BTF_INT_BITS(VAL) ((VAL) & 0x000003ff) The ``BTF_INT_ENCODING`` has the following attributes::@@ -147,7 +147,7 @@ pretty print. At most one encoding can be specified for the int type. The ``BTF_INT_BITS()`` specifies the number of actual bits held by this int type. For example, a 4-bit bitfield encodes ``BTF_INT_BITS()`` equals to 4. The ``btf_type.size * 8`` must be equal to or greater than ``BTF_INT_BITS()`` -for the type. The maximum value of ``BTF_INT_BITS()`` is 128. +for the type. The maximum value of ``BTF_INT_BITS()`` is 512. The ``BTF_INT_OFFSET()`` specifies the starting bit offset to calculate values for this int. For example, a bitfield struct member has:include/uapi/linux/btf.h +1
-1@@ -84,7 +84,7 @@ struct btf_type {*/ #define BTF_INT_ENCODING (VAL ) (((VAL) & 0x0f000000) >> 24)#define BTF_INT_OFFSET (VAL ) (((VAL) & 0x00ff0000) >> 16) -#define BTF_INT_BITS (VAL ) ((VAL) & 0x000000ff) +#define BTF_INT_BITS (VAL ) ((VAL) & 0x000003ff)/* Attributes stored in the BTF_INT_ENCODING */ #define BTF_INT_SIGNED (1 << 0)kernel/bpf/btf.c +22
-8@@ -166,7 +166,8 @@* */ -#define BITS_PER_U128 (sizeof(u64) * BITS_PER_BYTE * 2) +#define BITS_PER_U128 128 +#define BITS_PER_U512 512#define BITS_PER_BYTE_MASK (BITS_PER_BYTE - 1)#define BITS_PER_BYTE_MASKED (bits) ((bits) & BITS_PER_BYTE_MASK)#define BITS_ROUNDDOWN_BYTES (bits) ((bits) >> 3)@@ -1907,9 +1908,9 @@ static int btf_int_check_member(struct btf_verifier_env *env, nr_copy_bits =BTF_INT_BITS (int_data) +BITS_PER_BYTE_MASKED (struct_bits_off); -if (nr_copy_bits >BITS_PER_U128 ) { +if (nr_copy_bits >BITS_PER_U512 ) {btf_verifier_log_member (env, struct_type, member, -"nr_copy_bits exceeds 128" ); +"nr_copy_bits exceeds 512" );return -EINVAL ; }@@ -1963,9 +1964,9 @@ static int btf_int_check_kflag_member(struct btf_verifier_env *env, bytes_offset =BITS_ROUNDDOWN_BYTES (struct_bits_off); nr_copy_bits = nr_bits +BITS_PER_BYTE_MASKED (struct_bits_off); -if (nr_copy_bits >BITS_PER_U128 ) { +if (nr_copy_bits >BITS_PER_U512 ) {btf_verifier_log_member (env, struct_type, member, -"nr_copy_bits exceeds 128" ); +"nr_copy_bits exceeds 512" );return -EINVAL ; }@@ -2012,9 +2013,9 @@ static s32 btf_int_check_meta(struct btf_verifier_env *env, nr_bits =BTF_INT_BITS (int_data) +BTF_INT_OFFSET (int_data); -if (nr_bits >BITS_PER_U128 ) { -btf_verifier_log_type (env, t,"nr_bits exceeds %zu" , -BITS_PER_U128 ); +if (nr_bits >BITS_PER_U512 ) { +btf_verifier_log_type (env, t,"nr_bits exceeds %u" , +BITS_PER_U512 );return -EINVAL ; }@@ -2080,6 +2081,37 @@ static void btf_int128_print(struct btf_show *show, void *data) lower_num); } +static void btf_bigint_print (struct btf_show *show,void *data,u16 nr_bits) +{ +/* data points to 256 or 512 bit int type */ +char buf[129 ]; +int last_u64 = nr_bits /64 -1 ; +bool seen_nonzero = false; +int i; + +for (i =0 ; i <= last_u64; i++) { +#ifdef __BIG_ENDIAN_BITFIELD +u64 v = ((u64 *)data)[i]; +#else +u64 v = ((u64 *)data)[last_u64 - i];
kernel/bpf/btf.c static void btf_int128_print(struct btf_show *show, void *data) · line 2106
Quoted 10 lines
kernel/bpf/btf.c +10
-0+#endif +if (!seen_nonzero) { +if (!v && i != last_u64) +continue ; + +snprintf (buf,sizeof (buf),"%llx" , v); + + seen_nonzero = true; + }else { +size_t off =strlen (buf);
this is wasteful, snprintf() returns number of characters printed, so you can maintain offset properly
kernel/bpf/btf.c static void btf_int128_print(struct btf_show *show, void *data) · line 2113
Quoted 7 lines
kernel/bpf/btf.c +7
-0+ +snprintf (buf + off,sizeof (buf) - off,"%016llx" , v); + } + } + +btf_show_type_value (show,"0x%s" , buf); +}
seen_nonzero is a bit convoluted, two simple loops might be more straightforward:
u64 v;
int off;
/* find first non-zero u64 (or stop on the last one regardless) */ for (i = 0; i < last_u64; i++) {
v = ...;
if (!v)
continue; }
/* print non-zero or zero, but last u64 */
off = snprintf(buf, sizeof(buf), "%llx", v);
/* print the rest with zero padding */
for (i++; i <= last_u64; i++) {
v = ...;
off += snprintf(buf + off, sizeof(buf) - off, "%016llx", v);
}
Quoted 14 lines
kernel/bpf/btf.c +2
-1+static void btf_int128_shift (u64 *print_num,u16 left_shift_bits,u16 right_shift_bits) {@@ -2172,7 +2204,7 @@ static void btf_int_show(const struct btf *btf, const struct btf_type *t,u32 int_data =btf_type_int (t);u8 encoding =BTF_INT_ENCODING (int_data);bool sign = encoding &BTF_INT_SIGNED ; -u8 nr_bits =BTF_INT_BITS (int_data); +u16 nr_bits =BTF_INT_BITS (int_data);void *safe_data; safe_data =btf_show_start_type (show, t, type_id, data);
kernel/bpf/btf.c static void btf_int_show(const struct btf *btf, const struct btf_type *t, · line 2226
Quoted 9 lines
kernel/bpf/btf.c +4
-0@@ -2186,6 +2218,10 @@ static void btf_int_show(const struct btf *btf, const struct btf_type *t, }switch (nr_bits) { +case 512 : +case 256 : +btf_bigint_print (show, safe_data, nr_bits); +break ;case 128 :btf_int128_print (show, safe_data);
btf_bigint_print() supersedes btf_int128_print(), why maintain both?
Quoted 17 lines
kernel/bpf/btf.c +0
-0break ;tools/include/uapi/linux/btf.h +1
-2@@ -84,7 +84,7 @@ struct btf_type {*/ #define BTF_INT_ENCODING (VAL ) (((VAL) & 0x0f000000) >> 24)#define BTF_INT_OFFSET (VAL ) (((VAL) & 0x00ff0000) >> 16) -#define BTF_INT_BITS (VAL ) ((VAL) & 0x000000ff) +#define BTF_INT_BITS (VAL ) ((VAL) & 0x000003ff)/* Attributes stored in the BTF_INT_ENCODING */ #define BTF_INT_SIGNED (1 << 0) --2.29.2
Re: [PATCH v3 1/4] btf: add support for ints larger than 128 bits
Quoted 113 lines · Andrii Nakryiko
Quoted 111 lines · Sean Young
clang supports arbitrary length ints using the
_ExtIntextension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.Larger types (e.g. 1024 bits) are possible but I am unaware of a use case for these.
This requires the
_ExtIntextension enabled in clang, which is under review.Signed-off-by Sean Young <[email protected]>--- Documentation/bpf/btf.rst | 4 +-- include/uapi/linux/btf.h | 2 +- kernel/bpf/btf.c | 54 ++++++++++++++++++++++++++++------ tools/include/uapi/linux/btf.h | 2 +- 4 files changed, 49 insertions(+), 13 deletions(-)Documentation/bpf/btf.rst +2
-2@@ -132,7 +132,7 @@ The following sections detail encoding of each kind. #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) #define BTF_INT_OFFSET(VAL) (((VAL) & 0x00ff0000) >> 16) - #define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff) + #define BTF_INT_BITS(VAL) ((VAL) & 0x000003ff) The ``BTF_INT_ENCODING`` has the following attributes::@@ -147,7 +147,7 @@ pretty print. At most one encoding can be specified for the int type. The ``BTF_INT_BITS()`` specifies the number of actual bits held by this int type. For example, a 4-bit bitfield encodes ``BTF_INT_BITS()`` equals to 4. The ``btf_type.size * 8`` must be equal to or greater than ``BTF_INT_BITS()`` -for the type. The maximum value of ``BTF_INT_BITS()`` is 128. +for the type. The maximum value of ``BTF_INT_BITS()`` is 512. The ``BTF_INT_OFFSET()`` specifies the starting bit offset to calculate values for this int. For example, a bitfield struct member has:include/uapi/linux/btf.h +1
-1@@ -84,7 +84,7 @@ struct btf_type {*/ #define BTF_INT_ENCODING (VAL ) (((VAL) & 0x0f000000) >> 24)#define BTF_INT_OFFSET (VAL ) (((VAL) & 0x00ff0000) >> 16) -#define BTF_INT_BITS (VAL ) ((VAL) & 0x000000ff) +#define BTF_INT_BITS (VAL ) ((VAL) & 0x000003ff)/* Attributes stored in the BTF_INT_ENCODING */ #define BTF_INT_SIGNED (1 << 0)kernel/bpf/btf.c +9
-8@@ -166,7 +166,8 @@* */ -#define BITS_PER_U128 (sizeof(u64) * BITS_PER_BYTE * 2) +#define BITS_PER_U128 128 +#define BITS_PER_U512 512#define BITS_PER_BYTE_MASK (BITS_PER_BYTE - 1)#define BITS_PER_BYTE_MASKED (bits) ((bits) & BITS_PER_BYTE_MASK)#define BITS_ROUNDDOWN_BYTES (bits) ((bits) >> 3)@@ -1907,9 +1908,9 @@ static int btf_int_check_member(struct btf_verifier_env *env, nr_copy_bits =BTF_INT_BITS (int_data) +BITS_PER_BYTE_MASKED (struct_bits_off); -if (nr_copy_bits >BITS_PER_U128 ) { +if (nr_copy_bits >BITS_PER_U512 ) {btf_verifier_log_member (env, struct_type, member, -"nr_copy_bits exceeds 128" ); +"nr_copy_bits exceeds 512" );return -EINVAL ; }@@ -1963,9 +1964,9 @@ static int btf_int_check_kflag_member(struct btf_verifier_env *env, bytes_offset =BITS_ROUNDDOWN_BYTES (struct_bits_off); nr_copy_bits = nr_bits +BITS_PER_BYTE_MASKED (struct_bits_off); -if (nr_copy_bits >BITS_PER_U128 ) { +if (nr_copy_bits >BITS_PER_U512 ) {btf_verifier_log_member (env, struct_type, member, -"nr_copy_bits exceeds 128" ); +"nr_copy_bits exceeds 512" );return -EINVAL ; }@@ -2012,9 +2013,9 @@ static s32 btf_int_check_meta(struct btf_verifier_env *env, nr_bits =BTF_INT_BITS (int_data) +BTF_INT_OFFSET (int_data); -if (nr_bits >BITS_PER_U128 ) { -btf_verifier_log_type (env, t,"nr_bits exceeds %zu" , -BITS_PER_U128 ); +if (nr_bits >BITS_PER_U512 ) { +btf_verifier_log_type (env, t,"nr_bits exceeds %u" , +BITS_PER_U512 );return -EINVAL ; }@@ -2080,6 +2081,37 @@ static void btf_int128_print(struct btf_show *show, void *data) lower_num); }
Quoted 14 lines
Quoted 4 lines
kernel/bpf/btf.c +4
-0+static void btf_bigint_print (struct btf_show *show,void *data,u16 nr_bits) +{ +/* data points to 256 or 512 bit int type */ +char buf[129 ];kernel/bpf/btf.c static void btf_int128_print(struct btf_show *show, void *data) · line 2097
Quoted 10 lines
kernel/bpf/btf.c +10
-0+int last_u64 = nr_bits /64 -1 ; +bool seen_nonzero = false; +int i; + +for (i =0 ; i <= last_u64; i++) { +#ifdef __BIG_ENDIAN_BITFIELD +u64 v = ((u64 *)data)[i]; +#else +u64 v = ((u64 *)data)[last_u64 - i]; +#endif
to avoid duplicating this #ifdef with my suggestion, you can do something like
#ifdef __BIG_ENDIAN_BITFIELD
u64 *v = (u64 *)data;
int step = 1;
#else
u64 *v = (u64 *)data + last_u64;
int step = -1;
#endif
and then just v += step; everywhere
Quoted 84 lines
kernel/bpf/btf.c static void btf_int128_print(struct btf_show *show, void *data) · line 2106
Quoted 9 lines
kernel/bpf/btf.c +9
-0+if (!seen_nonzero) { +if (!v && i != last_u64) +continue ; + +snprintf (buf,sizeof (buf),"%llx" , v); + + seen_nonzero = true; + }else { +size_t off =strlen (buf);this is wasteful,
snprintf()returns number of characters printed, so you can maintain offset properlykernel/bpf/btf.c static void btf_int128_print(struct btf_show *show, void *data) · line 2113
Quoted 7 lines
kernel/bpf/btf.c +7
-0+ +snprintf (buf + off,sizeof (buf) - off,"%016llx" , v); + } + } + +btf_show_type_value (show,"0x%s" , buf); +}
seen_nonzerois a bit convoluted, two simple loops might be more straightforward:u64 v;
int off;/* find first non-zero u64 (or stop on the last one regardless) */ for (i = 0; i <
last_u64; i++) {
v = ...;
if (!v)continue; }/* print non-zero or zero, but last u64 */
off =snprintf(buf, sizeof(buf), "%llx", v);
/* print the rest with zero padding */
for (i++; i <=last_u64; i++) {
v = ...;
off +=snprintf(buf + off, sizeof(buf) - off, "%016llx", v);
}Quoted 14 lines
kernel/bpf/btf.c +2
-1+static void btf_int128_shift (u64 *print_num,u16 left_shift_bits,u16 right_shift_bits) {@@ -2172,7 +2204,7 @@ static void btf_int_show(const struct btf *btf, const struct btf_type *t,u32 int_data =btf_type_int (t);u8 encoding =BTF_INT_ENCODING (int_data);bool sign = encoding &BTF_INT_SIGNED ; -u8 nr_bits =BTF_INT_BITS (int_data); +u16 nr_bits =BTF_INT_BITS (int_data);void *safe_data; safe_data =btf_show_start_type (show, t, type_id, data);kernel/bpf/btf.c static void btf_int_show(const struct btf *btf, const struct btf_type *t, · line 2226
Quoted 9 lines
kernel/bpf/btf.c +4
-0@@ -2186,6 +2218,10 @@ static void btf_int_show(const struct btf *btf, const struct btf_type *t, }switch (nr_bits) { +case 512 : +case 256 : +btf_bigint_print (show, safe_data, nr_bits); +break ;case 128 :btf_int128_print (show, safe_data);
btf_bigint_print()supersedesbtf_int128_print(), why maintain both?Quoted 17 lines
kernel/bpf/btf.c +0
-0break ;tools/include/uapi/linux/btf.h +1
-2@@ -84,7 +84,7 @@ struct btf_type {*/ #define BTF_INT_ENCODING (VAL ) (((VAL) & 0x0f000000) >> 24)#define BTF_INT_OFFSET (VAL ) (((VAL) & 0x00ff0000) >> 16) -#define BTF_INT_BITS (VAL ) ((VAL) & 0x000000ff) +#define BTF_INT_BITS (VAL ) ((VAL) & 0x000003ff)/* Attributes stored in the BTF_INT_ENCODING */ #define BTF_INT_SIGNED (1 << 0) --2.29.2
PATCH v3 2/4 libbpf: add support for ints larger than 128 bits
In reply to Sean Youngclang supports arbitrary length ints using the _ExtInt extension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.
This requires the _ExtInt extension enabled in clang, which is under review.
--- tools/lib/bpf/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/bpf/btf.c +1 -1
@@ -1722,7 +1722,7 @@ int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encodingif (!name || !name[0 ])return -EINVAL ;/* byte_sz must be power of 2 */ -if (!byte_sz || (byte_sz & (byte_sz -1 )) || byte_sz >16 ) +if (!byte_sz || (byte_sz & (byte_sz -1 )) || byte_sz >64 )return -EINVAL ;if (encoding & ~(BTF_INT_SIGNED |BTF_INT_CHAR |BTF_INT_BOOL ))return -EINVAL ;
Signature · 1 line
2.29.2
PATCH v3 3/4 bpftool: add support for ints larger than 128 bits
In reply to Sean Youngclang supports arbitrary length ints using the _ExtInt extension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.
This requires the _ExtInt extension enabled in clang, which is under review.
--- tools/bpf/bpftool/btf_dumper.c | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
tools/bpf/bpftool/btf_dumper.c +40 -0
@@ -271,6 +271,41 @@ static void btf_int128_print(json_writer_t *jw, const void *data, } } +static void btf_bigint_print (json_writer_t *jw,const void *data,int nr_bits, +bool is_plain_text) +{ +char buf[nr_bits /4 +1 ]; +int last_u64 = nr_bits /64 -1 ; +bool seen_nonzero = false; +int i; + +for (i =0 ; i <= last_u64; i++) { +#ifdef __BIG_ENDIAN_BITFIELD +__u64 v = ((__u64 *)data)[i]; +#else +__u64 v = ((__u64 *)data)[last_u64 - i]; +#endif + +if (!seen_nonzero) { +if (!v && i != last_u64) +continue ; + +snprintf (buf,sizeof (buf),"%llx" , v); + + seen_nonzero = true; + }else { +size_t off =strlen (buf); + +snprintf (buf + off,sizeof (buf) - off,"%016llx" , v); + } + } + +if (is_plain_text) +jsonw_printf (jw,"0x%s" , buf); +else +jsonw_printf (jw,"\"0x%s\"" , buf); +} +static void btf_int128_shift (__u64 *print_num,__u16 left_shift_bits,__u16 right_shift_bits) {
@@ -373,6 +408,11 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,return 0 ; } +if (nr_bits >128 ) { +btf_bigint_print (jw, data, nr_bits, is_plain_text); +return 0 ; + } +if (nr_bits ==128 ) {btf_int128_print (jw, data, is_plain_text);return 0 ;
Signature · 1 line
2.29.2
Re: [PATCH v3 3/4] bpftool: add support for ints larger than 128 bits
Quoted 4 lines · Sean Young
clang supports arbitrary length ints using the
_ExtIntextension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.
Quoted 8 lines
This requires the
_ExtIntextension enabled in clang, which is under review.Signed-off-by Sean Young <[email protected]>---
all the same comments as in patch #1
Quoted 10 lines
tools/bpf/bpftool/btf_dumper.c | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)tools/bpf/bpftool/btf_dumper.c +0
-0@@ -271,6 +271,41 @@ static void btf_int128_print(json_writer_t *jw, const void *data, } }
[...]
PATCH v3 4/4 bpf: add tests for ints larger than 128 bits
In reply to Sean Youngclang supports arbitrary length ints using the _ExtInt extension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.
Larger types (e.g. 1024 bits) are possible but I am unaware of a use case for these.
This requires the _ExtInt extension enabled in clang, which is under review.
--- tools/testing/selftests/bpf/Makefile | 3 +- tools/testing/selftests/bpf/prog_tests/btf.c | 3 +- .../selftests/bpf/progs/test_btf_extint.c | 50 ++ tools/testing/selftests/bpf/test_extint.py | 535 ++++++++++++++++++ 4 files changed, 589 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/test_btf_extint.c create mode 100755 tools/testing/selftests/bpf/test_extint.py
tools/testing/selftests/bpf/Makefile +2 -1
@@ -70,7 +70,8 @@ TEST_PROGS := test_kmod.sh \ test_bpftool_build.sh \ test_bpftool.sh \ test_bpftool_metadata.sh \ - test_xsk.sh + test_xsk.sh \ + test_extint.py TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \
tools/testing/selftests/bpf/prog_tests/btf.c +2 -1
@@ -4073,6 +4073,7 @@ struct btf_file_test {static struct btf_file_test file_tests[] = { { .file ="test_btf_haskv.o" , }, { .file ="test_btf_newkv.o" , }, + { .file ="test_btf_extint.o" , }, { .file ="test_btf_nokv.o" , .btf_kv_notfound = true, }, };
@@ -4414,7 +4415,7 @@ static struct btf_raw_test pprint_test_template[] = {* will have both int and enum types. */ .raw_types = { -/* unsighed char */ /* [1] */ +/* unsigned char */ /* [1] */ BTF_TYPE_INT_ENC (NAME_TBD ,0 ,0 ,8 ,1 ),/* unsigned short */ /* [2] */ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
tools/testing/selftests/bpf/progs/test_btf_extint.c new file +50 -0
50 lines not on this page · raw message
tools/testing/selftests/bpf/test_extint.py new file +535 -0
535 lines not on this page · raw message
Signature · 1 line
2.29.2
Re: [PATCH v3 4/4] bpf: add tests for ints larger than 128 bits
Quoted 50 lines · Sean Young
clang supports arbitrary length ints using the
_ExtIntextension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.Larger types (e.g. 1024 bits) are possible but I am unaware of a use case for these.
This requires the
_ExtIntextension enabled in clang, which is under review.Signed-off-by Sean Young <[email protected]>--- tools/testing/selftests/bpf/Makefile | 3 +- tools/testing/selftests/bpf/prog_tests/btf.c | 3 +- .../selftests/bpf/progs/test_btf_extint.c | 50 ++ tools/testing/selftests/bpf/test_extint.py | 535 ++++++++++++++++++ 4 files changed, 589 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/test_btf_extint.c create mode 100755 tools/testing/selftests/bpf/test_extint.pytools/testing/selftests/bpf/Makefile +2
-1@@ -70,7 +70,8 @@ TEST_PROGS := test_kmod.sh \ test_bpftool_build.sh \ test_bpftool.sh \ test_bpftool_metadata.sh \ - test_xsk.sh + test_xsk.sh \ + test_extint.py TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \tools/testing/selftests/bpf/prog_tests/btf.c +1
-0@@ -4073,6 +4073,7 @@ struct btf_file_test {static struct btf_file_test file_tests[] = { { .file ="test_btf_haskv.o" , }, { .file ="test_btf_newkv.o" , }, + { .file ="test_btf_extint.o" , }, { .file ="test_btf_nokv.o" , .btf_kv_notfound = true, }, };
tools/testing/selftests/bpf/prog_tests/btf.c static struct btf_raw_test pprint_test_template[] = { · line 4418
Quoted 5 lines
tools/testing/selftests/bpf/prog_tests/btf.c +1
-1@@ -4414,7 +4415,7 @@ static struct btf_raw_test pprint_test_template[] = {* will have both int and enum types. */ .raw_types = { -/* unsighed char */ /* [1] */ +/* unsigned char */ /* [1] */
unintentional whitespaces change?
Quoted 17 lines
tools/testing/selftests/bpf/prog_tests/btf.c +0
-0BTF_TYPE_INT_ENC (NAME_TBD ,0 ,0 ,8 ,1 ),/* unsigned short */ /* [2] */ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),tools/testing/selftests/bpf/progs/test_btf_extint.c new file +8
-0@@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/bpf.h> +#include <bpf/bpf_helpers.h> +#include "bpf_legacy.h" + +struct extint { + _ExtInt(256) v256; + _ExtInt(512) v512;
tools/testing/selftests/bpf/progs/test_btf_extint.c line 18
Quoted 10 lines
tools/testing/selftests/bpf/progs/test_btf_extint.c new file +10
-0+}; + +struct bpf_map_def SEC("maps") btf_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(int), + .value_size = sizeof(struct extint), + .max_entries = 1, +}; + +BPF_ANNOTATE_KV_PAIR(btf_map, int, struct extint);
this is deprecated, don't add new tests using it. Please use BTF-based map definition instead (see any other selftests).
Quoted 20 lines
tools/testing/selftests/bpf/progs/test_btf_extint.c new file +20
-0+ +__attribute__((noinline)) +int test_long_fname_2 (void ) +{ +struct extint *bi; +int key =0 ; + + bi =bpf_map_lookup_elem (&btf_map, &key); +if (!bi) +return 0 ; + + bi->v256 <<=64 ; + bi->v256 += (_ExtInt(256))0xcafedead; + bi->v512 <<=128 ; + bi->v512 += (_ExtInt(512))0xff00ff00ff00ffull; + +return 0 ; +} + +__attribute__((noinline))
tools/testing/selftests/bpf/progs/test_btf_extint.c line 48
Quoted 10 lines
tools/testing/selftests/bpf/progs/test_btf_extint.c new file +10
-0+int test_long_fname_1 (void ) +{ +return test_long_fname_2 (); +} + +SEC("dummy_tracepoint") +int _dummy_tracepoint (void *arg) +{ +return test_long_fname_1 (); +}
why the chain of test_long_fname functions? Please minimize the test to only test the essential logic - _ExtInt handling.
tools/testing/selftests/bpf/test_extint.py
Quoted 7 lines
tools/testing/selftests/bpf/progs/test_btf_extint.c new file +2
-0+ +char _license[] SEC("license") = "GPL";tools/testing/selftests/bpf/test_extint.py new file +0
-0
this looks like a total overkill (with a lot of unrelated code) for a pretty simple test you need to perform. you can run bpftool and get its output from test_progs with popen().
Quoted 2 lines
tools/testing/selftests/bpf/test_extint.py new file +1
-0@@ -0,0 +1,535 @@ +#!/usr/bin/python3
[...]
Quoted 8 lines · Sean Young
clang supports arbitrary length ints using the
_ExtIntextension. This can be useful to hold very large values, e.g. 256 bit or 512 bit types.Larger types (e.g. 1024 bits) are possible but I am unaware of a use case for these.
This requires the
_ExtIntextension enabled in clang, which is under review.
1. Please explain the use case.
2. All patches have the same commit message which is not useful. Please spend some time in the commit message to explain what each individual patch does.
3. The test_extint.py is mostly a copy-and-paste from the existing test_offload.py? Does it need most of the test_offload.py to test the BTF 256/512 bit int? Please create a minimal test and use the test_progs.c infra-structure.