Re: [PATCHv3 0/9] Mark literal strings in __init / __exit code

From: Mathias Krause
Date: Sun Aug 24 2014 - 12:04:19 EST


On 21 August 2014 18:25, Sam Ravnborg <sam@xxxxxxxxxxxx> wrote:
> On Thu, Aug 21, 2014 at 02:23:03PM +0200, Mathias Krause wrote:
>> This is v3 of the patch series initially posted here:
>>
>> https://lkml.org/lkml/2014/6/22/149
>>
>> This series tries to address the problem of dangling strings of __init
>> functions after initialization, as well as __exit strings for code not
>> even included in the final kernel image. The code might get freed, but
>> the format strings are not, as they're in the wrong section.
>
> What potential are we looking at here?

I tried to address that a few lines later in that email, also in the
individual patches. Let me quote the relevant lines here again:

>> The changes to arch/x86/ already
>> lead to moving ~3kb of memory from .rodata to .init.rodata.

>> To show that there's actual more value to it: A hacked up script, dully
>> changing pr_<level> to pi_<level> for __init functions under arch/x86/
>> is able to move ~8kB of r/o data into the .init section (partly already
>> covered by the patches of this series). The script, though, is dump. It
>> does not handle any of the printk() calls, nor does it handle panic()
>> calls or other strings used only in initialization code. So there's more
>> to squeeze out.

> Anything less than a page in size would likely not matter as this
> is the granularity we look into.

This is not true. The goal is not to increase the size of an .init
section but to decrease the size of the .text and .rodata sections.
For these even minor changes can lead to an additional free page if
that decrease makes the size of the .text / .rodata section cross a
page boundary. Thereby even small moves to the .init section like
format strings used only during initialization might make this happen.

> And the code needs to be built-in - which most drivers are not.

This, again, is not true. In fact, quite the opposite is true as
modules can benefit from it much better as the small reduction of
.text / .rodata sizes are not summed up but accounted per module. If
such a small decrease makes the .text / .rodata section cross a page
boundary, a whole page can be saved.

> So is it really worth it?

I took the hacky script mentioned in the first email (now also
attached, init_str.awk), let it ran over the whole kernel, fixed the
fall-out and did an allmodconfig build. Beside the script being far
from perfect (it catches a few false positives and, more important,
only covers a fraction of the potential strings -- only the pr_*()
macros) it already leads to 24 modules requiring a page less during
run-time because of the afore mentioned page crossing. It includes
popular modules like hid.ko and ipv6.ko, so almost anybody would
benefit from it. But as the page crossing effect depends on the
particular kernel configuration and toolchain setup, fell free to do
your own tests. The script doing the measurement is attached, too
(mod_info.sh)

> The places that already moves the string to __init/__exit should maybe
> be droopped to avoid the complication.

...or just be changed to hide the "magic".


Thanks,
Mathias

Attachment: init_str.awk
Description: application/awk

Attachment: mod_info.sh
Description: Bourne shell script