This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: inlining between sections


Geoff Keating <geoffk@geoffk.org> wrote:
>
> Andrew Morton <akpm@osdl.org> writes:
> 
> > Folks, we have an instance here in the 2.6 kernel where gcc-3.4 is inlining
> > init/main.c:rest_init() inside its caller, init/main.c:start_kernel(). 
> > This causes the kernel to crash, because start_kernel() lives in a text
> > section which gets unloaded later in the boot.
> > 
> > I'd suggest that this is a gcc bug:
> > 
> > static void rest_init(void)
> > {
> > 	...
> > }
> > 
> >  __attribute__((regparm(0))) void
> > 	__attribute__ ((__section__ (".init.text")))
> > 		start_kernel(void)
> > {
> > 	...
> > 	rest_init();
> > }
> > 
> > start_kernel() and rest_init() have been placed into different text sections,
> > so it is wrong to inline one inside the other.
> 
> You really don't want to use that logic.  For example, in C++
> virtually every function is in a different section, but we don't want
> to prohibit all inlining in C++.

That's different.  In this case the programmer explicitly used
attribute(section)).

>  For another example, I see that in
> the kernel on my machine (some extremely patched Red Hat 2.4.22),
> start_kernel calls lock_kernel.  Yet, include/asm-i386/smplock.h says
> 
> static __inline__ void lock_kernel(void)
> {
> 
> and you will notice there is no __section__ attribute on this
> function, so it will go in .text and therefore not be inlined.
> 

But the programmer added the `inline' to lock_kernel().  The problem with
rest_init() is that the programmer did not specify `inline', but the
compiler went and did it anyway.  Despite the programmer having placed
rest_init() in a different section.

> The problem is not that start_kernel is in a different section.  The
> problem is that rest_init unloads the section it is in.  Since GCC
> cannot know what rest_init is doing, there is no way to detect this
> case.  (GCC cannot even be sure that rest_init() will not return.)

Not inlining across programmer-defined sections would be suitable.

> I think this is a very special case, and the correct thing to do is either:
> 
> 1. Use the appropriate attribute to prevent rest_init from being inlined; or
> 2. Compile rest_init and start_kernel to completely separate .o files.

I used __attribute__((noinline)).

This is the single place where the kernel transfers execution from
.text.init into .text.  It is a special case and I do not expect the
problem to occur elsewhere.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]