]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/x86/kernel/tlb_uv.c
x86, UV: Make kdump avoid stack dumps
[karo-tx-linux.git] / arch / x86 / kernel / tlb_uv.c
index a1615058fad3ae59b955ff234b071f4fcbf4fc10..59efb5390b37bec6d0de735c93483c35ba0ca43a 100644 (file)
@@ -484,6 +484,47 @@ static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u)
        return 1;
 }
 
+/*
+ * Our retries are blocked by all destination swack resources being
+ * in use, and a timeout is pending. In that case hardware immediately
+ * returns the ERROR that looks like a destination timeout.
+ */
+static void
+destination_plugged(struct bau_desc *bau_desc, struct bau_control *bcp,
+                       struct bau_control *hmaster, struct ptc_stats *stat)
+{
+       udelay(bcp->plugged_delay);
+       bcp->plugged_tries++;
+       if (bcp->plugged_tries >= bcp->plugsb4reset) {
+               bcp->plugged_tries = 0;
+               quiesce_local_uvhub(hmaster);
+               spin_lock(&hmaster->queue_lock);
+               uv_reset_with_ipi(&bau_desc->distribution, bcp->cpu);
+               spin_unlock(&hmaster->queue_lock);
+               end_uvhub_quiesce(hmaster);
+               bcp->ipi_attempts++;
+               stat->s_resets_plug++;
+       }
+}
+
+static void
+destination_timeout(struct bau_desc *bau_desc, struct bau_control *bcp,
+                       struct bau_control *hmaster, struct ptc_stats *stat)
+{
+       hmaster->max_bau_concurrent = 1;
+       bcp->timeout_tries++;
+       if (bcp->timeout_tries >= bcp->timeoutsb4reset) {
+               bcp->timeout_tries = 0;
+               quiesce_local_uvhub(hmaster);
+               spin_lock(&hmaster->queue_lock);
+               uv_reset_with_ipi(&bau_desc->distribution, bcp->cpu);
+               spin_unlock(&hmaster->queue_lock);
+               end_uvhub_quiesce(hmaster);
+               bcp->ipi_attempts++;
+               stat->s_resets_timeout++;
+       }
+}
+
 /*
  * Completions are taking a very long time due to a congested numalink
  * network.
@@ -518,7 +559,7 @@ disable_for_congestion(struct bau_control *bcp, struct ptc_stats *stat)
  *
  * Send a broadcast and wait for it to complete.
  *
- * The flush_mask contains the cpus the broadcast is to be sent to, plus
+ * The flush_mask contains the cpus the broadcast is to be sent to including
  * cpus that are on the local uvhub.
  *
  * Returns 0 if all flushing represented in the mask was done.
@@ -553,7 +594,6 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
                        &hmaster->active_descriptor_count,
                        hmaster->max_bau_concurrent));
        }
-
        while (hmaster->uvhub_quiesce)
                cpu_relax();
 
@@ -584,40 +624,9 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
                        right_shift, this_cpu, bcp, smaster, try);
 
                if (completion_status == FLUSH_RETRY_PLUGGED) {
-                       /*
-                        * Our retries may be blocked by all destination swack
-                        * resources being consumed, and a timeout pending. In
-                        * that case hardware immediately returns the ERROR
-                        * that looks like a destination timeout.
-                        */
-                       udelay(bcp->plugged_delay);
-                       bcp->plugged_tries++;
-                       if (bcp->plugged_tries >= bcp->plugsb4reset) {
-                               bcp->plugged_tries = 0;
-                               quiesce_local_uvhub(hmaster);
-                               spin_lock(&hmaster->queue_lock);
-                               uv_reset_with_ipi(&bau_desc->distribution,
-                                                       this_cpu);
-                               spin_unlock(&hmaster->queue_lock);
-                               end_uvhub_quiesce(hmaster);
-                               bcp->ipi_attempts++;
-                               stat->s_resets_plug++;
-                       }
+                       destination_plugged(bau_desc, bcp, hmaster, stat);
                } else if (completion_status == FLUSH_RETRY_TIMEOUT) {
-                       hmaster->max_bau_concurrent = 1;
-                       bcp->timeout_tries++;
-                       udelay(TIMEOUT_DELAY);
-                       if (bcp->timeout_tries >= bcp->timeoutsb4reset) {
-                               bcp->timeout_tries = 0;
-                               quiesce_local_uvhub(hmaster);
-                               spin_lock(&hmaster->queue_lock);
-                               uv_reset_with_ipi(&bau_desc->distribution,
-                                                               this_cpu);
-                               spin_unlock(&hmaster->queue_lock);
-                               end_uvhub_quiesce(hmaster);
-                               bcp->ipi_attempts++;
-                               stat->s_resets_timeout++;
-                       }
+                       destination_timeout(bau_desc, bcp, hmaster, stat);
                }
                if (bcp->ipi_attempts >= bcp->ipi_reset_limit) {
                        bcp->ipi_attempts = 0;
@@ -628,10 +637,8 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
        } while ((completion_status == FLUSH_RETRY_PLUGGED) ||
                 (completion_status == FLUSH_RETRY_TIMEOUT));
        time2 = get_cycles();
-
        bcp->plugged_tries = 0;
        bcp->timeout_tries = 0;
-
        if ((completion_status == FLUSH_COMPLETE) &&
            (bcp->conseccompletes > bcp->complete_threshold) &&
            (hmaster->max_bau_concurrent <
@@ -740,7 +747,6 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
 
        bau_desc = bcp->descriptor_base;
        bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu;
-
        bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
 
        /* cpu statistics */
@@ -1629,12 +1635,16 @@ static int __init uv_bau_init(void)
        alloc_intr_gate(vector, uv_bau_message_intr1);
 
        for_each_possible_blade(uvhub) {
-               pnode = uv_blade_to_pnode(uvhub);
-               /* INIT the bau */
-               uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL,
-                                     ((unsigned long)1 << 63));
-               mmr = 1; /* should be 1 to broadcast to both sockets */
-               uv_write_global_mmr64(pnode, UVH_BAU_DATA_BROADCAST, mmr);
+               if (uv_blade_nr_possible_cpus(uvhub)) {
+                       pnode = uv_blade_to_pnode(uvhub);
+                       /* INIT the bau */
+                       uv_write_global_mmr64(pnode,
+                                       UVH_LB_BAU_SB_ACTIVATION_CONTROL,
+                                       ((unsigned long)1 << 63));
+                       mmr = 1; /* should be 1 to broadcast to both sockets */
+                       uv_write_global_mmr64(pnode, UVH_BAU_DATA_BROADCAST,
+                                               mmr);
+               }
        }
 
        return 0;