Skip to contentSkip to conversation

Rework alarm timer infrastrucure.

PATCH In review Luca Tettamanti 3 participants 8 messages Aug 16, 2007 – Aug 19, 2007 6 messages not in the archive KVM

lore
Share & tools
lore
#0 lore raw

cover Rework alarm timer infrastrucure.

Hello,
in reply to this mail I will send a serie of 4 patches that cleans up and expands the alarm timer handling in QEMU. Patches apply to current kvm-userspace tree, but I think I can rebase it to QEMU svn if desired.

Patch 1 is mostly a cleanup of the existing code; instead of having multiple #ifdefs to handle different timers scattered all over the code I've created a modular infrastructure where each timer type is self-contained and generic code is more readable. The resulting code is functionally equivalent to the old one.

Patch 2 implements the "-clock" command line option proposed by Daniel Berrange and Avi Kivity. By default QEMU tries RTC and then falls back to unix timer; user can override the order of the timer through this options. Syntax is pretty
simple: -clock timer1,timer2,etc. (QEMU will pick the first one that works).

Patch 3 adds support for HPET under Linux (which is basically my old patch). As suggested HPET takes precedence over other timers, but of course this can be overridden.

Patch 4 introduces "dynticks" timer source; patch is mostly based on the work Dan Kenigsberg. dynticks is now the default alarm timer.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

A message that is not in the archive (sent off-list or not yet received): 11872968773449-git-send-email-kronos.it-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#2 lore raw

PATCH 1/4 Rework alarm timer infrastrucure.

Make the alarm code modular, removing #ifdef from the generic code and abstract a common interface for all the timer. The result is functionally equivalent to the old code.

---
 qemu/vl.c |  292 +++++++++++++++++++++++++++++++++------------------
 1 files changed, 189 insertions(+), 103 deletions(-)
qemu/vl.c +189 -103
index 5360ed7..33443ca 100644
@@ -745,18 +745,58 @@ struct QEMUTimer {
     struct QEMUTimer *next;
 };
 
-QEMUClock *rt_clock;
-QEMUClock *vm_clock;
+struct qemu_alarm_timer {
+    char const *name;
+
+    int (*start)(struct qemu_alarm_timer *t);
+    void (*stop)(struct qemu_alarm_timer *t);
+    void *priv;
+};
+
+static struct qemu_alarm_timer *alarm_timer;
 
-static QEMUTimer *active_timers[2];
 #ifdef _WIN32
-static MMRESULT timerID;
-static HANDLE host_alarm = NULL;
-static unsigned int period = 1;
+
+struct qemu_alarm_win32 {
+    MMRESULT timerId;
+    HANDLE host_alarm;
+    unsigned int period;
+} alarm_win32_data = {0, NULL, -1};
+
+static int win32_start_timer(struct qemu_alarm_timer *t);
+static void win32_stop_timer(struct qemu_alarm_timer *t);
+
+#else
+
+static int unix_start_timer(struct qemu_alarm_timer *t);
+static void unix_stop_timer(struct qemu_alarm_timer *t);
+
+#ifdef __linux__
+
+static int rtc_start_timer(struct qemu_alarm_timer *t);
+static void rtc_stop_timer(struct qemu_alarm_timer *t);
+
+#endif
+
+#endif /* _WIN32 */
+
+static struct qemu_alarm_timer alarm_timers[] = {
+#ifdef __linux__
+    /* RTC - if available - is preferred */
+    {"rtc", rtc_start_timer, rtc_stop_timer, NULL},
+#endif
+#ifndef _WIN32
+    {"unix", unix_start_timer, unix_stop_timer, NULL},
 #else
-/* frequency of the times() clock tick */
-static int timer_freq;
+    {"win32", win32_start_timer, win32_stop_timer, &alarm_win32_data},
 #endif
+    {NULL, }
+};
+
+QEMUClock *rt_clock;
+QEMUClock *vm_clock;
+
+static QEMUTimer *active_timers[2];
 
 QEMUClock *qemu_new_clock(int type)
 {
@@ -973,7 +1013,8 @@ static void host_alarm_handler(int host_signum)
         qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
                            qemu_get_clock(rt_clock))) {
 #ifdef _WIN32
-        SetEvent(host_alarm);
+        struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
+        SetEvent(data->host_alarm);
 #endif
         CPUState *env = cpu_single_env;
         if (env) {
@@ -995,10 +1036,31 @@ static void host_alarm_handler(int host_signum)
 #define RTC_FREQ 1024
 
 static int use_rtc = 1;
-static int rtc_fd;
 
-static int start_rtc_timer(void)
+static void enable_sigio_timer(int fd)
+{
+    struct sigaction act;
+
+    /* timer signal */
+    sigfillset(&act.sa_mask);
+    act.sa_flags = 0;
+#if defined (TARGET_I386) && defined(USE_CODE_COPY)
+    act.sa_flags |= SA_ONSTACK;
+#endif
+    act.sa_handler = host_alarm_handler;
+
+    sigaction(SIGIO, &act, NULL);
+    fcntl(fd, F_SETFL, O_ASYNC);
+    fcntl(fd, F_SETOWN, getpid());
+}
+
+static int rtc_start_timer(struct qemu_alarm_timer *t)
 {
+    int rtc_fd;
+
+    if (!use_rtc)
+            return -1;
+
     rtc_fd = open("/dev/rtc", O_RDONLY);
     if (rtc_fd < 0)
         return -1;
@@ -1009,121 +1071,145 @@ static int start_rtc_timer(void)
         goto fail;
     }
     if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
-    fail:
+fail:
         close(rtc_fd);
         return -1;
     }
-    pit_min_timer_count = PIT_FREQ / RTC_FREQ;
+
+    enable_sigio_timer(rtc_fd);
+
+    t->priv = (void *)rtc_fd;
+
     return 0;
 }
 
-#else
-
-static int start_rtc_timer(void)
+static void rtc_stop_timer(struct qemu_alarm_timer *t)
 {
-    return -1;
+    int rtc_fd = (int)t->priv;
+
+    close(rtc_fd);
 }
 
 #endif /* !defined(__linux__) */
 
-#endif /* !defined(_WIN32) */
+static int unix_start_timer(struct qemu_alarm_timer *t)
+{
+    struct sigaction act;
+    struct itimerval itv;
+    int err;
 
-static void init_timer_alarm(void)
+    /* timer signal */
+    sigfillset(&act.sa_mask);
+    act.sa_flags = 0;
+#if defined(TARGET_I386) && defined(USE_CODE_COPY)
+    act.sa_flags |= SA_ONSTACK;
+#endif
+    act.sa_handler = host_alarm_handler;
+
+    sigaction(SIGALRM, &act, NULL);
+
+    itv.it_interval.tv_sec = 0;
+    /* for i386 kernel 2.6 to get 1 ms */
+    itv.it_interval.tv_usec = 999;
+    itv.it_value.tv_sec = 0;
+    itv.it_value.tv_usec = 10 * 1000;
+
+    err = setitimer(ITIMER_REAL, &itv, NULL);
+    if (err)
+        return -1;
+
+    return 0;
+}
+
+static void unix_stop_timer(struct qemu_alarm_timer *t)
 {
+    struct itimerval itv;
+
+    memset(&itv, 0, sizeof(itv));
+    setitimer(ITIMER_REAL, &itv, NULL);
+}
+
+#endif /* !defined(_WIN32) */
+
 #ifdef _WIN32
-    {
-        int count=0;
-        TIMECAPS tc;
-
-        ZeroMemory(&tc, sizeof(TIMECAPS));
-        timeGetDevCaps(&tc, sizeof(TIMECAPS));
-        if (period < tc.wPeriodMin)
-            period = tc.wPeriodMin;
-        timeBeginPeriod(period);
-        timerID = timeSetEvent(1,     // interval (ms)
-                               period,     // resolution
-                               host_alarm_handler, // function
-                               (DWORD)&count,  // user parameter
-                               TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
- 	if( !timerID ) {
-            perror("failed timer alarm");
-            exit(1);
- 	}
-        host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
-        if (!host_alarm) {
-            perror("failed CreateEvent");
-            exit(1);
-        }
-        qemu_add_wait_object(host_alarm, NULL, NULL);
+
+static int win32_start_timer(struct qemu_alarm_timer *t)
+{
+    TIMECAPS tc;
+    struct qemu_alarm_win32 *data = t->priv;
+
+    data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (!data->host_alarm) {
+        perror("Failed CreateEvent");
+        return -1;
     }
-    pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
-#else
-    {
-        struct sigaction act;
-        struct itimerval itv;
-        
-        /* get times() syscall frequency */
-        timer_freq = sysconf(_SC_CLK_TCK);
-        
-        /* timer signal */
-        sigfillset(&act.sa_mask);
-       act.sa_flags = 0;
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
-        act.sa_flags |= SA_ONSTACK;
-#endif
-        act.sa_handler = host_alarm_handler;
-        sigaction(SIGALRM, &act, NULL);
 
-        itv.it_interval.tv_sec = 0;
-        itv.it_interval.tv_usec = 999; /* for i386 kernel 2.6 to get 1 ms */
-        itv.it_value.tv_sec = 0;
-        itv.it_value.tv_usec = 10 * 1000;
-        setitimer(ITIMER_REAL, &itv, NULL);
-        /* we probe the tick duration of the kernel to inform the user if
-           the emulated kernel requested a too high timer frequency */
-        getitimer(ITIMER_REAL, &itv);
+    memset(&tc, 0, sizeof(tc));
+    timeGetDevCaps(&tc, sizeof(tc));
 
-#if defined(__linux__)
-        /* XXX: force /dev/rtc usage because even 2.6 kernels may not
-           have timers with 1 ms resolution. The correct solution will
-           be to use the POSIX real time timers available in recent
-           2.6 kernels */
-        if (itv.it_interval.tv_usec > 1000 || 1) {
-            /* try to use /dev/rtc to have a faster timer */
-            if (!use_rtc || (start_rtc_timer() < 0))
-                goto use_itimer;
-            /* disable itimer */
-            itv.it_interval.tv_sec = 0;
-            itv.it_interval.tv_usec = 0;
-            itv.it_value.tv_sec = 0;
-            itv.it_value.tv_usec = 0;
-            setitimer(ITIMER_REAL, &itv, NULL);
-
-            /* use the RTC */
-            sigaction(SIGIO, &act, NULL);
-            fcntl(rtc_fd, F_SETFL, O_ASYNC);
-            fcntl(rtc_fd, F_SETOWN, getpid());
-        } else 
-#endif /* defined(__linux__) */
-        {
-        use_itimer:
-            pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * 
-                                   PIT_FREQ) / 1000000;
-        }
+    if (data->period < tc.wPeriodMin)
+        data->period = tc.wPeriodMin;
+
+    timeBeginPeriod(data->period);
+
+    data->timerId = timeSetEvent(1,         // interval (ms)
+                        data->period,       // resolution
+                        host_alarm_handler, // function
+                        (DWORD)t,           // parameter
+                        TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
+
+    if (!data->timerId) {
+        perror("Failed to initialize win32 alarm timer");
+
+        CloseHandle(data->host_alarm);
+        return -1;
     }
+    
+    qemu_add_wait_object(data->host_alarm, NULL, NULL);
+
+    return 0;
+}
+
+static void win32_stop_timer(struct qemu_alarm_timer *t)
+{
+    struct qemu_alarm_win32 *data = t->priv;
+
+    timeKillEvent(data->timerId);
+    timeEndPeriod(data->period);
+
+    CloseHandle(data->host_alarm);
+}
+
 #endif
+
+static void init_timer_alarm(void)
+{
+    struct qemu_alarm_timer *t;
+    int i, err = -1;
+
+    for (i = 0; alarm_timers[i].name; i++) {
+        t = &alarm_timers[i];
+
+        printf("trying %s...\n", t->name);
+
+        err = t->start(t);
+        if (!err)
+                break;
+    }
+
+    if (err) {
+        fprintf(stderr, "Unable to find any suitable alarm timer.\n");
+        fprintf(stderr, "Terminating\n");
+        exit(1);
+    }
+
+    alarm_timer = t;
 }
 
 void quit_timers(void)
 {
-#ifdef _WIN32
-    timeKillEvent(timerID);
-    timeEndPeriod(period);
-    if (host_alarm) {
-        CloseHandle(host_alarm);
-        host_alarm = NULL;
-    }
-#endif
+    alarm_timer->stop(alarm_timer);
+    alarm_timer = NULL;
 }
 
 /***********************************************************/
Signature · 8 lines
1.5.2.4


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

A message that is not in the archive (sent off-list or not yet received): 11872968771257-git-send-email-kronos.it-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#4 lore raw

PATCH 2/4 Add -clock option.

Allow user to override the list of available alarm timers and their priority. The format of the options is -clock clk1,clk2,...

---
 qemu/vl.c |   90 ++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 72 insertions(+), 18 deletions(-)
qemu/vl.c +72 -18
index 33443ca..f0b4896 100644
@@ -793,6 +793,71 @@ static struct qemu_alarm_timer alarm_timers[] = {
     {NULL, }
 };
 
+static void show_available_alarms()
+{
+    int i;
+
+    printf("Available alarm timers, in order of precedence:\n");
+    for (i = 0; alarm_timers[i].name; i++)
+        printf("%s\n", alarm_timers[i].name);
+}
+
+static void configure_alarms(char const *opt)
+{
+    int i;
+    int cur = 0;
+    int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
+    char *arg;
+    char *name;
+    
+    if (!strcmp(opt, "help")) {
+        show_available_alarms();
+        exit(0);
+    }
+    
+    arg = strdup(opt);
+
+    /* Reorder the array */
+    name = strtok(arg, ",");
+    while (name) {
+        struct qemu_alarm_timer tmp;
+
+        for (i = 0; i < count; i++) {
+            if (!strcmp(alarm_timers[i].name, name))
+                break;
+        }
+
+        if (i == count) {
+            fprintf(stderr, "Unknown clock %s\n", name);
+            goto next;
+        }
+
+        if (i < cur)
+            /* Ignore */
+            goto next;
+
+	/* Swap */
+        tmp = alarm_timers[i];
+        alarm_timers[i] = alarm_timers[cur];
+        alarm_timers[cur] = tmp;
+
+        cur++;
+next:
+        name = strtok(NULL, ",");
+    }
+
+    free(arg);
+
+    if (cur) {
+	/* Disable remaining timers */
+        for (i = cur; i < count; i++)
+            alarm_timers[i].name = NULL;
+    }
+
+    /* debug */
+    show_available_alarms();
+}
+
 QEMUClock *rt_clock;
 QEMUClock *vm_clock;
 
@@ -1035,8 +1100,6 @@ static void host_alarm_handler(int host_signum)
 
 #define RTC_FREQ 1024
 
-static int use_rtc = 1;
-
 static void enable_sigio_timer(int fd)
 {
     struct sigaction act;
@@ -1058,9 +1121,6 @@ static int rtc_start_timer(struct qemu_alarm_timer *t)
 {
     int rtc_fd;
 
-    if (!use_rtc)
-            return -1;
-
     rtc_fd = open("/dev/rtc", O_RDONLY);
     if (rtc_fd < 0)
         return -1;
@@ -6566,9 +6626,8 @@ void help(void)
 	   "-daemonize      daemonize QEMU after initializing\n"
 #endif
            "-tdf            inject timer interrupts that got lost\n"
-#if defined(__linux__)
-           "-no-rtc         don't use /dev/rtc for timer alarm (do use gettimeofday)\n"
-#endif
+           "-clock          force the use of the given methods for timer alarm.\n"
+           "                To see what timers are available use -clock help\n"
 	   "-option-rom rom load a file, rom, into the option ROM space\n"
            "\n"
            "During emulation, the following keys are useful:\n"
@@ -6658,9 +6717,7 @@ enum {
     QEMU_OPTION_semihosting,
     QEMU_OPTION_incoming,
     QEMU_OPTION_tdf,
-#if defined(__linux__)
-    QEMU_OPTION_no_rtc,
-#endif
+    QEMU_OPTION_clock,
     QEMU_OPTION_cpu_vendor,
 };
 
@@ -6755,9 +6812,7 @@ const QEMUOption qemu_options[] = {
     { "semihosting", 0, QEMU_OPTION_semihosting },
 #endif
     { "tdf", 0, QEMU_OPTION_tdf }, /* enable time drift fix */
-#if defined(__linux__)
-    { "no-rtc", 0, QEMU_OPTION_no_rtc },
-#endif
+    { "clock", HAS_ARG, QEMU_OPTION_clock },
     { "cpu-vendor", HAS_ARG, QEMU_OPTION_cpu_vendor },
     { NULL },
 };
@@ -7477,11 +7532,10 @@ int main(int argc, char **argv)
                 break;
             case QEMU_OPTION_tdf:
                 time_drift_fix = 1;
-#if defined(__linux__)
-	    case QEMU_OPTION_no_rtc:
-		use_rtc = 0;
 		break;
-#endif
+            case QEMU_OPTION_clock:
+                configure_alarms(optarg);
+                break;
 	    case QEMU_OPTION_cpu_vendor:
 		cpu_vendor_string = optarg;
 		break;
Signature · 8 lines
1.5.2.4


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

A message that is not in the archive (sent off-list or not yet received): 11872968773155-git-send-email-kronos.it-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#6 lore raw

PATCH 3/4 Add support for HPET periodic timer.

Linux operates the HPET timer in legacy replacement mode, which means that the periodic interrupt of the CMOS RTC is not delivered (qemu won't be able to use /dev/rtc). Add support for HPET (/dev/hpet) as a replacement for the RTC; the periodic interrupt is delivered via SIGIO and is handled in the same way as the RTC timer.

---
 qemu/vl.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 56 insertions(+), 1 deletions(-)
qemu/vl.c +56 -1
index f0b4896..0373beb 100644
@@ -54,6 +54,7 @@
 #include <pty.h>
 #include <malloc.h>
 #include <linux/rtc.h>
+#include <linux/hpet.h>
 #include <linux/ppdev.h>
 #endif
 #endif
@@ -773,6 +774,9 @@ static void unix_stop_timer(struct qemu_alarm_timer *t);
 
 #ifdef __linux__
 
+static int hpet_start_timer(struct qemu_alarm_timer *t);
+static void hpet_stop_timer(struct qemu_alarm_timer *t);
+
 static int rtc_start_timer(struct qemu_alarm_timer *t);
 static void rtc_stop_timer(struct qemu_alarm_timer *t);
 
@@ -782,7 +786,9 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t);
 
 static struct qemu_alarm_timer alarm_timers[] = {
 #ifdef __linux__
-    /* RTC - if available - is preferred */
+    /* HPET - if available - is preferred */
+    {"hpet", hpet_start_timer, hpet_stop_timer, NULL},
+    /* ...otherwise try RTC */
     {"rtc", rtc_start_timer, rtc_stop_timer, NULL},
 #endif
 #ifndef _WIN32
@@ -1117,6 +1123,55 @@ static void enable_sigio_timer(int fd)
     fcntl(fd, F_SETOWN, getpid());
 }
 
+static int hpet_start_timer(struct qemu_alarm_timer *t)
+{
+    struct hpet_info info;
+    int r, fd;
+
+    fd = open("/dev/hpet", O_RDONLY);
+    if (fd < 0)
+        return -1;
+
+    /* Set frequency */
+    r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
+    if (r < 0) {
+        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
+                "error, but for better emulation accuracy type:\n"
+                "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
+        goto fail;
+    }
+
+    /* Check capabilities */
+    r = ioctl(fd, HPET_INFO, &info);
+    if (r < 0)
+        goto fail;
+
+    /* Enable periodic mode */
+    r = ioctl(fd, HPET_EPI, 0);
+    if (info.hi_flags && (r < 0))
+        goto fail;
+
+    /* Enable interrupt */
+    r = ioctl(fd, HPET_IE_ON, 0);
+    if (r < 0)
+        goto fail;
+
+    enable_sigio_timer(fd);
+    t->priv = (void *)fd;
+
+    return 0;
+fail:
+    close(fd);
+    return -1;
+}
+
+static void hpet_stop_timer(struct qemu_alarm_timer *t)
+{
+    int fd = (int)t->priv;
+
+    close(fd);
+}
+
 static int rtc_start_timer(struct qemu_alarm_timer *t)
 {
     int rtc_fd;
Signature · 8 lines
1.5.2.4


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

A message that is not in the archive (sent off-list or not yet received): 11872968773524-git-send-email-kronos.it-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#8 lore raw

PATCH 4/4 Add support for dynamic ticks.

If DYNAMIC_TICKS is defined qemu does not attepmt to generate SIGALRM at a constant rate. Rather, the system timer is set to generate SIGALRM only when it is needed. DYNAMIC_TICKS reduces the number of SIGALRMs sent to idle dynamic-ticked guests.
Original patch from Dan Kenigsberg <dank-atKUWr5tajBWk0Htik3J/[email protected]>

---
 qemu/configure |    5 ++
 qemu/vl.c      |  149 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 148 insertions(+), 6 deletions(-)
qemu/configure +5 -0
index 365b7fb..38373db 100755
@@ -262,6 +262,8 @@ for opt do
   ;;
   --enable-uname-release=*) uname_release="$optarg"
   ;;
+  --disable-dynamic-ticks) dynamic_ticks="no"
+  ;;
   esac
 done
 
@@ -788,6 +790,9 @@ echo "TARGET_DIRS=$target_list" >> $config_mak
 if [ "$build_docs" = "yes" ] ; then
   echo "BUILD_DOCS=yes" >> $config_mak
 fi
+if test "$dynamic_ticks" != "no" ; then
+  echo "#define DYNAMIC_TICKS 1" >> $config_h
+fi
 
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
qemu/vl.c +143 -6

208 lines not on this page · raw message

Signature · 8 lines
1.5.2.4


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

A message that is not in the archive (sent off-list or not yet received): 1187296877557-git-send-email-kronos.it-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#10 lore raw

Re: [PATCH/RFC 4/4] Add support for dynamic ticks.

Quoted 7 lines

If DYNAMIC_TICKS is defined qemu does not attepmt to generate SIGALRM at a constant rate. Rather, the system timer is set to generate SIGALRM only when it is needed. DYNAMIC_TICKS reduces the number of SIGALRMs sent to idle dynamic-ticked guests.
Original patch from Dan Kenigsberg <dank-atKUWr5tajBWk0Htik3J/[email protected]>

Wow, this patch sure made a difference for some timings I've been doing with kvm-35 and hackbench. All tests using 2.6.23-rc3+hrtimers patch for x86_64/i386 tickless and a quad core intel:

[mkent@localhost ~]$ time ./hackbench 50
x86_64 host : real 0m10.845s
x86_64 host, bound to 1 cpu : real 0m21.884s

i386 guest+unix clock       : real 0m49.206s
i386 guest+hpet clock       : real 0m48.292s
i386 guest+dynticks clock   : real 0m28.835s

Results are repeatable and verfied with a stopwatch because I didn't believe them at first :)

Great stuff.

Signature · 9 lines
Matthew Kent <mkent-rTVjrLRGJfNWk0Htik3J/[email protected]>
http://magoazul.com


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

A message that is not in the archive (sent off-list or not yet received): 42755.207.81.93.54.1187334969.squirrel-N19E6/[email protected]

#12 lore raw

Re: [PATCH/RFC 4/4] Add support for dynamic ticks.

Quoted 16 lines · Matthew Kent
Quoted 8 lines

If DYNAMIC_TICKS is defined qemu does not attepmt to generate SIGALRM at a constant rate. Rather, the system timer is set to generate SIGALRM only when it is needed. DYNAMIC_TICKS reduces the number of SIGALRMs sent to idle dynamic-ticked guests.
Original patch from Dan Kenigsberg <[email protected]>

Wow, this patch sure made a difference for some timings I've been doing with kvm-35 and hackbench. All tests using 2.6.23-rc3+hrtimers patch for x86_64/i386 tickless and a quad core intel:

[mkent@localhost ~]$ time ./hackbench 50
x86_64 host : real 0m10.845s
x86_64 host, bound to 1 cpu : real 0m21.884s

Quoted 9 lines
i386 guest+unix clock       : real 0m49.206s
i386 guest+hpet clock       : real 0m48.292s
i386 guest+dynticks clock   : real 0m28.835s

Results are repeatable and verfied with a stopwatch because I didn't believe them at first :)

Great stuff.

I'm not sure what these results mean...

Signature · 1 line
error compiling committee.c: too many arguments to function
#13 lore raw
In reply to a message not in the archive
Quoted 6 lines · Luca Tettamanti

Hello,
in reply to this mail I will send a serie of 4 patches that cleans up and expands the alarm timer handling in QEMU. Patches apply to current kvm-userspace tree, but I think I can rebase it to QEMU svn if desired.

I would really like to see this go into qemu first (assuming the qemu maintainers want it). So far kvm changes are minor additions, but this is a fairly intrusive change. In addition, it benefits qemu as much as kvm.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/