qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Add ioport statistics


From: Dor Laor
Subject: [Qemu-devel] Add ioport statistics
Date: Tue, 23 Oct 2007 13:34:49 +0200
User-agent: Thunderbird 2.0.0.6 (Windows/20070728)

On some occaisons a VM can consume up to 100% host cpu due
to intensive portio activity. The current DEBUG_IPPORT prints
just write every access into the log file. This patch enable
ioport debug statistics so a summary of ioport access is printed
every second to the log file. This helps debugging production
problems.

Signed-off-by: Dor Laor <address@hidden>
---
qemu/exec.c |    3 ---
qemu/vl.c   |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/qemu/exec.c b/qemu/exec.c
index 3e588d5..974ac98 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -50,7 +50,6 @@
//#define DEBUG_TB_CHECK
//#define DEBUG_TLB_CHECK

-//#define DEBUG_IOPORT
//#define DEBUG_SUBPAGE

#if !defined(CONFIG_USER_ONLY)
@@ -1268,10 +1267,8 @@ CPULogItem cpu_log_items[] = {
    { CPU_LOG_PCALL, "pcall",
      "show protected mode far calls/returns/exceptions" },
#endif
-#ifdef DEBUG_IOPORT
    { CPU_LOG_IOPORT, "ioport",
      "show all i/o ports accesses" },
-#endif
    { 0, NULL, NULL },
};

diff --git a/qemu/vl.c b/qemu/vl.c
index 8dd839e..0e3aa70 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -129,6 +129,7 @@ int inet_aton(const char *cp, struct in_addr *ia);

//#define DEBUG_UNUSED_IOPORT
//#define DEBUG_IOPORT
+#define DEBUG_IOPORT_STAT

#if HOST_LONG_BITS < 64
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
@@ -155,6 +156,9 @@ char phys_ram_file[1024];
void *ioport_opaque[MAX_IOPORTS];
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
+#ifdef DEBUG_IOPORT_STAT
+uint32_t ioport_stat[MAX_IOPORTS] = {0};
+#endif
/* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
   to store the VM snapshots */
BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD];
@@ -379,6 +383,10 @@ void cpu_outb(CPUState *env, int addr, int val)
    if (loglevel & CPU_LOG_IOPORT)
        fprintf(logfile, "outb: %04x %02x\n", addr, val);
#endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
+
    ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
#ifdef USE_KQEMU
    if (env)
@@ -392,6 +400,9 @@ void cpu_outw(CPUState *env, int addr, int val)
    if (loglevel & CPU_LOG_IOPORT)
        fprintf(logfile, "outw: %04x %04x\n", addr, val);
#endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
    ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
#ifdef USE_KQEMU
    if (env)
@@ -405,6 +416,9 @@ void cpu_outl(CPUState *env, int addr, int val)
    if (loglevel & CPU_LOG_IOPORT)
        fprintf(logfile, "outl: %04x %08x\n", addr, val);
#endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
    ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
#ifdef USE_KQEMU
    if (env)
@@ -420,6 +434,9 @@ int cpu_inb(CPUState *env, int addr)
    if (loglevel & CPU_LOG_IOPORT)
        fprintf(logfile, "inb : %04x %02x\n", addr, val);
#endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
#ifdef USE_KQEMU
    if (env)
        env->last_io_time = cpu_get_time_fast();
@@ -435,6 +452,9 @@ int cpu_inw(CPUState *env, int addr)
    if (loglevel & CPU_LOG_IOPORT)
        fprintf(logfile, "inw : %04x %04x\n", addr, val);
#endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
#ifdef USE_KQEMU
    if (env)
        env->last_io_time = cpu_get_time_fast();
@@ -450,6 +470,9 @@ int cpu_inl(CPUState *env, int addr)
    if (loglevel & CPU_LOG_IOPORT)
        fprintf(logfile, "inl : %04x %08x\n", addr, val);
#endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
#ifdef USE_KQEMU
    if (env)
        env->last_io_time = cpu_get_time_fast();
@@ -1141,6 +1164,36 @@ static int timer_load(QEMUFile *f, void *opaque, int 
version_id)
    return 0;
}

+#ifdef DEBUG_IOPORT_STAT
+QEMUTimer *ioport_stat_qtimer;
+
+static void ioport_stat_timer(void *opaque)
+{
+    uint64_t curr_time;
+    int i;
+
+    curr_time = qemu_get_clock(vm_clock);
+    qemu_mod_timer(ioport_stat_qtimer, curr_time + ticks_per_sec);
+
+    if (loglevel & CPU_LOG_IOPORT) {
+        fprintf(logfile, "%s: port_addr(h) access_times(d)\n", __FUNCTION__);
+        for (i = 0; i < MAX_IOPORTS; i++)
+             if (ioport_stat[i]) {
+                 fprintf(logfile, "%04x %d\n", i, ioport_stat[i]);
+                 ioport_stat[i] = 0;
+             }
+        fprintf(logfile, "%s: end stat\n", __FUNCTION__);
+    }
+}
+
+static void ioport_stat_init(void)
+{
+    ioport_stat_qtimer = qemu_new_timer(vm_clock, ioport_stat_timer, NULL);
+    qemu_mod_timer(ioport_stat_qtimer, qemu_get_clock(vm_clock));
+}
+
+#endif
+
#ifdef _WIN32
void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
                                 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
@@ -8738,6 +8791,11 @@ int main(int argc, char **argv)

    init_timers();
    init_timer_alarm();
+
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat_init();
+#endif
+
    qemu_aio_init();

#ifdef _WIN32
--
1.5.3

>From 5678da1976a01bc3f1d57a304cd0542a40d75a21 Mon Sep 17 00:00:00 2001
From: Dor Laor <address@hidden>
Date: Tue, 23 Oct 2007 13:28:06 +0200
Subject: [PATCH] Add ioport statistics

On some occaisons a VM can consume up to 100% host cpu due
to intensive portio activity. The current DEBUG_IPPORT prints
just write every access into the log file. This patch enable
ioport debug statistics so a summary of ioport access is printed
every second to the log file. This helps debugging production
problems.

Signed-off-by: Dor Laor <address@hidden>
---
 qemu/exec.c |    3 ---
 qemu/vl.c   |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/qemu/exec.c b/qemu/exec.c
index 3e588d5..974ac98 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -50,7 +50,6 @@
 //#define DEBUG_TB_CHECK
 //#define DEBUG_TLB_CHECK
 
-//#define DEBUG_IOPORT
 //#define DEBUG_SUBPAGE
 
 #if !defined(CONFIG_USER_ONLY)
@@ -1268,10 +1267,8 @@ CPULogItem cpu_log_items[] = {
     { CPU_LOG_PCALL, "pcall",
       "show protected mode far calls/returns/exceptions" },
 #endif
-#ifdef DEBUG_IOPORT
     { CPU_LOG_IOPORT, "ioport",
       "show all i/o ports accesses" },
-#endif
     { 0, NULL, NULL },
 };
 
diff --git a/qemu/vl.c b/qemu/vl.c
index 8dd839e..0e3aa70 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -129,6 +129,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
 
 //#define DEBUG_UNUSED_IOPORT
 //#define DEBUG_IOPORT
+#define DEBUG_IOPORT_STAT
 
 #if HOST_LONG_BITS < 64
 #define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
@@ -155,6 +156,9 @@ char phys_ram_file[1024];
 void *ioport_opaque[MAX_IOPORTS];
 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
+#ifdef DEBUG_IOPORT_STAT
+uint32_t ioport_stat[MAX_IOPORTS] = {0};
+#endif
 /* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
    to store the VM snapshots */
 BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD];
@@ -379,6 +383,10 @@ void cpu_outb(CPUState *env, int addr, int val)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "outb: %04x %02x\n", addr, val);
 #endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
+
     ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
 #ifdef USE_KQEMU
     if (env)
@@ -392,6 +400,9 @@ void cpu_outw(CPUState *env, int addr, int val)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "outw: %04x %04x\n", addr, val);
 #endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
     ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
 #ifdef USE_KQEMU
     if (env)
@@ -405,6 +416,9 @@ void cpu_outl(CPUState *env, int addr, int val)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "outl: %04x %08x\n", addr, val);
 #endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
     ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
 #ifdef USE_KQEMU
     if (env)
@@ -420,6 +434,9 @@ int cpu_inb(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inb : %04x %02x\n", addr, val);
 #endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
 #ifdef USE_KQEMU
     if (env)
         env->last_io_time = cpu_get_time_fast();
@@ -435,6 +452,9 @@ int cpu_inw(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inw : %04x %04x\n", addr, val);
 #endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
 #ifdef USE_KQEMU
     if (env)
         env->last_io_time = cpu_get_time_fast();
@@ -450,6 +470,9 @@ int cpu_inl(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inl : %04x %08x\n", addr, val);
 #endif
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat[addr]++;
+#endif
 #ifdef USE_KQEMU
     if (env)
         env->last_io_time = cpu_get_time_fast();
@@ -1141,6 +1164,36 @@ static int timer_load(QEMUFile *f, void *opaque, int 
version_id)
     return 0;
 }
 
+#ifdef DEBUG_IOPORT_STAT
+QEMUTimer *ioport_stat_qtimer;
+
+static void ioport_stat_timer(void *opaque)
+{
+    uint64_t curr_time;
+    int i;
+
+    curr_time = qemu_get_clock(vm_clock);
+    qemu_mod_timer(ioport_stat_qtimer, curr_time + ticks_per_sec);
+
+    if (loglevel & CPU_LOG_IOPORT) {
+        fprintf(logfile, "%s: port_addr(h) access_times(d)\n", __FUNCTION__);
+        for (i = 0; i < MAX_IOPORTS; i++)
+             if (ioport_stat[i]) {
+                 fprintf(logfile, "%04x %d\n", i, ioport_stat[i]);
+                 ioport_stat[i] = 0;
+             }
+        fprintf(logfile, "%s: end stat\n", __FUNCTION__);
+    }
+}
+
+static void ioport_stat_init(void)
+{
+    ioport_stat_qtimer = qemu_new_timer(vm_clock, ioport_stat_timer, NULL);
+    qemu_mod_timer(ioport_stat_qtimer, qemu_get_clock(vm_clock));
+}
+
+#endif
+
 #ifdef _WIN32
 void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
                                  DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR 
dw2)
@@ -8738,6 +8791,11 @@ int main(int argc, char **argv)
 
     init_timers();
     init_timer_alarm();
+
+#ifdef DEBUG_IOPORT_STAT
+    ioport_stat_init();
+#endif
+
     qemu_aio_init();
 
 #ifdef _WIN32
-- 
1.5.3


reply via email to

[Prev in Thread] Current Thread [Next in Thread]