ia64/xen-unstable

changeset 4302:86d00dbf81dd

bitkeeper revision 1.1236.43.4 (424334begQSfXEFH2X7nIwb4TohPsA)

Fix TLB flushing on page type changes for SMP guests.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Mar 24 21:44:30 2005 +0000 (2005-03-24)
parents 2587eb489863
children 818774e72986
files xen/arch/x86/mm.c xen/common/page_alloc.c xen/include/asm-x86/flushtlb.h
line diff
     1.1 --- a/xen/arch/x86/mm.c	Thu Mar 24 18:50:40 2005 +0000
     1.2 +++ b/xen/arch/x86/mm.c	Thu Mar 24 21:44:30 2005 +0000
     1.3 @@ -1147,13 +1147,16 @@ int get_page_type(struct pfn_info *page,
     1.4                   * may be unnecessary (e.g., page was GDT/LDT) but those
     1.5                   * circumstances should be very rare.
     1.6                   */
     1.7 -                struct domain *d = page_get_owner(page);
     1.8 -                if ( unlikely(NEED_FLUSH(tlbflush_time[d->exec_domain[0]->
     1.9 -                                                      processor],
    1.10 -                                         page->tlbflush_timestamp)) )
    1.11 +                struct exec_domain *ed;
    1.12 +                unsigned long mask = 0;
    1.13 +                for_each_exec_domain ( page_get_owner(page), ed )
    1.14 +                    mask |= 1 << ed->processor;
    1.15 +                mask = tlbflush_filter_cpuset(mask, page->tlbflush_timestamp);
    1.16 +
    1.17 +                if ( unlikely(mask != 0) )
    1.18                  {
    1.19 -                    perfc_incr(need_flush_tlb_flush);
    1.20 -                    flush_tlb_cpu(d->exec_domain[0]->processor);
    1.21 +                    perfc_incrc(need_flush_tlb_flush);
    1.22 +                    flush_tlb_mask(mask);
    1.23                  }
    1.24  
    1.25                  /* We lose existing type, back pointer, and validity. */
     2.1 --- a/xen/common/page_alloc.c	Thu Mar 24 18:50:40 2005 +0000
     2.2 +++ b/xen/common/page_alloc.c	Thu Mar 24 21:44:30 2005 +0000
     2.3 @@ -470,43 +470,30 @@ void init_domheap_pages(unsigned long ps
     2.4  struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order)
     2.5  {
     2.6      struct pfn_info *pg;
     2.7 -    unsigned long mask, flushed_mask, pfn_stamp, cpu_stamp;
     2.8 -    int i, j;
     2.9 +    unsigned long mask = 0;
    2.10 +    int i;
    2.11  
    2.12      ASSERT(!in_irq());
    2.13  
    2.14      if ( unlikely((pg = alloc_heap_pages(MEMZONE_DOM, order)) == NULL) )
    2.15          return NULL;
    2.16  
    2.17 -    flushed_mask = 0;
    2.18      for ( i = 0; i < (1 << order); i++ )
    2.19      {
    2.20 -        if ( (mask = (pg[i].u.free.cpu_mask & ~flushed_mask)) != 0 )
    2.21 -        {
    2.22 -            pfn_stamp = pg[i].tlbflush_timestamp;
    2.23 -            for ( j = 0; (mask != 0) && (j < smp_num_cpus); j++ )
    2.24 -            {
    2.25 -                if ( mask & (1UL<<j) )
    2.26 -                {
    2.27 -                    cpu_stamp = tlbflush_time[j];
    2.28 -                    if ( !NEED_FLUSH(cpu_stamp, pfn_stamp) )
    2.29 -                        mask &= ~(1UL<<j);
    2.30 -                }
    2.31 -            }
    2.32 -            
    2.33 -            if ( unlikely(mask != 0) )
    2.34 -            {
    2.35 -                flush_tlb_mask(mask);
    2.36 -                perfc_incrc(need_flush_tlb_flush);
    2.37 -                flushed_mask |= mask;
    2.38 -            }
    2.39 -        }
    2.40 +        mask |= tlbflush_filter_cpuset(
    2.41 +            pg[i].u.free.cpu_mask & ~mask, pg[i].tlbflush_timestamp);
    2.42  
    2.43          pg[i].count_info        = 0;
    2.44          pg[i].u.inuse._domain   = 0;
    2.45          pg[i].u.inuse.type_info = 0;
    2.46      }
    2.47  
    2.48 +    if ( unlikely(mask != 0) )
    2.49 +    {
    2.50 +        perfc_incrc(need_flush_tlb_flush);
    2.51 +        flush_tlb_mask(mask);
    2.52 +    }
    2.53 +
    2.54      if ( d == NULL )
    2.55          return pg;
    2.56  
    2.57 @@ -570,7 +557,7 @@ void free_domheap_pages(struct pfn_info 
    2.58          /* NB. May recursively lock from domain_relinquish_memory(). */
    2.59          spin_lock_recursive(&d->page_alloc_lock);
    2.60  
    2.61 -        for_each_exec_domain(d, ed)
    2.62 +        for_each_exec_domain ( d, ed )
    2.63              cpu_mask |= 1 << ed->processor;
    2.64  
    2.65          for ( i = 0; i < (1 << order); i++ )
     3.1 --- a/xen/include/asm-x86/flushtlb.h	Thu Mar 24 18:50:40 2005 +0000
     3.2 +++ b/xen/include/asm-x86/flushtlb.h	Thu Mar 24 21:44:30 2005 +0000
     3.3 @@ -43,6 +43,26 @@ static inline int NEED_FLUSH(u32 cpu_sta
     3.4               (lastuse_stamp <= curr_time)));
     3.5  }
     3.6  
     3.7 +/*
     3.8 + * Filter the given set of CPUs, returning only those that may not have
     3.9 + * flushed their TLBs since @page_timestamp.
    3.10 + */
    3.11 +static inline unsigned long tlbflush_filter_cpuset(
    3.12 +    unsigned long cpuset, u32 page_timestamp)
    3.13 +{
    3.14 +    int i;
    3.15 +    unsigned long remain;
    3.16 +
    3.17 +    for ( i = 0, remain = ~0UL; (cpuset & remain) != 0; i++, remain <<= 1 )
    3.18 +    {
    3.19 +        if ( (cpuset & (1UL << i)) &&
    3.20 +             !NEED_FLUSH(tlbflush_time[i], page_timestamp) )
    3.21 +            cpuset &= ~(1UL << i);
    3.22 +    }
    3.23 +
    3.24 +    return cpuset;
    3.25 +}
    3.26 +
    3.27  extern void new_tlbflush_clock_period(void);
    3.28  
    3.29  /* Read pagetable base. */