diff mbox

patch for virtual machine oriented scheduling(4)

Message ID 820ac2e90904220757n51d626c8i41e5b56f1a1d51a1@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

alex April 22, 2009, 2:57 p.m. UTC
the debug tools I used.
---------------------------------------------------------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Michael S. Tsirkin Sept. 24, 2009, 6:28 a.m. UTC | #1
On Wed, Apr 22, 2009 at 10:57:13PM +0800, alex wrote:
> the debug tools I used.
> ---------------------------------------------------------------------------------------
> 
> diff --git a/arch/x86/kvm/trace.c b/arch/x86/kvm/trace.c
> new file mode 100644
> index 0000000..5718e94
> --- /dev/null
> +++ b/arch/x86/kvm/trace.c
> @@ -0,0 +1,147 @@

License/attribution/description seems to be missing for this and other
new files. Also, try running scripts/checkpatch.pl on the patches.
diff mbox

Patch

diff --git a/arch/x86/kvm/trace.c b/arch/x86/kvm/trace.c
new file mode 100644
index 0000000..5718e94
--- /dev/null
+++ b/arch/x86/kvm/trace.c
@@ -0,0 +1,147 @@ 
+#include <linux/kvm_host.h>
+#include <linux/trace.h>
+#include <linux/sched-if.h>
+
+static char *info[]={
+    "sched_vm_add",            // 0
+    "sched_sleep",             // 1
+    "sched_wake",              // 2
+    "sched_yield",             // 3
+    "sched_switch_inf_prev",   // 4
+    "sched_swithc_inf_next",   // 5
+    "sched_switch",            // 6
+    "sched_timer",             // 7
+    "sched_relayed_timer",     // 8
+    "vcpu_schedule",           // 9
+    "runq_tickle",             // 10
+    "tasklet_schedule",                // 11
+    "csched_tick_stub",                // 12
+    "csched_sleep",            // 13
+    "csched_vcpu_wake",                // 14
+    "csched_tick",             // 15
+    "do_pending_svc",          // 16
+    "pseudo_cli",              // 17
+    "pseudo_sti",              // 18
+    "csched_load_balance",     // 19
+    "csched_schedule",         // 20
+    "pseudo_intr",             // 21
+    "pseudo_eoi",              // 22
+    "pseudo_open_intr",                // 23
+    "s_timer_fn",              // 24
+    "preempt_send_ipi",                // 25
+    "inject_pend_ipi",         // 26
+    "do_pending_intr",         // 27
+    "csched_runq_sort",                // 28
+    NULL
+};
+
+static DEFINE_PER_CPU(struct trace_logger, t_logger);
+
+extern volatile int err_cnt;
+extern spinlock_t dbg_lock;
+
+int init_trace_buf(int cpu)
+{
+    struct trace_logger *my_logger = &per_cpu(t_logger, cpu);
+    struct t_rec* t_bufs = kzalloc(sizeof(struct t_rec)*NR_TRACES, GFP_KERNEL);
+
+    if(!t_bufs) return -ENOMEM;
+
+    my_logger->buf = t_bufs;
+    my_logger->ptr = 0;
+    spin_lock_init(&my_logger->lock);
+
+    return 0;
+}
+void free_trace_buf(int cpu)
+{
+    /*XXX: what if someone else is using the trace buf? */
+    struct trace_logger *my_logger = &per_cpu(t_logger, cpu);
+
+    spin_lock(&my_logger->lock);
+    kfree(my_logger->buf);
+    spin_unlock(&my_logger->lock);
+}
+void trace(u32 event, unsigned long d0, unsigned long d1,
+       unsigned long d2, unsigned long d3, unsigned long d4)
+{
+       unsigned long flags;
+       int idx;
+       int cpu;
+       struct trace_logger *my_logger;
+       struct t_rec *rec;
+
+       local_irq_save(flags);
+
+       cpu = get_cpu();
+       my_logger = &per_cpu(t_logger, cpu);
+
+       BUG_ON(!my_logger);
+
+       spin_lock(&my_logger->lock);
+       rec= my_logger->buf;
+       idx = my_logger->ptr++;
+       idx %= NR_TRACES;
+       rec += idx;
+
+       rdtscll(rec->cycles);
+       rec->event = event;
+       rec->data[0] = d0;
+       rec->data[1] = d1;
+       rec->data[2] = d2;
+       rec->data[3] = d3;
+       rec->data[4] = d4;
+
+
+       spin_unlock(&my_logger->lock);
+       put_cpu();
+
+       local_irq_restore(flags);
+
+}
+/* when executing, it is assumed that we are holding a spinlock */
+static void dump_per_cpu_trace(struct trace_logger* log)
+{
+       int i;
+       struct t_rec *records= log->buf;
+
+       i = log->ptr - 1;
+       if (i < 0) i = 0;
+       for( ;(i > (log->ptr - NR_TRACES) && (i>=0)); i--){
+           struct t_rec* rec = &records[i % NR_TRACES];
+           if(unlikely(rec->cycles == 0)) break;
+           printk("(%llx)e:%s (%lx %lx %lx %lx %lx)\n",
+                   rec->cycles, info[rec->event], rec->data[0],
+                   rec->data[1], rec->data[2], rec->data[3], rec->data[4]);
+       }
+}
+enum hrtimer_restart dump_cpu_trace(struct hrtimer *timer)
+{
+       dump_traces(NULL);
+       return HRTIMER_RESTART;
+}
+
+enum hrtimer_restart dump_traces(void* _unused)
+{
+    int cpu;
+    unsigned long flags;
+
+    for_each_online_cpu(cpu) {
+       struct trace_logger *logger = &per_cpu(t_logger, cpu);
+       printk("dumping trace logged on cpu %d\n", cpu);
+
+       spin_lock(&logger->lock);
+       local_irq_save(flags);
+       preempt_disable();
+
+       dump_per_cpu_trace(logger);
+       printk("dumping trace line %d\n", __LINE__);
+
+       spin_unlock(&logger->lock);
+       preempt_enable();
+       local_irq_restore(flags);
+    }
+    printk("log trace dump finished\n");
+    return HRTIMER_NORESTART;
+}
+EXPORT_SYMBOL(dump_traces);