Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Mon, 4 Mar 2002 14:16:00 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Mon, 4 Mar 2002 14:15:54 -0500 Received: from naughty.monkey.org ([204.181.64.8]:7008 "HELO naughty.monkey.org") by vger.kernel.org with SMTP id ; Mon, 4 Mar 2002 14:15:46 -0500 Date: Mon, 4 Mar 2002 14:15:45 -0500 (EST) From: Chuck Lever To: Cc: Subject: compiler bug generates incorrect code in swap_free() (fix included) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org 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: personal: - 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/