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.
Link: https://clang.llvm.org/docs/LanguageExtensions.html#extended-integer-types
Link: https://reviews.llvm.org/D93103
Signed-off-by: Sean Young <[email protected]>
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
--
2.29.2
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.
This requires the _ExtInt extension enabled in clang, which is under
review.
Link: https://clang.llvm.org/docs/LanguageExtensions.html#extended-integer-types
Link: https://reviews.llvm.org/D93103
Signed-off-by: Sean Young <[email protected]>
---
tools/lib/bpf/btf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 3c3f2bc6c652..a676373f052b 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -1722,7 +1722,7 @@ int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding
if (!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;
--
2.29.2
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.
This requires the _ExtInt extension enabled in clang, which is under
review.
Link: https://clang.llvm.org/docs/LanguageExtensions.html#extended-integer-types
Link: https://reviews.llvm.org/D93103
Signed-off-by: Sean Young <[email protected]>
---
tools/bpf/bpftool/btf_dumper.c | 40 ++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
index 0e9310727281..8b5318ec5c26 100644
--- a/tools/bpf/bpftool/btf_dumper.c
+++ b/tools/bpf/bpftool/btf_dumper.c
@@ -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;
--
2.29.2
On Tue, Jan 05, 2021 at 02:45:30PM +0000, Sean Young wrote:
> 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.
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.
On Tue, Jan 5, 2021 at 6:45 AM Sean Young <[email protected]> wrote:
>
> 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.
>
> This requires the _ExtInt extension enabled in clang, which is under
> review.
>
> Link: https://clang.llvm.org/docs/LanguageExtensions.html#extended-integer-types
> Link: https://reviews.llvm.org/D93103
>
> Signed-off-by: Sean Young <[email protected]>
> ---
all the same comments as in patch #1
> tools/bpf/bpftool/btf_dumper.c | 40 ++++++++++++++++++++++++++++++++++
> 1 file changed, 40 insertions(+)
>
> diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
> index 0e9310727281..8b5318ec5c26 100644
> --- a/tools/bpf/bpftool/btf_dumper.c
> +++ b/tools/bpf/bpftool/btf_dumper.c
> @@ -271,6 +271,41 @@ static void btf_int128_print(json_writer_t *jw, const void *data,
> }
> }
[...]