compiler bug generates incorrect code in swap_free() (fix included)

From: Chuck Lever (cel@monkey.org)
Date: Mon Mar 04 2002 - 14:15:45 EST


please respond directly to me, as i am not subscribed to lkml.

executive summary: older versions of gcc generate bad assembler in
swap_free(), causing Oopses when the system is pushed into swapping.
fix suggested for 2.4.19-pre.

i run RedHat 7.0 on my laptop and have encountered system instability on
late releases of 2.4 that have kept me using 2.4.12. this week i finally
tracked the problem down.

anytime i run something that pushes the system into swap, processes start
oopsing because of a bad EIP, then the system deadlocks. the oops stack
traceback was always incomplete, but eventually i determined that these
processes had made it to swap_free() then were branching arbitrarily.

after screwing around with this a little, i determined that making
swap_entry_free() an "inline" function caused the problem to go away. i've
compared the object code in swap_free() generated by the stock compiler on
my 7.0 laptop, and the same object generated on 7.1 and 7.2 systems. the
newer gcc adds some extra pop instructions after the call to
swap_entry_free(), but otherwise the two compilers generate nearly the
same object code.

my theory is the pops are missing in the 7.0-generated object, causing the
"ret" at the end of swap_free() to return to some arbitrary value from the
stack.

inlining swap_entry_free() is a simple way to get this working for buggy
versions of gcc. the function is about 64 bytes and is only called in two
places in this module, so this change doesn't bloat the module terribly.

i also tested inlining swap_info_put(). this causes the compiler to
generate better code on UP systems because the spinlocks are no-ops, so no
calls or branches are generated. this is a worth-while change for
performance reasons, and almost makes up for the additional object code
generated when inlining swap_entry_free().

        - Chuck Lever

--
corporate:	<cel@netapp.com>
personal:	<chucklever@bigfoot.com>

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Mar 07 2002 - 21:00:35 EST