<div dir="ltr"><div dir="ltr">On Mon, Aug 30, 2021 at 1:37 PM Andrii Nakryiko <<a href="mailto:andriin@fb.com">andriin@fb.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><blockquote type="cite"><div dir="ltr"><div>
<div>
<div>2) Tell users that they can either include either the
autogenerated "vmlinux.h", OR set the pragma and include
normal kernel headers. But not both. AFAICT, the vmlinux.h
file is not really version-independent -- except that it
uses the "preserve_access_index" pragma in order to allow
field accesses to be adjusted at load-time to match the
actual struct layout. Doesn't putting the same pragma
around the normal kernel headers work, too?</div>
</div>
</div>
</div>
</blockquote>
<p>That's what we are telling users right now. And that's what users
are complaining about. vmlinux.h is sufficiently
version-independent with BPF CO-RE, unless some fields are
removed/renamed, or you need the very latest new field added in
more recent kernel than the one you used to generate vmlinux.h.<br>
</p>
<p></p></div></blockquote><div>I understand the problem with using only vmlinux.h. What is the complaint users have with using <i>only</i> the kernel-internal headers, though?</div><div><br></div><div>Using the type definitions from normal kernel headers will have a result which is just as version-independent, so long as you use `<span style="font-variant-ligatures:no-common-ligatures;color:rgb(0,0,0);font-family:Menlo;font-size:11px">#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)</span>`, right?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><blockquote type="cite">
<div dir="ltr">
<div>
<div>
<div>3) Automatically extract #defines from kernel headers
(e.g. using -dD to print all macro-expansions) to create a
new header with those values. (Or defines and inline
functions. Or everything but struct definitions. Or
something along those lines). Have people include that,
instead.<br>
</div>
</div>
<div><br>
</div>
<div>
<div>...Although, IIUC, you want use the kernel-internal
headers e.g. "include/linux/socket.h", not the stable
"uapi" headers, e.g. "include/uapi/linux/socket.h". But
can't those defines change arbitrarily? Doesn't that ruin
the version-independence aspect? So, maybe you want:</div>
</div>
</div>
</div>
</blockquote>
<p>Yes, users often need to work with types defined in
kernel-internal headers. You are right that internal #defines are
"unstable", so users are usually interested in stable #defines in
UAPI headers. The problem is that vmlinux.h is all or nothing
approach, currently. If you use vmlinux.h (because you need
internal types, not just UAPI ones), you can't include UAPI
headers (for those #defines) anymore due to type conflicts. That's
exactly what Yonghong is trying to solve here.<br></p></div></blockquote><div>So, is the desire here to enable mixing uapi headers + vmlinux.h, or mix kernel internal headers + vmlinux.h, or it doesn't really matter, either one would be fine, whichever can be made to work?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><blockquote type="cite">
<div dir="ltr">
<div>
<div>4) Enhance BPF/CO:RE to support defines as
compile-time-unknown/runtime-constants [at least some useful
subset of them]. Then they too can be fixed up at BPF
load-time, instead of hoping that the values never change.<br>
</div>
</div>
</div>
</blockquote>
<p>#defines are not relocatable at runtime by any means, because
they are just arbitrary text substituted by compiler. Once Clang
compiled BPF program into object file, there is nothing you can do
about #defines used. I don't see any way for BPF CO-RE to do
"relocatable" #defines.</p></div></blockquote><div>In this proposal, I was imagining that the unstable values would be exposed as globals, instead, and treated as constants at load time. (Similar to what you're doing with CONFIG_* values, where they are unknown globals at compile-time, and constants at load time.)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><blockquote type="cite">
<div dir="ltr">
<div>Though, the example you give is "TCP" (IPPROTO_TCP?) which <i>is</i> in
the uapi. Maybe you do need only the stable uapi defines? In
which case,<br>
</div>
<div><br>
</div>
<div>
<div>5) Create a set of modified uapi headers for use with
bpf, which omits struct definitions, and instead has
#include vmlinux.h at the top instead. Distribute with
libbpf-dev, perhaps?<br>
</div>
</div>
</div>
</blockquote>
<p>That's not really a solution, rather a maintenance nightmare.
It's never a good idea to maintain a separate copy of something
that's developed by thousands of developers, and have hope to keep
up with all the changes. If that's the only possible solution,
then going back to status quo (making this user's problem and
telling them no to use vmlinux.h at all) is a less painful way.</p></div></blockquote><div>I meant to say that this set of modified headers could be generated, not that you'd want to manually maintain a separate fork of it.</div><div><br></div></div></div>