I was looking at some changes to the 2.6.26.y kernel in "compiler-gcc.h" and had some questions. ( http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.26.y.git;a=commitdiff;h=ae3... ) I was attempting to cross-compile Linux for a Marvell core with Optimizations turned off and ran across an error due to the __attribute__((always_inline)) attribute. It looks like the default behavior used to always have this feature on, but Ingo committed some changes that allows this behavior to be turned off (With the correct Kconfig file changes). I'm VERY new to Linux but was wondering if there was a way (config option) to turn this inline attribute off in previous versions of the kernel besides these new macros. It seems building with optimization level 0 should be a natural thing for kernel driver developers to do for debugging purposes. In summary: I want to compile with optimizations off and the compile is failing now when I try this. How can this be resolved? For reference: - Stable Kernel 2.6.26 - I'm using arm-marvell-eabi-gcc 4.1.1 - Compiling for ARM architecture - Neither CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING nor CONFIG_OPTIMIZE_INLINING are on (or even options in the ARM architecture) - The error I receive is: "sorry, unimplemented: inlining failed in call to '<inline function>': function body not available" Thanks in advance, -- Keith Prickett --
There are several places in the kernel where we e.g. rely on gcc
removing dead code, and otherwise the linking of the kernel fails.
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
--
I am currently running the kernel compiled with -O0. The final problem I ran into was some NULL pointer dereference and compiling ONLY files in the mm directory with -O2 fixed the issue. To build with -O0 I had to change a few things (for my ARM architecture): 1. Ensure the __attribute__((always_inline)) was turned off in the "inline" #define (compiler.h) 2. Fix some inline assembly in kprobes (ARM only) that, due to no optimization, needed more registers than the compiler had available. (Similar to this issue: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13850) 3. Implement a fix as described here: (http://lists.arm.linux.org.uk/lurker/message/20050201.210458.5cc93c10.en.html) 4. Change -O2 to -O0 in the root Makefile 5. Add extra cflags in the mm Makefile so it builds with -O2 only in that directory. All of this could, potentially be changed by a configuration parameter and added into the kernel release. Does someone have a primer on why this kind of behavior is not desired or "possible"? Doing this has given me SO much visibility into stack variables data values while single-stepping the code. I feel that the time invested to make this work is well worth the return. In the book "Writing Solid Code" (http://www.amazon.com/Writing-Solid-Code-Microsofts-Programming/dp/1556155514) one technique discussed is: stepping through your code. In order to be able to do this effectively you need optimizations turned off. --
Sorry, I couldn't resist after being required to write code in VC++/MFC, where memory leaks are "normal," and pointers passed to "methods" don't remain valid if there is any other activity besides yours occurring in the machine. If you have to single-step through kernel procedures, you are not writing proper code for a kernel. Furthermore, even when using the kernel debugger, you are not executing the exact same path that would be executed without the debugger attached. These are some of the reasons why any attempt to compile with no optimization will usually fall upon deaf ears. There is a lot of in-line assembly that can't work with -O0 and if you change the code so that it does, it will not be the same as "normal" code so whatever it is that you are trying to accomplish will probably fail to work as planned. Cheers, Dick Johnson Penguin : Linux version 2.6.25.17 on an i686 machine (4786.16 BogoMips). My book : http://www.AbominableFirebug.com/ _ **************************************************************** The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them. Thank you. --
Traditionally it was not allowed because -O0 didn't inline and
the kernel relied on inlining in some cases. But with always_inline
that is obsolete -- all functions that rely on inlining should be
marked __always_inline.
I think a few more cases crept in where it was common to write
build time asserts as
if (some condition the compiler evaluates at runtime)
__error_condition_xyz_is_false();
and this obviously relies on the optimizer to build. But these
are all slowly moving over the BUILD_BUG_ON() which also doesn't
rely on the optimizer, so it's also obsolete.
Then there's the issue that some of the kernel macros will
generate absolutely terrible code without optimizer
(good examples are the macros in asm-x86/uaccess.h). But I guess
that could be tolerated too.
Then another reason was that traditionally no source level
debugger was included and if you do assembly level debugging
optimized code is typically easier to read and debug because
the unoptimized gcc code is so terrible.
And with kgdb now being a standard option that has also changed.
And I agree with you that sometimes stepping through code
is very educational. And gdb tends to be a lot happier
with -O0 code indeed.
So if you can make it all work cleanly, ideally tested on
other architectures too and a bit broader (e.g. with allyesconfig)
and track down whatever the mm/* issue
is correctly I don't see any real reason to not submit
a mainline patch that enables this as a CONFIG. Of course
it has to be very clean and not contain hacks.
If you're not familiar with submitting kernel patches
please read Documentation/{SubmittingPatches,SubmitChecklist}
first.
Hope this helps,
-Andi
--
ak@linux.intel.com
--
^^^^^^^
The reason why it works for Keith at all seems to be that even with -O0
gcc already does this kind of optimizations.
Check e.g. the assembler generated for the following
(userspace) program with -O0:
<-- snip -->
int foobar;
int main()
{
if (1) return 0;
foobar = 12345;
return 42;
}
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
--
What I mean is global optimization over the whole function, like constant propagation. That is required for some of the more complex macros like the *_user() ones. Some expression evaluation is required by the C standard (e.g. otherwise you couldn't generally declare global arrays with expressions) While that's technically not required in the body of the function outside declarations the compiler does it normally. But only inside a statement. -Andi --
Compiling with -O0 has worked previously, but not for a while. David --
You can call me surprised.
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
--
When 2.4 was the cutting edge kernel. I don't remember the dates or versions exactly. David --
