WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Add Xenoprof passive domain support

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Add Xenoprof passive domain support
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 27 Jun 2006 12:50:19 +0000
Delivery-date: Tue, 27 Jun 2006 05:53:17 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 23591d2c46aa666a9d50cf36baf73aa0b95aa11b
# Parent  b12cd185d579a0fb3b74b73e44add5524304d8cc
Add Xenoprof passive domain support
Signed-off-by: Yang Xiaowei <xiaowei.yang@xxxxxxxxx>
Signed-off-by: Jose Renato Santos <jsantos@xxxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c |  134 +++++++
 patches/linux-2.6.16.13/xenoprof-generic.patch     |   81 ++--
 xen/arch/x86/oprofile/nmi_int.c                    |    2 
 xen/arch/x86/oprofile/xenoprof.c                   |  358 +++++++++++++--------
 xen/include/public/xenoprof.h                      |    9 
 xen/include/xen/xenoprof.h                         |    1 
 6 files changed, 404 insertions(+), 181 deletions(-)

diff -r b12cd185d579 -r 23591d2c46aa 
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Tue Jun 27 
11:17:14 2006 +0100
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Tue Jun 27 
11:23:06 2006 +0100
@@ -28,6 +28,7 @@
 
 #include <xen/interface/xen.h>
 #include <xen/interface/xenoprof.h>
+#include <../../../drivers/oprofile/cpu_buffer.h>
 
 static int xenoprof_start(void);
 static void xenoprof_stop(void);
@@ -50,6 +51,11 @@ 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)
@@ -102,16 +108,14 @@ static void __exit exit_driverfs(void)
 #endif /* CONFIG_PM */
 
 unsigned long long oprofile_samples = 0;
-
-static irqreturn_t 
-xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+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;
-       struct xenoprof_buf * buf;
-       int cpu;
-
-       cpu = smp_processor_id();
-       buf = xenoprof_buf[cpu];
 
        head = buf->event_head;
        tail = buf->event_tail;
@@ -122,7 +126,10 @@ xenoprof_ovf_interrupt(int irq, void * d
                        oprofile_add_pc(buf->event_log[tail].eip,
                                        buf->event_log[tail].mode,
                                        buf->event_log[tail].event);
-                       oprofile_samples++;
+                       if (!is_passive)
+                               oprofile_samples++;
+                       else
+                               p_oprofile_samples++;
                        tail++;
                }
                tail = 0;
@@ -131,11 +138,47 @@ xenoprof_ovf_interrupt(int irq, void * d
                oprofile_add_pc(buf->event_log[tail].eip,
                                buf->event_log[tail].mode,
                                buf->event_log[tail].event);
-               oprofile_samples++;
+               if (!is_passive)
+                       oprofile_samples++;
+               else
+                       p_oprofile_samples++;
                tail++;
        }
 
        buf->event_tail = tail;
+}
+
+static void xenoprof_handle_passive(void)
+{
+       int i, j;
+
+       for (i = 0; i < pdomains; i++)
+               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;
+                        oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_START, 
passive_domains[i].domain_id);
+                       xenoprof_add_pc(buf, 1);
+                        oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_STOP, 
passive_domains[i].domain_id);
+               }                       
+}
+
+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();
+               clear_bit(0, &flag);
+       }
 
        return IRQ_HANDLED;
 }
@@ -312,6 +355,63 @@ out:
        return ret;
 }
 
+static int xenoprof_set_passive(int * p_domains,
+                                unsigned int pdoms)
+{
+       int ret;
+       int i, j;
+       int vm_size;
+       int npages;
+       struct xenoprof_buf *buf;
+       pgprot_t prot = __pgprot(_KERNPG_TABLE);
+
+       if (!is_primary)
+               return 0;
+
+       if (pdoms > MAX_OPROF_DOMAINS)
+               return -E2BIG;
+
+       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)
+                       return ret;
+
+               npages = (passive_domains[i].bufsize * passive_domains[i].nbuf 
- 1) / PAGE_SIZE + 1;
+               vm_size = npages * PAGE_SIZE;
+
+               p_shared_buffer[i] = (char 
*)vm_map_xen_pages(passive_domains[i].buf_maddr,
+                                                             vm_size, prot);
+               if (!p_shared_buffer[i]) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               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;
+               }
+
+       }
+
+       pdomains = pdoms;
+       return 0;
+
+out:
+       for (j = 0; j < i; j++) {
+               vunmap(p_shared_buffer[j]);
+               p_shared_buffer[j] = NULL;
+       }
+
+       return ret;
+}
 
 struct op_counter_config counter_config[OP_MAX_COUNTER];
 
@@ -346,6 +446,7 @@ struct oprofile_operations xenoprof_ops 
 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,
@@ -420,6 +521,8 @@ int __init oprofile_arch_init(struct opr
 
 void __exit oprofile_arch_exit(void)
 {
+       int i;
+
        if (using_xenoprof)
                exit_driverfs();
 
@@ -427,6 +530,13 @@ void __exit oprofile_arch_exit(void)
                vunmap(shared_buffer);
                shared_buffer = NULL;
        }
-       if (is_primary)
+       if (is_primary) {
+               for (i = 0; i < pdomains; i++)
+                       if (p_shared_buffer[i]) {
+                               vunmap(p_shared_buffer[i]);
+                               p_shared_buffer[i] = NULL;
+                       }
                HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL);
-}
+        }
+
+}
diff -r b12cd185d579 -r 23591d2c46aa 
patches/linux-2.6.16.13/xenoprof-generic.patch
--- a/patches/linux-2.6.16.13/xenoprof-generic.patch    Tue Jun 27 11:17:14 
2006 +0100
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch    Tue Jun 27 11:23:06 
2006 +0100
@@ -1,6 +1,6 @@ diff -pruN ../pristine-linux-2.6.16.13/d
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 
./drivers/oprofile/buffer_sync.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/buffer_sync.c   2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 
./drivers/oprofile/buffer_sync.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/buffer_sync.c   2006-06-27 12:14:53.000000000 +0800
 @@ -6,6 +6,10 @@
   *
   * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -12,7 +12,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
   * This is the core of the buffer management. Each
   * CPU buffer is processed and entered into the
   * global event buffer. Such processing is necessary
-@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
+@@ -275,15 +279,30 @@ static void add_cpu_switch(int i)
        last_cookie = INVALID_COOKIE;
  }
  
@@ -33,7 +33,13 @@ diff -pruN ../pristine-linux-2.6.16.13/d
 +              break;
 +      case CPU_MODE_XEN:
 +              add_event_entry(XEN_ENTER_SWITCH_CODE);
-+              break;
++              break;
++        case CPU_MODE_PASSIVE_START:
++                add_event_entry(PASSIVE_START_CODE);
++                break;
++        case CPU_MODE_PASSIVE_STOP:
++                add_event_entry(PASSIVE_STOP_CODE);
++                break;
 +      default:
 +              break;
 +      }
@@ -43,7 +49,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  static void
  add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
  {
-@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
+@@ -348,9 +367,9 @@ static int add_us_sample(struct mm_struc
   * for later lookup from userspace.
   */
  static int
@@ -55,7 +61,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
                add_sample_entry(s->eip, s->event);
                return 1;
        } else if (mm) {
-@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
+@@ -496,10 +515,11 @@ void sync_buffer(int cpu)
        struct mm_struct *mm = NULL;
        struct task_struct * new;
        unsigned long cookie = 0;
@@ -64,34 +70,62 @@ diff -pruN ../pristine-linux-2.6.16.13/d
        unsigned int i;
        sync_buffer_state state = sb_buffer_start;
        unsigned long available;
-@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
++      int domain_switch = NO_DOMAIN_SWITCH;
+ 
+       down(&buffer_sem);
+  
+@@ -513,12 +533,19 @@ void sync_buffer(int cpu)
                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) {
++                      if (s->event < CPU_TRACE_BEGIN) {
                                /* 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);
++
++                              if (s->event == CPU_MODE_PASSIVE_START)
++                                      domain_switch = 
DOMAIN_SWITCH_START_EVENT1;
++                              else if (s->event == CPU_MODE_PASSIVE_STOP)
++                                      domain_switch = 
DOMAIN_SWITCH_STOP_EVENT1;
++
++                              if (domain_switch != DOMAIN_SWITCH_START_EVENT2)
++                                      add_cpu_mode_switch(s->event);
                        } else if (s->event == CPU_TRACE_BEGIN) {
                                state = sb_bt_start;
                                add_trace_begin();
-@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
+@@ -535,11 +562,20 @@ void sync_buffer(int cpu)
+                               add_user_ctx_switch(new, cookie);
                        }
                } else {
-                       if (state >= sb_bt_start &&
+-                      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 -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 
./drivers/oprofile/cpu_buffer.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c  2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.c    2006-05-04 17:41:51.000000000 +0100
+-                              if (state == sb_bt_start) {
+-                                      state = sb_bt_ignore;
+-                                      
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
++                      if (domain_switch == DOMAIN_SWITCH_START_EVENT1) {
++                              add_event_entry(s->event);
++                              domain_switch = DOMAIN_SWITCH_START_EVENT2;
++                      } else if (domain_switch == DOMAIN_SWITCH_START_EVENT1) 
{
++                              add_sample_entry(s->eip, s->event);
++                      } else if (domain_switch == DOMAIN_SWITCH_STOP_EVENT1) {
++                              domain_switch = NO_DOMAIN_SWITCH;
++                      } else {
++                              if (state >= sb_bt_start &&
++                                  !add_sample(mm, s, cpu_mode)) {
++                                      if (state == sb_bt_start) {
++                                              state = sb_bt_ignore;
++                                              
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
++                                      }
+                               }
+                       }
+               }
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 
./drivers/oprofile/cpu_buffer.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c  2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/cpu_buffer.c    2006-06-19 22:43:53.000000000 +0800
 @@ -6,6 +6,10 @@
   *
   * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -139,13 +173,12 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  {
        struct task_struct * task;
  
-@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
+@@ -181,16 +185,14 @@ static int log_sample(struct oprofile_cp
                return 0;
        }
  
 -      is_kernel = !!is_kernel;
-+      WARN_ON(cpu_mode > CPU_MODE_XEN);
- 
+-
        task = current;
  
        /* notice a switch from user->kernel or vice versa */
@@ -161,9 +194,9 @@ diff -pruN ../pristine-linux-2.6.16.13/d
        /* notice a task switch */
        if (cpu_buf->last_task != task) {
                cpu_buf->last_task = task;
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 
./drivers/oprofile/cpu_buffer.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h  2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.h    2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 
./drivers/oprofile/cpu_buffer.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h  2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/cpu_buffer.h    2006-06-27 10:38:08.000000000 +0800
 @@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
        volatile unsigned long tail_pos;
        unsigned long buffer_size;
@@ -173,22 +206,26 @@ diff -pruN ../pristine-linux-2.6.16.13/d
        int tracing;
        struct op_sample * buffer;
        unsigned long sample_received;
-@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
+@@ -51,7 +51,13 @@ extern struct oprofile_cpu_buffer cpu_bu
  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
++#define CPU_MODE_USER           0
++#define CPU_MODE_KERNEL         1
++#define CPU_MODE_XEN            2
++#define CPU_MODE_PASSIVE_START  3
++#define CPU_MODE_PASSIVE_STOP   4
++#define CPU_TRACE_BEGIN         5
++
++#define IGNORED_PC              0
  
  #endif /* OPROFILE_CPU_BUFFER_H */
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 
./drivers/oprofile/event_buffer.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h        
2006-05-02 22:38:44.000000000 +0100
-+++ ./drivers/oprofile/event_buffer.h  2006-05-04 17:41:51.000000000 +0100
-@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 
./drivers/oprofile/event_buffer.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h        
2006-05-03 05:38:44.000000000 +0800
++++ ./drivers/oprofile/event_buffer.h  2006-06-19 22:43:53.000000000 +0800
+@@ -29,11 +29,14 @@ void wake_up_buffer_waiter(void);
  #define CPU_SWITCH_CODE               2
  #define COOKIE_SWITCH_CODE            3
  #define KERNEL_ENTER_SWITCH_CODE      4
@@ -199,12 +236,14 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  #define TRACE_BEGIN_CODE              8
  #define TRACE_END_CODE                        9
 +#define XEN_ENTER_SWITCH_CODE         10
++#define PASSIVE_START_CODE            11
++#define PASSIVE_STOP_CODE             12
   
  #define INVALID_COOKIE ~0UL
  #define NO_COOKIE 0UL
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 
./drivers/oprofile/oprof.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c       2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprof.c 2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 
./drivers/oprofile/oprof.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c       2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprof.c 2006-06-19 23:45:17.000000000 +0800
 @@ -5,6 +5,10 @@
   * @remark Read the file COPYING
   *
@@ -225,7 +264,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  struct oprofile_operations oprofile_ops;
  
  unsigned long oprofile_started;
-@@ -33,6 +37,19 @@ static DECLARE_MUTEX(start_sem);
+@@ -33,6 +37,32 @@ static DECLARE_MUTEX(start_sem);
   */
  static int timer = 0;
  
@@ -242,23 +281,37 @@ diff -pruN ../pristine-linux-2.6.16.13/d
 +      return err;
 +}
 +
++int oprofile_set_passive(int passive_domains[], unsigned int pdomains)
++{
++      int err;
++
++      if (!oprofile_ops.set_passive)
++              return -EINVAL;
++
++      down(&start_sem);
++      err = oprofile_ops.set_passive(passive_domains, pdomains);
++      up(&start_sem);
++      return err;
++}
++
  int oprofile_setup(void)
  {
        int err;
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 
./drivers/oprofile/oprof.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h       2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprof.h 2006-05-04 17:41:51.000000000 +0100
-@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 
./drivers/oprofile/oprof.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h       2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprof.h 2006-06-19 23:42:36.000000000 +0800
+@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
  void oprofile_timer_init(struct oprofile_operations * ops);
  
  int oprofile_set_backtrace(unsigned long depth);
 +
 +int oprofile_set_active(int active_domains[], unsigned int adomains);
++int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
   
  #endif /* OPROF_H */
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 
./drivers/oprofile/oprofile_files.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c      
2006-05-02 22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprofile_files.c        2006-05-04 17:41:51.000000000 
+0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 
./drivers/oprofile/oprofile_files.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c      
2006-05-03 05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprofile_files.c        2006-06-19 23:29:07.000000000 
+0800
 @@ -5,15 +5,21 @@
   * @remark Read the file COPYING
   *
@@ -282,7 +335,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  unsigned long fs_buffer_size = 131072;
  unsigned long fs_cpu_buffer_size = 8192;
  unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-@@ -117,11 +123,108 @@ static ssize_t dump_write(struct file * 
+@@ -117,11 +123,202 @@ static ssize_t dump_write(struct file * 
  static struct file_operations dump_fops = {
        .write          = dump_write,
  };
@@ -384,17 +437,110 @@ diff -pruN ../pristine-linux-2.6.16.13/d
 +      .write          = adomain_write,
 +};
 +
++static unsigned int pdomains = 0;
++static int passive_domains[MAX_OPROF_DOMAINS];
++static DEFINE_MUTEX(pdom_mutex);
++
++static ssize_t pdomain_write(struct file * file, char const __user * buf, 
++                           size_t count, loff_t * offset)
++{
++      char *tmpbuf;
++      char *startp, *endp;
++      int i;
++      unsigned long val;
++      ssize_t retval = count;
++      
++      if (*offset)
++              return -EINVAL; 
++      if (count > TMPBUFSIZE - 1)
++              return -EINVAL;
++
++      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
++              return -ENOMEM;
++
++      if (copy_from_user(tmpbuf, buf, count)) {
++              kfree(tmpbuf);
++              return -EFAULT;
++      }
++      tmpbuf[count] = 0;
++
++      mutex_lock(&pdom_mutex);
++
++      startp = tmpbuf;
++      /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
++      for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
++              val = simple_strtoul(startp, &endp, 0);
++              if (endp == startp)
++                      break;
++              while (ispunct(*endp) || isspace(*endp))
++                      endp++;
++              passive_domains[i] = val;
++              if (passive_domains[i] != val)
++                      /* Overflow, force error below */
++                      i = MAX_OPROF_DOMAINS + 1;
++              startp = endp;
++      }
++      /* Force error on trailing junk */
++      pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
++
++      kfree(tmpbuf);
++
++      if (pdomains > MAX_OPROF_DOMAINS
++          || oprofile_set_passive(passive_domains, pdomains)) {
++              pdomains = 0;
++              retval = -EINVAL;
++      }
++
++      mutex_unlock(&pdom_mutex);
++      return retval;
++}
++
++static ssize_t pdomain_read(struct file * file, char __user * buf, 
++                          size_t count, loff_t * offset)
++{
++      char * tmpbuf;
++      size_t len;
++      int i;
++      ssize_t retval;
++
++      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
++              return -ENOMEM;
++
++      mutex_lock(&pdom_mutex);
++
++      len = 0;
++      for (i = 0; i < pdomains; i++)
++              len += snprintf(tmpbuf + len,
++                              len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
++                              "%u ", passive_domains[i]);
++      WARN_ON(len > TMPBUFSIZE);
++      if (len != 0 && len <= TMPBUFSIZE)
++              tmpbuf[len-1] = '\n';
++
++      mutex_unlock(&pdom_mutex);
++
++      retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
++
++      kfree(tmpbuf);
++      return retval;
++}
++
++static struct file_operations passive_domain_ops = {
++      .read           = pdomain_read,
++      .write          = pdomain_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, "passive_domains", 
&passive_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 -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h 
./include/linux/oprofile.h
---- ../pristine-linux-2.6.16.13/include/linux/oprofile.h       2006-05-02 
22:38:44.000000000 +0100
-+++ ./include/linux/oprofile.h 2006-05-04 17:41:51.000000000 +0100
+--- ../pristine-linux-2.6.16.13/include/linux/oprofile.h       2006-05-03 
05:38:44.000000000 +0800
++++ ./include/linux/oprofile.h 2006-06-19 23:52:00.000000000 +0800
 @@ -16,6 +16,8 @@
  #include <linux/types.h>
  #include <linux/spinlock.h>
@@ -404,12 +550,15 @@ diff -pruN ../pristine-linux-2.6.16.13/i
   
  struct super_block;
  struct dentry;
-@@ -27,6 +29,8 @@ struct oprofile_operations {
+@@ -27,6 +29,11 @@ struct oprofile_operations {
        /* 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);
++        /* setup passive domains with Xen */
++        int (*set_passive)(int *passive_domains, unsigned int pdomains);
++      
        /* Do any necessary interrupt setup. Optional. */
        int (*setup)(void);
        /* Do any necessary interrupt shutdown. Optional. */
diff -r b12cd185d579 -r 23591d2c46aa xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c   Tue Jun 27 11:17:14 2006 +0100
+++ b/xen/arch/x86/oprofile/nmi_int.c   Tue Jun 27 11:23:06 2006 +0100
@@ -269,7 +269,7 @@ static int __init p4_init(char * cpu_typ
 { 
        __u8 cpu_model = current_cpu_data.x86_model;
 
-       if (cpu_model > 4)
+       if ((cpu_model > 6) || (cpu_model == 5))
                return 0;
 
 #ifndef CONFIG_SMP
diff -r b12cd185d579 -r 23591d2c46aa xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c  Tue Jun 27 11:17:14 2006 +0100
+++ b/xen/arch/x86/oprofile/xenoprof.c  Tue Jun 27 11:23:06 2006 +0100
@@ -13,9 +13,13 @@
 /* Limit amount of pages used for shared buffer (per domain) */
 #define MAX_OPROF_SHARED_PAGES 32
 
-domid_t active_domains[MAX_OPROF_DOMAINS];
+struct domain *active_domains[MAX_OPROF_DOMAINS];
 int active_ready[MAX_OPROF_DOMAINS];
 unsigned int adomains;
+
+struct domain *passive_domains[MAX_OPROF_DOMAINS];
+unsigned int pdomains;
+
 unsigned int activated;
 struct domain *primary_profiler;
 int xenoprof_state = XENOPROF_IDLE;
@@ -25,6 +29,7 @@ u64 corrupted_buffer_samples;
 u64 corrupted_buffer_samples;
 u64 lost_samples;
 u64 active_samples;
+u64 passive_samples;
 u64 idle_samples;
 u64 others_samples;
 
@@ -44,9 +49,15 @@ int is_active(struct domain *d)
     return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_ACTIVE));
 }
 
+int is_passive(struct domain *d)
+{
+    struct xenoprof *x = d->xenoprof;
+    return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_PASSIVE));
+}
+
 int is_profiled(struct domain *d)
 {
-    return is_active(d);
+    return (is_active(d) || is_passive(d));
 }
 
 static void xenoprof_reset_stat(void)
@@ -56,6 +67,7 @@ static void xenoprof_reset_stat(void)
     corrupted_buffer_samples = 0;
     lost_samples = 0;
     active_samples = 0;
+    passive_samples = 0;
     idle_samples = 0;
     others_samples = 0;
 }
@@ -83,13 +95,122 @@ static void xenoprof_reset_buf(struct do
     }
 }
 
+char *alloc_xenoprof_buf(struct domain *d, int npages)
+{
+    char *rawbuf;
+    int i, order;
+
+    /* allocate pages to store sample buffer shared with domain */
+    order  = get_order_from_pages(npages);
+    rawbuf = alloc_xenheap_pages(order);
+    if ( rawbuf == NULL )
+    {
+        printk("alloc_xenoprof_buf(): memory allocation failed\n");
+        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;
+}
+
+int alloc_xenoprof_struct(struct domain *d, int max_samples, int is_passive)
+{
+    struct vcpu *v;
+    int nvcpu, npages, bufsize, max_bufsize;
+    int i;
+
+    d->xenoprof = xmalloc(struct xenoprof);
+
+    if ( d->xenoprof == NULL )
+    {
+        printk ("alloc_xenoprof_struct(): memory "
+                "allocation (xmalloc) failed\n");
+        return -ENOMEM;
+    }
+
+    memset(d->xenoprof, 0, sizeof(*d->xenoprof));
+
+    nvcpu = 0;
+    for_each_vcpu ( d, v )
+        nvcpu++;
+
+    /* reduce buffer size if necessary to limit pages allocated */
+    bufsize = sizeof(struct xenoprof_buf) +
+        (max_samples - 1) * sizeof(struct event_log);
+    max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu;
+    if ( bufsize > max_bufsize )
+    {
+        bufsize = max_bufsize;
+        max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) /
+                        sizeof(struct event_log) ) + 1;
+    }
+
+    npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
+    
+    d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages);
+
+    if ( d->xenoprof->rawbuf == NULL )
+    {
+        xfree(d->xenoprof);
+        d->xenoprof = NULL;
+        return -ENOMEM;
+    }
+
+    d->xenoprof->npages = npages;
+    d->xenoprof->nbuf = nvcpu;
+    d->xenoprof->bufsize = bufsize;
+    d->xenoprof->domain_ready = 0;
+    d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED;
+
+    /* Update buffer pointers for active vcpus */
+    i = 0;
+    for_each_vcpu ( d, v )
+    {
+        d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
+        d->xenoprof->vcpu[v->vcpu_id].buffer =
+            (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize];
+        d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples;
+        d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id;
+
+        i++;
+        /* in the unlikely case that the number of active vcpus changes */
+        if ( i >= nvcpu )
+            break;
+    }
+    
+    return 0;
+}
+
+void free_xenoprof_pages(struct domain *d)
+{
+    struct xenoprof *x;
+    int order;
+
+    x = d->xenoprof;
+    if ( x == NULL )
+        return;
+
+    if ( x->rawbuf != NULL )
+    {
+        order = get_order_from_pages(x->npages);
+        free_xenheap_pages(x->rawbuf, order);
+    }
+
+    xfree(x);
+    d->xenoprof = NULL;
+}
+
 int active_index(struct domain *d)
 {
     int i;
-    domid_t id = d->domain_id;
 
     for ( i = 0; i < adomains; i++ )
-        if ( active_domains[i] == id )
+        if ( active_domains[i] == d )
             return i;
 
     return -1;
@@ -132,47 +253,116 @@ int reset_active(struct domain *d)
     x->domain_ready = 0;
     x->domain_type = XENOPROF_DOMAIN_IGNORED;
     active_ready[ind] = 0;
+    active_domains[ind] = NULL;
     activated--;
+    put_domain(d); 
+
     if ( activated <= 0 )
         adomains = 0;
 
     return 0;
 }
 
-int reset_active_list(void)
+void reset_passive(struct domain *d)
+{
+    struct xenoprof *x;
+
+    if (d==0)
+        return;
+
+    x = d->xenoprof;
+    if ( x == NULL )
+        return;
+
+    x->domain_type = XENOPROF_DOMAIN_IGNORED;
+
+    return;
+}
+
+void reset_active_list(void)
 {
     int i;
-    struct domain *d;
 
     for ( i = 0; i < adomains; i++ )
     {
         if ( active_ready[i] )
         {
-            d = find_domain_by_id(active_domains[i]);
-            if ( d != NULL )
-            {
-                reset_active(d);
-                put_domain(d);
-            }
+            reset_active(active_domains[i]);
         }
     }
 
     adomains = 0;
     activated = 0;
-
-    return 0;
+}
+
+void reset_passive_list(void)
+{
+    int i;
+
+    for ( i = 0; i < pdomains; i++ )
+    {
+        reset_passive(passive_domains[i]);
+        put_domain(passive_domains[i]);
+        passive_domains[i] = NULL;
+    }
+
+    pdomains = 0;
 }
 
 int add_active_list (domid_t domid)
 {
+    struct domain *d;
+
     if ( adomains >= MAX_OPROF_DOMAINS )
         return -E2BIG;
 
-    active_domains[adomains] = domid;
+    d = find_domain_by_id(domid); 
+    if ( d == NULL )
+        return -EINVAL;
+
+    active_domains[adomains] = d;
     active_ready[adomains] = 0;
     adomains++;
 
     return 0;
+}
+
+int add_passive_list(XEN_GUEST_HANDLE(void) arg)
+{
+    struct xenoprof_passive passive;
+    struct domain *d;
+    int ret = 0;
+
+    if ( pdomains >= MAX_OPROF_DOMAINS )
+        return -E2BIG;
+
+    if ( copy_from_guest(&passive, arg, 1) )
+        return -EFAULT;
+
+    d = find_domain_by_id(passive.domain_id); 
+    if ( d == NULL )
+        return -EINVAL;
+
+    if ( (d->xenoprof == NULL) && 
+         ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) ) {
+        put_domain(d);
+        return -ENOMEM;
+    }
+
+    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 ( copy_to_guest(arg, &passive, 1) ) {
+        put_domain(d);
+        return -EFAULT;
+    }
+    
+    passive_domains[pdomains] = d;
+    pdomains++;
+
+    return ret;
 }
 
 void xenoprof_log_event(
@@ -231,7 +421,10 @@ void xenoprof_log_event(
         if ( head >= size )
             head = 0;
         buf->event_head = head;
-        active_samples++;
+        if ( is_active(vcpu->domain) )
+            active_samples++;
+        else
+            passive_samples++;
         if ( mode == 0 )
             buf->user_samples++;
         else if ( mode == 1 )
@@ -241,114 +434,6 @@ void xenoprof_log_event(
     }
 }
 
-char *alloc_xenoprof_buf(struct domain *d, int npages)
-{
-    char *rawbuf;
-    int i, order;
-
-    /* allocate pages to store sample buffer shared with domain */
-    order  = get_order_from_pages(npages);
-    rawbuf = alloc_xenheap_pages(order);
-    if ( rawbuf == NULL )
-    {
-        printk("alloc_xenoprof_buf(): memory allocation failed\n");
-        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;
-}
-
-int alloc_xenoprof_struct(struct domain *d, int max_samples)
-{
-    struct vcpu *v;
-    int nvcpu, npages, bufsize, max_bufsize;
-    int i;
-
-    d->xenoprof = xmalloc(struct xenoprof);
-
-    if ( d->xenoprof == NULL )
-    {
-        printk ("alloc_xenoprof_struct(): memory "
-                "allocation (xmalloc) failed\n");
-        return -ENOMEM;
-    }
-
-    memset(d->xenoprof, 0, sizeof(*d->xenoprof));
-
-    nvcpu = 0;
-    for_each_vcpu ( d, v )
-        nvcpu++;
-
-    /* reduce buffer size if necessary to limit pages allocated */
-    bufsize = sizeof(struct xenoprof_buf) +
-        (max_samples - 1) * sizeof(struct event_log);
-    max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu;
-    if ( bufsize > max_bufsize )
-    {
-        bufsize = max_bufsize;
-        max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) /
-                        sizeof(struct event_log) ) + 1;
-    }
-
-    npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
-    d->xenoprof->rawbuf = alloc_xenoprof_buf(d, npages);
-    if ( d->xenoprof->rawbuf == NULL )
-    {
-        xfree(d->xenoprof);
-        d->xenoprof = NULL;
-        return -ENOMEM;
-    }
-
-    d->xenoprof->npages = npages;
-    d->xenoprof->nbuf = nvcpu;
-    d->xenoprof->bufsize = bufsize;
-    d->xenoprof->domain_ready = 0;
-    d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED;
-
-    /* Update buffer pointers for active vcpus */
-    i = 0;
-    for_each_vcpu ( d, v )
-    {
-        d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
-        d->xenoprof->vcpu[v->vcpu_id].buffer =
-            (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize];
-        d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples;
-        d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id;
-
-        i++;
-        /* in the unlikely case that the number of active vcpus changes */
-        if ( i >= nvcpu )
-            break;
-    }
-
-    return 0;
-}
-
-void free_xenoprof_pages(struct domain *d)
-{
-    struct xenoprof *x;
-    int order;
-
-    x = d->xenoprof;
-    if ( x == NULL )
-        return;
-
-    if ( x->rawbuf != NULL )
-    {
-        order = get_order_from_pages(x->npages);
-        free_xenheap_pages(x->rawbuf, order);
-    }
-
-    xfree(x);
-    d->xenoprof = NULL;
-}
-
 int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
 {
     struct xenoprof_init xenoprof_init;
@@ -373,7 +458,7 @@ int xenoprof_op_init(XEN_GUEST_HANDLE(vo
      * is called. Memory is then kept until domain is destroyed.
      */
     if ( (d->xenoprof == NULL) &&
-         ((ret = alloc_xenoprof_struct(d, xenoprof_init.max_samples)) < 0) )
+         ((ret = alloc_xenoprof_struct(d, xenoprof_init.max_samples, 0)) < 0) )
         goto err;
 
     xenoprof_reset_buf(d);
@@ -429,7 +514,14 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
 
     case XENOPROF_reset_active_list:
     {
-        ret = reset_active_list();
+        reset_active_list();
+        ret = 0;
+        break;
+    }
+    case XENOPROF_reset_passive_list:
+    {
+        reset_passive_list();
+        ret = 0;
         break;
     }
     case XENOPROF_set_active:
@@ -440,6 +532,13 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         if ( copy_from_guest(&domid, arg, 1) )
             return -EFAULT;
         ret = add_active_list(domid);
+        break;
+    }
+    case XENOPROF_set_passive:
+    {
+        if ( xenoprof_state != XENOPROF_IDLE )
+            return -EPERM;
+        ret = add_passive_list(arg);
         break;
     }
     case XENOPROF_reserve_counters:
@@ -484,14 +583,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         break;
 
     case XENOPROF_enable_virq:
+    {
+        int i;
         if ( current->domain == primary_profiler )
         {
             nmi_enable_virq();
             xenoprof_reset_stat();
+            for ( i = 0; i < pdomains; i++ ) {
+                xenoprof_reset_buf(passive_domains[i]);
+            }
         }
         xenoprof_reset_buf(current->domain);
         ret = set_active(current->domain);
         break;
+    }
 
     case XENOPROF_start:
         ret = -EPERM;
@@ -525,6 +630,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
             xenoprof_state = XENOPROF_IDLE;
             nmi_release_counters();
             nmi_disable_virq();
+            reset_passive_list();
             ret = 0;
         }
         break;
diff -r b12cd185d579 -r 23591d2c46aa xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h     Tue Jun 27 11:17:14 2006 +0100
+++ b/xen/include/public/xenoprof.h     Tue Jun 27 11:23:06 2006 +0100
@@ -80,6 +80,15 @@ typedef struct xenoprof_counter xenoprof
 typedef struct xenoprof_counter xenoprof_counter_t;
 DEFINE_XEN_GUEST_HANDLE(xenoprof_counter_t);
 
+typedef struct xenoprof_passive {
+    uint16_t domain_id;
+    int32_t  max_samples;
+    int32_t  nbuf;
+    int32_t  bufsize;
+    uint64_t buf_maddr;
+} xenoprof_passive_t;
+DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t);
+
 
 #endif /* __XEN_PUBLIC_XENOPROF_H__ */
 
diff -r b12cd185d579 -r 23591d2c46aa xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h        Tue Jun 27 11:17:14 2006 +0100
+++ b/xen/include/xen/xenoprof.h        Tue Jun 27 11:23:06 2006 +0100
@@ -14,6 +14,7 @@
 
 #define XENOPROF_DOMAIN_IGNORED    0
 #define XENOPROF_DOMAIN_ACTIVE     1
+#define XENOPROF_DOMAIN_PASSIVE    2
 
 #define XENOPROF_IDLE              0
 #define XENOPROF_COUNTERS_RESERVED 1

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Add Xenoprof passive domain support, Xen patchbot-unstable <=