lkml.org 
[lkml]   [2013]   [Jan]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 16/80] SGI-XP: handle non-fatal traps
    Date
    3.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Robin Holt <holt@sgi.com>

    commit 891348ca0f66206f1dc0e30d63757e3df1ae2d15 upstream.

    We found a user code which was raising a divide-by-zero trap. That trap
    would lead to XPC connections between system-partitions being torn down
    due to the die_chain notifier callouts it received.

    This also revealed a different issue where multiple callers into
    xpc_die_deactivate() would all attempt to do the disconnect in parallel
    which would sometimes lock up but often overwhelm the console on very
    large machines as each would print at least one line of output at the
    end of the deactivate.

    I reviewed all the users of the die_chain notifier and changed the code
    to ignore the notifier callouts for reasons which will not actually lead
    to a system to continue on to call die().

    [akpm@linux-foundation.org: fix ia64]
    Signed-off-by: Robin Holt <holt@sgi.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/misc/sgi-xp/xpc_main.c | 34 ++++++++++++++++++++++++++++++++--
    1 file changed, 32 insertions(+), 2 deletions(-)

    --- a/drivers/misc/sgi-xp/xpc_main.c
    +++ b/drivers/misc/sgi-xp/xpc_main.c
    @@ -53,6 +53,10 @@
    #include <linux/kthread.h>
    #include "xpc.h"

    +#ifdef CONFIG_X86_64
    +#include <asm/traps.h>
    +#endif
    +
    /* define two XPC debug device structures to be used with dev_dbg() et al */

    struct device_driver xpc_dbg_name = {
    @@ -1079,6 +1083,9 @@ xpc_system_reboot(struct notifier_block
    return NOTIFY_DONE;
    }

    +/* Used to only allow one cpu to complete disconnect */
    +static unsigned int xpc_die_disconnecting;
    +
    /*
    * Notify other partitions to deactivate from us by first disengaging from all
    * references to our memory.
    @@ -1092,6 +1099,9 @@ xpc_die_deactivate(void)
    long keep_waiting;
    long wait_to_print;

    + if (cmpxchg(&xpc_die_disconnecting, 0, 1))
    + return;
    +
    /* keep xpc_hb_checker thread from doing anything (just in case) */
    xpc_exiting = 1;

    @@ -1159,7 +1169,7 @@ xpc_die_deactivate(void)
    * about the lack of a heartbeat.
    */
    static int
    -xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
    +xpc_system_die(struct notifier_block *nb, unsigned long event, void *_die_args)
    {
    #ifdef CONFIG_IA64 /* !!! temporary kludge */
    switch (event) {
    @@ -1191,7 +1201,27 @@ xpc_system_die(struct notifier_block *nb
    break;
    }
    #else
    - xpc_die_deactivate();
    + struct die_args *die_args = _die_args;
    +
    + switch (event) {
    + case DIE_TRAP:
    + if (die_args->trapnr == X86_TRAP_DF)
    + xpc_die_deactivate();
    +
    + if (((die_args->trapnr == X86_TRAP_MF) ||
    + (die_args->trapnr == X86_TRAP_XF)) &&
    + !user_mode_vm(die_args->regs))
    + xpc_die_deactivate();
    +
    + break;
    + case DIE_INT3:
    + case DIE_DEBUG:
    + break;
    + case DIE_OOPS:
    + case DIE_GPF:
    + default:
    + xpc_die_deactivate();
    + }
    #endif

    return NOTIFY_DONE;



    \
     
     \ /
      Last update: 2013-01-09 23:21    [W:4.315 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site