|
|
Subscribe / Log in / New account

Building header files into the kernel

By Jonathan Corbet
March 21, 2019
Kernel developers learn, one way or another, to be careful about memory use; any memory taken by the kernel is not available for use by the actual applications that people keep the computer around to run. So it is unsurprising that eyebrows went up when Joel Fernandes proposed building the source for all of the kernel's headers files into the kernel itself, at a cost of nearly 4MB of unswappable, kernel-space memory. The discussion is ongoing, but it has already highlighted some pain points felt by Android developers in particular.

Fernandes first posted this work in January; version 5 was posted on March 20. As part of the build process, it gathers up all of the kernel's headers (the ".h" files) and a few other artifacts into a compressed tar file; that file is then built into a kernel module. If that module is loaded into the running kernel, the tar file containing the headers can be read from /proc/kheaders.tgz. This is, thus, a way of allowing applications to access the header files that were used to build whatever kernel is running at the moment.

The purpose of this mechanism is to make those header files available in situations where they are otherwise unavailable. In particular, developers building kernel modules need access to this information, as do those who are building BPF programs to analyze a system's behavior. In some systems, notably Android-based devices, those header files are almost certainly not easily available. Fernandes has tried other solutions to this problem, such as BPFd, in the past, but all have fallen short. Providing headers with the kernel itself is the solution he has settled on.

Some of the initial reviews were less than entirely favorable; Christoph Hellwig described it as "a pretty horrible idea and waste of kernel memory" while Alexey Dobriyan said that it was "gross". H. Peter Anvin also questioned the memory use and suggested that the data should, at a minimum, be stored in a swappable filesystem. Numerous others chimed in as well, describing the work as a "hack" and saying that, rather than building the tar file into a kernel module, it would be far more straightforward to just place that file in the module directory where it could be read directly. At the same time, a number of other developers have indicated that this feature would be useful; Daniel Colascione even asked whether it could be expanded to hold all of the kernel source.

Nobody seems to disagree with the overall objective of this work. There are times when the kernel headers are needed for development, but those headers tend to be absent on systems like Android. The disagreement is over the idea of building those headers into the kernel itself. This opposition is easy enough to understand; the kernel itself does not need that information to function, so there would have to be a strong reason indeed to sacrifice that much system memory to hold it in kernel space.

There are indeed reasons for doing so, many of which seem to come down to how Android systems are built rather than something more technical. It would be nice if Android simply had a "kernel headers" package but, as Fernandes explained, that is not really practical:

In the Android ecosystem, the Android teams only provide a "userspace system image" which goes on the system partition of the flash. This image is not GPL and doesn't contain anything GPL. It is thus not possible to put kernel headers on the system image and I already had many discussions on the subject with the teams, it is something that is just not done. Now for kernel modules, there's another image called the "vendor image" which is flashed onto the vendor partition, this is where kernel modules go. This vendor image is not provided by Google for non-Pixel devices. So we have no control over what goes there.

The seeming aversion to putting anything GPL-licensed into the system image rubs some developers the wrong way, but it is consistent with the GPL avoidance practiced in most of the Android system. There is another reason why putting the kernel headers there is not a complete solution, though: developers will often cross-build a kernel and ship it to a device for direct booting with the fastboot command. Any headers stored on the device itself will not match that new kernel, so they are useless at best. If the headers are built into the kernel itself, though, they will transfer to the device with that kernel and always be correct.

Even for kernels shipped with devices, though, the "store the headers in the filesystem" solution is problematic. As Fernandes noted, the Android project does not have much control over what vendors put onto their devices or where it goes, so it would be difficult (if not impossible) to mandate the presence of the kernel headers in any sort of standard location. Android can, though, mandate that specific kernel configuration options must be set; with this patch merged, vendors could be made to ship the headers for their kernels in a place where they could always be found. Even if vendors tend to hide their kernel modules in strange places (and they are vendors, so of course they do), the user space code on any given device knows how to find and load them.

In other words, building this information into the kernel is, among other things, a technical solution to the social problem of getting vendors to provide that information in a consistent way. Sometimes such solutions can be what is needed. As Colascione put it: "here's the bottom line: without this work, doing certain kinds of system tracing is a nightmare, and with this patch, it Just Works". Or, as Karim Yaghmour described it:

That, in my view, is a big part of the problem Joel's patch solves: in a system whose functionality requires multiple *independent* parties to work together, I can still get the necessary kernel headers for user-space tools to properly operate regardless of which part of the system is being substituted or replaced.

Proponents argue that, since the information is built into a kernel module, it can be configured out (or simply not loaded) when it is not needed. Anvin worried, though, that mechanisms like this tend to grow into a mandatory role over time.

One associated question is whether providing kernel header files is the best way to provide the needed information to user space. Steve Rostedt said that he would rather have a table describing the kernel's structures, including the offset, size, and type of each field. That is the information that is actually needed much of the time, and it could be more compact than the source code is. Colascione sympathized with the desire for a cleaner format, but argued that it would be better to go with what works now: "Think of the headers as encoding this information and more and the C compiler as a magical decoder ring". Header files also include macros, constant definitions, and other information needed to build BPF programs.

The discussion has gone on at length, provoked anew by each new posting of the patch set. It does not appear to have changed a lot of minds on either side of the debate. Sooner or later, presumably as the 5.2 merge window approaches, somebody (most likely Andrew Morton) will have to make a decision. Given the evident advantages from this patch set, it seems likely that Android kernels may ship it regardless, so it may be mostly a matter of whether the mainline follows suit.

Index entries for this article
KernelBuild system
KernelModules


to post comments

Building header files into the kernel

Posted Mar 21, 2019 22:26 UTC (Thu) by xorbe (guest, #3165) [Link] (6 responses)

Wouldn't xz be far preferable for this use case? I've seen some impressive gains on text files. I suppose that requires an xz binary though ... but it's on storage not memory.

Compression formats

Posted Mar 21, 2019 23:28 UTC (Thu) by corbet (editor, #1) [Link] (3 responses)

There were a couple of side discussions on the best compression format; I'll freely admit to having mostly glossed over them as being a secondary issue.

Compression formats

Posted Mar 21, 2019 23:34 UTC (Thu) by Sesse (subscriber, #53779) [Link] (1 responses)

If the size is the core of the issue, I guess you could also remove all whitespace and comments…

Allow me to add to the bike-shedding...

Posted Mar 22, 2019 1:55 UTC (Fri) by pr1268 (guest, #24648) [Link]

I guess you could also remove all whitespace and comments…

You'd probably want to keep the comments. After all, there's a wealth of information in what the *human* programmer wanted when writing the header file that's not usually obvious in the code itself. I mean, if we're going to shove all this extra data into a kernel module anyway...

As for the various compression formats, why not give users a choice? I propose gzip, bz2, lzma, xz, and lzma at a minimum. After all, open source is all about choice, right?

</sarcastic humor>

Seriously, though, if this whole feature is limited to a loadable module, and optional at build time, then perhaps this isn't a bad idea. If this [grows] into a mandatory role over time, then perhaps its use (or over-use) is a sign that this is a badly needed feature that should remain.

Compression formats

Posted Mar 22, 2019 22:41 UTC (Fri) by jsmith45 (guest, #125263) [Link]

Later versions of the patch are indeed using .tar.xz as the file format.

Building header files into the kernel

Posted Mar 22, 2019 0:37 UTC (Fri) by Tov (subscriber, #61080) [Link] (1 responses)

Maybe using a SquashFS file instead of a tar file would be beneficial?
Squashfs supports several compression formats and can be mounted in-place.

Building header files into the kernel

Posted Mar 22, 2019 22:48 UTC (Fri) by jsmith45 (guest, #125263) [Link]

Squashfs was ruled out by the patch author because it requires squashfs-tools, which is neither provided with the kernel, nor otherwise required to build it, and is not installed by default on most systems. On the other hand GNU tar does xz compression itself, and is installed by default on most Linux systems.

Building header files into the kernel

Posted Mar 22, 2019 1:42 UTC (Fri) by IanKelling (subscriber, #89418) [Link] (9 responses)

"This vendor image is not provided by Google for non-Pixel devices. So we have no control over what goes there."
...
"Android can, though, mandate that specific kernel configuration options must be set"

So, they have no control over what goes there, except they control the modules that go there, which means they do control what goes there.

"In a system whose functionality requires multiple *independent* parties to work together."

Except one party forces the others to build their kernels in a certain way through some contract, so they aren't independent.

What is going on with these unexplained contradictions?

Building header files into the kernel

Posted Mar 22, 2019 3:05 UTC (Fri) by ndesaulniers (subscriber, #110768) [Link]

You can't stop vendors from putting whatever in Android; you can make it so their additions go in their own partition.

Building header files into the kernel

Posted Mar 22, 2019 12:29 UTC (Fri) by excors (subscriber, #95769) [Link] (5 responses)

There's already one part of the vendor image that Google controls: https://source.android.com/compatibility/9/android-9-cdd.... has a requirement on /vendor/etc/public.libraries.txt. So I don't understand the "we have no control" argument - Google can assert control over whatever they want, simply by writing it in the CDD and CTS.

Building header files into the kernel

Posted Mar 22, 2019 22:11 UTC (Fri) by NAR (subscriber, #1313) [Link] (1 responses)

And as the kernel is GPL, those header files should be a downloadable anyway, shouldn't they?

Building header files into the kernel

Posted Apr 1, 2019 15:37 UTC (Mon) by neuland (guest, #126936) [Link]

My understanding is that despite being required to by GPL, many vendors don't comply or make it difficult to get the source. And Linus Torvalds (and maybe other leadership people, idk) doesn't like the idea of suing these vendors over violations, because it will hurt the community (as well as the possibility they could lose and be worse off): https://lists.linuxfoundation.org/pipermail/ksummit-discu...

He also talks negatively in the same message about individual contributors who attempt to sue based on their copyright and organizations that facilitate that, such as the Software Freedom Conservancy.

Building header files into the kernel

Posted Mar 22, 2019 23:01 UTC (Fri) by jsmith45 (guest, #125263) [Link] (1 responses)

Sure, but it does not handle the case of a development kernel loaded with fastboot. In that case there is no opportunity to add any files to the system, so the corresponding headers must be included in the kernel in order to ensure the corresponding headers are available. But this proposal lets you compile this as a non-module for that scenario, which would ensure the headers are available.

Building header files into the kernel

Posted Apr 2, 2019 9:26 UTC (Tue) by robbe (guest, #16131) [Link]

I don’t get this scenario. If you are running a one-off kernel with „fastboot boot …“ you would have the headers on your controlling computer.

Building header files into the kernel

Posted Mar 24, 2019 1:37 UTC (Sun) by _joel_ (subscriber, #112763) [Link]

It is arguably much harder to enforce vendors to have kernel headers tar balls for their kernels on the vendor partition. However, we have more control over which kernel modules are built into the vendor partition and which CONFIG options are enabled. We can enforce certain CONFIG options to be built since a sufficient kernel functionality is needed for Android userspace to work correctly. This is what I was trying to say. This is more of a social problem than a technical problem, and is only one of the many advantages of having this, that I was sighting

Building header files into the kernel

Posted Mar 28, 2019 5:48 UTC (Thu) by thestinger (guest, #91827) [Link] (1 responses)

The real answer is that independent updates of the 3 standard OS partitions are supported where the others are left untouched: boot (kernel), vendor (userspace driver components / HALs for the hardware) and system (with Treble ensuring compatibility with an unmodified AOSP system image, but not actually requiring vendors ship that). These can be updated independently including major updates between OS versions with many changes. The vbmeta image is the only OS level image that actually has to be signed and verified via the signature by the bootloader and has a rollback index enforced, with the other partitions all verified via vbmeta.

They could come up with a scheme where they stick the headers elsewhere in the boot image, and have something like init expose access to it. The main advantage I can see with the kernel approach is that it wouldn't be only available for Android and is probably the simplest approach.

https://source.android.com/devices/bootloader/boot-image-...

Building header files into the kernel

Posted Mar 28, 2019 5:59 UTC (Thu) by thestinger (guest, #91827) [Link]

A more complex setup can have multiple vbmetas, but in practice there's one. There can also be more OS partitions, but the only additional one for Pixels is dtbo, rather than having it in boot.

https://source.android.com/devices/architecture/dto/parti...

Unless they made a new partition with a filesystem mounted in userspace that's shipped with the boot image, there's not really great a place to put the kernel headers other than the kernel. I think that may be a better solution, although it'd be Android specific and not portable.

Building header files into the kernel

Posted Mar 22, 2019 2:07 UTC (Fri) by neilbrown (subscriber, #359) [Link] (11 responses)

Why not move it to swapable memory?
Store the compressed image in the __init section (which is discarded somewhere in the boot sequence) and have code to copy it into a tmpfs filesystem (which can be paged out).
Maybe put /proc/config.gz there too.
(and maybe a "cowsay" binary too, just it case it is ever needed).

Building header files into the kernel

Posted Mar 22, 2019 10:02 UTC (Fri) by mjthayer (guest, #39183) [Link] (1 responses)

> Why not move it to swapable memory?
> Store the compressed image in the __init section (which is discarded somewhere in the boot sequence) and have code to copy it into a tmpfs filesystem (which can be paged out).
> Maybe put /proc/config.gz there too.

Glad to see someone else had the same idea. Might it make sense to reduce the in-kernel policy a bit by letting user-space handle the tmpfs? One possible (!) implementation would be to have a device which a) lets you read out the archive and b) lets you free the in-kernel memory holding the archive after you have done with it. (Maybe that could mean putting it into __init first and copying it from there to free-able kernel memory.)

Then again, perhaps the same thing could be achieved without it ever being in kernel memory. Tagged onto the end of the kernel binary? Something similar to initramfs? I was going to write "put into initramfs", which would avoid kernel changes altogether, but the thought of bloating that even more is not appealing.

Building header files into the kernel

Posted Mar 23, 2019 22:12 UTC (Sat) by Mattimo (subscriber, #129903) [Link]

Actually you could use a compressed cpio archive of the headers and just present it as a subtree in procfs because initramfs already has all the primitives available for that. Maybe that would even allow something like /proc/include that just contains the headers in plain sight.

Building header files into the kernel

Posted Mar 22, 2019 12:33 UTC (Fri) by excors (subscriber, #95769) [Link] (2 responses)

> Why not move it to swapable memory?

I think most Android devices don't have swap. They prefer to just kill background apps whenever RAM gets low.

Building header files into the kernel

Posted Mar 22, 2019 15:20 UTC (Fri) by dezgeg (subscriber, #92243) [Link] (1 responses)

Plenty of devices use zram, I think.

Building header files into the kernel

Posted Mar 22, 2019 17:45 UTC (Fri) by excors (subscriber, #95769) [Link]

Ah, true, I suppose that technically is swap. But moving a gz file from RAM into tmpfs that gets swapped to zram that is stored in RAM, doesn't sound especially useful.

Building header files into the kernel

Posted Mar 24, 2019 1:29 UTC (Sun) by _joel_ (subscriber, #112763) [Link] (5 responses)

Neil, thanks for the suggestion. How do you create an invisible tmpfs mount in the kernel and later mount it in userspace though? I am not aware of any such thing. Any existing code or examples would be appreciated.

Also note that on Android, we don't use disk-based swap. We have a memory based compressed swap called ZRAM, but the archive is already compressed so the suggested idea would provide no benefit (to us).

One thing I have thought of doing in the future is to make the /proc entry of the archive writeable and write an empty string into it thus freeing the archive's allocated memory and requiring a reboot. However at the moment, I am considering only building this as a module for production Android, and as a built-in when debugging. After the patches can make it, and if others want to free that memory, we can cross that bridge there IMO - such as by writing an empty string into the proc entry.

Building header files into the kernel

Posted Mar 24, 2019 1:38 UTC (Sun) by _joel_ (subscriber, #112763) [Link]

About requiring a reboot, I meant "requiring a reboot if headers are needed again"

Building header files into the kernel

Posted Mar 24, 2019 4:28 UTC (Sun) by neilbrown (subscriber, #359) [Link]

You can create an invisible tmpfs mount with kern_mount(). mm/shmem.c does this.
I don't think there is an existing way to mount this into a mount namespace, but I suspect you could add a mount option to tmpfs to say "use pre-exist superblock named foo".

If you don't have real swap, this doesn't help you, but it might be a useful answer to people who complain about a waste of kernel memory, or who emphasize that it is non-swapable memory (the article mentions both).

Building header files into the kernel

Posted Mar 24, 2019 5:39 UTC (Sun) by jsmith45 (guest, #125263) [Link] (1 responses)

Joel, why even bother remounting? You can just directly use the pre-existing internal kernel mount as if it was a special form of swappable kernel memory. CONFIG_BIG_KEYS actually does that, and the the bpfilter user mode helper module copies data that is baked into its module (as discardable init data) into the main internal tmpfs mount, so there is precedent for most of this.

I'll be showing code as if making the file swappable was unconditional, but it should be very obvious how to add a config option that hybridizes what patch V5 has, and the below.

One word of warning: This basically requires CONFIG_TMPFS. It will also work if !CONFIG_SHMEM, because then it uses tiny-shmem (which is ramfs). However using CONFIG_SHMEM without CONFIG_TMPFS yields a tmpfs that is excessively limited.

Now lets create the file in tmpfs, and copy the data into it:


static struct path *mem_path;

static int __init ikheaders_init(void)
{
	struct proc_dir_entry *entry;
        size_t kernel_headers_data_size = &kernel_headers_data_end - &kernel_headers_data;
        int err;

        ssize_t written;
	loff_t pos = 0;

        /* copy data to a new tmpfs file, so it can be swapped out */
        mem_file = shmem_kernel_file_setup("", kernel_headers_data_size, 0);
        if (IS_ERR(mem_file)) {
		err = PTR_ERR(mem_file);
		goto err_no_fput;
	}

        written = kernel_write(mem_file, kernel_headers_data, kernel_headers_data_size, &pos);
        if (written != kernel_headers_data_size) {
		err = written;
		if (err >= 0)
			err = -ENOMEM;
		goto error;
	}

	/* create the current headers file */
	entry = proc_create("kheaders.tar.xz", S_IRUGO, NULL,
			    &ikheaders_file_ops);
	if (!entry) {
		err = -ENOMEM;
		goto error;
	}
	
	proc_set_size(entry,
		      kernel_headers_data_size);
	return 0;
error:
	fput(mem_file);
error_no_fput:
	return ret;
}

static void __exit ikheaders_cleanup(void)
{
	remove_proc_entry("kheaders.tar.xz", NULL);
	path_put(mem_path);
}

OK. Next up, we need to change the section the baked-in data is stored in to be .init.data so it gets discarded after init.


asm (
"	.pushsection .init.data, \"a\"	\n"
/*...*/
);

Almost done. All that is left is to make reads of the proc file return data from the in memory file. There are actually several ways to approach this. We could use a magic symlink to the internal file, similar to how the proc file descriptor symlinks work. But to make this act as much like a normal file as possible, the following might be easiest. It is definitely a bit odd to have the read delegate back to vfs_read, but as far as I can tell it should work. I'd bet one of VFS guys can come up with some improvements to this approach.


static int ikheaders_open_current(struct inode *inode, struct file *file)
{
	struct file *mem_file
	file = dentry_open(path, O_RDONLY, current_cred());

	if (IS_ERR(file)) 
		return PTR_ERR(file);

	file->private_data = mem_file;
	return 0;
}
static ssize_t
ikheaders_read_current(struct file *file, char __user *buf,
		      size_t len, loff_t *offset)
{
        struct file *mem_file = file->private_data;
	return vfs_read(mem_file, buf, len, offset);
}
static int ikheaders_release_current(struct inode *inode, struct file *file)
{
        struct file *mem_file = file->private_data;
	fput(mem_file);
	return 0;
}

static const struct file_operations ikheaders_file_ops = {
        .open = ikheaders_open_current,
        .release = ikheaders_release_current,
	.read = ikheaders_read_current,
	.llseek = default_llseek,
};

Please note that all this code is untested, and is intended to a show the basic approach, although it probably works as-is, modulo any typos (since most of it was copy-pasted from existing parts of the kernel or your patch).

Hope you find this helpful, or at least interesting

Building header files into the kernel

Posted Mar 26, 2019 23:53 UTC (Tue) by quotemstr (subscriber, #45331) [Link]

> One word of warning: This basically requires CONFIG_TMPFS. It will also work if !CONFIG_SHMEM, because then it uses tiny-shmem (which is ramfs). However using CONFIG_SHMEM without CONFIG_TMPFS yields a tmpfs that is excessively limited.

It occurs to me that we shouldn't even have these options. The kernel would be simpler to reason about if basic, fundamental, and cheap things like tmpfs and shmem (and procfs!) were hardwired to =y. I've never understood the rationale for extreme configurability. Fundamental things should always be available.

Building header files into the kernel

Posted Mar 26, 2019 7:34 UTC (Tue) by minchan (subscriber, #61813) [Link]

>> Also note that on Android, we don't use disk-based swap. We have a memory based compressed swap called ZRAM, but the archive is already compressed so the suggested idea would provide no benefit (to us).

zRAM supports idle and/or incompressible page writeback once admin configures backing store.
If the data is used rarely or incompressible, it will be written back to the storage from the memory of zram.

Building header files into the kernel

Posted Mar 22, 2019 3:54 UTC (Fri) by wahern (subscriber, #37304) [Link] (14 responses)

Sun invented a minimalist debug symbol format for use by DTrace called CTF (Compact C Type Format). It's also been adopted by FreeBSD. You can read more about it here: http://www.smnd.sk/lovasko/paper.pdf

CTF is lightweight enough (cf DWARF) that GCC and clang could emit CTF data by default without too much hemming and hawing; we could rely on its presence and enjoy a world where we could not only statically analyze compiled objects, but also generate FFI accessors dynamically at runtime with strong type safety.

Building header files into the kernel

Posted Mar 22, 2019 12:21 UTC (Fri) by adirat (subscriber, #86623) [Link] (12 responses)

Building header files into the kernel

Posted Mar 22, 2019 18:37 UTC (Fri) by wahern (subscriber, #37304) [Link] (1 responses)

Indeed! Thanks for sharing.

Apparently they got it down to 1.5MB. Why are people still talking about shipping header tarballs? Is the BTF work just not well known? Since the motivating use case is BPF, which already requires a specialized tool chain, I don't see the downside.

Building header files into the kernel

Posted Mar 22, 2019 23:07 UTC (Fri) by adirat (subscriber, #86623) [Link]

I think it's just a matter of the left hand not talking to the right hand: Google "bleeding-edge" devs not talking to Facebook's "bleeding edge". :) Also BTF is quite new to the kernel itself and it was added to BCC literally weeks ago.

Wake up people!

Building header files into the kernel

Posted Mar 22, 2019 18:58 UTC (Fri) by dezgeg (subscriber, #92243) [Link] (9 responses)

Does BTF record any #defines that the BPF code might want to use? Or is that out of its' scope?

Building header files into the kernel

Posted Mar 22, 2019 23:31 UTC (Fri) by ay (guest, #79347) [Link]

It doesn't look like #define and other preprocessor stuff is covered so BTF is probably not usable for that they're trying to achieve here. I imagine things like ioctls would be a deal breaker here...

Building header files into the kernel

Posted Mar 23, 2019 0:36 UTC (Sat) by adirat (subscriber, #86623) [Link] (7 responses)

All this is really bleeding edge development and I'm not one of the few experts, but I can point you to this presentation from the last LPC microconf which talks about #defines in BTF a little. The consensus among the experts seems to be that, at least for the time beeing, BTF can't replace kernel headers, while the Android devs need a solution yesterday, so here we are at this kernel-headers patch instead of waiting and investing more time to do research :)

http://vger.kernel.org/lpc-bpf2018.html#session-2

Building header files into the kernel

Posted Mar 24, 2019 1:32 UTC (Sun) by _joel_ (subscriber, #112763) [Link] (6 responses)

We already know about BTF and this was already discussed in the patch postings. Please read the threads in v4 of the posting. BTF is insufficient for this usecase.

Building header files into the kernel

Posted Mar 25, 2019 13:34 UTC (Mon) by adirat (subscriber, #86623) [Link] (5 responses)

I've read the v4 discussion and honestly it only strengthens my assessment: Google engineers are really rushing this patchset instead of exploring alternative solutions. It seems like you just want something ready to use now with minimum effort. Please take a timeout, go back to the drawing board and come back in 1 year with a BTF extension or something similar based on ORC/DWARF.

I get it that some people are afraid of hard work or telling their managers/marketing they need more time, but you guys are burning a lot of credibility here by saying some very silly things, for example let me quote from the v4 thread exchange [1]:

> Think of the headers as encoding this information and more and the C
> compiler as a magical decoder ring. :-) I totally get the desire for a
> metadata format a little less messy than C code, but as a practical
> matter, a rich C-compilation pipeline already exists, and the
> debuginfo you're proposing doesn't, (...)

The C compiler as magical decoder ring? Really? It never crossed your mind to actually develop that debug info which you need? :) What's next, including GCC/LLVM itself in the kernel as a module because eBPF also needs them to compile its "restricted-C"? Then BCC and python/lua? Again: wake up, do the proper work and stop pushing bad solutions.

[1] https://lkml.org/lkml/2019/3/11/1352

Building header files into the kernel

Posted Mar 26, 2019 23:46 UTC (Tue) by jsmith45 (guest, #125263) [Link]

Sure, with the right flags you can get macro definitions in the DWARF data, and extract them. But apparently compiling the kernel even with the normal debug flags can cause compilation to be quite a bit slower, and generate an enormous amount of data, and this would need even more data.

And parsing out the correct set of macros from that debug info may not be entirely trivial. (Some macros may have multiple values in different spots in the kernel.) Even if those issues were solved, and we had the macro data to combine with BTF it is not equivalent to headers. One thing that does not get captured is inline functions defined in the headers. I've no idea if those ever get used in BPF programs, but I could certainly imagine that at least some of them may work (e.g. if they are just abstracting over a struct access). And those are impossible to extract from any form of debugging information.

Building header files into the kernel

Posted Sep 14, 2021 1:13 UTC (Tue) by nickodell (subscriber, #125165) [Link] (3 responses)

> I get it that some people are afraid of hard work or telling their managers/marketing they need more time, but you guys are burning a lot of credibility here by saying some very silly things, for example let me quote from the v4 thread exchange [1]:
>[...]
>The C compiler as magical decoder ring? Really? It never crossed your mind to actually develop that debug info which you need? :)

I think you're underestimating the work involved in getting a C compiler to both emit and understand the new debug info. E.g. the preprocessor must know how to use macros from the debug info for substitution. The typechecker must know how to use function prototypes to check that a function is being called with the appropriate types. The compiler must know how to load structure definitions so that it knows what offset to access data from within a struct.

The only current data format that carries all that information is a C header file. Could you develop a new format which does not carry extraneous information like comments? Sure. But you'd be introducing an unknown number of bugs. The payoff for doing that is at most 4MB of freed memory. Approaches which load the tar file on demand, or that allow it to be paged in and out, seem much more promising.

Building header files into the kernel

Posted Sep 15, 2021 12:42 UTC (Wed) by nix (subscriber, #2304) [Link] (2 responses)

Well... both CTF and BTF carry all that information, and weigh in at a few megabytes for a full monster enterprise kernel (complete with, in the CTF case, all types used by in-tree modules as well). They're certainly both a lot smaller than the header files that were the source for a lot of their content would be.

Building header files into the kernel

Posted Sep 15, 2021 13:30 UTC (Wed) by rahulsundaram (subscriber, #21946) [Link] (1 responses)

What's the difference between CTF and BTF and do we need both? I couldn't find a succinct summary.

Building header files into the kernel

Posted Sep 15, 2021 16:49 UTC (Wed) by nix (subscriber, #2304) [Link]

They are distinct things these days and can both be present at the same time without conflict. BTF is created from DWARF by pahole (in dwarves) and has no plans to work for anything but the kernel (not that this matters for this use case): CTF is generated by trunk GCC and linked and dedupped by recent-enough GNU ld, but you cannot yet generate header files from CTF (not because it's impossible, but just because I haven't written the code to do that yet: I will do it soon, and add it as an objdump option).

They are both derived from the same ancestor (Solaris CTF) but have a significant number of differences by now, mostly reflecting their kernel-only versus userspace focuses (e.g. CTF supports symbol -> type lookup using the ELF symtab, which obviously makes little sense for BTF; BTF has a whole elaborate pile of relocation machinery for CO-RE, tightly tied to LLVM at present, that isn't in CTF).

Building header files into the kernel

Posted Mar 25, 2019 15:17 UTC (Mon) by nix (subscriber, #2304) [Link]

See also http://github.com/oracle/libdtrace-ctf.git for an evolution of the same file format (and indeed code) with a (much) larger range, GPLv2 and UPL-licensed. It's under active development: further improvements are planned in the near future.

Building header files into the kernel

Posted Mar 28, 2019 7:23 UTC (Thu) by marcH (subscriber, #57642) [Link] (2 responses)

> developers will often cross-build a kernel and ship it to a device for direct booting with the fastboot command. Any headers stored on the device itself will not match that new kernel, so they are useless at best. If the headers are built into the kernel itself, though, they will transfer to the device with that kernel and always be correct.

Déjà vu: what about kernel *modules*? Typical deployment problem on any Linux-based OS. For Android how does fastboot deploy kernel modules and where to ? I mean the mainline & GPL drivers, not vendor modules.

This page seems to refer to vendor modules only: https://source.android.com/devices/architecture/kernel/mo...

Modules

Posted Mar 28, 2019 13:09 UTC (Thu) by corbet (editor, #1) [Link] (1 responses)

If modules really turn out to be a problem, one can, of course, just build them directly into the kernel image.

Modules

Posted Mar 28, 2019 16:36 UTC (Thu) by marcH (subscriber, #57642) [Link]

You almost answered my question except for the first word "If".

Do Android/fastboot/etc. support compiling mailine drivers as modules or not really?


Copyright © 2019, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds