[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Improved TLB flushing of subsets of CPUs. Can now do remote invlpg
ChangeSet 1.1410, 2005/03/31 14:12:29+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx Improved TLB flushing of subsets of CPUs. Can now do remote invlpg as well as complete flush. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> arch/x86/mm.c | 31 +++++++++++++++++++--------- arch/x86/mtrr/generic.c | 4 +-- arch/x86/smp.c | 15 +++++++++---- arch/x86/x86_32/mm.c | 4 +-- arch/x86/x86_64/mm.c | 4 +-- common/grant_table.c | 25 ++++++++++++---------- include/asm-x86/flushtlb.h | 49 +++++++++++++++++---------------------------- include/asm-x86/page.h | 13 ----------- 8 files changed, 70 insertions(+), 75 deletions(-) diff -Nru a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c 2005-03-31 09:02:28 -05:00 +++ b/xen/arch/x86/mm.c 2005-03-31 09:02:28 -05:00 @@ -1476,23 +1476,34 @@ break; case MMUEXT_INVLPG_LOCAL: - __flush_tlb_one(op.linear_addr); + local_flush_tlb_one(op.linear_addr); break; case MMUEXT_TLB_FLUSH_MULTI: - flush_tlb_mask(d->cpuset); /* XXX KAF XXX */ - break; - case MMUEXT_INVLPG_MULTI: - flush_tlb_mask(d->cpuset); /* XXX KAF XXX */ + { + unsigned long inset = op.cpuset, outset = 0; + while ( inset != 0 ) + { + unsigned int vcpu = find_first_set_bit(inset); + inset &= ~(1UL<<vcpu); + if ( (vcpu < MAX_VIRT_CPUS) && + ((ed = d->exec_domain[vcpu]) != NULL) ) + outset |= 1UL << ed->processor; + } + if ( op.cmd == MMUEXT_TLB_FLUSH_MULTI ) + flush_tlb_mask(outset & d->cpuset); + else + flush_tlb_one_mask(outset & d->cpuset, op.linear_addr); break; + } case MMUEXT_TLB_FLUSH_ALL: flush_tlb_mask(d->cpuset); break; case MMUEXT_INVLPG_ALL: - flush_tlb_mask(d->cpuset); /* XXX KAF XXX */ + flush_tlb_one_mask(d->cpuset, op.linear_addr); break; case MMUEXT_FLUSH_CACHE: @@ -2029,10 +2040,10 @@ percpu_info[cpu].deferred_ops &= ~DOP_FLUSH_TLB; break; case UVMF_INVLPG_LOCAL: - __flush_tlb_one(va); + local_flush_tlb_one(va); break; case UVMF_INVLPG_ALL: - flush_tlb_mask(d->cpuset); /* XXX KAF XXX */ + flush_tlb_one_mask(d->cpuset, va); break; } @@ -2317,7 +2328,7 @@ /* Ensure that there are no stale writable mappings in any TLB. */ /* NB. INVLPG is a serialising instruction: flushes pending updates. */ - __flush_tlb_one(l1va); /* XXX Multi-CPU guests? */ + local_flush_tlb_one(l1va); /* XXX Multi-CPU guests? */ PTWR_PRINTK("[%c] disconnected_l1va at %p now %p\n", PTWR_PRINT_WHICH, ptep, pte); @@ -2636,7 +2647,7 @@ likely(!shadow_mode_enabled(ed->domain)) ) { *pl2e = mk_l2_pgentry(l2e & ~_PAGE_PRESENT); - flush_tlb(); /* XXX Multi-CPU guests? */ + local_flush_tlb(); /* XXX Multi-CPU guests? */ } /* Temporarily map the L1 page, and make a copy of it. */ diff -Nru a/xen/arch/x86/mtrr/generic.c b/xen/arch/x86/mtrr/generic.c --- a/xen/arch/x86/mtrr/generic.c 2005-03-31 09:02:28 -05:00 +++ b/xen/arch/x86/mtrr/generic.c 2005-03-31 09:02:28 -05:00 @@ -261,7 +261,7 @@ } /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ - __flush_tlb(); + local_flush_tlb(); /* Save MTRR state */ rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); @@ -273,7 +273,7 @@ static void post_set(void) { /* Flush TLBs (no need to flush caches - they are disabled) */ - __flush_tlb(); + local_flush_tlb(); /* Intel (P6) standard MTRRs */ wrmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); diff -Nru a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c --- a/xen/arch/x86/smp.c 2005-03-31 09:02:28 -05:00 +++ b/xen/arch/x86/smp.c 2005-03-31 09:02:28 -05:00 @@ -148,17 +148,20 @@ } static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED; -static unsigned long flush_cpumask; +static unsigned long flush_cpumask, flush_va; asmlinkage void smp_invalidate_interrupt(void) { ack_APIC_irq(); perfc_incrc(ipis); - local_flush_tlb(); + if ( flush_va == FLUSHVA_ALL ) + local_flush_tlb(); + else + local_flush_tlb_one(flush_va); clear_bit(smp_processor_id(), &flush_cpumask); } -void flush_tlb_mask(unsigned long mask) +void __flush_tlb_mask(unsigned long mask, unsigned long va) { ASSERT(local_irq_is_enabled()); @@ -172,6 +175,7 @@ { spin_lock(&flush_lock); flush_cpumask = mask; + flush_va = va; send_IPI_mask(mask, INVALIDATE_TLB_VECTOR); while ( flush_cpumask != 0 ) cpu_relax(); @@ -190,6 +194,7 @@ spin_lock(&flush_lock); flush_cpumask = (1UL << smp_num_cpus) - 1; flush_cpumask &= ~(1UL << smp_processor_id()); + flush_va = FLUSHVA_ALL; send_IPI_allbutself(INVALIDATE_TLB_VECTOR); while ( flush_cpumask != 0 ) cpu_relax(); @@ -203,13 +208,13 @@ static void flush_tlb_all_pge_ipi(void *info) { - __flush_tlb_pge(); + local_flush_tlb_pge(); } void flush_tlb_all_pge(void) { smp_call_function(flush_tlb_all_pge_ipi, 0, 1, 1); - __flush_tlb_pge(); + local_flush_tlb_pge(); } void smp_send_event_check_mask(unsigned long cpu_mask) diff -Nru a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c --- a/xen/arch/x86/x86_32/mm.c 2005-03-31 09:02:28 -05:00 +++ b/xen/arch/x86/x86_32/mm.c 2005-03-31 09:02:28 -05:00 @@ -48,7 +48,7 @@ { /* Super-page mapping. */ if ( (l2_pgentry_val(*pl2e) & _PAGE_PRESENT) ) - __flush_tlb_pge(); + local_flush_tlb_pge(); *pl2e = mk_l2_pgentry(p|flags|_PAGE_PSE); v += 1 << L2_PAGETABLE_SHIFT; @@ -66,7 +66,7 @@ } pl1e = l2_pgentry_to_l1(*pl2e) + l1_table_offset(v); if ( (l1_pgentry_val(*pl1e) & _PAGE_PRESENT) ) - __flush_tlb_one(v); + local_flush_tlb_one(v); *pl1e = mk_l1_pgentry(p|flags); v += 1 << L1_PAGETABLE_SHIFT; diff -Nru a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c --- a/xen/arch/x86/x86_64/mm.c 2005-03-31 09:02:28 -05:00 +++ b/xen/arch/x86/x86_64/mm.c 2005-03-31 09:02:28 -05:00 @@ -89,7 +89,7 @@ { /* Super-page mapping. */ if ( (l2_pgentry_val(*pl2e) & _PAGE_PRESENT) ) - __flush_tlb_pge(); + local_flush_tlb_pge(); *pl2e = mk_l2_pgentry(p|flags|_PAGE_PSE); v += 1 << L2_PAGETABLE_SHIFT; @@ -107,7 +107,7 @@ } pl1e = l2_pgentry_to_l1(*pl2e) + l1_table_offset(v); if ( (l1_pgentry_val(*pl1e) & _PAGE_PRESENT) ) - __flush_tlb_one(v); + local_flush_tlb_one(v); *pl1e = mk_l1_pgentry(p|flags); v += 1 << L1_PAGETABLE_SHIFT; diff -Nru a/xen/common/grant_table.c b/xen/common/grant_table.c --- a/xen/common/grant_table.c 2005-03-31 09:02:28 -05:00 +++ b/xen/common/grant_table.c 2005-03-31 09:02:28 -05:00 @@ -102,7 +102,8 @@ if ( ((host_virt_addr != 0) || (flags & GNTMAP_host_map) ) && unlikely(!__addr_ok(host_virt_addr))) { - DPRINTK("Bad virtual address (%x) or flags (%x).\n", host_virt_addr, flags); + DPRINTK("Bad virtual address (%x) or flags (%x).\n", + host_virt_addr, flags); (void)__put_user(GNTST_bad_virt_addr, &uop->handle); return GNTST_bad_gntref; } @@ -332,8 +333,10 @@ */ } - /* Only make the maptrack live _after_ writing the pte, in case - * we overwrite the same frame number, causing a maptrack walk to find it */ + /* + * Only make the maptrack live _after_ writing the pte, in case we + * overwrite the same frame number, causing a maptrack walk to find it. + */ ld->grant_table->maptrack[handle].domid = dom; ld->grant_table->maptrack[handle].ref_and_flags = (ref << MAPTRACK_REF_SHIFT) | (flags & MAPTRACK_GNTMAP_MASK); @@ -364,13 +367,14 @@ unsigned long va = 0; for ( i = 0; i < count; i++ ) - if ( __gnttab_map_grant_ref(&uop[i], &va) == 0) + if ( __gnttab_map_grant_ref(&uop[i], &va) == 0 ) flush++; + /* XXX KAF: I think we are probably flushing too much here. */ if ( flush == 1 ) - __flush_tlb_one(va); + flush_tlb_one_mask(current->domain->cpuset, va); else if ( flush != 0 ) - local_flush_tlb(); + flush_tlb_mask(current->domain->cpuset); return 0; } @@ -457,7 +461,7 @@ unsigned long _ol1e; pl1e = &linear_pg_table[l1_linear_offset(virt)]; - + if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) ) { DPRINTK("Could not find PTE entry for address %x\n", virt); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |