diff -urN c/xen/common/keyhandler.c d/xen/common/keyhandler.c --- c/xen/common/keyhandler.c 2005-06-02 22:21:41.000000000 -0500 +++ d/xen/common/keyhandler.c 2005-06-03 09:48:15.075135457 -0500 @@ -12,6 +12,7 @@ #include #include #include +#include #define KEY_MAX 256 #define STR_MAX 64 @@ -139,6 +140,33 @@ read_unlock(&domlist_lock); } +static void do_dump_confer(unsigned char key) +{ + struct domain *d; + struct vcpu *v; + s_time_t now = NOW(); + + printk("'%c' pressed -> dumping confer stats (now=0x%X:%08X)\n", key, + (u32)(now>>32), (u32)now); + + read_lock(&domlist_lock); + for_each_domain ( d ) + { + for_each_vcpu ( d, v ) + { + printk("Xen: D%d, V%d, C%d," + " cnfs %d, c_out %d," + " c_in %d, ycnt %d\n", + d->domain_id, v->vcpu_id, v->processor, + v->confercnt, v->confer_out, + v->confer_in, v->vcpu_info->yield_count + ); + } + + } + read_unlock(&domlist_lock); +} + extern void dump_runq(unsigned char key); extern void print_sched_histo(unsigned char key); extern void reset_sched_histo(unsigned char key); @@ -184,6 +212,8 @@ register_keyhandler( 'q', do_task_queues, "dump task queues + guest state"); register_keyhandler( + 'c', do_dump_confer, "dump confer stats"); + register_keyhandler( 'r', dump_runq, "dump run queues"); register_irq_keyhandler( 'R', halt_machine, "reboot machine"); diff -urN c/xen/common/schedule.c d/xen/common/schedule.c --- c/xen/common/schedule.c 2005-06-03 09:41:49.540601494 -0500 +++ d/xen/common/schedule.c 2005-06-03 09:46:01.768032249 -0500 @@ -223,6 +223,9 @@ if ( test_bit(_VCPUF_conferring, ¤t->vcpu_flags) ) { clear_bit(_VCPUF_conferring, ¤t->vcpu_flags); set_bit(_VCPUF_conferred, ¤t->vcpu_flags); + /* increment confer counters */ + current->confer_out++; + v->confer_in++; } SCHED_OP(wake, v); #ifdef WAKE_HISTO @@ -270,6 +273,9 @@ { struct domain *d = current->domain; + /* count hcalls */ + current->confercnt++; + /* Validate CONFER prereqs: * - vcpu is within bounds * - vcpu is a valid in this domain @@ -286,16 +292,22 @@ if (unlikely(d->vcpu[vcpu] == NULL)) return 0; - if (unlikely(!test_bit(_VCPUF_canconfer, ¤t->vcpu_flags))) + if (unlikely(!test_bit(_VCPUF_canconfer, ¤t->vcpu_flags))) { + printk("confer: canconfer not set, %d->vcpu-flags = 0x%08lx\n", current->vcpu_id, current->vcpu_flags); return 0; + } /* even counts indicate a running vcpu, odd is preempted/conferred */ /* don't confer if holder is currently running */ - if (unlikely((d->vcpu[vcpu]->vcpu_info->yield_count & 1) == 0)) + if (unlikely((d->vcpu[vcpu]->vcpu_info->yield_count & 1) == 0)) { + printk("confer: vcpu %d already running\n", vcpu); return 0; + } - if (unlikely(d->vcpu[vcpu]->vcpu_info->yield_count != yield_count)) + if (unlikely(d->vcpu[vcpu]->vcpu_info->yield_count != yield_count)) { + printk("confer: yield_count mismatch\n"); return 0; + } /* * set current's state to conferring, wake target diff -urN c/xen/include/xen/sched.h d/xen/include/xen/sched.h --- c/xen/include/xen/sched.h 2005-06-03 09:41:11.042994158 -0500 +++ d/xen/include/xen/sched.h 2005-06-03 09:43:52.881249246 -0500 @@ -76,6 +76,9 @@ atomic_t pausecnt; cpumap_t cpumap; /* which cpus this domain can run on */ + u32 confer_out; /* inc when conferring to another vcpu */ + u32 confer_in; /* inc when conferred from another vcpu */ + u32 confercnt; /* # of do_confer hcalls */ struct arch_vcpu arch; };