# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1161840540 -32400 # Node ID 0a16a1f7f4cbada65003e81f0526238c7394ac6b # Parent 84d25efc3a014ea7d1d7aa7f06f753622b470c4a separate xenoprof files in linux-sparse into arch-generic/depedent part. PATCHNAME: xenoprof_x86_linux_side Signed-off-by: Isaku Yamahata diff -r 84d25efc3a01 -r 0a16a1f7f4cb linux-2.6-xen-sparse/arch/i386/oprofile/Makefile --- a/linux-2.6-xen-sparse/arch/i386/oprofile/Makefile Mon Oct 23 14:36:46 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/i386/oprofile/Makefile Thu Oct 26 14:29:00 2006 +0900 @@ -7,7 +7,10 @@ DRIVER_OBJS = $(addprefix ../../../drive timer_int.o ) ifdef CONFIG_XEN -oprofile-y := $(DRIVER_OBJS) xenoprof.o +XENOPROF_COMMON_OBJS = $(addprefix ../../../drivers/xen/xenoprof/, \ + xenoprofile.o) +oprofile-y := $(DRIVER_OBJS) \ + $(XENOPROF_COMMON_OBJS) xenoprof.o else oprofile-y := $(DRIVER_OBJS) init.o backtrace.o oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \ diff -r 84d25efc3a01 -r 0a16a1f7f4cb linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c --- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Mon Oct 23 14:36:46 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Thu Oct 26 14:29:00 2006 +0900 @@ -9,249 +9,83 @@ * Modified by Aravind Menon and Jose Renato Santos for Xen * These modifications are: * Copyright (C) 2005 Hewlett-Packard Co. + * + * x86-specific part + * Copyright (c) 2006 Isaku Yamahata + * VA Linux Systems Japan K.K. */ #include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include "op_counter.h" #include #include #include -#include <../../../drivers/oprofile/cpu_buffer.h> -#include <../../../drivers/oprofile/event_buffer.h> +#include +#include "op_counter.h" -#define MAX_XENOPROF_SAMPLES 16 +static unsigned int num_events = 0; -static int xenoprof_start(void); -static void xenoprof_stop(void); - -static int xenoprof_enabled = 0; -static unsigned int num_events = 0; -static int is_primary = 0; -static int active_defined; - -/* sample buffers shared with Xen */ -xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS]; -/* Shared buffer area */ -char * shared_buffer = NULL; -/* Number of buffers in shared area (one per VCPU) */ -int nbuf; -/* Mappings of VIRQ_XENOPROF to irq number (per cpu) */ -int ovf_irq[NR_CPUS]; -/* cpu model type string - copied from Xen memory space on XENOPROF_init command */ -char cpu_type[XENOPROF_CPU_TYPE_SIZE]; - -/* Passive sample buffers shared with Xen */ -xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS]; -/* Passive shared buffer area */ -char *p_shared_buffer[MAX_OPROF_DOMAINS]; - -#ifdef CONFIG_PM - -static int xenoprof_suspend(struct sys_device * dev, pm_message_t state) +void __init xenoprof_arch_init_counter(struct xenoprof_init *init) { - if (xenoprof_enabled == 1) - xenoprof_stop(); - return 0; -} - - -static int xenoprof_resume(struct sys_device * dev) -{ - if (xenoprof_enabled == 1) - xenoprof_start(); - return 0; -} - - -static struct sysdev_class oprofile_sysclass = { - set_kset_name("oprofile"), - .resume = xenoprof_resume, - .suspend = xenoprof_suspend -}; - - -static struct sys_device device_oprofile = { - .id = 0, - .cls = &oprofile_sysclass, -}; - - -static int __init init_driverfs(void) -{ - int error; - if (!(error = sysdev_class_register(&oprofile_sysclass))) - error = sysdev_register(&device_oprofile); - return error; -} - - -static void __exit exit_driverfs(void) -{ - sysdev_unregister(&device_oprofile); - sysdev_class_unregister(&oprofile_sysclass); -} - -#else -#define init_driverfs() do { } while (0) -#define exit_driverfs() do { } while (0) -#endif /* CONFIG_PM */ - -unsigned long long oprofile_samples = 0; -unsigned long long p_oprofile_samples = 0; - -unsigned int pdomains; -struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS]; - -static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive) -{ - int head, tail, size; - - head = buf->event_head; - tail = buf->event_tail; - size = buf->event_size; - - if (tail > head) { - while (tail < size) { - oprofile_add_pc(buf->event_log[tail].eip, - buf->event_log[tail].mode, - buf->event_log[tail].event); - if (!is_passive) - oprofile_samples++; - else - p_oprofile_samples++; - tail++; - } - tail = 0; - } - while (tail < head) { - oprofile_add_pc(buf->event_log[tail].eip, - buf->event_log[tail].mode, - buf->event_log[tail].event); - if (!is_passive) - oprofile_samples++; - else - p_oprofile_samples++; - tail++; - } - - buf->event_tail = tail; -} - -static void xenoprof_handle_passive(void) -{ - int i, j; - int flag_domain, flag_switch = 0; - - for (i = 0; i < pdomains; i++) { - flag_domain = 0; - for (j = 0; j < passive_domains[i].nbuf; j++) { - xenoprof_buf_t *buf = p_xenoprof_buf[i][j]; - if (buf->event_head == buf->event_tail) - continue; - if (!flag_domain) { - if (!oprofile_add_domain_switch(passive_domains[i]. - domain_id)) - goto done; - flag_domain = 1; - } - xenoprof_add_pc(buf, 1); - flag_switch = 1; - } - } -done: - if (flag_switch) - oprofile_add_domain_switch(COORDINATOR_DOMAIN); -} - -static irqreturn_t -xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs) -{ - struct xenoprof_buf * buf; - int cpu; - static unsigned long flag; - - cpu = smp_processor_id(); - buf = xenoprof_buf[cpu]; - - xenoprof_add_pc(buf, 0); - - if (is_primary && !test_and_set_bit(0, &flag)) { - xenoprof_handle_passive(); - smp_mb__before_clear_bit(); - clear_bit(0, &flag); - } - - return IRQ_HANDLED; -} - - -static void unbind_virq(void) -{ - int i; - - for_each_cpu(i) { - if (ovf_irq[i] >= 0) { - unbind_from_irqhandler(ovf_irq[i], NULL); - ovf_irq[i] = -1; - } + num_events = init->num_events; + /* just in case - make sure we do not overflow event list + (i.e. counter_config list) */ + if (num_events > OP_MAX_COUNTER) { + num_events = OP_MAX_COUNTER; + init->num_events = num_events; } } +void xenoprof_arch_counter(void) +{ + int i; + struct xenoprof_counter counter; -static int bind_virq(void) -{ - int i, result; - - for_each_cpu(i) { - result = bind_virq_to_irqhandler(VIRQ_XENOPROF, - i, - xenoprof_ovf_interrupt, - SA_INTERRUPT, - "xenoprof", - NULL); - - if (result < 0) { - unbind_virq(); - return result; - } - - ovf_irq[i] = result; + for (i=0; ibuffer) { + vunmap(sbuf->buffer); + sbuf->buffer = NULL; + } +} + +int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer * get_buffer, + struct xenoprof_shared_buffer * sbuf) +{ + int npages, ret; struct vm_struct *area; - if ( shared_buffer ) - return 0; - - get_buffer.max_samples = max_samples; - - if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, &get_buffer)) ) + sbuf->buffer = NULL; + if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, get_buffer)) ) return ret; - nbuf = get_buffer.nbuf; - npages = (get_buffer.bufsize * nbuf - 1) / PAGE_SIZE + 1; + npages = (get_buffer->bufsize * get_buffer->nbuf - 1) / PAGE_SIZE + 1; area = alloc_vm_area(npages * PAGE_SIZE); if (area == NULL) @@ -259,231 +93,55 @@ static int map_xenoprof_buffer(int max_s if ( (ret = direct_kernel_remap_pfn_range( (unsigned long)area->addr, - get_buffer.buf_maddr >> PAGE_SHIFT, - npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE), DOMID_SELF)) ) { + get_buffer->buf_gmaddr >> PAGE_SHIFT, + npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE), + DOMID_SELF)) ) { vunmap(area->addr); return ret; } - shared_buffer = area->addr; - for (i=0; i< nbuf; i++) { - buf = (struct xenoprof_buf*) - &shared_buffer[i * get_buffer.bufsize]; - BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS); - xenoprof_buf[buf->vcpu_id] = buf; - } - - return 0; -} - - -static int xenoprof_setup(void) -{ - int ret; - int i; - - if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) ) - return ret; - - if ( (ret = bind_virq()) ) - return ret; - - if (is_primary) { - struct xenoprof_counter counter; - - /* Define dom0 as an active domain if not done yet */ - if (!active_defined) { - domid_t domid; - ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL); - if (ret) - goto err; - domid = 0; - ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid); - if (ret) - goto err; - active_defined = 1; - } - - ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters, NULL); - if (ret) - goto err; - for (i=0; ibuffer = area->addr; return ret; } - -static void xenoprof_shutdown(void) -{ - xenoprof_enabled = 0; - - HYPERVISOR_xenoprof_op(XENOPROF_disable_virq, NULL); - - if (is_primary) { - HYPERVISOR_xenoprof_op(XENOPROF_release_counters, NULL); - active_defined = 0; - } - - unbind_virq(); - -} - - -static int xenoprof_start(void) -{ - int ret = 0; - - if (is_primary) - ret = HYPERVISOR_xenoprof_op(XENOPROF_start, NULL); - - return ret; -} - - -static void xenoprof_stop(void) -{ - if (is_primary) - HYPERVISOR_xenoprof_op(XENOPROF_stop, NULL); -} - - -static int xenoprof_set_active(int * active_domains, - unsigned int adomains) -{ - int ret = 0; - int i; - int set_dom0 = 0; - domid_t domid; - - if (!is_primary) - return 0; - - if (adomains > MAX_OPROF_DOMAINS) - return -E2BIG; - - ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL); - if (ret) - return ret; - - for (i=0; ibuffer = NULL; + ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, pdomain); + if (ret) + goto out; - if (pdoms > MAX_OPROF_DOMAINS) - return -E2BIG; + npages = (pdomain->bufsize * pdomain->nbuf - 1) / PAGE_SIZE + 1; - ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL); - if (ret) - return ret; - - for (i = 0; i < pdoms; i++) { - passive_domains[i].domain_id = p_domains[i]; - passive_domains[i].max_samples = 2048; - ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, - &passive_domains[i]); - if (ret) - goto out; - - npages = (passive_domains[i].bufsize * passive_domains[i].nbuf - 1) / PAGE_SIZE + 1; - - area = alloc_vm_area(npages * PAGE_SIZE); - if (area == NULL) { - ret = -ENOMEM; - goto out; - } - - ret = direct_kernel_remap_pfn_range( - (unsigned long)area->addr, - passive_domains[i].buf_maddr >> PAGE_SHIFT, - npages * PAGE_SIZE, prot, DOMID_SELF); - if (ret) { - vunmap(area->addr); - goto out; - } - - p_shared_buffer[i] = area->addr; - - for (j = 0; j < passive_domains[i].nbuf; j++) { - buf = (struct xenoprof_buf *) - &p_shared_buffer[i][j * passive_domains[i].bufsize]; - BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS); - p_xenoprof_buf[i][buf->vcpu_id] = buf; - } - + area = alloc_vm_area(npages * PAGE_SIZE); + if (area == NULL) { + ret = -ENOMEM; + goto out; } - pdomains = pdoms; - return 0; + ret = direct_kernel_remap_pfn_range( + (unsigned long)area->addr, + pdomain->buf_gmaddr >> PAGE_SHIFT, + npages * PAGE_SIZE, prot, DOMID_SELF); + if (ret) { + vunmap(area->addr); + goto out; + } + sbuf->buffer = area->addr; out: - for (j = 0; j < i; j++) { - vunmap(p_shared_buffer[j]); - p_shared_buffer[j] = NULL; - } - - return ret; + return ret; } struct op_counter_config counter_config[OP_MAX_COUNTER]; -static int xenoprof_create_files(struct super_block * sb, struct dentry * root) +int xenoprof_create_files(struct super_block * sb, struct dentry * root) { unsigned int i; @@ -510,75 +168,12 @@ static int xenoprof_create_files(struct return 0; } - -struct oprofile_operations xenoprof_ops = { - .create_files = xenoprof_create_files, - .set_active = xenoprof_set_active, - .set_passive = xenoprof_set_passive, - .setup = xenoprof_setup, - .shutdown = xenoprof_shutdown, - .start = xenoprof_start, - .stop = xenoprof_stop -}; - - -/* in order to get driverfs right */ -static int using_xenoprof; - int __init oprofile_arch_init(struct oprofile_operations * ops) { - struct xenoprof_init init; - int ret, i; - - ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init); - - if (!ret) { - num_events = init.num_events; - is_primary = init.is_primary; - - /* just in case - make sure we do not overflow event list - (i.e. counter_config list) */ - if (num_events > OP_MAX_COUNTER) - num_events = OP_MAX_COUNTER; - - /* cpu_type is detected by Xen */ - cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0; - strncpy(cpu_type, init.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1); - xenoprof_ops.cpu_type = cpu_type; - - init_driverfs(); - using_xenoprof = 1; - *ops = xenoprof_ops; - - for (i=0; i + * + * Modified by Aravind Menon and Jose Renato Santos for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. + * + * Separated out arch-generic part + * Copyright (c) 2006 Isaku Yamahata + * VA Linux Systems Japan K.K. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../drivers/oprofile/cpu_buffer.h" +#include "../../../drivers/oprofile/event_buffer.h" + +#define MAX_XENOPROF_SAMPLES 16 + +/* sample buffers shared with Xen */ +xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS]; +/* Shared buffer area */ +struct xenoprof_shared_buffer shared_buffer; + +/* Passive sample buffers shared with Xen */ +xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS]; +/* Passive shared buffer area */ +struct xenoprof_shared_buffer p_shared_buffer[MAX_OPROF_DOMAINS]; + +static int xenoprof_start(void); +static void xenoprof_stop(void); + +static int xenoprof_enabled = 0; +int xenoprof_is_primary = 0; +static int active_defined; + +/* Number of buffers in shared area (one per VCPU) */ +int nbuf; +/* Mappings of VIRQ_XENOPROF to irq number (per cpu) */ +int ovf_irq[NR_CPUS]; +/* cpu model type string - copied from Xen memory space on XENOPROF_init command */ +char cpu_type[XENOPROF_CPU_TYPE_SIZE]; + +#ifdef CONFIG_PM + +static int xenoprof_suspend(struct sys_device * dev, pm_message_t state) +{ + if (xenoprof_enabled == 1) + xenoprof_stop(); + return 0; +} + + +static int xenoprof_resume(struct sys_device * dev) +{ + if (xenoprof_enabled == 1) + xenoprof_start(); + return 0; +} + + +static struct sysdev_class oprofile_sysclass = { + set_kset_name("oprofile"), + .resume = xenoprof_resume, + .suspend = xenoprof_suspend +}; + + +static struct sys_device device_oprofile = { + .id = 0, + .cls = &oprofile_sysclass, +}; + + +static int __init init_driverfs(void) +{ + int error; + if (!(error = sysdev_class_register(&oprofile_sysclass))) + error = sysdev_register(&device_oprofile); + return error; +} + + +static void /* __exit */ exit_driverfs(void) +{ + sysdev_unregister(&device_oprofile); + sysdev_class_unregister(&oprofile_sysclass); +} + +#else +#define init_driverfs() do { } while (0) +#define exit_driverfs() do { } while (0) +#endif /* CONFIG_PM */ + +unsigned long long oprofile_samples = 0; +unsigned long long p_oprofile_samples = 0; + +unsigned int pdomains; +struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS]; + +static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive) +{ + int head, tail, size; + + head = buf->event_head; + tail = buf->event_tail; + size = buf->event_size; + + if (tail > head) { + while (tail < size) { + oprofile_add_pc(buf->event_log[tail].eip, + buf->event_log[tail].mode, + buf->event_log[tail].event); + if (!is_passive) + oprofile_samples++; + else + p_oprofile_samples++; + tail++; + } + tail = 0; + } + while (tail < head) { + oprofile_add_pc(buf->event_log[tail].eip, + buf->event_log[tail].mode, + buf->event_log[tail].event); + if (!is_passive) + oprofile_samples++; + else + p_oprofile_samples++; + tail++; + } + + buf->event_tail = tail; +} + +static void xenoprof_handle_passive(void) +{ + int i, j; + int flag_domain, flag_switch = 0; + + for (i = 0; i < pdomains; i++) { + flag_domain = 0; + for (j = 0; j < passive_domains[i].nbuf; j++) { + xenoprof_buf_t *buf = p_xenoprof_buf[i][j]; + if (buf->event_head == buf->event_tail) + continue; + if (!flag_domain) { + if (!oprofile_add_domain_switch(passive_domains[i]. + domain_id)) + goto done; + flag_domain = 1; + } + xenoprof_add_pc(buf, 1); + flag_switch = 1; + } + } +done: + if (flag_switch) + oprofile_add_domain_switch(COORDINATOR_DOMAIN); +} + +static irqreturn_t +xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs) +{ + struct xenoprof_buf * buf; + int cpu; + static unsigned long flag; + + cpu = smp_processor_id(); + buf = xenoprof_buf[cpu]; + + xenoprof_add_pc(buf, 0); + + if (xenoprof_is_primary && !test_and_set_bit(0, &flag)) { + xenoprof_handle_passive(); + smp_mb__before_clear_bit(); + clear_bit(0, &flag); + } + + return IRQ_HANDLED; +} + + +static void unbind_virq(void) +{ + int i; + + for_each_online_cpu(i) { + if (ovf_irq[i] >= 0) { + unbind_from_irqhandler(ovf_irq[i], NULL); + ovf_irq[i] = -1; + } + } +} + + +static int bind_virq(void) +{ + int i, result; + + for_each_online_cpu(i) { + result = bind_virq_to_irqhandler(VIRQ_XENOPROF, + i, + xenoprof_ovf_interrupt, + SA_INTERRUPT, + "xenoprof", + NULL); + + if (result < 0) { + unbind_virq(); + return result; + } + + ovf_irq[i] = result; + } + + return 0; +} + + +static void unmap_passive_list(void) +{ + int i; + for (i = 0; i < pdomains; i++) + xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]); + pdomains = 0; +} + + +static int map_xenoprof_buffer(int max_samples) +{ + struct xenoprof_get_buffer get_buffer; + struct xenoprof_buf *buf; + int ret, i; + + if ( shared_buffer.buffer ) + return 0; + + get_buffer.max_samples = max_samples; + ret = xenoprof_arch_map_shared_buffer(&get_buffer, &shared_buffer); + if (ret) + return ret; + nbuf = get_buffer.nbuf; + + for (i=0; i< nbuf; i++) { + buf = (struct xenoprof_buf*) + &shared_buffer.buffer[i * get_buffer.bufsize]; + BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS); + xenoprof_buf[buf->vcpu_id] = buf; + } + + return 0; +} + + +static int xenoprof_setup(void) +{ + int ret; + + if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) ) + return ret; + + if ( (ret = bind_virq()) ) + return ret; + + if (xenoprof_is_primary) { + /* Define dom0 as an active domain if not done yet */ + if (!active_defined) { + domid_t domid; + ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL); + if (ret) + goto err; + domid = 0; + ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid); + if (ret) + goto err; + active_defined = 1; + } + + ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters, NULL); + if (ret) + goto err; + xenoprof_arch_counter(); + ret = HYPERVISOR_xenoprof_op(XENOPROF_setup_events, NULL); + + if (ret) + goto err; + } + + ret = HYPERVISOR_xenoprof_op(XENOPROF_enable_virq, NULL); + if (ret) + goto err; + + xenoprof_enabled = 1; + return 0; + err: + unbind_virq(); + return ret; +} + + +static void xenoprof_shutdown(void) +{ + xenoprof_enabled = 0; + + HYPERVISOR_xenoprof_op(XENOPROF_disable_virq, NULL); + + if (xenoprof_is_primary) { + HYPERVISOR_xenoprof_op(XENOPROF_release_counters, NULL); + active_defined = 0; + } + + unbind_virq(); + + xenoprof_arch_unmap_shared_buffer(&shared_buffer); + if (xenoprof_is_primary) + unmap_passive_list(); +} + + +static int xenoprof_start(void) +{ + int ret = 0; + + if (xenoprof_is_primary) + ret = HYPERVISOR_xenoprof_op(XENOPROF_start, NULL); + if (!ret) + xenoprof_arch_start(); + return ret; +} + + +static void xenoprof_stop(void) +{ + if (xenoprof_is_primary) + HYPERVISOR_xenoprof_op(XENOPROF_stop, NULL); + xenoprof_arch_stop(); +} + + +static int xenoprof_set_active(int * active_domains, + unsigned int adomains) +{ + int ret = 0; + int i; + int set_dom0 = 0; + domid_t domid; + + if (!xenoprof_is_primary) + return 0; + + if (adomains > MAX_OPROF_DOMAINS) + return -E2BIG; + + ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL); + if (ret) + return ret; + + for (i=0; i MAX_OPROF_DOMAINS) + return -E2BIG; + + ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL); + if (ret) + return ret; + unmap_passive_list(); + + for (i = 0; i < pdoms; i++) { + passive_domains[i].domain_id = p_domains[i]; + passive_domains[i].max_samples = 2048; + ret = xenoprof_arch_set_passive(&passive_domains[i], + &p_shared_buffer[i]); + if (ret) + goto out; + for (j = 0; j < passive_domains[i].nbuf; j++) { + buf = (struct xenoprof_buf *) + &p_shared_buffer[i].buffer[j * passive_domains[i].bufsize]; + BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS); + p_xenoprof_buf[i][buf->vcpu_id] = buf; + } + } + + pdomains = pdoms; + return 0; + +out: + for (j = 0; j < i; j++) + xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]); + + return ret; +} + +struct oprofile_operations xenoprof_ops = { +#ifdef HAVE_XENOPROF_CREATE_FILES + .create_files = xenoprof_create_files, +#endif + .set_active = xenoprof_set_active, + .set_passive = xenoprof_set_passive, + .setup = xenoprof_setup, + .shutdown = xenoprof_shutdown, + .start = xenoprof_start, + .stop = xenoprof_stop +}; + + +/* in order to get driverfs right */ +static int using_xenoprof; + +int __init xenoprofile_init(struct oprofile_operations * ops) +{ + struct xenoprof_init init; + int ret, i; + + ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init); + if (!ret) { + xenoprof_arch_init_counter(&init); + xenoprof_is_primary = init.is_primary; + + /* cpu_type is detected by Xen */ + cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0; + strncpy(cpu_type, init.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1); + xenoprof_ops.cpu_type = cpu_type; + + init_driverfs(); + using_xenoprof = 1; + *ops = xenoprof_ops; + + for (i=0; i + * VA Linux Systems Japan K.K. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef __ASM_XENOPROF_H__ +#define __ASM_XENOPROF_H__ + +struct super_block; +struct dentry; +int xenoprof_create_files(struct super_block * sb, struct dentry * root); +#define HAVE_XENOPROF_CREATE_FILES + +struct xenoprof_init; +void xenoprof_arch_init_counter(struct xenoprof_init *init); +void xenoprof_arch_counter(void); +void xenoprof_arch_start(void); +void xenoprof_arch_stop(void); + +struct xenoprof_arch_shared_buffer { + /* nothing */ +}; +struct xenoprof_shared_buffer; +void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer* sbuf); +struct xenoprof_get_buffer; +int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer* get_buffer, struct xenoprof_shared_buffer* sbuf); +struct xenoprof_passive; +int xenoprof_arch_set_passive(struct xenoprof_passive* pdomain, struct xenoprof_shared_buffer* sbuf); + +#endif /* __ASM_XENOPROF_H__ */ diff -r 84d25efc3a01 -r 0a16a1f7f4cb linux-2.6-xen-sparse/include/xen/xenoprof.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux-2.6-xen-sparse/include/xen/xenoprof.h Thu Oct 26 14:29:00 2006 +0900 @@ -0,0 +1,46 @@ +/****************************************************************************** + * xen/xenoprof.h + * + * Copyright (c) 2006 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __XEN_XENOPROF_H__ +#define __XEN_XENOPROF_H__ + +#ifdef CONFIG_OPROFILE +#include + +struct oprofile_operations; +int xenoprofile_init(struct oprofile_operations * ops); +void xenoprofile_exit(void); + +// for perfmon/xen +extern int xenoprof_is_primary; +#define is_xenoprof_primary() (xenoprof_is_primary) +#else +#define xenoprofile_init(ops) do { } while (0) +#define xenoprofile_exit() do { } while (0) +#define is_xenoprof_primary() (0) +#endif + +struct xenoprof_shared_buffer { + char *buffer; + struct xenoprof_arch_shared_buffer arch; +}; +#endif /* __XEN_XENOPROF_H__ */