aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/uv
diff options
context:
space:
mode:
authorCliff Wickman <cpw@sgi.com>2012-01-16 16:19:47 -0500
committerIngo Molnar <mingo@elte.hu>2012-01-17 03:09:54 -0500
commitc5d35d399e685acccc85a675e8765c26b2a9813a (patch)
tree5b66e875217ccc2e106162a089efddd5fec40c21 /arch/x86/include/asm/uv
parentd059f9fa84a30e04279c6ff615e9e2cf3b260191 (diff)
x86/UV2: Work around BAU bug
This patch implements a workaround for a UV2 hardware bug. The bug is a non-atomic update of a memory-mapped register. When hardware message delivery and software message acknowledge occur simultaneously the pending message acknowledge for the arriving message may be lost. This causes the sender's message status to stay busy. Part of the workaround is to not acknowledge a completed message until it is verified that no other message is actually using the resource that is mistakenly recorded in the completed message. Part of the workaround is to test for long elapsed time in such a busy condition, then handle it by using a spare sending descriptor. The stay-busy condition is eventually timed out by hardware, and then the original sending descriptor can be re-used. Most of that logic change is in keeping track of the current descriptor and the state of the spares. The occurrences of the workaround are added to the BAU statistics. Signed-off-by: Cliff Wickman <cpw@sgi.com> Link: http://lkml.kernel.org/r/20120116211947.GC5767@sgi.com Cc: <stable@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/include/asm/uv')
-rw-r--r--arch/x86/include/asm/uv/uv_bau.h13
1 files changed, 12 insertions, 1 deletions
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h
index 4a46b27ee9a0..1b82f7e87393 100644
--- a/arch/x86/include/asm/uv/uv_bau.h
+++ b/arch/x86/include/asm/uv/uv_bau.h
@@ -167,6 +167,7 @@
167#define FLUSH_RETRY_TIMEOUT 2 167#define FLUSH_RETRY_TIMEOUT 2
168#define FLUSH_GIVEUP 3 168#define FLUSH_GIVEUP 3
169#define FLUSH_COMPLETE 4 169#define FLUSH_COMPLETE 4
170#define FLUSH_RETRY_BUSYBUG 5
170 171
171/* 172/*
172 * tuning the action when the numalink network is extremely delayed 173 * tuning the action when the numalink network is extremely delayed
@@ -463,7 +464,6 @@ struct bau_pq_entry {
463struct msg_desc { 464struct msg_desc {
464 struct bau_pq_entry *msg; 465 struct bau_pq_entry *msg;
465 int msg_slot; 466 int msg_slot;
466 int swack_slot;
467 struct bau_pq_entry *queue_first; 467 struct bau_pq_entry *queue_first;
468 struct bau_pq_entry *queue_last; 468 struct bau_pq_entry *queue_last;
469}; 469};
@@ -517,6 +517,9 @@ struct ptc_stats {
517 unsigned long s_retry_messages; /* retry broadcasts */ 517 unsigned long s_retry_messages; /* retry broadcasts */
518 unsigned long s_bau_reenabled; /* for bau enable/disable */ 518 unsigned long s_bau_reenabled; /* for bau enable/disable */
519 unsigned long s_bau_disabled; /* for bau enable/disable */ 519 unsigned long s_bau_disabled; /* for bau enable/disable */
520 unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */
521 unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */
522 unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */
520 /* destination statistics */ 523 /* destination statistics */
521 unsigned long d_alltlb; /* times all tlb's on this 524 unsigned long d_alltlb; /* times all tlb's on this
522 cpu were flushed */ 525 cpu were flushed */
@@ -593,6 +596,8 @@ struct bau_control {
593 short cpus_in_socket; 596 short cpus_in_socket;
594 short cpus_in_uvhub; 597 short cpus_in_uvhub;
595 short partition_base_pnode; 598 short partition_base_pnode;
599 short using_desc; /* an index, like uvhub_cpu */
600 unsigned int inuse_map;
596 unsigned short message_number; 601 unsigned short message_number;
597 unsigned short uvhub_quiesce; 602 unsigned short uvhub_quiesce;
598 short socket_acknowledge_count[DEST_Q_SIZE]; 603 short socket_acknowledge_count[DEST_Q_SIZE];
@@ -610,6 +615,7 @@ struct bau_control {
610 int cong_response_us; 615 int cong_response_us;
611 int cong_reps; 616 int cong_reps;
612 int cong_period; 617 int cong_period;
618 unsigned long clocks_per_100_usec;
613 cycles_t period_time; 619 cycles_t period_time;
614 long period_requests; 620 long period_requests;
615 struct hub_and_pnode *thp; 621 struct hub_and_pnode *thp;
@@ -670,6 +676,11 @@ static inline void write_mmr_sw_ack(unsigned long mr)
670 uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr); 676 uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr);
671} 677}
672 678
679static inline void write_gmmr_sw_ack(int pnode, unsigned long mr)
680{
681 write_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr);
682}
683
673static inline unsigned long read_mmr_sw_ack(void) 684static inline unsigned long read_mmr_sw_ack(void)
674{ 685{
675 return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); 686 return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);