Skip to contentSkip to conversation

Is extern inline -> static inline OK?

DISCUSSION Tim Bird 3 participants 6 messages Aug 6, 2004 – Aug 7, 2004 1 message not in the archive

lore
Share & tools
lore

Tim Bird

author
#0 lore raw

Pardon my ignorance...

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

Quoted 9 lines · Linus once

- "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: [email protected]
=============================

#1 lore raw
Followup to:  <[email protected]>
By author:    Tim Bird <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 6 lines

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

author
#5 lore raw
In reply to a message not in the archive
Quoted 5 lines · Richard Henderson
Quoted 2 lines · Tim Bird

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.

Quoted 2 lines

... 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: [email protected]
=============================

author
#2 lore raw
In reply to H. Peter Anvin
Quoted 4 lines · H. Peter Anvin
Followup to:  <[email protected]>
By author:    Tim Bird <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 8 lines
Quoted 5 lines

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: [email protected]
=============================

#3 lore raw
Quoted 6 lines · Tim Bird

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?

Quoted 9 lines

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
#6 lore raw
In reply to Tim Bird
Quoted 1 line · Tim Bird

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~