[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XENOPROFILE] Make xenoprof arch-generic with dynamic mapping/unmapping xenoprof
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 1d7d5d48fcdc2e73ce63e3aa8f6959e3669f9123 # Parent 1ef9954a26686b35b946d889726d4d35c283c2a0 [XENOPROFILE] Make xenoprof arch-generic with dynamic mapping/unmapping xenoprof buffer support and auto translated mode support. renamed xenoprof_get_buffer::buf_maddr, xenoprof_passive::buf_maddr to xenoprof_get_buffer::buf_gmaddr, xenoprof_passive::buf_gmaddr to support auto translated mode. With auto translated mode enabled, it is gmaddr, not maddr. Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> Simplify the share function. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c | 4 xen/arch/x86/oprofile/nmi_int.c | 5 xen/common/xenoprof.c | 122 +++++++++++++++------ xen/include/asm-x86/xenoprof.h | 11 + xen/include/public/xenoprof.h | 4 xen/include/xen/xenoprof.h | 4 6 files changed, 113 insertions(+), 37 deletions(-) diff -r 1ef9954a2668 -r 1d7d5d48fcdc linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c --- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Nov 22 09:51:20 2006 +0000 +++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Nov 22 10:09:28 2006 +0000 @@ -93,7 +93,7 @@ int xenoprof_arch_map_shared_buffer(stru if ( (ret = direct_kernel_remap_pfn_range( (unsigned long)area->addr, - get_buffer->buf_maddr >> PAGE_SHIFT, + get_buffer->buf_gmaddr >> PAGE_SHIFT, npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE), DOMID_SELF)) ) { vunmap(area->addr); @@ -127,7 +127,7 @@ int xenoprof_arch_set_passive(struct xen ret = direct_kernel_remap_pfn_range( (unsigned long)area->addr, - pdomain->buf_maddr >> PAGE_SHIFT, + pdomain->buf_gmaddr >> PAGE_SHIFT, npages * PAGE_SIZE, prot, DOMID_SELF); if (ret) { vunmap(area->addr); diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/arch/x86/oprofile/nmi_int.c --- a/xen/arch/x86/oprofile/nmi_int.c Wed Nov 22 09:51:20 2006 +0000 +++ b/xen/arch/x86/oprofile/nmi_int.c Wed Nov 22 10:09:28 2006 +0000 @@ -33,7 +33,6 @@ static unsigned long saved_lvtpc[NR_CPUS #define VIRQ_BITMASK_SIZE (MAX_OPROF_DOMAINS/32 + 1) extern int active_domains[MAX_OPROF_DOMAINS]; extern unsigned int adomains; -extern struct domain *primary_profiler; extern struct domain *adomain_ptrs[MAX_OPROF_DOMAINS]; extern unsigned long virq_ovf_pending[VIRQ_BITMASK_SIZE]; extern int is_active(struct domain *d); @@ -339,10 +338,10 @@ int nmi_init(int *num_events, int *is_pr return -ENODEV; } - if (primary_profiler == NULL) { + if (xenoprof_primary_profiler == NULL) { /* For now, only dom0 can be the primary profiler */ if (current->domain->domain_id == 0) { - primary_profiler = current->domain; + xenoprof_primary_profiler = current->domain; prim = 1; } } diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/common/xenoprof.c --- a/xen/common/xenoprof.c Wed Nov 22 09:51:20 2006 +0000 +++ b/xen/common/xenoprof.c Wed Nov 22 10:09:28 2006 +0000 @@ -2,15 +2,17 @@ * Copyright (C) 2005 Hewlett-Packard Co. * written by Aravind Menon & Jose Renato Santos * (email: xenoprof@xxxxxxxxxxxxx) + * + * arch generic xenoprof and IA64 support. + * dynamic map/unmap xenoprof buffer support. * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp> * VA Linux Systems Japan K.K. - * arch generic xenoprof and IA64 support. */ #include <xen/guest_access.h> #include <xen/sched.h> #include <public/xenoprof.h> -#include <asm/hvm/support.h> +#include <asm/shadow.h> /* Limit amount of pages used for shared buffer (per domain) */ #define MAX_OPROF_SHARED_PAGES 32 @@ -26,7 +28,7 @@ unsigned int pdomains; unsigned int pdomains; unsigned int activated; -struct domain *primary_profiler; +struct domain *xenoprof_primary_profiler; int xenoprof_state = XENOPROF_IDLE; u64 total_samples; @@ -90,10 +92,46 @@ static void xenoprof_reset_buf(struct do } } -static char *alloc_xenoprof_buf(struct domain *d, int npages) +static void +share_xenoprof_page_with_guest(struct domain* d, unsigned long mfn, int npages) +{ + int i; + + for ( i = 0; i < npages; i++ ) + share_xen_page_with_guest(mfn_to_page(mfn + i), d, XENSHARE_writable); +} + +static void +unshare_xenoprof_page_with_guest(unsigned long mfn, int npages) +{ + int i; + + for ( i = 0; i < npages; i++ ) + { + struct page_info *page = mfn_to_page(mfn + i); + BUG_ON(page_get_owner(page) != current->domain); + if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) + put_page(page); + } +} + +static void +xenoprof_shared_gmfn_with_guest( + struct domain* d, unsigned long maddr, unsigned long gmaddr, int npages) +{ + int i; + + for ( i = 0; i < npages; i++, maddr += PAGE_SIZE, gmaddr += PAGE_SIZE ) + { + BUG_ON(page_get_owner(maddr_to_page(maddr)) != d); + xenoprof_shared_gmfn(d, gmaddr, maddr); + } +} + +static char *alloc_xenoprof_buf(struct domain *d, int npages, uint64_t gmaddr) { char *rawbuf; - int i, order; + int order; /* allocate pages to store sample buffer shared with domain */ order = get_order_from_pages(npages); @@ -104,17 +142,11 @@ static char *alloc_xenoprof_buf(struct d return 0; } - /* Share pages so that kernel can map it */ - for ( i = 0; i < npages; i++ ) - share_xen_page_with_guest( - virt_to_page(rawbuf + i * PAGE_SIZE), - d, XENSHARE_writable); - return rawbuf; } static int alloc_xenoprof_struct( - struct domain *d, int max_samples, int is_passive) + struct domain *d, int max_samples, int is_passive, uint64_t gmaddr) { struct vcpu *v; int nvcpu, npages, bufsize, max_bufsize; @@ -147,7 +179,8 @@ static int alloc_xenoprof_struct( (max_samples - 1) * sizeof(struct event_log); npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1; - d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages); + d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages, + gmaddr); if ( d->xenoprof->rawbuf == NULL ) { @@ -269,6 +302,7 @@ static void reset_passive(struct domain if ( x == NULL ) return; + unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages); x->domain_type = XENOPROF_DOMAIN_IGNORED; } @@ -332,17 +366,30 @@ static int add_passive_list(XEN_GUEST_HA if ( d == NULL ) return -EINVAL; - if ( (d->xenoprof == NULL) && - ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) ) - { - put_domain(d); - return -ENOMEM; - } + if ( d->xenoprof == NULL ) + { + ret = alloc_xenoprof_struct( + d, passive.max_samples, 1, passive.buf_gmaddr); + if ( ret < 0 ) + { + put_domain(d); + return -ENOMEM; + } + } + + share_xenoprof_page_with_guest( + current->domain, virt_to_mfn(d->xenoprof->rawbuf), + d->xenoprof->npages); d->xenoprof->domain_type = XENOPROF_DOMAIN_PASSIVE; passive.nbuf = d->xenoprof->nbuf; passive.bufsize = d->xenoprof->bufsize; - passive.buf_maddr = __pa(d->xenoprof->rawbuf); + if ( !shadow_mode_translate(d) ) + passive.buf_gmaddr = __pa(d->xenoprof->rawbuf); + else + xenoprof_shared_gmfn_with_guest( + current->domain, __pa(d->xenoprof->rawbuf), + passive.buf_gmaddr, d->xenoprof->npages); if ( copy_to_guest(arg, &passive, 1) ) { @@ -442,7 +489,7 @@ static int xenoprof_op_init(XEN_GUEST_HA return -EFAULT; if ( xenoprof_init.is_primary ) - primary_profiler = current->domain; + xenoprof_primary_profiler = current->domain; return 0; } @@ -462,20 +509,30 @@ static int xenoprof_op_get_buffer(XEN_GU */ if ( d->xenoprof == NULL ) { - ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0); + ret = alloc_xenoprof_struct( + d, xenoprof_get_buffer.max_samples, 0, + xenoprof_get_buffer.buf_gmaddr); if ( ret < 0 ) return ret; } + share_xenoprof_page_with_guest( + d, virt_to_mfn(d->xenoprof->rawbuf), d->xenoprof->npages); + xenoprof_reset_buf(d); d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED; d->xenoprof->domain_ready = 0; - d->xenoprof->is_primary = (primary_profiler == current->domain); + d->xenoprof->is_primary = (xenoprof_primary_profiler == current->domain); xenoprof_get_buffer.nbuf = d->xenoprof->nbuf; xenoprof_get_buffer.bufsize = d->xenoprof->bufsize; - xenoprof_get_buffer.buf_maddr = __pa(d->xenoprof->rawbuf); + if ( !shadow_mode_translate(d) ) + xenoprof_get_buffer.buf_gmaddr = __pa(d->xenoprof->rawbuf); + else + xenoprof_shared_gmfn_with_guest( + d, __pa(d->xenoprof->rawbuf), xenoprof_get_buffer.buf_gmaddr, + d->xenoprof->npages); if ( copy_to_guest(arg, &xenoprof_get_buffer, 1) ) return -EFAULT; @@ -499,7 +556,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN return -EINVAL; } - if ( !NONPRIV_OP(op) && (current->domain != primary_profiler) ) + if ( !NONPRIV_OP(op) && (current->domain != xenoprof_primary_profiler) ) { printk("xenoprof: dom %d denied privileged operation %d\n", current->domain->domain_id, op); @@ -592,7 +649,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN case XENOPROF_enable_virq: { int i; - if ( current->domain == primary_profiler ) + if ( current->domain == xenoprof_primary_profiler ) { xenoprof_arch_enable_virq(); xenoprof_reset_stat(); @@ -609,7 +666,6 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN if ( (xenoprof_state == XENOPROF_READY) && (activated == adomains) ) ret = xenoprof_arch_start(); - if ( ret == 0 ) xenoprof_state = XENOPROF_PROFILING; break; @@ -624,14 +680,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN break; case XENOPROF_disable_virq: + { + struct xenoprof *x; if ( (xenoprof_state == XENOPROF_PROFILING) && (is_active(current->domain)) ) { ret = -EPERM; break; } - ret = reset_active(current->domain); - break; + if ( (ret = reset_active(current->domain)) != 0 ) + break; + x = current->domain->xenoprof; + unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages); + break; + } case XENOPROF_release_counters: ret = -EPERM; @@ -652,7 +714,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN { activated = 0; adomains=0; - primary_profiler = NULL; + xenoprof_primary_profiler = NULL; ret = 0; } break; diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/include/asm-x86/xenoprof.h --- a/xen/include/asm-x86/xenoprof.h Wed Nov 22 09:51:20 2006 +0000 +++ b/xen/include/asm-x86/xenoprof.h Wed Nov 22 10:09:28 2006 +0000 @@ -44,6 +44,17 @@ void nmi_release_counters(void); int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg); +struct vcpu; +struct cpu_user_regs; +int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs); +#define xenoprof_shared_gmfn(d, gmaddr, maddr) \ + do { \ + (void)(maddr); \ + gdprintk(XENLOG_WARNING, \ + "xenoprof/x86 with autotranslated mode enabled" \ + "isn't supported yet\n"); \ + } while (0) + #endif /* __ASM_X86_XENOPROF_H__ */ /* diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/include/public/xenoprof.h --- a/xen/include/public/xenoprof.h Wed Nov 22 09:51:20 2006 +0000 +++ b/xen/include/public/xenoprof.h Wed Nov 22 10:09:28 2006 +0000 @@ -87,7 +87,7 @@ struct xenoprof_get_buffer { int32_t max_samples; int32_t nbuf; int32_t bufsize; - uint64_t buf_maddr; + uint64_t buf_gmaddr; }; typedef struct xenoprof_get_buffer xenoprof_get_buffer_t; DEFINE_XEN_GUEST_HANDLE(xenoprof_get_buffer_t); @@ -110,7 +110,7 @@ typedef struct xenoprof_passive { int32_t max_samples; int32_t nbuf; int32_t bufsize; - uint64_t buf_maddr; + uint64_t buf_gmaddr; } xenoprof_passive_t; DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t); diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/include/xen/xenoprof.h --- a/xen/include/xen/xenoprof.h Wed Nov 22 09:51:20 2006 +0000 +++ b/xen/include/xen/xenoprof.h Wed Nov 22 10:09:28 2006 +0000 @@ -41,4 +41,8 @@ struct domain; struct domain; void free_xenoprof_pages(struct domain *d); +int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg); + +extern struct domain *xenoprof_primary_profiler; + #endif /* __XEN__XENOPROF_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |