x86/platform/uv/BAU: Add status mmr location fields to bau_control
authorAndrew Banman <abanman@hpe.com>
Thu, 9 Mar 2017 16:42:12 +0000 (10:42 -0600)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 13 Mar 2017 13:26:29 +0000 (14:26 +0100)
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>
arch/x86/include/asm/uv/uv_bau.h
arch/x86/platform/uv/tlb_uv.c

index 695b873f4fd37ef33701279648d204ec28d7529b..0ec7631ad651f2dab448601903c772457bcd5867 100644 (file)
@@ -601,8 +601,12 @@ struct uvhub_desc {
        struct socket_desc      socket[2];
 };
 
-/*
- * one per-cpu; to locate the software tables
+/**
+ * struct bau_control
+ * @status_mmr: location of status mmr, determined by uvhub_cpu
+ * @status_index: index of ERR|BUSY bits in status mmr, determined by uvhub_cpu
+ *
+ * Per-cpu control struct containing CPU topology information and BAU tuneables.
  */
 struct bau_control {
        struct bau_desc         *descriptor_base;
@@ -620,6 +624,8 @@ struct bau_control {
        int                     timeout_tries;
        int                     ipi_attempts;
        int                     conseccompletes;
+       u64                     status_mmr;
+       int                     status_index;
        bool                    nobau;
        short                   baudisabled;
        short                   cpu;
index e6994fd5597a52d4a2ac9589a144ad3444a65486..13a7055e0dffea561b0ae563e7ee1945457b1f1e 100644 (file)
@@ -527,11 +527,12 @@ static unsigned long uv1_read_status(unsigned long mmr_offset, int right_shift)
  * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP
  */
 static int uv1_wait_completion(struct bau_desc *bau_desc,
-                               unsigned long mmr_offset, int right_shift,
                                struct bau_control *bcp, long try)
 {
        unsigned long descriptor_status;
        cycles_t ttm;
+       u64 mmr_offset = bcp->status_mmr;
+       int right_shift = bcp->status_index;
        struct ptc_stats *stat = bcp->statp;
 
        descriptor_status = uv1_read_status(mmr_offset, right_shift);
@@ -619,11 +620,12 @@ int handle_uv2_busy(struct bau_control *bcp)
 }
 
 static int uv2_3_wait_completion(struct bau_desc *bau_desc,
-                               unsigned long mmr_offset, int right_shift,
                                struct bau_control *bcp, long try)
 {
        unsigned long descriptor_stat;
        cycles_t ttm;
+       u64 mmr_offset = bcp->status_mmr;
+       int right_shift = bcp->status_index;
        int desc = bcp->uvhub_cpu;
        long busy_reps = 0;
        struct ptc_stats *stat = bcp->statp;
@@ -684,29 +686,12 @@ static int uv2_3_wait_completion(struct bau_desc *bau_desc,
        return FLUSH_COMPLETE;
 }
 
-/*
- * There are 2 status registers; each and array[32] of 2 bits. Set up for
- * which register to read and position in that register based on cpu in
- * current hub.
- */
 static int wait_completion(struct bau_desc *bau_desc, struct bau_control *bcp, long try)
 {
-       int right_shift;
-       unsigned long mmr_offset;
-       int desc = bcp->uvhub_cpu;
-
-       if (desc < UV_CPUS_PER_AS) {
-               mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
-               right_shift = desc * UV_ACT_STATUS_SIZE;
-       } else {
-               mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
-               right_shift = ((desc - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE);
-       }
-
        if (bcp->uvhub_version == UV_BAU_V1)
-               return uv1_wait_completion(bau_desc, mmr_offset, right_shift, bcp, try);
+               return uv1_wait_completion(bau_desc, bcp, try);
        else
-               return uv2_3_wait_completion(bau_desc, mmr_offset, right_shift, bcp, try);
+               return uv2_3_wait_completion(bau_desc, bcp, try);
 }
 
 /*
@@ -2024,8 +2009,7 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
                        struct bau_control **smasterp,
                        struct bau_control **hmasterp)
 {
-       int i;
-       int cpu;
+       int i, cpu, uvhub_cpu;
        struct bau_control *bcp;
 
        for (i = 0; i < sdp->num_cpus; i++) {
@@ -2054,7 +2038,21 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
                        return 1;
                }
                bcp->uvhub_master = *hmasterp;
-               bcp->uvhub_cpu = uv_cpu_blade_processor_id(cpu);
+               uvhub_cpu = uv_cpu_blade_processor_id(cpu);
+               bcp->uvhub_cpu = uvhub_cpu;
+
+               /*
+                * The ERROR and BUSY status registers are located pairwise over
+                * the STATUS_0 and STATUS_1 mmrs; each an array[32] of 2 bits.
+                */
+               if (uvhub_cpu < UV_CPUS_PER_AS) {
+                       bcp->status_mmr = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
+                       bcp->status_index = uvhub_cpu * UV_ACT_STATUS_SIZE;
+               } else {
+                       bcp->status_mmr = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
+                       bcp->status_index = (uvhub_cpu - UV_CPUS_PER_AS)
+                                               * UV_ACT_STATUS_SIZE;
+               }
 
                if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
                        pr_emerg("%d cpus per uvhub invalid\n",