ebpf icon indicating copy to clipboard operation
ebpf copied to clipboard

Support for BTF_KIND_DECL_TAG and BTF_KIND_TYPE_TAG

Open lmb opened this issue 3 years ago • 4 comments

Linux 5.18 added a two new BTF kinds DECL_TAG and TYPE_TAG. TYPE_TAG seems fine, the encoding for DECL_TAG looks like a headache.

Most relevant Linux commit: https://github.com/torvalds/linux/commit/7472d5a642c94a0ee1882ff3038de72ffe803a01

pahole only generates these kinds from v1.23 onwards:

  • DECL_TAG https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?h=next&id=ec62499774c4bcac720706018385ced0c1f060ab
  • TYPE_TAG https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?h=next&id=d99d551930cf4b4bc41eb5d68b7da69d718a6553

clang-14 is also required: https://reviews.llvm.org/D111199

  • [x] Parse / skip the new types
  • [ ] Omit encoding new types in Spec.marshal if the kernel doesn't understand them
  • [ ] Export types from btf

lmb avatar Jun 15 '22 17:06 lmb

With BTF-enabled kernels becoming generally available in distro's, we might need to think about tolerating/ignoring unknown types so older tools written with CO-RE are forwards-compatible with newer kernels.

Time for a btf.ReaderOptions of some sort? :)

ti-mo avatar Jun 28 '22 21:06 ti-mo

BTF isn't self describing unfortunately, so skipping unknown types is not possible.

lmb avatar Jun 29 '22 14:06 lmb

My current reading of this is that vmlinux BTF will only contain these new types if:

  • clang >= 14
  • pahole >= 1.23
  • the kernel is built with clang instead of gcc

Not sure how many production kernels use clang instead of gcc.

lmb avatar Jul 20 '22 09:07 lmb

An idea I've been kicking around: DECL_TAG and TYPE_TAG are a bit of a bodge to add stringly typed metadata to the BTF wire format. What if we didn't represent them as Type, but instead added the metadata to Pointer or whatever?

type Pointer struct {
	...
	Tags []string
}

When decoding BTF we'd add TYPE_TAGs to Pointer.Tags and during marshaling we'd create TYPE_TAG on the fly. Similar for DECL_TAG which applies to Struct and Union (and others?) This is the best solution from an API perspective, it's very easy to add and remove tags from a Type.

Downsides:

  • We're creating a mismatch with upstream BTF. With this approach it would be impossible to get the type ID of a *_TAG, so if we ever need to pass such an ID to the kernel we'd be in a pickle.
  • We might also have to add Tags to a large number of Types.
  • We'd have to follow tag2 -> tag1 -> type chains during decoding somehow.

lmb avatar Jan 12 '23 16:01 lmb