diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-05-13 15:09:41 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-05-13 15:09:41 +0000 |
commit | cde62b6cc81b19067a739d6f59faf0b1cf49cace (patch) | |
tree | 9249fbcb380fe5a6a553c8671995d9d0d3dce252 /xen | |
parent | 462dfb2f90b56afcdebe67d1f0302c059e0bbb1b (diff) | |
download | xen-cde62b6cc81b19067a739d6f59faf0b1cf49cace.tar.gz xen-cde62b6cc81b19067a739d6f59faf0b1cf49cace.tar.bz2 xen-cde62b6cc81b19067a739d6f59faf0b1cf49cace.zip |
bitkeeper revision 1.891.1.16 (40a38fb5auV2wZtbB0nLg2hIQ75DjA)
Optimisations for new network IO model. Much better receive
performance.
Diffstat (limited to 'xen')
-rw-r--r-- | xen/arch/i386/entry.S | 15 | ||||
-rw-r--r-- | xen/common/dom_mem_ops.c | 64 | ||||
-rw-r--r-- | xen/common/domain.c | 5 | ||||
-rw-r--r-- | xen/common/memory.c | 27 | ||||
-rw-r--r-- | xen/include/hypervisor-ifs/hypervisor-if.h | 1 |
5 files changed, 63 insertions, 49 deletions
diff --git a/xen/arch/i386/entry.S b/xen/arch/i386/entry.S index b522f4f754..4e9163a75d 100644 --- a/xen/arch/i386/entry.S +++ b/xen/arch/i386/entry.S @@ -183,20 +183,22 @@ do_multicall: multicall_loop: pushl %ecx multicall_fault1: - pushl 20(%ebx) + pushl 20(%ebx) # args[4] multicall_fault2: - pushl 16(%ebx) + pushl 16(%ebx) # args[3] multicall_fault3: - pushl 12(%ebx) + pushl 12(%ebx) # args[2] multicall_fault4: - pushl 8(%ebx) + pushl 8(%ebx) # args[1] multicall_fault5: - pushl 4(%ebx) + pushl 4(%ebx) # args[0] multicall_fault6: - movl (%ebx),%eax + movl (%ebx),%eax # op andl $255,%eax call *SYMBOL_NAME(hypervisor_call_table)(,%eax,4) multicall_return_from_call: +multicall_fault7: + movl %eax,24(%ebx) # args[5] == result addl $20,%esp popl %ecx addl $(ARGS_PER_MULTICALL_ENTRY*4),%ebx @@ -745,6 +747,7 @@ ENTRY(hypervisor_call_table) .long SYMBOL_NAME(do_xen_version) .long SYMBOL_NAME(do_console_io) .long SYMBOL_NAME(do_physdev_op) + .long SYMBOL_NAME(do_update_va_mapping_otherdomain) /* 25 */ .rept NR_syscalls-((.-hypervisor_call_table)/4) .long SYMBOL_NAME(do_ni_syscall) .endr diff --git a/xen/common/dom_mem_ops.c b/xen/common/dom_mem_ops.c index 79d0bb1df1..fcc4977bee 100644 --- a/xen/common/dom_mem_ops.c +++ b/xen/common/dom_mem_ops.c @@ -18,24 +18,22 @@ static long alloc_dom_mem(struct task_struct *p, reservation_increase_t op) { - struct pfn_info *page; - unsigned long mpfn; /* machine frame number of current page */ - void *va; /* Xen-usable mapping of current page */ - unsigned long i; + struct pfn_info *page; + unsigned long i; - for ( i = 0; i < op.size; i++ ) + /* Leave some slack pages; e.g., for the network. */ + if ( unlikely(free_pfns < (op.size + (SLACK_DOMAIN_MEM_KILOBYTES >> + (PAGE_SHIFT-10)))) ) { - /* Leave some slack pages; e.g., for the network. */ - if ( unlikely(free_pfns < (SLACK_DOMAIN_MEM_KILOBYTES >> - (PAGE_SHIFT-10))) ) - { - DPRINTK("Not enough slack: %u %u\n", - free_pfns, - SLACK_DOMAIN_MEM_KILOBYTES >> (PAGE_SHIFT-10)); - break; - } + DPRINTK("Not enough slack: %u %u\n", + free_pfns, + SLACK_DOMAIN_MEM_KILOBYTES >> (PAGE_SHIFT-10)); + return 0; + } - /* NB. 'alloc_domain_page' does limit checking on pages per domain. */ + for ( i = 0; i < op.size; i++ ) + { + /* NB. 'alloc_domain_page' does limit-checking on pages per domain. */ if ( unlikely((page = alloc_domain_page(p)) == NULL) ) { DPRINTK("Could not allocate a frame\n"); @@ -43,14 +41,8 @@ static long alloc_dom_mem(struct task_struct *p, reservation_increase_t op) } /* Inform the domain of the new page's machine address. */ - mpfn = (unsigned long)(page - frame_table); - copy_to_user(op.pages, &mpfn, sizeof(mpfn)); - op.pages++; - - /* Zero out the page to prevent information leakage. */ - va = map_domain_mem(mpfn << PAGE_SHIFT); - memset(va, 0, PAGE_SIZE); - unmap_domain_mem(va); + if ( unlikely(put_user(page_to_pfn(page), &op.pages[i]) != 0) ) + break; } return i; @@ -58,22 +50,21 @@ static long alloc_dom_mem(struct task_struct *p, reservation_increase_t op) static long free_dom_mem(struct task_struct *p, reservation_decrease_t op) { - struct pfn_info *page; - unsigned long mpfn; /* machine frame number of current page */ - unsigned long i; - long rc = 0; - int need_flush = 0; + struct pfn_info *page; + unsigned long i, mpfn; + long rc = 0; for ( i = 0; i < op.size; i++ ) { - copy_from_user(&mpfn, op.pages, sizeof(mpfn)); - op.pages++; - if ( mpfn >= max_page ) + if ( unlikely(get_user(mpfn, &op.pages[i]) != 0) ) + break; + + if ( unlikely(mpfn >= max_page) ) { DPRINTK("Domain %llu page number out of range (%08lx>=%08lx)\n", p->domain, mpfn, max_page); rc = -EINVAL; - goto out; + break; } page = &frame_table[mpfn]; @@ -81,7 +72,7 @@ static long free_dom_mem(struct task_struct *p, reservation_decrease_t op) { DPRINTK("Bad page free for domain %llu\n", p->domain); rc = -EINVAL; - goto out; + break; } if ( test_and_clear_bit(_PGC_guest_pinned, &page->count_and_flags) ) @@ -93,13 +84,6 @@ static long free_dom_mem(struct task_struct *p, reservation_decrease_t op) put_page(page); } - out: - if ( need_flush ) - { - __flush_tlb(); - perfc_incr(need_flush_tlb_flush); - } - return rc ? rc : op.size; } diff --git a/xen/common/domain.c b/xen/common/domain.c index f19c05eaf2..c40c052425 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -324,8 +324,7 @@ struct pfn_info *alloc_domain_page(struct task_struct *p) page->type_and_flags = 0; if ( p != NULL ) { - if ( unlikely(in_irq()) ) - BUG(); + ASSERT(!in_irq()); wmb(); /* Domain pointer must be visible before updating refcnt. */ spin_lock(&p->page_list_lock); if ( unlikely(p->tot_pages >= p->max_pages) ) @@ -369,7 +368,7 @@ void free_domain_page(struct pfn_info *page) if ( !(page->count_and_flags & PGC_zombie) ) { page->tlbflush_timestamp = tlbflush_clock; - if (p) + if ( likely(p != NULL) ) { page->u.cpu_mask = 1 << p->processor; spin_lock(&p->page_list_lock); diff --git a/xen/common/memory.c b/xen/common/memory.c index 3f8ee288ee..87ddf4c917 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1209,6 +1209,33 @@ int do_update_va_mapping(unsigned long page_nr, return err; } +int do_update_va_mapping_otherdomain(unsigned long page_nr, + unsigned long val, + unsigned long flags, + domid_t domid) +{ + unsigned int cpu = smp_processor_id(); + struct task_struct *p; + int rc; + + if ( unlikely(!IS_PRIV(current)) ) + return -EPERM; + + percpu_info[cpu].gps = p = find_domain_by_id(domid); + if ( unlikely(p == NULL) ) + { + MEM_LOG("Unknown domain '%llu'", domid); + return -ESRCH; + } + + rc = do_update_va_mapping(page_nr, val, flags); + + put_task_struct(p); + percpu_info[cpu].gps = NULL; + + return rc; +} + #ifndef NDEBUG /* diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h index 5cde5d46e4..efe34e2184 100644 --- a/xen/include/hypervisor-ifs/hypervisor-if.h +++ b/xen/include/hypervisor-ifs/hypervisor-if.h @@ -39,6 +39,7 @@ #define __HYPERVISOR_xen_version 22 #define __HYPERVISOR_console_io 23 #define __HYPERVISOR_physdev_op 24 +#define __HYPERVISOR_update_va_mapping_otherdomain 25 /* * MULTICALLS |