[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Schedule page scrubbing for dead domains off the per-cpu periodic
ChangeSet 1.1159.256.68, 2005/03/22 19:26:37+00:00, kaf24@xxxxxxxxxxxxxxxxxxxx Schedule page scrubbing for dead domains off the per-cpu periodic ticker. We take 10% of busy cpus and all of idle cpu time. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> arch/x86/domain.c | 3 + common/page_alloc.c | 89 +++++++++++++++++++++++++++++++++++++++++++------- common/schedule.c | 2 + include/xen/mm.h | 13 +++++++ include/xen/softirq.h | 3 + 5 files changed, 97 insertions(+), 13 deletions(-) diff -Nru a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c 2005-03-22 15:04:13 -05:00 +++ b/xen/arch/x86/domain.c 2005-03-22 15:04:13 -05:00 @@ -69,7 +69,10 @@ { irq_stat[cpu].idle_timestamp = jiffies; while ( !softirq_pending(cpu) ) + { + page_scrub_schedule_work(); default_idle(); + } do_softirq(); } } diff -Nru a/xen/common/page_alloc.c b/xen/common/page_alloc.c --- a/xen/common/page_alloc.c 2005-03-22 15:04:13 -05:00 +++ b/xen/common/page_alloc.c 2005-03-22 15:04:13 -05:00 @@ -28,6 +28,7 @@ #include <xen/spinlock.h> #include <xen/slab.h> #include <xen/irq.h> +#include <xen/softirq.h> #include <asm/domain_page.h> /* @@ -551,7 +552,6 @@ { int i, drop_dom_ref; struct domain *d = pg->u.inuse.domain; - void *p; ASSERT(!in_irq()); @@ -579,26 +579,31 @@ pg[i].tlbflush_timestamp = tlbflush_current_time(); pg[i].u.free.cpu_mask = 1 << d->processor; list_del(&pg[i].list); + } + + d->tot_pages -= 1 << order; + drop_dom_ref = (d->tot_pages == 0); + + spin_unlock_recursive(&d->page_alloc_lock); + if ( likely(!test_bit(DF_DYING, &d->flags)) ) + { + free_heap_pages(MEMZONE_DOM, pg, order); + } + else + { /* * Normally we expect a domain to clear pages before freeing them, * if it cares about the secrecy of their contents. However, after * a domain has died we assume responsibility for erasure. */ - if ( unlikely(test_bit(DF_DYING, &d->flags)) ) + for ( i = 0; i < (1 << order); i++ ) { - p = map_domain_mem(page_to_phys(&pg[i])); - clear_page(p); - unmap_domain_mem(p); + spin_lock(&page_scrub_lock); + list_add(&pg[i].list, &page_scrub_list); + spin_unlock(&page_scrub_lock); } } - - d->tot_pages -= 1 << order; - drop_dom_ref = (d->tot_pages == 0); - - spin_unlock_recursive(&d->page_alloc_lock); - - free_heap_pages(MEMZONE_DOM, pg, order); } else { @@ -616,3 +621,63 @@ { return avail[MEMZONE_DOM]; } + + + +/************************* + * PAGE SCRUBBING + */ + +static spinlock_t page_scrub_lock; +struct list_head page_scrub_list; + +static void page_scrub_softirq(void) +{ + struct list_head *ent; + struct pfn_info *pg; + void *p; + int i; + s_time_t start = NOW(); + + /* Aim to do 1ms of work (ten percent of a 10ms jiffy). */ + do { + spin_lock(&page_scrub_lock); + + if ( unlikely((ent = page_scrub_list.next) == &page_scrub_list) ) + { + spin_unlock(&page_scrub_lock); + return; + } + + /* Peel up to 16 pages from the list. */ + for ( i = 0; i < 16; i++ ) + if ( (ent = ent->next) == &page_scrub_list ) + break; + + /* Remove peeled pages from the list. */ + ent->next->prev = &page_scrub_list; + page_scrub_list.next = ent->next; + + spin_unlock(&page_scrub_lock); + + /* Working backwards, scrub each page in turn. */ + while ( ent != &page_scrub_list ) + { + pg = list_entry(ent, struct pfn_info, list); + ent = ent->prev; + p = map_domain_mem(page_to_phys(pg)); + clear_page(p); + unmap_domain_mem(p); + free_heap_pages(MEMZONE_DOM, pg, 0); + } + } while ( (NOW() - start) < MILLISECS(1) ); +} + +static __init int page_scrub_init(void) +{ + spin_lock_init(&page_scrub_lock); + INIT_LIST_HEAD(&page_scrub_list); + open_softirq(PAGE_SCRUB_SOFTIRQ, page_scrub_softirq); + return 0; +} +__initcall(page_scrub_init); diff -Nru a/xen/common/schedule.c b/xen/common/schedule.c --- a/xen/common/schedule.c 2005-03-22 15:04:13 -05:00 +++ b/xen/common/schedule.c 2005-03-22 15:04:13 -05:00 @@ -437,6 +437,8 @@ if ( !is_idle_task(d) && update_dom_time(d) ) send_guest_virq(d, VIRQ_TIMER); + page_scrub_schedule_work(); + t_timer[d->processor].expires = NOW() + MILLISECS(10); add_ac_timer(&t_timer[d->processor]); } diff -Nru a/xen/include/xen/mm.h b/xen/include/xen/mm.h --- a/xen/include/xen/mm.h 2005-03-22 15:04:13 -05:00 +++ b/xen/include/xen/mm.h 2005-03-22 15:04:13 -05:00 @@ -2,6 +2,10 @@ #ifndef __XEN_MM_H__ #define __XEN_MM_H__ +#include <xen/config.h> +#include <xen/list.h> +#include <xen/spinlock.h> + struct domain; struct pfn_info; @@ -33,6 +37,15 @@ unsigned long avail_domheap_pages(void); #define alloc_domheap_page(_d) (alloc_domheap_pages(_d,0)) #define free_domheap_page(_p) (free_domheap_pages(_p,0)) + +/* Automatic page scrubbing for dead domains. */ +extern spinlock_t page_scrub_lock; +extern struct list_head page_scrub_list; +#define page_scrub_schedule_work() \ + do { \ + if ( !list_empty(&page_scrub_list) ) \ + raise_softirq(PAGE_SCRUB_SOFTIRQ); \ + } while ( 0 ) #include <asm/mm.h> diff -Nru a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h --- a/xen/include/xen/softirq.h 2005-03-22 15:04:13 -05:00 +++ b/xen/include/xen/softirq.h 2005-03-22 15:04:13 -05:00 @@ -7,7 +7,8 @@ #define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2 #define KEYPRESS_SOFTIRQ 3 #define NMI_SOFTIRQ 4 -#define NR_SOFTIRQS 5 +#define PAGE_SCRUB_SOFTIRQ 5 +#define NR_SOFTIRQS 6 #ifndef __ASSEMBLY__ ------------------------------------------------------- This SF.net email is sponsored by: 2005 Windows Mobile Application Contest Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones for the chance to win $25,000 and application distribution. Enter today at http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |