aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-13 21:00:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-13 21:00:25 -0400
commitc206d44ffdd539f5f4553e1a92cc7711084c1d3c (patch)
treec2bfef721c91c3f468fb9a52bf69a785e4889128
parent83ae170092c8ec4d8a268d93438054e32493ee17 (diff)
parent1d6225e8cc5598f2bc5c992f9c88b1137763e8e1 (diff)
Merge branch 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* '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
-rw-r--r--arch/x86/include/asm/kdebug.h6
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c4
-rw-r--r--arch/x86/kernel/crash.c3
-rw-r--r--arch/x86/kernel/tlb_uv.c26
4 files changed, 27 insertions, 12 deletions
diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h
index fa7c0b974761..5bdfca86581b 100644
--- a/arch/x86/include/asm/kdebug.h
+++ b/arch/x86/include/asm/kdebug.h
@@ -33,5 +33,11 @@ extern void __show_regs(struct pt_regs *regs, int all);
33extern void show_regs(struct pt_regs *regs); 33extern void show_regs(struct pt_regs *regs);
34extern unsigned long oops_begin(void); 34extern unsigned long oops_begin(void);
35extern void oops_end(unsigned long, struct pt_regs *, int signr); 35extern void oops_end(unsigned long, struct pt_regs *, int signr);
36#ifdef CONFIG_KEXEC
37extern int in_crash_kexec;
38#else
39/* no crash dump is ever in progress if no crash kernel can be kexec'd */
40#define in_crash_kexec 0
41#endif
36 42
37#endif /* _ASM_X86_KDEBUG_H */ 43#endif /* _ASM_X86_KDEBUG_H */
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index e46f98f36e31..7b598b84c902 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -604,6 +604,10 @@ int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data)
604{ 604{
605 if (reason != DIE_NMI_IPI) 605 if (reason != DIE_NMI_IPI)
606 return NOTIFY_OK; 606 return NOTIFY_OK;
607
608 if (in_crash_kexec)
609 /* do nothing if entering the crash kernel */
610 return NOTIFY_OK;
607 /* 611 /*
608 * Use a lock so only one cpu prints at a time 612 * Use a lock so only one cpu prints at a time
609 * to prevent intermixed output. 613 * to prevent intermixed output.
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index ebd4c51d096a..764c7c2b1811 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -28,6 +28,8 @@
28#include <asm/reboot.h> 28#include <asm/reboot.h>
29#include <asm/virtext.h> 29#include <asm/virtext.h>
30 30
31int in_crash_kexec;
32
31#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) 33#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
32 34
33static void kdump_nmi_callback(int cpu, struct die_args *args) 35static 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)
61 63
62static void kdump_nmi_shootdown_cpus(void) 64static void kdump_nmi_shootdown_cpus(void)
63{ 65{
66 in_crash_kexec = 1;
64 nmi_shootdown_cpus(kdump_nmi_callback); 67 nmi_shootdown_cpus(kdump_nmi_callback);
65 68
66 disable_local_APIC(); 69 disable_local_APIC();
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 59efb5390b37..312ef0292815 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -1484,15 +1484,16 @@ calculate_destination_timeout(void)
1484/* 1484/*
1485 * initialize the bau_control structure for each cpu 1485 * initialize the bau_control structure for each cpu
1486 */ 1486 */
1487static void uv_init_per_cpu(int nuvhubs) 1487static void __init uv_init_per_cpu(int nuvhubs)
1488{ 1488{
1489 int i; 1489 int i;
1490 int cpu; 1490 int cpu;
1491 int pnode; 1491 int pnode;
1492 int uvhub; 1492 int uvhub;
1493 int have_hmaster;
1493 short socket = 0; 1494 short socket = 0;
1494 unsigned short socket_mask; 1495 unsigned short socket_mask;
1495 unsigned int uvhub_mask; 1496 unsigned char *uvhub_mask;
1496 struct bau_control *bcp; 1497 struct bau_control *bcp;
1497 struct uvhub_desc *bdp; 1498 struct uvhub_desc *bdp;
1498 struct socket_desc *sdp; 1499 struct socket_desc *sdp;
@@ -1516,28 +1517,29 @@ static void uv_init_per_cpu(int nuvhubs)
1516 uvhub_descs = (struct uvhub_desc *) 1517 uvhub_descs = (struct uvhub_desc *)
1517 kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); 1518 kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
1518 memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); 1519 memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
1520 uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
1519 for_each_present_cpu(cpu) { 1521 for_each_present_cpu(cpu) {
1520 bcp = &per_cpu(bau_control, cpu); 1522 bcp = &per_cpu(bau_control, cpu);
1521 memset(bcp, 0, sizeof(struct bau_control)); 1523 memset(bcp, 0, sizeof(struct bau_control));
1522 pnode = uv_cpu_hub_info(cpu)->pnode; 1524 pnode = uv_cpu_hub_info(cpu)->pnode;
1523 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; 1525 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
1524 uvhub_mask |= (1 << uvhub); 1526 *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8));
1525 bdp = &uvhub_descs[uvhub]; 1527 bdp = &uvhub_descs[uvhub];
1526 bdp->num_cpus++; 1528 bdp->num_cpus++;
1527 bdp->uvhub = uvhub; 1529 bdp->uvhub = uvhub;
1528 bdp->pnode = pnode; 1530 bdp->pnode = pnode;
1529 /* kludge: 'assuming' one node per socket, and assuming that 1531 /* kludge: 'assuming' one node per socket, and assuming that
1530 disabling a socket just leaves a gap in node numbers */ 1532 disabling a socket just leaves a gap in node numbers */
1531 socket = (cpu_to_node(cpu) & 1);; 1533 socket = (cpu_to_node(cpu) & 1);
1532 bdp->socket_mask |= (1 << socket); 1534 bdp->socket_mask |= (1 << socket);
1533 sdp = &bdp->socket[socket]; 1535 sdp = &bdp->socket[socket];
1534 sdp->cpu_number[sdp->num_cpus] = cpu; 1536 sdp->cpu_number[sdp->num_cpus] = cpu;
1535 sdp->num_cpus++; 1537 sdp->num_cpus++;
1536 } 1538 }
1537 uvhub = 0; 1539 for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
1538 while (uvhub_mask) { 1540 if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8))))
1539 if (!(uvhub_mask & 1)) 1541 continue;
1540 goto nexthub; 1542 have_hmaster = 0;
1541 bdp = &uvhub_descs[uvhub]; 1543 bdp = &uvhub_descs[uvhub];
1542 socket_mask = bdp->socket_mask; 1544 socket_mask = bdp->socket_mask;
1543 socket = 0; 1545 socket = 0;
@@ -1551,8 +1553,10 @@ static void uv_init_per_cpu(int nuvhubs)
1551 bcp->cpu = cpu; 1553 bcp->cpu = cpu;
1552 if (i == 0) { 1554 if (i == 0) {
1553 smaster = bcp; 1555 smaster = bcp;
1554 if (socket == 0) 1556 if (!have_hmaster) {
1557 have_hmaster++;
1555 hmaster = bcp; 1558 hmaster = bcp;
1559 }
1556 } 1560 }
1557 bcp->cpus_in_uvhub = bdp->num_cpus; 1561 bcp->cpus_in_uvhub = bdp->num_cpus;
1558 bcp->cpus_in_socket = sdp->num_cpus; 1562 bcp->cpus_in_socket = sdp->num_cpus;
@@ -1566,11 +1570,9 @@ nextsocket:
1566 socket++; 1570 socket++;
1567 socket_mask = (socket_mask >> 1); 1571 socket_mask = (socket_mask >> 1);
1568 } 1572 }
1569nexthub:
1570 uvhub++;
1571 uvhub_mask = (uvhub_mask >> 1);
1572 } 1573 }
1573 kfree(uvhub_descs); 1574 kfree(uvhub_descs);
1575 kfree(uvhub_mask);
1574 for_each_present_cpu(cpu) { 1576 for_each_present_cpu(cpu) {
1575 bcp = &per_cpu(bau_control, cpu); 1577 bcp = &per_cpu(bau_control, cpu);
1576 bcp->baudisabled = 0; 1578 bcp->baudisabled = 0;