aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Banman <abanman@hpe.com>2017-03-09 11:42:12 -0500
committerThomas Gleixner <tglx@linutronix.de>2017-03-13 09:26:29 -0400
commitdfeb28f068ff9cc4f714c7d1edaf61597ea1768b (patch)
tree738ac9ba84d3e7ff43aabbe29a79fb7fb0063bec
parent8e3b21b6dbf0318d5b3a598572acc23f07189c40 (diff)
x86/platform/uv/BAU: Add status mmr location fields to bau_control
The location of the ERROR and BUSY status bits depends on the descriptor index, i.e. the CPU, of the message. Since this index does not change, there is no need to calculate the mmr and index location during message processing. The less work we do in the hot path the better. Add status_mmr and status_index fields to bau_control and compute their values during initialization. Add kerneldoc descriptions for the new fields. Update uv*_wait_completion to use these fields rather than receiving the information as parameters. Signed-off-by: Andrew Banman <abanman@hpe.com> Acked-by: Ingo Molnar <mingo@kernel.org> Acked-by: Mike Travis <mike.travis@hpe.com> Cc: sivanich@hpe.com Cc: rja@hpe.com Cc: akpm@linux-foundation.org Link: http://lkml.kernel.org/r/1489077734-111753-5-git-send-email-abanman@hpe.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/include/asm/uv/uv_bau.h10
-rw-r--r--arch/x86/platform/uv/tlb_uv.c46
2 files changed, 30 insertions, 26 deletions
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h
index 695b873f4fd3..0ec7631ad651 100644
--- a/arch/x86/include/asm/uv/uv_bau.h
+++ b/arch/x86/include/asm/uv/uv_bau.h
@@ -601,8 +601,12 @@ struct uvhub_desc {
601 struct socket_desc socket[2]; 601 struct socket_desc socket[2];
602}; 602};
603 603
604/* 604/**
605 * one per-cpu; to locate the software tables 605 * struct bau_control
606 * @status_mmr: location of status mmr, determined by uvhub_cpu
607 * @status_index: index of ERR|BUSY bits in status mmr, determined by uvhub_cpu
608 *
609 * Per-cpu control struct containing CPU topology information and BAU tuneables.
606 */ 610 */
607struct bau_control { 611struct bau_control {
608 struct bau_desc *descriptor_base; 612 struct bau_desc *descriptor_base;
@@ -620,6 +624,8 @@ struct bau_control {
620 int timeout_tries; 624 int timeout_tries;
621 int ipi_attempts; 625 int ipi_attempts;
622 int conseccompletes; 626 int conseccompletes;
627 u64 status_mmr;
628 int status_index;
623 bool nobau; 629 bool nobau;
624 short baudisabled; 630 short baudisabled;
625 short cpu; 631 short cpu;
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
index e6994fd5597a..13a7055e0dff 100644
--- a/arch/x86/platform/uv/tlb_uv.c
+++ b/arch/x86/platform/uv/tlb_uv.c
@@ -527,11 +527,12 @@ static unsigned long uv1_read_status(unsigned long mmr_offset, int right_shift)
527 * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP 527 * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP
528 */ 528 */
529static int uv1_wait_completion(struct bau_desc *bau_desc, 529static int uv1_wait_completion(struct bau_desc *bau_desc,
530 unsigned long mmr_offset, int right_shift,
531 struct bau_control *bcp, long try) 530 struct bau_control *bcp, long try)
532{ 531{
533 unsigned long descriptor_status; 532 unsigned long descriptor_status;
534 cycles_t ttm; 533 cycles_t ttm;
534 u64 mmr_offset = bcp->status_mmr;
535 int right_shift = bcp->status_index;
535 struct ptc_stats *stat = bcp->statp; 536 struct ptc_stats *stat = bcp->statp;
536 537
537 descriptor_status = uv1_read_status(mmr_offset, right_shift); 538 descriptor_status = uv1_read_status(mmr_offset, right_shift);
@@ -619,11 +620,12 @@ int handle_uv2_busy(struct bau_control *bcp)
619} 620}
620 621
621static int uv2_3_wait_completion(struct bau_desc *bau_desc, 622static int uv2_3_wait_completion(struct bau_desc *bau_desc,
622 unsigned long mmr_offset, int right_shift,
623 struct bau_control *bcp, long try) 623 struct bau_control *bcp, long try)
624{ 624{
625 unsigned long descriptor_stat; 625 unsigned long descriptor_stat;
626 cycles_t ttm; 626 cycles_t ttm;
627 u64 mmr_offset = bcp->status_mmr;
628 int right_shift = bcp->status_index;
627 int desc = bcp->uvhub_cpu; 629 int desc = bcp->uvhub_cpu;
628 long busy_reps = 0; 630 long busy_reps = 0;
629 struct ptc_stats *stat = bcp->statp; 631 struct ptc_stats *stat = bcp->statp;
@@ -684,29 +686,12 @@ static int uv2_3_wait_completion(struct bau_desc *bau_desc,
684 return FLUSH_COMPLETE; 686 return FLUSH_COMPLETE;
685} 687}
686 688
687/*
688 * There are 2 status registers; each and array[32] of 2 bits. Set up for
689 * which register to read and position in that register based on cpu in
690 * current hub.
691 */
692static int wait_completion(struct bau_desc *bau_desc, struct bau_control *bcp, long try) 689static int wait_completion(struct bau_desc *bau_desc, struct bau_control *bcp, long try)
693{ 690{
694 int right_shift;
695 unsigned long mmr_offset;
696 int desc = bcp->uvhub_cpu;
697
698 if (desc < UV_CPUS_PER_AS) {
699 mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
700 right_shift = desc * UV_ACT_STATUS_SIZE;
701 } else {
702 mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
703 right_shift = ((desc - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE);
704 }
705
706 if (bcp->uvhub_version == UV_BAU_V1) 691 if (bcp->uvhub_version == UV_BAU_V1)
707 return uv1_wait_completion(bau_desc, mmr_offset, right_shift, bcp, try); 692 return uv1_wait_completion(bau_desc, bcp, try);
708 else 693 else
709 return uv2_3_wait_completion(bau_desc, mmr_offset, right_shift, bcp, try); 694 return uv2_3_wait_completion(bau_desc, bcp, try);
710} 695}
711 696
712/* 697/*
@@ -2024,8 +2009,7 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
2024 struct bau_control **smasterp, 2009 struct bau_control **smasterp,
2025 struct bau_control **hmasterp) 2010 struct bau_control **hmasterp)
2026{ 2011{
2027 int i; 2012 int i, cpu, uvhub_cpu;
2028 int cpu;
2029 struct bau_control *bcp; 2013 struct bau_control *bcp;
2030 2014
2031 for (i = 0; i < sdp->num_cpus; i++) { 2015 for (i = 0; i < sdp->num_cpus; i++) {
@@ -2054,7 +2038,21 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
2054 return 1; 2038 return 1;
2055 } 2039 }
2056 bcp->uvhub_master = *hmasterp; 2040 bcp->uvhub_master = *hmasterp;
2057 bcp->uvhub_cpu = uv_cpu_blade_processor_id(cpu); 2041 uvhub_cpu = uv_cpu_blade_processor_id(cpu);
2042 bcp->uvhub_cpu = uvhub_cpu;
2043
2044 /*
2045 * The ERROR and BUSY status registers are located pairwise over
2046 * the STATUS_0 and STATUS_1 mmrs; each an array[32] of 2 bits.
2047 */
2048 if (uvhub_cpu < UV_CPUS_PER_AS) {
2049 bcp->status_mmr = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
2050 bcp->status_index = uvhub_cpu * UV_ACT_STATUS_SIZE;
2051 } else {
2052 bcp->status_mmr = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
2053 bcp->status_index = (uvhub_cpu - UV_CPUS_PER_AS)
2054 * UV_ACT_STATUS_SIZE;
2055 }
2058 2056
2059 if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { 2057 if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
2060 pr_emerg("%d cpus per uvhub invalid\n", 2058 pr_emerg("%d cpus per uvhub invalid\n",