* RE: RE: [PATCH] xenoprof (xen)
@ 2005-11-24 1:44 Santos, Jose Renato G
2005-11-24 2:51 ` John Levon
0 siblings, 1 reply; 8+ messages in thread
From: Santos, Jose Renato G @ 2005-11-24 1:44 UTC (permalink / raw)
To: Ian Pratt, Keir Fraser
Cc: John Levon, Jose Renato Santos, xen-devel, G John Janakiraman,
Turner, Yoshio
[-- Attachment #1: Type: text/plain, Size: 1845 bytes --]
Ian, Keir
Here are the xenoprof patches for the linux-2.6-xen.hg tree.
John Levon has reviewed these patches and I have included all his
suggestions on this version.
According to John, it is unlikely to have these patches included into
main stream linux until Xen is also included.
I am not sure how would you like to distribute it for now. I suggest
that we include the architecture specific driver for xen
(xenoprof-arch-linux-2.6.14.patch) into the linux sparse-tree for 2.6.14
(all code in this patch is under arch/i386/xen); and include the generic
oprofile driver modifications (xenoprof-generic-linux-2.6.14) in the
patches automatically applied when builting the linux trees for xen (all
code in this patch are under drivers/oprofile and include/linux). Please
let me know if this is acceptable or if you prefer an alternative
approach?
Thanks
Renato
>> -----Original Message-----
>> From: Ian Pratt [mailto:m+Ian.Pratt@cl.cam.ac.uk]
>> Sent: Sunday, November 13, 2005 11:24 AM
>> To: Santos, Jose Renato G; Keir Fraser
>> Cc: Turner, Yoshio; xen-devel@lists.xensource.com; Jose
>> Renato Santos; G John Janakiraman; ian.pratt@cl.cam.ac.uk
>> Subject: RE: [Xen-devel] RE: [PATCH] xenoprof (xen)
>>
>>
>> > Is there anything I can do to make your job easier?
>> > Would you like to receive multiple smaller patches (one patch
>> > per file)?
>>
>> I think we should hold-off applying the linux patches to the
>> sparse tree for the moment for a couple of reasons: John
>> Levon would like to see some cleanups, and I think we'll be
>> better off applying once the sparse tree has moved to 2.6.14
>> anyhow (generated from the merge tree).
>>
>> Jose: please could you have a go generating the patch
>> against the linux-2.6-xen.hg tree.
>>
>> Thanks,
>> Ian
>>
[-- Attachment #2: xenoprof-generic-linux-2.6.14.patch --]
[-- Type: application/octet-stream, Size: 11433 bytes --]
diff -r e52af3942d55 drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c Sat Nov 12 04:30:38 2005
+++ b/drivers/oprofile/buffer_sync.c Wed Nov 23 14:44:03 2005
@@ -5,6 +5,10 @@
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*
* This is the core of the buffer management. Each
* CPU buffer is processed and entered into the
@@ -272,15 +276,24 @@
last_cookie = INVALID_COOKIE;
}
-static void add_kernel_ctx_switch(unsigned int in_kernel)
-{
- add_event_entry(ESCAPE_CODE);
- if (in_kernel)
- add_event_entry(KERNEL_ENTER_SWITCH_CODE);
- else
- add_event_entry(KERNEL_EXIT_SWITCH_CODE);
-}
-
+static void add_cpu_mode_switch(unsigned int cpu_mode)
+{
+ add_event_entry(ESCAPE_CODE);
+ switch (cpu_mode) {
+ case CPU_MODE_USER:
+ add_event_entry(USER_ENTER_SWITCH_CODE);
+ break;
+ case CPU_MODE_KERNEL:
+ add_event_entry(KERNEL_ENTER_SWITCH_CODE);
+ break;
+ case CPU_MODE_XEN:
+ add_event_entry(XEN_ENTER_SWITCH_CODE);
+ break;
+ default:
+ break;
+ }
+}
+
static void
add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
{
@@ -345,9 +358,9 @@
* for later lookup from userspace.
*/
static int
-add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
-{
- if (in_kernel) {
+add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
+{
+ if (cpu_mode >= CPU_MODE_KERNEL) {
add_sample_entry(s->eip, s->event);
return 1;
} else if (mm) {
@@ -496,7 +509,7 @@
struct mm_struct *mm = NULL;
struct task_struct * new;
unsigned long cookie = 0;
- int in_kernel = 1;
+ int cpu_mode = 1;
unsigned int i;
sync_buffer_state state = sb_buffer_start;
unsigned long available;
@@ -513,12 +526,12 @@
struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
if (is_code(s->eip)) {
- if (s->event <= CPU_IS_KERNEL) {
+ if (s->event <= CPU_MODE_XEN) {
/* kernel/userspace switch */
- in_kernel = s->event;
+ cpu_mode = s->event;
if (state == sb_buffer_start)
state = sb_sample_start;
- add_kernel_ctx_switch(s->event);
+ add_cpu_mode_switch(s->event);
} else if (s->event == CPU_TRACE_BEGIN) {
state = sb_bt_start;
add_trace_begin();
@@ -536,7 +549,7 @@
}
} else {
if (state >= sb_bt_start &&
- !add_sample(mm, s, in_kernel)) {
+ !add_sample(mm, s, cpu_mode)) {
if (state == sb_bt_start) {
state = sb_bt_ignore;
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
diff -r e52af3942d55 drivers/oprofile/cpu_buffer.c
--- a/drivers/oprofile/cpu_buffer.c Sat Nov 12 04:30:38 2005
+++ b/drivers/oprofile/cpu_buffer.c Wed Nov 23 14:44:03 2005
@@ -5,6 +5,10 @@
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*
* Each CPU has a local buffer that stores PC value/event
* pairs. We also log context switches when we notice them.
@@ -57,7 +61,7 @@
goto fail;
b->last_task = NULL;
- b->last_is_kernel = -1;
+ b->last_cpu_mode = -1;
b->tracing = 0;
b->buffer_size = buffer_size;
b->tail_pos = 0;
@@ -113,7 +117,7 @@
* collected will populate the buffer with proper
* values to initialize the buffer
*/
- cpu_buf->last_is_kernel = -1;
+ cpu_buf->last_cpu_mode = -1;
cpu_buf->last_task = NULL;
}
@@ -163,13 +167,13 @@
* because of the head/tail separation of the writer and reader
* of the CPU buffer.
*
- * is_kernel is needed because on some architectures you cannot
+ * cpu_mode is needed because on some architectures you cannot
* tell if you are in kernel or user space simply by looking at
- * pc. We tag this in the buffer by generating kernel enter/exit
- * events whenever is_kernel changes
+ * pc. We tag this in the buffer by generating kernel/user (and xen)
+ * enter events whenever cpu_mode changes
*/
static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
- int is_kernel, unsigned long event)
+ int cpu_mode, unsigned long event)
{
struct task_struct * task;
@@ -180,16 +184,16 @@
return 0;
}
- is_kernel = !!is_kernel;
+ WARN_ON(cpu_mode > CPU_MODE_XEN);
task = current;
/* notice a switch from user->kernel or vice versa */
- if (cpu_buf->last_is_kernel != is_kernel) {
- cpu_buf->last_is_kernel = is_kernel;
- add_code(cpu_buf, is_kernel);
- }
-
+ if (cpu_buf->last_cpu_mode != cpu_mode) {
+ cpu_buf->last_cpu_mode = cpu_mode;
+ add_code(cpu_buf, cpu_mode);
+ }
+
/* notice a task switch */
if (cpu_buf->last_task != task) {
cpu_buf->last_task = task;
diff -r e52af3942d55 drivers/oprofile/cpu_buffer.h
--- a/drivers/oprofile/cpu_buffer.h Sat Nov 12 04:30:38 2005
+++ b/drivers/oprofile/cpu_buffer.h Wed Nov 23 14:44:03 2005
@@ -36,7 +36,7 @@
volatile unsigned long tail_pos;
unsigned long buffer_size;
struct task_struct * last_task;
- int last_is_kernel;
+ int last_cpu_mode;
int tracing;
struct op_sample * buffer;
unsigned long sample_received;
@@ -51,7 +51,9 @@
void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
/* transient events for the CPU buffer -> event buffer */
-#define CPU_IS_KERNEL 1
-#define CPU_TRACE_BEGIN 2
+#define CPU_MODE_USER 0
+#define CPU_MODE_KERNEL 1
+#define CPU_MODE_XEN 2
+#define CPU_TRACE_BEGIN 3
#endif /* OPROFILE_CPU_BUFFER_H */
diff -r e52af3942d55 drivers/oprofile/event_buffer.c
--- a/drivers/oprofile/event_buffer.c Sat Nov 12 04:30:38 2005
+++ b/drivers/oprofile/event_buffer.c Wed Nov 23 14:44:03 2005
@@ -56,6 +56,7 @@
/* Wake up the waiting process if any. This happens
* on "echo 0 >/dev/oprofile/enable" so the daemon
* processes the data remaining in the event buffer.
+ * also called on echo 1 > /dev/oprofile/dump
*/
void wake_up_buffer_waiter(void)
{
diff -r e52af3942d55 drivers/oprofile/event_buffer.h
--- a/drivers/oprofile/event_buffer.h Sat Nov 12 04:30:38 2005
+++ b/drivers/oprofile/event_buffer.h Wed Nov 23 14:44:03 2005
@@ -5,6 +5,10 @@
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*/
#ifndef EVENT_BUFFER_H
@@ -29,11 +33,12 @@
#define CPU_SWITCH_CODE 2
#define COOKIE_SWITCH_CODE 3
#define KERNEL_ENTER_SWITCH_CODE 4
-#define KERNEL_EXIT_SWITCH_CODE 5
+#define USER_ENTER_SWITCH_CODE 5
#define MODULE_LOADED_CODE 6
#define CTX_TGID_CODE 7
#define TRACE_BEGIN_CODE 8
#define TRACE_END_CODE 9
+#define XEN_ENTER_SWITCH_CODE 10
#define INVALID_COOKIE ~0UL
#define NO_COOKIE 0UL
diff -r e52af3942d55 drivers/oprofile/oprof.c
--- a/drivers/oprofile/oprof.c Sat Nov 12 04:30:38 2005
+++ b/drivers/oprofile/oprof.c Wed Nov 23 14:44:03 2005
@@ -5,6 +5,10 @@
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*/
#include <linux/kernel.h>
@@ -32,6 +36,17 @@
1 - use the timer int mechanism regardless
*/
static int timer = 0;
+
+extern unsigned int adomains;
+extern int active_domains[MAX_OPROF_DOMAINS];
+
+int oprofile_set_active(void)
+{
+ if (oprofile_ops.set_active)
+ return oprofile_ops.set_active(active_domains, adomains);
+
+ return -EINVAL;
+}
int oprofile_setup(void)
{
diff -r e52af3942d55 drivers/oprofile/oprof.h
--- a/drivers/oprofile/oprof.h Sat Nov 12 04:30:38 2005
+++ b/drivers/oprofile/oprof.h Wed Nov 23 14:44:03 2005
@@ -35,5 +35,7 @@
void oprofile_timer_init(struct oprofile_operations * ops);
int oprofile_set_backtrace(unsigned long depth);
+
+int oprofile_set_active(void);
#endif /* OPROF_H */
diff -r e52af3942d55 drivers/oprofile/oprofile_files.c
--- a/drivers/oprofile/oprofile_files.c Sat Nov 12 04:30:38 2005
+++ b/drivers/oprofile/oprofile_files.c Wed Nov 23 14:44:03 2005
@@ -5,10 +5,16 @@
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*/
#include <linux/fs.h>
#include <linux/oprofile.h>
+#include <asm/uaccess.h>
+#include <linux/ctype.h>
#include "event_buffer.h"
#include "oprofile_stats.h"
@@ -117,11 +123,79 @@
static struct file_operations dump_fops = {
.write = dump_write,
};
-
+
+#define TMPBUFSIZE 512
+
+unsigned int adomains = 0;
+long active_domains[MAX_OPROF_DOMAINS];
+
+static ssize_t adomain_write(struct file * file, char const __user * buf,
+ size_t count, loff_t * offset)
+{
+ char tmpbuf[TMPBUFSIZE];
+ char * startp = tmpbuf;
+ char * endp = tmpbuf;
+ int i;
+ unsigned long val;
+
+ if (*offset)
+ return -EINVAL;
+ if (!count)
+ return 0;
+ if (count > TMPBUFSIZE - 1)
+ return -EINVAL;
+
+ memset(tmpbuf, 0x0, TMPBUFSIZE);
+
+ if (copy_from_user(tmpbuf, buf, count))
+ return -EFAULT;
+
+ for (i = 0; i < MAX_OPROF_DOMAINS; i++)
+ active_domains[i] = -1;
+ adomains = 0;
+
+ while (1) {
+ val = simple_strtol(startp, &endp, 0);
+ if (endp == startp)
+ break;
+ while (ispunct(*endp))
+ endp++;
+ active_domains[adomains++] = val;
+ if (adomains >= MAX_OPROF_DOMAINS)
+ break;
+ startp = endp;
+ }
+ if (oprofile_set_active())
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t adomain_read(struct file * file, char __user * buf,
+ size_t count, loff_t * offset)
+{
+ char tmpbuf[TMPBUFSIZE];
+ size_t len = 0;
+ int i;
+ /* This is all screwed up if we run out of space */
+ for (i = 0; i < adomains; i++)
+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len,
+ "%u ", (unsigned int)active_domains[i]);
+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n");
+ return simple_read_from_buffer((void __user *)buf, count,
+ offset, tmpbuf, len);
+}
+
+
+static struct file_operations active_domain_ops = {
+ .read = adomain_read,
+ .write = adomain_write,
+};
+
void oprofile_create_files(struct super_block * sb, struct dentry * root)
{
oprofilefs_create_file(sb, root, "enable", &enable_fops);
oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
+ oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
diff -r e52af3942d55 include/linux/oprofile.h
--- a/include/linux/oprofile.h Sat Nov 12 04:30:38 2005
+++ b/include/linux/oprofile.h Wed Nov 23 14:44:03 2005
@@ -8,6 +8,10 @@
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*/
#ifndef OPROFILE_H
@@ -27,6 +31,8 @@
/* create any necessary configuration files in the oprofile fs.
* Optional. */
int (*create_files)(struct super_block * sb, struct dentry * root);
+ /* setup active domains with Xen */
+ int (*set_active)(int *active_domains, unsigned int adomains);
/* Do any necessary interrupt setup. Optional. */
int (*setup)(void);
/* Do any necessary interrupt shutdown. Optional. */
[-- Attachment #3: xenoprof-arch-linux-2.6.14.patch --]
[-- Type: application/octet-stream, Size: 15842 bytes --]
diff -r e52af3942d55 arch/i386/Kconfig
--- a/arch/i386/Kconfig Sat Nov 12 04:30:38 2005
+++ b/arch/i386/Kconfig Wed Nov 23 14:48:18 2005
@@ -1325,6 +1325,10 @@
source "arch/i386/oprofile/Kconfig"
endif
+if X86_XEN
+source "arch/i386/xen/oprofile/Kconfig"
+endif
+
source "arch/i386/Kconfig.debug"
source "security/Kconfig"
diff -r e52af3942d55 arch/i386/Makefile
--- a/arch/i386/Makefile Sat Nov 12 04:30:38 2005
+++ b/arch/i386/Makefile Wed Nov 23 14:48:18 2005
@@ -136,7 +136,12 @@
drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/
drivers-$(CONFIG_PCI) += $(pci)
# must be linked after kernel/
+ifdef CONFIG_X86_XEN
+drivers-$(CONFIG_OPROFILE) += arch/i386/xen/oprofile/
+else
drivers-$(CONFIG_OPROFILE) += arch/i386/oprofile/
+endif
+
drivers-$(CONFIG_PM) += arch/i386/power/
CFLAGS += $(mflags-y)
diff -r e52af3942d55 arch/i386/xen/mm/ioremap.c
--- a/arch/i386/xen/mm/ioremap.c Sat Nov 12 04:30:38 2005
+++ b/arch/i386/xen/mm/ioremap.c Wed Nov 23 14:48:18 2005
@@ -171,6 +171,32 @@
}
EXPORT_SYMBOL(touch_pte_range);
+
+void *vm_map_xen_pages (unsigned long maddr, int vm_size, pgprot_t prot)
+{
+ int error;
+
+ struct vm_struct *vma;
+ vma = get_vm_area (vm_size, VM_IOREMAP);
+
+ if (vma == NULL) {
+ printk ("ioremap.c,vm_map_xen_pages(): Failed to get VMA area\n");
+ return NULL;
+ }
+
+ error = direct_kernel_remap_pfn_range((unsigned long) vma->addr,
+ maddr >> PAGE_SHIFT, vm_size,
+ prot, DOMID_SELF );
+ if (error == 0){
+ return (vma->addr);
+
+ }
+ else {
+ printk ("ioremap.c,vm_map_xen_pages(): Failed to map xen shared pages into kernel space\n");
+ return NULL;
+ }
+}
+EXPORT_SYMBOL(vm_map_xen_pages);
#ifdef CONFIG_XEN_PHYSDEV_ACCESS
diff -r e52af3942d55 include/asm-i386/mach-xen/asm/hypercall.h
--- a/include/asm-i386/mach-xen/asm/hypercall.h Sat Nov 12 04:30:38 2005
+++ b/include/asm-i386/mach-xen/asm/hypercall.h Wed Nov 23 14:48:18 2005
@@ -300,6 +300,23 @@
SHUTDOWN_suspend, srec);
}
+static inline int
+HYPERVISOR_pmc_op(
+ int op, unsigned int arg1, unsigned int arg2)
+{
+ int ret;
+ unsigned long ign1, ign2, ign3;
+
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a"(ret), "=b"(ign1), "=c"(ign2), "=d"(ign3)
+ : "0"(__HYPERVISOR_pmc_op), "1"(op), "2"(arg1), "3"(arg2)
+ : "memory" );
+
+ return ret;
+}
+
+
#endif /* __HYPERCALL_H__ */
/*
diff -r e52af3942d55 include/asm-xen/xen-public/xen.h
--- a/include/asm-xen/xen-public/xen.h Sat Nov 12 04:30:38 2005
+++ b/include/asm-xen/xen-public/xen.h Wed Nov 23 14:48:18 2005
@@ -4,6 +4,10 @@
* Guest OS interface to Xen.
*
* Copyright (c) 2004, K A Fraser
+ *
+ * Modified by Aravind Menon for supporting oprofile
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*/
#ifndef __XEN_PUBLIC_XEN_H__
@@ -59,6 +63,7 @@
#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */
#define __HYPERVISOR_mmuext_op 26
#define __HYPERVISOR_acm_op 27
+#define __HYPERVISOR_pmc_op 28
/*
* VIRTUAL INTERRUPTS
@@ -72,7 +77,8 @@
#define VIRQ_PARITY_ERR 4 /* (DOM0) NMI parity error. */
#define VIRQ_IO_ERR 5 /* (DOM0) NMI I/O error. */
#define VIRQ_DEBUGGER 6 /* (DOM0) A domain has paused for debugging. */
-#define NR_VIRQS 7
+#define VIRQ_PMC_OVF 7 /* PMC Overflow */
+#define NR_VIRQS 8
/*
* MMU-UPDATE REQUESTS
@@ -211,6 +217,21 @@
#define VMASST_TYPE_writable_pagetables 2
#define MAX_VMASST_TYPE 2
+/*
+ * Commands to HYPERVISOR_pmc_op().
+ */
+#define PMC_INIT 0
+#define PMC_SET_ACTIVE 1
+#define PMC_SET_PASSIVE 2
+#define PMC_RESERVE_COUNTERS 3
+#define PMC_SETUP_EVENTS 4
+#define PMC_ENABLE_VIRQ 5
+#define PMC_START 6
+#define PMC_STOP 7
+#define PMC_DISABLE_VIRQ 8
+#define PMC_RELEASE_COUNTERS 9
+#define PMC_SHUTDOWN 10
+
#ifndef __ASSEMBLY__
typedef uint16_t domid_t;
@@ -266,6 +287,8 @@
*/
#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
+#define MAX_OPROF_EVENTS 32
+#define MAX_OPROF_DOMAINS 25
/*
* Per-VCPU information goes here. This will be cleaned up more when Xen
* actually supports multi-VCPU guests.
@@ -433,6 +456,33 @@
typedef uint8_t xen_domain_handle_t[16];
+struct event_log {
+ uint32_t eip;
+ uint8_t mode;
+ uint8_t event;
+};
+
+/* Xenoprof buffer shared between Xen and domain - 1 per VCPU */
+typedef struct xenoprof_buf {
+ uint32_t event_head;
+ uint32_t event_tail;
+ uint32_t event_size;
+ uint32_t vcpu_id;
+ uint64_t xen_samples;
+ uint64_t kernel_samples;
+ uint64_t user_samples;
+ uint64_t lost_samples;
+ struct event_log event_log[1];
+} xenoprof_buf_t;
+
+typedef struct pmc_init_result {
+ int num_events;
+ int is_primary;
+ int nbuf;
+ int bufsize;
+ uint32_t buf_maddr;
+} pmc_init_result_t;
+
#endif /* !__ASSEMBLY__ */
#endif /* __XEN_PUBLIC_XEN_H__ */
diff -r e52af3942d55 arch/i386/xen/oprofile/Kconfig
--- /dev/null Sat Nov 12 04:30:38 2005
+++ b/arch/i386/xen/oprofile/Kconfig Wed Nov 23 14:48:18 2005
@@ -0,0 +1,25 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ default n
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ default n
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include Xen, the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff -r e52af3942d55 arch/i386/xen/oprofile/Makefile
--- /dev/null Sat Nov 12 04:30:38 2005
+++ b/arch/i386/xen/oprofile/Makefile Wed Nov 23 14:48:18 2005
@@ -0,0 +1,9 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../../drivers/oprofile/, \
+ oprof.o cpu_buffer.o buffer_sync.o \
+ event_buffer.o oprofile_files.o \
+ oprofilefs.o oprofile_stats.o \
+ timer_int.o )
+
+oprofile-y := $(DRIVER_OBJS) pmc.o
diff -r e52af3942d55 arch/i386/xen/oprofile/op_counter.h
--- /dev/null Sat Nov 12 04:30:38 2005
+++ b/arch/i386/xen/oprofile/op_counter.h Wed Nov 23 14:48:18 2005
@@ -0,0 +1,29 @@
+/**
+ * @file op_counter.h
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ */
+
+#ifndef OP_COUNTER_H
+#define OP_COUNTER_H
+
+#define OP_MAX_COUNTER 8
+
+/* Per-perfctr configuration as set via
+ * oprofilefs.
+ */
+struct op_counter_config {
+ unsigned long count;
+ unsigned long enabled;
+ unsigned long event;
+ unsigned long kernel;
+ unsigned long user;
+ unsigned long unit_mask;
+};
+
+extern struct op_counter_config counter_config[];
+
+#endif /* OP_COUNTER_H */
diff -r e52af3942d55 arch/i386/xen/oprofile/pmc.c
--- /dev/null Sat Nov 12 04:30:38 2005
+++ b/arch/i386/xen/oprofile/pmc.c Wed Nov 23 14:48:18 2005
@@ -0,0 +1,431 @@
+/**
+ * @file nmi_int.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon and Jose Renato Santos for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
+ */
+
+#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/smp.h>
+#include <linux/oprofile.h>
+#include <linux/sysdev.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+#include <asm/nmi.h>
+#include <asm/msr.h>
+#include <asm/apic.h>
+#include <asm/pgtable.h>
+#include <asm-xen/evtchn.h>
+#include "op_counter.h"
+
+static int pmc_start(void);
+static void pmc_stop(void);
+
+extern void * vm_map_xen_pages (unsigned long maddr, int vm_size, pgprot_t prot);
+static int pmc_enabled = 0;
+static int num_events = 0;
+static int is_primary = 0;
+
+/* sample buffers shared with Xen */
+xenoprof_buf_t* xenoprof_buf[MAX_VIRT_CPUS];
+/* Shared buffer area */
+char * shared_buffer;
+/* Number of buffers in shared area (one per VCPU) */
+int nbuf;
+/* Mappings of VIRQ_PMC_OVF to irq number (per cpu) */
+int ovf_irq[NR_CPUS];
+
+#ifdef CONFIG_PM
+
+static int pmc_suspend(struct sys_device * dev, pm_message_t state)
+{
+ if (pmc_enabled == 1)
+ pmc_stop();
+ return 0;
+}
+
+
+static int pmc_resume(struct sys_device * dev)
+{
+ if (pmc_enabled == 1)
+ pmc_start();
+ return 0;
+}
+
+
+static struct sysdev_class oprofile_sysclass = {
+ set_kset_name("oprofile"),
+ .resume = pmc_resume,
+ .suspend = pmc_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;
+
+static irqreturn_t pmc_ovf_interrupt (int irq, void * dev_id, struct pt_regs * regs)
+{
+ int head, tail, size;
+ xenoprof_buf_t * buf;
+ int cpu;
+
+ cpu = smp_processor_id();
+ buf = xenoprof_buf[cpu];
+
+ 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);
+ 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);
+ oprofile_samples++;
+ tail++;
+ }
+
+ buf->event_tail = tail;
+
+ return IRQ_HANDLED;
+}
+
+
+void unbind_pmc_ovf_cpu (void * info)
+{
+ int cpu = smp_processor_id();
+ if (ovf_irq[cpu] >= 0) {
+ unbind_from_irqhandler(ovf_irq[cpu], NULL);
+ ovf_irq[cpu] = -1;
+ }
+}
+
+
+void unbind_pmc_ovf (void)
+{
+ on_each_cpu (unbind_pmc_ovf_cpu, NULL, 0, 1);
+}
+
+
+int bind_pmc_error;
+
+void bind_pmc_ovf_cpu (void * info)
+{
+ int result;
+ int cpu = smp_processor_id();
+
+ result = bind_virq_to_irqhandler(VIRQ_PMC_OVF,
+ cpu,
+ pmc_ovf_interrupt,
+ SA_INTERRUPT,
+ "pmc_ovf",
+ NULL);
+
+ if (result<0) {
+ bind_pmc_error = result;
+ printk ("pmc.c: binding VIRQ_PMC_OVF to IRQ failed on CPU %d\n", cpu);
+ }
+ else
+ ovf_irq[cpu] = result;
+
+}
+
+
+int bind_pmc_ovf (void)
+{
+ bind_pmc_error = 0;
+ on_each_cpu (bind_pmc_ovf_cpu, NULL, 0, 1);
+ if (bind_pmc_error) {
+ unbind_pmc_ovf();
+ return bind_pmc_error;
+ }
+ else
+ return 0;
+}
+
+
+static int pmc_setup(void)
+{
+ int ret;
+
+ ret = bind_pmc_ovf();
+ if (ret)
+ return ret;
+
+ if (is_primary) {
+ ret = HYPERVISOR_pmc_op(PMC_RESERVE_COUNTERS,
+ (unsigned int)NULL,
+ (unsigned int)NULL);
+ if (ret)
+ goto err;
+
+ ret = HYPERVISOR_pmc_op(PMC_SETUP_EVENTS,
+ (unsigned int)&counter_config,
+ (unsigned int)num_events);
+ if (ret)
+ goto err;
+ }
+
+ ret = HYPERVISOR_pmc_op(PMC_ENABLE_VIRQ,
+ (unsigned int)NULL,
+ (unsigned int)NULL);
+ if (ret)
+ goto err;
+
+ pmc_enabled = 1;
+ return 0;
+ err:
+ unbind_pmc_ovf();
+ return ret;
+
+}
+
+
+static void pmc_shutdown(void)
+{
+
+ pmc_enabled = 0;
+
+ HYPERVISOR_pmc_op(PMC_DISABLE_VIRQ,
+ (unsigned int)NULL,
+ (unsigned int)NULL);
+
+ if (is_primary) {
+ HYPERVISOR_pmc_op(PMC_RELEASE_COUNTERS,
+ (unsigned int)NULL,
+ (unsigned int)NULL);
+ }
+
+ unbind_pmc_ovf ();
+
+}
+
+
+static int pmc_start(void)
+{
+ int ret = 0;
+
+ if (is_primary)
+ ret = HYPERVISOR_pmc_op(PMC_START,
+ (unsigned int)NULL,
+ (unsigned int)NULL);
+ return ret;
+}
+
+
+static void pmc_stop(void)
+{
+ if (is_primary)
+ HYPERVISOR_pmc_op(PMC_STOP,
+ (unsigned int)NULL,
+ (unsigned int)NULL);
+}
+
+
+static int pmc_set_active(int * active_domains,
+ unsigned int adomains)
+{
+ int ret = 0;
+ if (is_primary)
+ ret = HYPERVISOR_pmc_op(PMC_SET_ACTIVE,
+ (unsigned int)active_domains,
+ (unsigned int)adomains);
+ return ret;
+}
+
+
+struct op_counter_config counter_config[OP_MAX_COUNTER];
+
+static int pmc_create_files(struct super_block * sb, struct dentry * root)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_events; ++i) {
+ struct dentry * dir;
+ char buf[2];
+
+ snprintf(buf, 2, "%d", i);
+ dir = oprofilefs_mkdir(sb, root, buf);
+ oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);
+ oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event);
+ oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count);
+ oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);
+ oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);
+ oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);
+ }
+
+ return 0;
+}
+
+
+struct oprofile_operations pmc_ops = {
+ .create_files = pmc_create_files,
+ .set_active = pmc_set_active,
+ .setup = pmc_setup,
+ .shutdown = pmc_shutdown,
+ .start = pmc_start,
+ .stop = pmc_stop
+};
+
+static void __init p4_init(void)
+{
+ __u8 cpu_model = current_cpu_data.x86_model;
+
+ if (cpu_model > 3)
+ pmc_ops.cpu_type = "type_unknown";
+
+ /* We always use a non-HT system because that gives us more events */
+ pmc_ops.cpu_type = "i386/p4";
+}
+
+
+static void __init ppro_init(void)
+{
+ __u8 cpu_model = current_cpu_data.x86_model;
+
+ if (cpu_model > 0xd)
+ pmc_ops.cpu_type = "type_unknown";
+
+ if (cpu_model == 9) {
+ pmc_ops.cpu_type = "i386/p6_mobile";
+ } else if (cpu_model > 5) {
+ pmc_ops.cpu_type = "i386/piii";
+ } else if (cpu_model > 2) {
+ pmc_ops.cpu_type = "i386/pii";
+ } else {
+ pmc_ops.cpu_type = "i386/ppro";
+ }
+}
+
+
+/* in order to get driverfs right */
+static int using_pmc;
+
+int __init oprofile_arch_init(struct oprofile_operations * ops)
+{
+
+ pmc_init_result_t result;
+ xenoprof_buf_t * buf;
+ int max_samples = 16;
+ int vm_size;
+ int npages;
+ int i;
+
+ int ret = HYPERVISOR_pmc_op(PMC_INIT,
+ (unsigned int)max_samples,
+ (unsigned int)&result);
+
+ if (!ret) {
+ __u8 vendor = current_cpu_data.x86_vendor;
+ __u8 family = current_cpu_data.x86;
+ pgprot_t prot = __pgprot(_KERNPG_TABLE);
+
+ num_events = result.num_events;
+ is_primary = result.is_primary;
+ nbuf = result.nbuf;
+
+ npages = (result.bufsize * nbuf - 1) / PAGE_SIZE + 1;
+ vm_size = npages * PAGE_SIZE;
+
+
+ shared_buffer = (char *) vm_map_xen_pages(result.buf_maddr,
+ vm_size, prot);
+
+ if (!shared_buffer)
+ return -ENOMEM;
+
+ for (i=0; i< nbuf; i++) {
+ buf = (xenoprof_buf_t*) &shared_buffer[i * result.bufsize];
+ BUG_ON (buf->vcpu_id >= MAX_VIRT_CPUS);
+ xenoprof_buf[buf->vcpu_id] = buf;
+ }
+
+ if (vendor == X86_VENDOR_INTEL) {
+ switch (family) {
+ /* Pentium IV */
+ case 0xf:
+ p4_init();
+ break;
+ /* A P6-class processor */
+ case 6:
+ ppro_init();
+ break;
+ default:
+ pmc_ops.cpu_type = "type_unknown";
+ }
+ } else pmc_ops.cpu_type = "type_unknown";
+
+ init_driverfs();
+ using_pmc = 1;
+ *ops = pmc_ops;
+
+ for (i=0; i<NR_CPUS; i++)
+ ovf_irq[i] = -1;
+
+
+ printk (KERN_INFO "oprofile_arch_init: ret %d, events %d, is_primary %d\n",
+ ret, num_events, is_primary);
+ return ret;
+ }
+
+ return ret;
+}
+
+
+void __exit oprofile_arch_exit(void)
+{
+ if (using_pmc)
+ exit_driverfs();
+
+ if (shared_buffer) {
+ vunmap (shared_buffer);
+ shared_buffer = NULL;
+ }
+ if (is_primary)
+ HYPERVISOR_pmc_op(PMC_SHUTDOWN,
+ (unsigned int)NULL,
+ (unsigned int)NULL);
+
+}
[-- Attachment #4: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: RE: [PATCH] xenoprof (xen)
2005-11-24 1:44 RE: [PATCH] xenoprof (xen) Santos, Jose Renato G
@ 2005-11-24 2:51 ` John Levon
0 siblings, 0 replies; 8+ messages in thread
From: John Levon @ 2005-11-24 2:51 UTC (permalink / raw)
To: Santos, Jose Renato G
Cc: Ian Pratt, xen-devel, Turner, Yoshio, Jose Renato Santos,
G John Janakiraman
On Wed, Nov 23, 2005 at 05:44:16PM -0800, Santos, Jose Renato G wrote:
> John Levon has reviewed these patches and I have included all his
> suggestions on this version.
To clarify, I've only reviewed the first one so far
(xenoprof-generic-linux-2.6.14.patch). I still have outstanding issues
with the arch one.
regards,
john
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: RE: [PATCH] xenoprof (xen)
@ 2005-11-24 9:44 Santos, Jose Renato G
0 siblings, 0 replies; 8+ messages in thread
From: Santos, Jose Renato G @ 2005-11-24 9:44 UTC (permalink / raw)
To: John Levon
Cc: Ian Pratt, xen-devel, Turner, Yoshio, Jose Renato Santos,
G John Janakiraman
> -----Original Message-----
> From: John Levon [mailto:levon@movementarian.org
> Sent: Wednesday, November 23, 2005 6:52 PM
> To: Santos, Jose Renato G
> Cc: Ian Pratt; Keir Fraser; Jose Renato Santos;
> xen-devel@lists.xensource.com; G John Janakiraman; Turner, Yoshio
> Subject: Re: [Xen-devel] RE: [PATCH] xenoprof (xen)
>
> On Wed, Nov 23, 2005 at 05:44:16PM -0800, Santos, Jose Renato G wrote:
>
> > John Levon has reviewed these patches and I have included all his
> > suggestions on this version.
>
> To clarify, I've only reviewed the first one so far
> (xenoprof-generic-linux-2.6.14.patch). I still have
> outstanding issues with the arch one.
Not quite correct. You reviewed both patches and I thought I have
addressed all your concerns but apparently there are still some pending
issues on the arch patch. Will work on these after the Thanksgiving
holiday.
Regards
Renato
>
> regards,
> john
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: RE: [PATCH] xenoprof (xen)
@ 2005-11-14 1:23 Ian Pratt
0 siblings, 0 replies; 8+ messages in thread
From: Ian Pratt @ 2005-11-14 1:23 UTC (permalink / raw)
To: Santos, Jose Renato G, Keir Fraser, John Levon
Cc: Turner, Yoshio, xen-devel, Jose Renato Santos, G John Janakiraman
> Oh, I see. I did not know about this reorganization of the
> xen/linux tree.
> Do you prefer that I port the xenoprof patch into the
> "linux-2.6-xen.hg" tree right now or wait for when the tree
> goes into the xen repository?
Yes, please.
Ian
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: RE: [PATCH] xenoprof (xen)
@ 2005-11-14 1:07 Santos, Jose Renato G
0 siblings, 0 replies; 8+ messages in thread
From: Santos, Jose Renato G @ 2005-11-14 1:07 UTC (permalink / raw)
To: Ian Pratt, Keir Fraser, John Levon
Cc: Turner, Yoshio, xen-devel, Jose Renato Santos, G John Janakiraman
Ian,
Oh, I see. I did not know about this reorganization of the xen/linux
tree.
Do you prefer that I port the xenoprof patch into the
"linux-2.6-xen.hg" tree right now or wait for when the tree goes into
the xen repository?
Thanks
Renato
> -----Original Message-----
> From: Ian Pratt [mailto:m+Ian.Pratt@cl.cam.ac.uk]
> Sent: Sunday, November 13, 2005 4:18 PM
> To: Santos, Jose Renato G; Keir Fraser; John Levon
> Cc: Turner, Yoshio; xen-devel@lists.xensource.com; Jose
> Renato Santos; G John Janakiraman; ian.pratt@cl.cam.ac.uk
> Subject: RE: [Xen-devel] RE: [PATCH] xenoprof (xen)
>
> > From your message, I am assuming that you are agreeing to include
> > the
> > "arch/xen/oprofile" modifications into the sparse tree when
> > it moves to the 2.6.14 (please, correct it if I am wrong).
> > Any expectation of when this should happen?
>
> Well, arch/xen won't exist as xen is a subarch of i386/x86_64 in our
> 2.6.14 tree.
>
> See http://xenbits.xensource.com/linux-2.6-xen.hg
>
>
> This will replace the 2.6.12 in the xen repository at some
> point, after more testing.
>
> Ian
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: RE: [PATCH] xenoprof (xen)
@ 2005-11-14 0:18 Ian Pratt
0 siblings, 0 replies; 8+ messages in thread
From: Ian Pratt @ 2005-11-14 0:18 UTC (permalink / raw)
To: Santos, Jose Renato G, Keir Fraser, John Levon
Cc: Turner, Yoshio, xen-devel, Jose Renato Santos, G John Janakiraman
> From your message, I am assuming that you are agreeing to
> include the
> "arch/xen/oprofile" modifications into the sparse tree when
> it moves to the 2.6.14 (please, correct it if I am wrong).
> Any expectation of when this should happen?
Well, arch/xen won't exist as xen is a subarch of i386/x86_64 in our
2.6.14 tree.
See http://xenbits.xensource.com/linux-2.6-xen.hg
This will replace the 2.6.12 in the xen repository at some point, after
more testing.
Ian
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: RE: [PATCH] xenoprof (xen)
@ 2005-11-14 0:05 Santos, Jose Renato G
0 siblings, 0 replies; 8+ messages in thread
From: Santos, Jose Renato G @ 2005-11-14 0:05 UTC (permalink / raw)
To: Ian Pratt, Keir Fraser, John Levon
Cc: Turner, Yoshio, xen-devel, Jose Renato Santos, G John Janakiraman
> -----Original Message-----
> From: Ian Pratt [mailto:m+Ian.Pratt@cl.cam.ac.uk]
> Sent: Sunday, November 13, 2005 11:24 AM
> To: Santos, Jose Renato G; Keir Fraser
> Cc: Turner, Yoshio; xen-devel@lists.xensource.com; Jose
> Renato Santos; G John Janakiraman; ian.pratt@cl.cam.ac.uk
> Subject: RE: [Xen-devel] RE: [PATCH] xenoprof (xen)
>
> > Is there anything I can do to make your job easier?
> > Would you like to receive multiple smaller patches (one patch per
> > file)?
>
> I think we should hold-off applying the linux patches to the
> sparse tree for the moment for a couple of reasons: John
> Levon would like to see some cleanups, and I think we'll be
> better off applying once the sparse tree has moved to 2.6.14
> anyhow (generated from the merge tree).
>
Ok, Ian
Just a clarification. The cleanups suggested by John Levon,
are for the user level tools and for the modifications on the
generic code of Oprofile in "drivers/oprofile". Both of
these patches are not expected to go into the sparse tree,
anyhow. I was expecting that only the changes to "arch/xen/oprofile"
would go to the sparse tree. There is no cleanups suggested
by John Levon for this patch.
From your message, I am assuming that you are agreeing to include the
"arch/xen/oprofile" modifications into the sparse tree when
it moves to the 2.6.14 (please, correct it if I am wrong).
Any expectation of when this should happen?
In the mean time, I will be working on the cleanups suggested
by John for the user level tools and for generic Oprofile code
modifications.
> Jose: please could you have a go generating the patch against
> the linux-2.6-xen.hg tree.
>
Forgive me, but I am not sure I understand what you mean in this
sentence. Could you please clarify ...
Thanks
Renato
> Thanks,
> Ian
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: RE: [PATCH] xenoprof (xen)
@ 2005-11-13 19:24 Ian Pratt
0 siblings, 0 replies; 8+ messages in thread
From: Ian Pratt @ 2005-11-13 19:24 UTC (permalink / raw)
To: Santos, Jose Renato G, Keir Fraser
Cc: Turner, Yoshio, xen-devel, Jose Renato Santos, G John Janakiraman
> Is there anything I can do to make your job easier?
> Would you like to receive multiple smaller patches (one patch
> per file)?
I think we should hold-off applying the linux patches to the sparse tree
for the moment for a couple of reasons: John Levon would like to see
some cleanups, and I think we'll be better off applying once the sparse
tree has moved to 2.6.14 anyhow (generated from the merge tree).
Jose: please could you have a go generating the patch against the
linux-2.6-xen.hg tree.
Thanks,
Ian
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2005-11-24 9:44 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-24 1:44 RE: [PATCH] xenoprof (xen) Santos, Jose Renato G
2005-11-24 2:51 ` John Levon
-- strict thread matches above, loose matches on Subject: below --
2005-11-24 9:44 Santos, Jose Renato G
2005-11-14 1:23 Ian Pratt
2005-11-14 1:07 Santos, Jose Renato G
2005-11-14 0:18 Ian Pratt
2005-11-14 0:05 Santos, Jose Renato G
2005-11-13 19:24 Ian Pratt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.