Skip to contentSkip to conversation

Ensure that kernel_init_freeable() is not inlined into non __init code

PATCH RESEND In review Vineet Gupta 2 participants 4 messages Dec 21, 2012 – Dec 26, 2012

lore
Share & tools
lore
#0 lore raw

PATCH RESEND 1/1 Ensure that kernel_init_freeable() is not inlined into non __init code

Commit d6b2123802d "make sure that we always have a return path from kernel_execve()" reshuffled kernel_init()/init_post() to ensure that kernel_execve() has a caller to return to.

It removed __init annotation for kernel_init() and introduced/calls a new routine kernel_init_freeable(). Latter however is inlined by any reasonable compiler (ARC gcc 4.4 in this case), causing slight code bloat.

This patch forces kernel_init_freeable() as noinline reducing the .text

bloat-o-meter vmlinux vmlinux_new
add/remove: 1/0 grow/shrink: 0/1 up/down: 374/-334 (40)

function                        old     new   delta
kernel_init_freeable              -     374    +374 (.init.text)
kernel_init                     628     294    -334 (.text)

Just for documentation, here's what Al's orig commit did.

Orig
----

THREAD __init kernel_init()

	smp_init()
	...
	open("/dev/console")

	init_post() --> forced to be noinline
	return 0;

init_post()

	free_initmem() --> reaps caller kernel_init()
	run_init_process("/init")
		kernel_execve

New
---

THREAD kernel_init()

	kernel_init_freeable()	--> __init tagged
		smp_init()
		...
		open("/dev/console")
	free_initmem() --> reaps kernel_init_freeable()
	run_init_process "init"
		kernel_execve
CC Rusty Russell <[email protected]>
CC Jim Cromie <[email protected]>
CC Andrew Morton <[email protected]>
CC "H. Peter Anvin" <[email protected]>
---
 init/main.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
init/main.c +2 -2
index 85d69df..92d728a 100644
@@ -802,7 +802,7 @@ static int run_init_process(const char *init_filename)
 		(const char __user *const __user *)envp_init);
 }
 
-static void __init kernel_init_freeable(void);
+static noinline void __init kernel_init_freeable(void);
 
 static int __ref kernel_init(void *unused)
 {
@@ -845,7 +845,7 @@ static int __ref kernel_init(void *unused)
 	      "See Linux Documentation/init.txt for guidance.");
 }
 
-static void __init kernel_init_freeable(void)
+static noinline void __init kernel_init_freeable(void)
 {
 	/*
 	 * Wait until kthreadd is all set-up.
Signature · 1 line
1.7.4.1
#1 lore raw
Quoted 8 lines · Vineet Gupta

Commit d6b2123802d "make sure that we always have a return path from kernel_execve()" reshuffled kernel_init()/init_post() to ensure that kernel_execve() has a caller to return to.

It removed __init annotation for kernel_init() and introduced/calls a new routine kernel_init_freeable(). Latter however is inlined by any reasonable compiler (ARC gcc 4.4 in this case), causing slight code bloat.

Interesting... I assumed that explicitly set different section would be enough, but I'd been wrong (or the original noinline would've been pointless, now that I think of it). Consider it ACKed; I can pick it through signal.git, and while it's not urgent I'd send it to Linus after -rc1, with Cc: stable. Or you can send it to him yourself with my usual Acked-by - up to you.

#2 lore raw
Quoted 9 lines · Al Viro
Quoted 8 lines · Vineet Gupta

Commit d6b2123802d "make sure that we always have a return path from kernel_execve()" reshuffled kernel_init()/init_post() to ensure that kernel_execve() has a caller to return to.

It removed __init annotation for kernel_init() and introduced/calls a new routine kernel_init_freeable(). Latter however is inlined by any reasonable compiler (ARC gcc 4.4 in this case), causing slight code bloat.

Quoted 5 lines

Interesting... I assumed that explicitly set different section would be enough, but I'd been wrong (or the original noinline would've been pointless, now that I think of it). Consider it ACKed; I can pick it through signal.git, and while it's not urgent I'd send it to Linus after -rc1, with Cc: stable. Or you can send it to him yourself with my usual Acked-by - up to you.

Merging via your signal.git is fine.

Thx,
-Vineet

#3 lore raw
Quoted 16 lines · Vineet Gupta
Quoted 9 lines · Al Viro
Quoted 8 lines · Vineet Gupta

Commit d6b2123802d "make sure that we always have a return path from kernel_execve()" reshuffled kernel_init()/init_post() to ensure that kernel_execve() has a caller to return to.

It removed __init annotation for kernel_init() and introduced/calls a new routine kernel_init_freeable(). Latter however is inlined by any reasonable compiler (ARC gcc 4.4 in this case), causing slight code bloat.

Quoted 5 lines

Interesting... I assumed that explicitly set different section would be enough, but I'd been wrong (or the original noinline would've been pointless, now that I think of it). Consider it ACKed; I can pick it through signal.git, and while it's not urgent I'd send it to Linus after -rc1, with Cc: stable. Or you can send it to him yourself with my usual Acked-by - up to you.

Quoted 5 lines

Merging via your signal.git is fine.

Thx,
-Vineet

Hi Al,

Tickled by a spurious mail from "Kbuild test robot" with this change getting committed into your tree (please see below, which Fengguang acknowledged as a script error) I took a peek at the commit and it seems the commit log is truncated when describing the New call chain of kernel_init. If that's too much you might wanna delete all of the Old vs. New Call chains or preferably restore the "New" part.

Sorry for the nit.

Thx,
-Vineet

-------------->8-------------------------

tree:   git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal.git for-linus
head:   07570a268090d0a209d957e46d164900999c9e5b
commit: ec21b1033ee6dce41be78c10844f6169566d9d06 [1/6] Ensure that

kernel_init_freeable() is not inlined into non __init code
config: x86_64-randconfig-s542 (attached as .config)

Note: it may well be a FALSE warning. FWIW you are at least aware of it now. -------------->8-------------------------