[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] sn2 global_tlb_purge implementation



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1182365272 21600
# Node ID c20bc60f9243d08199cb0a9a837cbe11c6b3dcdc
# Parent  39a95178edbf6106f42918d3f6a7db914d1a9750
[IA64] sn2 global_tlb_purge implementation

Very simple global tlb purge implementation for SN2. ptcga isn't
propagated between nodes so IPI a CPU on each node to get the job
done. This is _slow_ and inefficient, but it works for now.

Signed-off-by: Jes Sorensen <jes@xxxxxxx>
---
 xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c |  101 ++++++++++++++++++++++++----
 1 files changed, 87 insertions(+), 14 deletions(-)

diff -r 39a95178edbf -r c20bc60f9243 xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c
--- a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c       Tue Jun 19 15:17:20 
2007 -0600
+++ b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c       Wed Jun 20 12:47:52 
2007 -0600
@@ -160,21 +160,97 @@ void sn_tlb_migrate_finish(struct mm_str
 // static cpumask_t mask_all = CPU_MASK_ALL;
 #endif
 
+#ifdef XEN
+static DEFINE_SPINLOCK(sn2_ptcg_lock);
+
+struct sn_flush_struct {
+       unsigned long start;
+       unsigned long end;
+       unsigned long nbits;
+};
+
+static void sn_flush_ptcga_cpu(void *ptr)
+{
+       struct sn_flush_struct *sn_flush = ptr;
+       unsigned long start, end, nbits;
+
+       start = sn_flush->start;
+       end = sn_flush->end;
+       nbits = sn_flush->nbits;
+
+       /*
+        * Contention me harder!!!
+        */
+       /* HW requires global serialization of ptc.ga.  */
+       spin_lock(&sn2_ptcg_lock);
+       {
+               do {
+                       /*
+                        * Flush ALAT entries also.
+                        */
+                       ia64_ptcga(start, (nbits<<2));
+                       ia64_srlz_i();
+                       start += (1UL << nbits);
+               } while (start < end);
+       }
+       spin_unlock(&sn2_ptcg_lock);
+}
+
 void
-#ifndef XEN
+sn2_global_tlb_purge(unsigned long start,
+                    unsigned long end, unsigned long nbits)
+{
+       nodemask_t nodes_flushed;
+       cpumask_t selected_cpus;
+       int cpu, cnode, i;
+       static DEFINE_SPINLOCK(sn2_ptcg_lock2);
+
+       nodes_clear(nodes_flushed);
+       cpus_clear(selected_cpus);
+
+       spin_lock(&sn2_ptcg_lock2);
+       node_set(cpu_to_node(smp_processor_id()), nodes_flushed);
+       i = 0;
+       for_each_cpu(cpu) {
+               cnode = cpu_to_node(cpu);
+               if (!node_isset(cnode, nodes_flushed)) {
+                       cpu_set(cpu, selected_cpus);
+                       i++;
+               }
+               node_set(cnode, nodes_flushed);
+       }
+
+       /* HW requires global serialization of ptc.ga.  */
+       spin_lock(&sn2_ptcg_lock);
+       {
+               do {
+                       /*
+                        * Flush ALAT entries also.
+                        */
+                       ia64_ptcga(start, (nbits<<2));
+                       ia64_srlz_i();
+                       start += (1UL << nbits);
+               } while (start < end);
+       }
+       spin_unlock(&sn2_ptcg_lock);
+
+       if (i) {
+               struct sn_flush_struct flush_data;
+               flush_data.start = start;
+               flush_data.end = end;
+               flush_data.nbits = nbits;
+               on_selected_cpus(selected_cpus, sn_flush_ptcga_cpu,
+                                &flush_data, 1, 1);
+       }
+       spin_unlock(&sn2_ptcg_lock2);
+}
+#else
+void
 sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
-#else
-sn2_global_tlb_purge(unsigned long start,
-#endif
                     unsigned long end, unsigned long nbits)
 {
        int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid;
-#ifndef XEN
        int mymm = (mm == current->active_mm && mm == current->mm);
-#else
-       // struct mm_struct *mm;
-       int mymm = 0;
-#endif
        int use_cpu_ptcga;
        volatile unsigned long *ptc0, *ptc1;
        unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr 
= 0;
@@ -206,6 +282,7 @@ sn2_global_tlb_purge(unsigned long start
 
        preempt_disable();
 
+#ifndef XEN
        if (likely(i == 1 && lcpu == smp_processor_id() && mymm)) {
                do {
                        ia64_ptcl(start, nbits << 2);
@@ -217,13 +294,8 @@ sn2_global_tlb_purge(unsigned long start
                return;
        }
 
-#ifndef XEN
        if (atomic_read(&mm->mm_users) == 1 && mymm) {
-#ifndef XEN  /* I hate Xen! */
                flush_tlb_mm(mm);
-#else
-               flush_tlb_mask(mask_all);
-#endif
                __get_cpu_var(ptcstats).change_rid++;
                preempt_enable();
                return;
@@ -335,6 +407,7 @@ sn2_global_tlb_purge(unsigned long start
 
        preempt_enable();
 }
+#endif
 
 /*
  * sn2_ptc_deadlock_recovery

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.