aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/uv
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2013-09-23 17:25:01 -0400
committerIngo Molnar <mingo@kernel.org>2013-09-24 03:02:02 -0400
commit0d12ef0c900078cc1f4e78dff2245521aa5d0c89 (patch)
tree153aa438154d72d7fd838bd6c26b594062654206 /arch/x86/include/asm/uv
parent1e019421bca68cfae1a61a09d9d49cf6a9e2143b (diff)
x86/UV: Update UV support for external NMI signals
The current UV NMI handler has not been updated for the changes in the system NMI handler and the perf operations. The UV NMI handler reads an MMR in the UV Hub to check to see if the NMI event was caused by the external 'system NMI' that the operator can initiate on the System Mgmt Controller. The problem arises when the perf tools are running, causing millions of perf events per second on very large CPU count systems. Previously this was okay because the perf NMI handler ran at a higher priority on the NMI call chain and if the NMI was a perf event, it would stop calling other NMI handlers remaining on the NMI call chain. Now the system NMI handler calls all the handlers on the NMI call chain including the UV NMI handler. This causes the UV NMI handler to read the MMRs at the same millions per second rate. This can lead to significant performance loss and possible system failures. It also can cause thousands of 'Dazed and Confused' messages being sent to the system console. This effectively makes perf tools unusable on UV systems. To avoid this excessive overhead when perf tools are running, this code has been optimized to minimize reading of the MMRs as much as possible, by moving to the NMI_UNKNOWN notifier chain. This chain is called only when all the users on the standard NMI_LOCAL call chain have been called and none of them have claimed this NMI. There is an exception where the NMI_LOCAL notifier chain is used. When the perf tools are in use, it's possible that the UV NMI was captured by some other NMI handler and then either ignored or mistakenly processed as a perf event. We set a per_cpu ('ping') flag for those CPUs that ignored the initial NMI, and then send them an IPI NMI signal. The NMI_LOCAL handler on each cpu does not need to read the MMR, but instead checks the in memory flag indicating it was pinged. There are two module variables, 'ping_count' indicating how many requested NMI events occurred, and 'ping_misses' indicating how many stray NMI events. These most likely are perf events so it shows the overhead of the perf NMI interrupts and how many MMR reads were avoided. This patch also minimizes the reads of the MMRs by having the first cpu entering the NMI handler on each node set a per HUB in-memory atomic value. (Having a per HUB value avoids sending lock traffic over NumaLink.) Both types of UV NMIs from the SMI layer are supported. Signed-off-by: Mike Travis <travis@sgi.com> Reviewed-by: Dimitri Sivanich <sivanich@sgi.com> Reviewed-by: Hedi Berriche <hedi@sgi.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Cc: Jason Wessel <jason.wessel@windriver.com> Link: http://lkml.kernel.org/r/20130923212500.353547733@asylum.americas.sgi.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/include/asm/uv')
-rw-r--r--arch/x86/include/asm/uv/uv_hub.h57
-rw-r--r--arch/x86/include/asm/uv/uv_mmrs.h31
2 files changed, 86 insertions, 2 deletions
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index 2c32df95bb78..a30836c8ac4d 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -502,8 +502,8 @@ struct uv_blade_info {
502 unsigned short nr_online_cpus; 502 unsigned short nr_online_cpus;
503 unsigned short pnode; 503 unsigned short pnode;
504 short memory_nid; 504 short memory_nid;
505 spinlock_t nmi_lock; 505 spinlock_t nmi_lock; /* obsolete, see uv_hub_nmi */
506 unsigned long nmi_count; 506 unsigned long nmi_count; /* obsolete, see uv_hub_nmi */
507}; 507};
508extern struct uv_blade_info *uv_blade_info; 508extern struct uv_blade_info *uv_blade_info;
509extern short *uv_node_to_blade; 509extern short *uv_node_to_blade;
@@ -576,6 +576,59 @@ static inline int uv_num_possible_blades(void)
576 return uv_possible_blades; 576 return uv_possible_blades;
577} 577}
578 578
579/* Per Hub NMI support */
580extern void uv_nmi_setup(void);
581
582/* BMC sets a bit this MMR non-zero before sending an NMI */
583#define UVH_NMI_MMR UVH_SCRATCH5
584#define UVH_NMI_MMR_CLEAR UVH_SCRATCH5_ALIAS
585#define UVH_NMI_MMR_SHIFT 63
586#define UVH_NMI_MMR_TYPE "SCRATCH5"
587
588/* Newer SMM NMI handler, not present in all systems */
589#define UVH_NMI_MMRX UVH_EVENT_OCCURRED0
590#define UVH_NMI_MMRX_CLEAR UVH_EVENT_OCCURRED0_ALIAS
591#define UVH_NMI_MMRX_SHIFT (is_uv1_hub() ? \
592 UV1H_EVENT_OCCURRED0_EXTIO_INT0_SHFT :\
593 UVXH_EVENT_OCCURRED0_EXTIO_INT0_SHFT)
594#define UVH_NMI_MMRX_TYPE "EXTIO_INT0"
595
596/* Non-zero indicates newer SMM NMI handler present */
597#define UVH_NMI_MMRX_SUPPORTED UVH_EXTIO_INT0_BROADCAST
598
599/* Indicates to BIOS that we want to use the newer SMM NMI handler */
600#define UVH_NMI_MMRX_REQ UVH_SCRATCH5_ALIAS_2
601#define UVH_NMI_MMRX_REQ_SHIFT 62
602
603struct uv_hub_nmi_s {
604 raw_spinlock_t nmi_lock;
605 atomic_t in_nmi; /* flag this node in UV NMI IRQ */
606 atomic_t cpu_owner; /* last locker of this struct */
607 atomic_t read_mmr_count; /* count of MMR reads */
608 atomic_t nmi_count; /* count of true UV NMIs */
609 unsigned long nmi_value; /* last value read from NMI MMR */
610};
611
612struct uv_cpu_nmi_s {
613 struct uv_hub_nmi_s *hub;
614 atomic_t state;
615 atomic_t pinging;
616 int queries;
617 int pings;
618};
619
620DECLARE_PER_CPU(struct uv_cpu_nmi_s, __uv_cpu_nmi);
621#define uv_cpu_nmi (__get_cpu_var(__uv_cpu_nmi))
622#define uv_hub_nmi (uv_cpu_nmi.hub)
623#define uv_cpu_nmi_per(cpu) (per_cpu(__uv_cpu_nmi, cpu))
624#define uv_hub_nmi_per(cpu) (uv_cpu_nmi_per(cpu).hub)
625
626/* uv_cpu_nmi_states */
627#define UV_NMI_STATE_OUT 0
628#define UV_NMI_STATE_IN 1
629#define UV_NMI_STATE_DUMP 2
630#define UV_NMI_STATE_DUMP_DONE 3
631
579/* Update SCIR state */ 632/* Update SCIR state */
580static inline void uv_set_scir_bits(unsigned char value) 633static inline void uv_set_scir_bits(unsigned char value)
581{ 634{
diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h
index bd5f80e58a23..e42249bcf7e1 100644
--- a/arch/x86/include/asm/uv/uv_mmrs.h
+++ b/arch/x86/include/asm/uv/uv_mmrs.h
@@ -461,6 +461,23 @@ union uvh_event_occurred0_u {
461 461
462 462
463/* ========================================================================= */ 463/* ========================================================================= */
464/* UVH_EXTIO_INT0_BROADCAST */
465/* ========================================================================= */
466#define UVH_EXTIO_INT0_BROADCAST 0x61448UL
467#define UVH_EXTIO_INT0_BROADCAST_32 0x3f0
468
469#define UVH_EXTIO_INT0_BROADCAST_ENABLE_SHFT 0
470#define UVH_EXTIO_INT0_BROADCAST_ENABLE_MASK 0x0000000000000001UL
471
472union uvh_extio_int0_broadcast_u {
473 unsigned long v;
474 struct uvh_extio_int0_broadcast_s {
475 unsigned long enable:1; /* RW */
476 unsigned long rsvd_1_63:63;
477 } s;
478};
479
480/* ========================================================================= */
464/* UVH_GR0_TLB_INT0_CONFIG */ 481/* UVH_GR0_TLB_INT0_CONFIG */
465/* ========================================================================= */ 482/* ========================================================================= */
466#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL 483#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL
@@ -2606,6 +2623,20 @@ union uvh_scratch5_u {
2606}; 2623};
2607 2624
2608/* ========================================================================= */ 2625/* ========================================================================= */
2626/* UVH_SCRATCH5_ALIAS */
2627/* ========================================================================= */
2628#define UVH_SCRATCH5_ALIAS 0x2d0208UL
2629#define UVH_SCRATCH5_ALIAS_32 0x780
2630
2631
2632/* ========================================================================= */
2633/* UVH_SCRATCH5_ALIAS_2 */
2634/* ========================================================================= */
2635#define UVH_SCRATCH5_ALIAS_2 0x2d0210UL
2636#define UVH_SCRATCH5_ALIAS_2_32 0x788
2637
2638
2639/* ========================================================================= */
2609/* UVXH_EVENT_OCCURRED2 */ 2640/* UVXH_EVENT_OCCURRED2 */
2610/* ========================================================================= */ 2641/* ========================================================================= */
2611#define UVXH_EVENT_OCCURRED2 0x70100UL 2642#define UVXH_EVENT_OCCURRED2 0x70100UL