]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Aug 2010 01:00:25 +0000 (18:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Aug 2010 01:00:25 +0000 (18:00 -0700)
* 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, UV: Make kdump avoid stack dumps - fix !CONFIG_KEXEC breakage
  x86, UV: Initialize BAU hub map
  x86, UV: Make kdump avoid stack dumps

arch/x86/include/asm/kdebug.h
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/crash.c
arch/x86/kernel/tlb_uv.c

index fa7c0b9747615ce6bd75c919b7ec884de076123c..5bdfca86581beb3b45c60fd1f8d900a5daa68bf9 100644 (file)
@@ -33,5 +33,11 @@ extern void __show_regs(struct pt_regs *regs, int all);
 extern void show_regs(struct pt_regs *regs);
 extern unsigned long oops_begin(void);
 extern void oops_end(unsigned long, struct pt_regs *, int signr);
+#ifdef CONFIG_KEXEC
+extern int in_crash_kexec;
+#else
+/* no crash dump is ever in progress if no crash kernel can be kexec'd */
+#define in_crash_kexec 0
+#endif
 
 #endif /* _ASM_X86_KDEBUG_H */
index e46f98f36e31f6e1b85211a87ea62de0c497cf6c..7b598b84c902e62f9f852d78c896acb03d4ba318 100644 (file)
@@ -604,6 +604,10 @@ int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data)
 {
        if (reason != DIE_NMI_IPI)
                return NOTIFY_OK;
+
+       if (in_crash_kexec)
+               /* do nothing if entering the crash kernel */
+               return NOTIFY_OK;
        /*
         * Use a lock so only one cpu prints at a time
         * to prevent intermixed output.
index ebd4c51d096a525cbc6978561e11b3a4afbeb385..764c7c2b18115f12e3edc673940dffcdf9f3b47f 100644 (file)
@@ -28,6 +28,8 @@
 #include <asm/reboot.h>
 #include <asm/virtext.h>
 
+int in_crash_kexec;
+
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
 static void kdump_nmi_callback(int cpu, struct die_args *args)
@@ -61,6 +63,7 @@ static void kdump_nmi_callback(int cpu, struct die_args *args)
 
 static void kdump_nmi_shootdown_cpus(void)
 {
+       in_crash_kexec = 1;
        nmi_shootdown_cpus(kdump_nmi_callback);
 
        disable_local_APIC();
index 59efb5390b37bec6d0de735c93483c35ba0ca43a..312ef0292815f1a3a757c10d3f994d67702b3531 100644 (file)
@@ -1484,15 +1484,16 @@ calculate_destination_timeout(void)
 /*
  * initialize the bau_control structure for each cpu
  */
-static void uv_init_per_cpu(int nuvhubs)
+static void __init uv_init_per_cpu(int nuvhubs)
 {
        int i;
        int cpu;
        int pnode;
        int uvhub;
+       int have_hmaster;
        short socket = 0;
        unsigned short socket_mask;
-       unsigned int uvhub_mask;
+       unsigned char *uvhub_mask;
        struct bau_control *bcp;
        struct uvhub_desc *bdp;
        struct socket_desc *sdp;
@@ -1516,28 +1517,29 @@ static void uv_init_per_cpu(int nuvhubs)
        uvhub_descs = (struct uvhub_desc *)
                kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
        memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
+       uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
        for_each_present_cpu(cpu) {
                bcp = &per_cpu(bau_control, cpu);
                memset(bcp, 0, sizeof(struct bau_control));
                pnode = uv_cpu_hub_info(cpu)->pnode;
                uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
-               uvhub_mask |= (1 << uvhub);
+               *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8));
                bdp = &uvhub_descs[uvhub];
                bdp->num_cpus++;
                bdp->uvhub = uvhub;
                bdp->pnode = pnode;
                /* kludge: 'assuming' one node per socket, and assuming that
                   disabling a socket just leaves a gap in node numbers */
-               socket = (cpu_to_node(cpu) & 1);;
+               socket = (cpu_to_node(cpu) & 1);
                bdp->socket_mask |= (1 << socket);
                sdp = &bdp->socket[socket];
                sdp->cpu_number[sdp->num_cpus] = cpu;
                sdp->num_cpus++;
        }
-       uvhub = 0;
-       while (uvhub_mask) {
-               if (!(uvhub_mask & 1))
-                       goto nexthub;
+       for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
+               if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8))))
+                       continue;
+               have_hmaster = 0;
                bdp = &uvhub_descs[uvhub];
                socket_mask = bdp->socket_mask;
                socket = 0;
@@ -1551,8 +1553,10 @@ static void uv_init_per_cpu(int nuvhubs)
                                bcp->cpu = cpu;
                                if (i == 0) {
                                        smaster = bcp;
-                                       if (socket == 0)
+                                       if (!have_hmaster) {
+                                               have_hmaster++;
                                                hmaster = bcp;
+                                       }
                                }
                                bcp->cpus_in_uvhub = bdp->num_cpus;
                                bcp->cpus_in_socket = sdp->num_cpus;
@@ -1566,11 +1570,9 @@ nextsocket:
                        socket++;
                        socket_mask = (socket_mask >> 1);
                }
-nexthub:
-               uvhub++;
-               uvhub_mask = (uvhub_mask >> 1);
        }
        kfree(uvhub_descs);
+       kfree(uvhub_mask);
        for_each_present_cpu(cpu) {
                bcp = &per_cpu(bau_control, cpu);
                bcp->baudisabled = 0;