public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Is extern inline -> static inline OK?
@ 2004-08-06  0:39 Tim Bird
  2004-08-06  0:58 ` H. Peter Anvin
       [not found] ` <20040806070027.GA20642@twiddle.net>
  0 siblings, 2 replies; 8+ messages in thread
From: Tim Bird @ 2004-08-06  0:39 UTC (permalink / raw)
  To: linux kernel; +Cc: rth

Pardon my ignorance...

Under what conditions is it NOT OK to convert "extern inline"
to "static inline"?

Linus once wrote:
>  - "static inline" means "we have to have this function, if you use it
>    but don't inline it, then make a static version of it in this
>    compilation unit"
> 
>  - "extern inline" means "I actually _have_ an extern for this function,
>    but if you want to inline it, here's the inline-version"
> 
> ... we should just convert
> all current users of "extern inline" to "static inline".

But Richard Henderson rejected (in 2002) the following patch (excerpt):

-#define __EXTERN_INLINE extern inline
+#define __EXTERN_INLINE static inline

presumably because the exact semantics of extern inline were
required.  I can only find __EXTERN_INLINE in the alpha
architecture.  Is the requirement to use 'extern' rather
than 'static' unique to alpha?

Thanks for any illumination on this.

=============================
Tim Bird
Architecture Group Co-Chair, CE Linux Forum
Senior Staff Engineer, Sony Electronics
E-mail: tim.bird@am.sony.com
=============================

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is extern inline -> static inline OK?
  2004-08-06  0:39 Is extern inline -> static inline OK? Tim Bird
@ 2004-08-06  0:58 ` H. Peter Anvin
  2004-08-06 22:29   ` Tim Bird
       [not found] ` <20040806070027.GA20642@twiddle.net>
  1 sibling, 1 reply; 8+ messages in thread
From: H. Peter Anvin @ 2004-08-06  0:58 UTC (permalink / raw)
  To: linux-kernel

Followup to:  <4112D32B.4060900@am.sony.com>
By author:    Tim Bird <tim.bird@am.sony.com>
In newsgroup: linux.dev.kernel
>
> Pardon my ignorance...
> 
> Under what conditions is it NOT OK to convert "extern inline"
> to "static inline"?
> 

When the code is broken if it doesn't inline.

	-hpa

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is extern inline -> static inline OK?
       [not found] ` <20040806070027.GA20642@twiddle.net>
@ 2004-08-06 18:57   ` Tim Bird
  2004-08-07  2:41     ` Richard Henderson
  0 siblings, 1 reply; 8+ messages in thread
From: Tim Bird @ 2004-08-06 18:57 UTC (permalink / raw)
  To: Richard Henderson; +Cc: linux kernel

Richard Henderson wrote:
> On Thu, Aug 05, 2004 at 05:39:07PM -0700, Tim Bird wrote:
>>Under what conditions is it NOT OK to convert "extern inline"
>>to "static inline"?
> 
> When... I arrange for an external version to exist.

Richard - thanks for responding.

As you probably know, many people use extern inline
incorrectly in the kernel.  Your construction appears
correct.

 > ... Grep for EXTERN_INLINE in arch/alpha/kernel to see how it is
 > used. If you can't figure it out, don't try to change anything.

I can see how it is used, but I can only guess the "why".
The only comment I can find about this usage is:
/* Do not touch, this should *NOT* be static inline */

There are a few different reasons someone might use
extern inline rather than static inline. Some affect
code correctness and some don't.  Based on the strength
of the wording in your comment, I would guess that
the related code would suffer code correctness issues if
changed.  However just examining the EXTERN_INLINE usage
itself did not reveal where the code would be incorrect
if static inline were used.

One type of usage which affects code correctness is
when the extern function definition differs from the
inline function definition. This type of usage of
"extern inline" is just plain wrong, since it RELIES
on the compiler to use a particular version of the
function (either the extern one or the inline one),
and the compiler is supposed to be free to make this
choice. This does not appear to be the case with your
code, since your construct uses the same source code
to create the extern functions as the extern inline
definitions. (But maybe I missed something.)

Other reasons for using extern inline are to minimize
code footprint by avoiding extra function copies in
different compilation units, and to increase cache hotness
by reusing the same code, when the compiler decides to not
inline a function.  This last benefit is usually unlikely,
since uninlined code in the same compilation unit as the
currently executing code is much more likely to be
in-cache than uninlined code in some other compilation
unit.

Finally, another reason for using extern inline is to
avoid pointer comparison mismatch for function pointers
to uninlined functions.

In any event, it is difficult to tell what incorrectness
is (presumably) introduced in the alpha code by
using 'static inline' vs. 'extern inline', for the functions
so designated.  Maybe you have specific code that breaks,
or maybe you just saw broken behaviour with the code compiled
differently.

If you could indicate WHY the alpha code must be 'extern inline',
it might be helpful to me, and instructive for others who
need to be educated on this same issue.
  1) have different definitions for functions with same name
  2) avoid wasting space with multiple function copies
  3) increased instruction cache effectiveness
  4) function pointers comparisons
  5) some other reason I still don't understand

If anyone else can tell me if they are aware of cases of either
1) or 5) for other uses of 'extern inline' in the kernel, that
would be helpful.

BTW - I'm trying to figure this out because an instrumentation
system I'm working with uses gcc's -finstrument-functions, which
doesn't deal well with extern inlines that don't really have extern
definitions.  I'm trying to get a grip on which 'extern inlines' it's
OK to change, and which aren't, and how to deal with the ones which
shouldn't be changed.

Thanks,

=============================
Tim Bird
Architecture Group Co-Chair, CE Linux Forum
Senior Staff Engineer, Sony Electronics
E-mail: tim.bird@am.sony.com
=============================

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is extern inline -> static inline OK?
  2004-08-06 22:29   ` Tim Bird
@ 2004-08-06 22:29     ` H. Peter Anvin
  0 siblings, 0 replies; 8+ messages in thread
From: H. Peter Anvin @ 2004-08-06 22:29 UTC (permalink / raw)
  To: Tim Bird; +Cc: linux kernel

Tim Bird wrote:
> 
> Thanks!
> 
>  From what I have read, for either 'extern inline' or 'static inline'
> the compiler is free to not inline the code. Is this wrong?
> 
> It is my understanding that...
> In the 'static inline' case the compiler may create a function in the
> local compilation unit. But in the 'extern inline' case an extern
> non-inline function must exist. If the compiler decides not to inline
> the function, and a non-inline function does not exist, you get a linker
> error.  Are you saying that, therefore, 'extern inline' functions are
> used (without definition of extern non-inline functions to back them)
> in order to guarantee that NO non-inline version of the function exists?
> 

Yes; the final link will fail with an undefined symbol if "extern inline" 
fails to inline.

	-=hpa

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is extern inline -> static inline OK?
  2004-08-06  0:58 ` H. Peter Anvin
@ 2004-08-06 22:29   ` Tim Bird
  2004-08-06 22:29     ` H. Peter Anvin
  0 siblings, 1 reply; 8+ messages in thread
From: Tim Bird @ 2004-08-06 22:29 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux kernel

H. Peter Anvin wrote:
> Followup to:  <4112D32B.4060900@am.sony.com>
> By author:    Tim Bird <tim.bird@am.sony.com>
> In newsgroup: linux.dev.kernel
> 
>>Pardon my ignorance...
>>
>>Under what conditions is it NOT OK to convert "extern inline"
>>to "static inline"?
>>
> 
> 
> When the code is broken if it doesn't inline.

Thanks!

 From what I have read, for either 'extern inline' or 'static inline'
the compiler is free to not inline the code. Is this wrong?

It is my understanding that...
In the 'static inline' case the compiler may create a function in the
local compilation unit. But in the 'extern inline' case an extern
non-inline function must exist. If the compiler decides not to inline
the function, and a non-inline function does not exist, you get a linker
error.  Are you saying that, therefore, 'extern inline' functions are
used (without definition of extern non-inline functions to back them)
in order to guarantee that NO non-inline version of the function exists?

Or are you saying that the non-inline version of the function may
be written differently than the inline version?

Sorry to be so dense... I really appreciate your help.

=============================
Tim Bird
Architecture Group Co-Chair, CE Linux Forum
Senior Staff Engineer, Sony Electronics
E-mail: tim.bird@am.sony.com
=============================

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is extern inline -> static inline OK?
       [not found]   ` <2qlo1-wO-37@gated-at.bofh.it>
@ 2004-08-06 23:26     ` Andi Kleen
  2004-08-07  1:26       ` Adrian Bunk
  0 siblings, 1 reply; 8+ messages in thread
From: Andi Kleen @ 2004-08-06 23:26 UTC (permalink / raw)
  To: Tim Bird; +Cc: linux-kernel

Tim Bird <tim.bird@am.sony.com> writes:

> H. Peter Anvin wrote:
>> Followup to:  <4112D32B.4060900@am.sony.com>
>> By author:    Tim Bird <tim.bird@am.sony.com>
>> In newsgroup: linux.dev.kernel
>>
>>>Pardon my ignorance...
>>>
>>>Under what conditions is it NOT OK to convert "extern inline"
>>>to "static inline"?
>>>
>> When the code is broken if it doesn't inline.
>
> Thanks!
>
>  From what I have read, for either 'extern inline' or 'static inline'
> the compiler is free to not inline the code. Is this wrong?

Yes, it's wrong in current Linux 2.6. It currently defines inline to
inline __attribute__((always_inline))

> It is my understanding that...
> In the 'static inline' case the compiler may create a function in the
> local compilation unit. But in the 'extern inline' case an extern
> non-inline function must exist. If the compiler decides not to inline
> the function, and a non-inline function does not exist, you get a linker
> error.  Are you saying that, therefore, 'extern inline' functions are
> used (without definition of extern non-inline functions to back them)
> in order to guarantee that NO non-inline version of the function exists?

Exactly.

Originally it was used this way, but then the inlining algorithms got
completely broken to not explode compile times on broken C++ template
horrors, and in order to still compile the kernel most uses of extern
inline were converted to static inline.

Drawback is that you suddenly got a lot of binary bloat
(e.g. at some point gcc decided to not inline anymore 
the constant evaluation code in copy_{to,from}_user,
which caused incredibly code bloat).

That is when the #define inline __attribute__((always_inline)) was
added.

> Or are you saying that the non-inline version of the function may
> be written differently than the inline version?

That was the original intention I think, but Linux always has used
it for the first interpretation.

It's pretty obsolete now, modern gcc has __attribute__((always_inline)),
which is a better way to do this. You get a compiler error when 
the function cannot inlined. It also has a __attribute__((noinline))
for the opposite case.

Hope this helps,

-Andi


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is extern inline -> static inline OK?
  2004-08-06 23:26     ` Andi Kleen
@ 2004-08-07  1:26       ` Adrian Bunk
  0 siblings, 0 replies; 8+ messages in thread
From: Adrian Bunk @ 2004-08-07  1:26 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Tim Bird, linux-kernel

On Sat, Aug 07, 2004 at 01:26:04AM +0200, Andi Kleen wrote:
> Tim Bird <tim.bird@am.sony.com> writes:
> >
> >  From what I have read, for either 'extern inline' or 'static inline'
> > the compiler is free to not inline the code. Is this wrong?
> 
> Yes, it's wrong in current Linux 2.6. It currently defines inline to
> inline __attribute__((always_inline))
>...

To be more exact:

It's defined this way in both 2.4 and 2.6, but only for gcc >= 3.1 
(which support __attribute__((always_inline)) ).

> Hope this helps,
> 
> -Andi

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is extern inline -> static inline OK?
  2004-08-06 18:57   ` Tim Bird
@ 2004-08-07  2:41     ` Richard Henderson
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2004-08-07  2:41 UTC (permalink / raw)
  To: Tim Bird; +Cc: linux kernel

On Fri, Aug 06, 2004 at 11:57:04AM -0700, Tim Bird wrote:
>  2) avoid wasting space with multiple function copies

Mostly this one.  The translation units that do the EXTERN_INLINE
defines also define tables containing (among other things) pointers
to all of these functions.  So we *know* that we require one out-of-line
copy in one translation unit, so we might as well make that version the
canonical out-of-line copy.

Also, I seem to recall some multiply-defined symbol something or
other the last time someone messed with our inlining construct.


r~

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2004-08-07  2:41 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-06  0:39 Is extern inline -> static inline OK? Tim Bird
2004-08-06  0:58 ` H. Peter Anvin
2004-08-06 22:29   ` Tim Bird
2004-08-06 22:29     ` H. Peter Anvin
     [not found] ` <20040806070027.GA20642@twiddle.net>
2004-08-06 18:57   ` Tim Bird
2004-08-07  2:41     ` Richard Henderson
     [not found] <2q0Wb-2Tc-17@gated-at.bofh.it>
     [not found] ` <2q1pe-3hq-17@gated-at.bofh.it>
     [not found]   ` <2qlo1-wO-37@gated-at.bofh.it>
2004-08-06 23:26     ` Andi Kleen
2004-08-07  1:26       ` Adrian Bunk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox