Re: [Qemu-devel] [RFC] QEMU Object Model

2011-07-21 Thread Luca Tettamanti
On Thu, Jul 21, 2011 at 4:49 PM, Anthony Liguori aligu...@us.ibm.com wrote:
[cut]
 And it's really not that much nicer than the C version.  The problem with
 C++ is that even though the type system is much, much nicer, it still
 doesn't have introspection or decorators.  These two things would be the
 killer feature for doing the sort of things we need to do and is really
 where most of the ugliness comes from.

QT has introspection; what about using the core (i.e. QObject and moc)
to build QEMU object model?

L



Re: [Qemu-devel] [RFC] qed: Add QEMU Enhanced Disk format

2010-09-06 Thread Luca Tettamanti
On Mon, Sep 6, 2010 at 12:25 PM, Alexander Graf ag...@suse.de wrote:
 On 06.09.2010, at 12:04, Stefan Hajnoczi wrote:
 +
 +const char *bytes_to_str(uint64_t size)
 +{
 +    static char buffer[64];
 +
 +    if (size  (1ULL  10)) {
 +        snprintf(buffer, sizeof(buffer), % PRIu64  byte(s), size);
 +    } else if (size  (1ULL  20)) {
 +        snprintf(buffer, sizeof(buffer), % PRIu64  KB(s), size  10);
 +    } else if (size  (1ULL  30)) {
 +        snprintf(buffer, sizeof(buffer), % PRIu64  MB(s), size  20);
 +    } else if (size  (1ULL  40)) {
 +        snprintf(buffer, sizeof(buffer), % PRIu64  GB(s), size  30);
 +    } else {
 +        snprintf(buffer, sizeof(buffer), % PRIu64  TB(s), size  40);
 +    }
 +
 +    return buffer;

 This returns a variable from the stack! Please make the target buffer caller 
 defined.

It's static, so it's formally correct. But probably not a good idea :)

Luca



Re: [Qemu-devel] [PATCH RFC] Advertise IDE physical block size as 4K

2009-12-29 Thread Luca Tettamanti
On Tue, Dec 29, 2009 at 2:21 PM, Jamie Lokier ja...@shareable.org wrote:
 Avi Kivity wrote:
 Guests use this number as a hint for alignment and I/O request sizes.

 It's not just a hint.  It is also the radius of corruption on failed
 write - important for journalling filesystems and databases.

 Given
 that modern disks have 4K block sizes,

 Do they, yet?

Yes, there are WD disks in the wild with 4k blocks, although in this
first transition phase the firmware hides the fact and emulates the
old 512b sector.

 We probably need to make this configurable depending on machine type.  It
 should be the default for -M 0.13 only as it can affect guest code paths.

 What about that Windows/Linux 4k sectors incompatibility thing, where
 disks with 4k sectors have to sense whether the first partition starts
 at 512-byte sector 63 (Linux) or 512-byte sector 1024 (or something;
 Windows), and then adjust their 512-byte sector to 4k-sector mapping
 so that 4k blocks within the partition are aligned to 4k sectors?

Linux tools put the first partition at sector 63 (512-byte) to retain
compatibility with Windows; Linux itself does not have any problem
with different layouts. See e.g. [1]
The problem seems to be limited to Win 5.x (XP, 2k3) and WD has an
utility[2] to re-align partitions in this case, so I guess that they
do cope fine with a 4k-aligned partition table, they just create it
unaligned by default.

 It has been discussed for hardware disk design with 4k sectors, and
 somehow there were plans to map sectors so that the Linux partition
 scheme results in nicely aligned filesystem blocks

Ugh, I hope you're wrong ;-) AFAICS remapping will lead only to
headaches... Linux does not have any problem with aligned partitions.

Luca
[1] 
http://thunk.org/tytso/blog/2009/02/20/aligning-filesystems-to-an-ssds-erase-block-size/
[2] http://support.wdc.com/product/download.asp?groupid=805sid=123lang=en




Re: [Qemu-devel] Build failure on OS X - dynticks

2007-08-31 Thread Luca Tettamanti
Andreas Färber ha scritto:
 Am 25.08.2007 um 09:37 schrieb Andreas F=E4rber:

 One of the recent patches (dynticks) has broken compilation on Mac
 OS X v10.4. Should this work on OS X or should this have been
 limited to Linux?

 Getting no answer on this I have prepared a quickfix which wraps all
 dynticks in conditional sections for __linux__, restoring compilation
 on OS X.
 If this is the right way to fix then the conditional sections can be
 merged with HPET, which is already limited to __linux__.

Sorry for the late reply, I totaly missed you mail. The timers I've used
are POSIX and are supported on *BSD so I guessed they would work on OSX
too... cleary that's not the case.
Can you grep the headers for timer_create? Maybe the prototypes are in a
different file.

Luca
-- 
Non sempre quello che viene dopo e` progresso.
Alessandro Manzoni




[Qemu-devel] Re: [kvm-devel] [PATCH 0/4] Rework alarm timer infrastrucure - take2

2007-08-22 Thread Luca Tettamanti
Il Wed, Aug 22, 2007 at 08:02:07AM +0300, Avi Kivity ha scritto: 
 Luca Tettamanti wrote:
 
  Actually I'm having troubles with cyclesoak (probably it's calibration),
  numbers are not very stable across multiple runs...

 
 I've had good results with cyclesoak; maybe you need to run it in
 runlevel 3 so the load generated by moving the mouse or breathing
 doesn't affect meaurements.

This is what I did, I tested with -no-grapich in text console.

  The guest is an idle kernel with HZ=1000.

 
 Can you double check this?  The dyntick results show that this is either
 a 100Hz kernel, or that there is a serious bug in dynticks.

Ops I sent the wrong files, sorry.

This is QEMU, with dynticks and HPET:

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 52.100.002966   0 96840   clock_gettime
 19.500.001110   0 37050   timer_gettime
 10.660.000607   0 20086   timer_settime
 10.400.000592   0  8985  2539 sigreturn
  4.940.000281   0  8361  2485 select
  2.410.000137   0  8362   gettimeofday
-- --- --- - - 
100.000.005693179684  5024 total

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 93.370.025541   3 10194 10193 select
  4.820.001319   0 33259   clock_gettime
  1.100.000301   0 10195   gettimeofday
  0.710.000195   0 10196 10194 sigreturn
-- --- --- - - 
100.000.027356 63844 20387 total

And this KVM:

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 42.660.002885   0 4552724 ioctl
 25.620.001733   0 89305   clock_gettime
 13.120.000887   0 34894   timer_gettime
  7.970.000539   0 18016   timer_settime
  4.700.000318   0 12224  7270 rt_sigtimedwait
  2.790.000189   0  7271   select
  1.860.000126   0  7271   gettimeofday
  1.270.86   0  4954   rt_sigaction
-- --- --- - - 
100.000.006763219462  7294 total

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 49.410.004606   0 5990027 ioctl
 24.140.002250   0 31252 21082 rt_sigtimedwait
  9.650.000900   0 51856   clock_gettime
  8.440.000787   0 17819   select
  4.420.000412   0 17819   gettimeofday
  3.940.000367   0 10170   rt_sigaction
-- --- --- - - 
100.000.009322188816 21109 total


Luca
-- 
Runtime error 6D at f000:a12f : user incompetente




[Qemu-devel] Re: [kvm-devel] [PATCH 0/4] Rework alarm timer infrastrucure - take2

2007-08-21 Thread Luca Tettamanti
Avi Kivity ha scritto: 
 Luca Tettamanti wrote:
 At 1000Hz:

 QEMU
 hpet5.5%
 dynticks   11.7%

 KVM
 hpet3.4%
 dynticks7.3%

 No surprises here, you can see the additional 1k syscalls per second. 

 This is very surprising to me.  The 6.2% difference for the qemu case 
 translates to 62ms per second, or 62us per tick at 1000Hz.  That's more 
 than a hundred simple syscalls on modern processors.  We shouldn't have to 
 issue a hundred syscalls per guest clock tick.

APIC or PIT interrupts are delivered using the timer, which will be
re-armed after each tick, so I'd expect 1k timer_settime per second. But
according to strace it's not happening, maybe I'm misreading the code?

 The difference with kvm is smaller (just 3.9%), which is not easily 
 explained as the time for the extra syscalls should be about the same.  My 
 guess is that guest behavior is different; with dynticks the guest does 
 about twice as much work as with hpet.

Actually I'm having troubles with cyclesoak (probably it's calibration),
numbers are not very stable across multiple runs...

I've also tried APC which was suggested by malc[1] and:
- readings are far more stable
- the gap between dynticks and non-dynticks seems not significant

 Can you verify this by running

strace -c -p `pgrep qemu`  sleep 10; pkill strace

 for all 4 cases, and posting the results?

Plain QEMU:

With dynticks:

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 57.970.000469   0 13795   clock_gettime
 32.880.000266   0  1350   gettimeofday
  7.420.60   0  1423  1072 sigreturn
  1.730.14   0  5049   timer_gettime
  0.000.00   0  1683  1072 select
  0.000.00   0  2978   timer_settime
-- --- --- - - 
100.000.000809 26278  2144 total

HPET:

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 87.480.010459   1 10381 10050 select
  8.450.001010   0 40736   clock_gettime
  2.730.000326   0 10049   gettimeofday
  1.350.000161   0 10086 10064 sigreturn
-- --- --- - - 
100.000.011956 71252 20114 total

Unix (SIGALRM):

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 90.360.011663   1 10291  9959 select
  7.380.000953   0 40355   clock_gettime
  2.050.000264   0  9960   gettimeofday
  0.210.27   0  9985  9969 sigreturn
-- --- --- - - 
100.000.012907 70591 19928 total

And KVM:

dynticks:

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 78.900.004001   1  6681  5088 rt_sigtimedwait
 10.870.000551   0 27901   clock_gettime
  4.930.000250   0  7622   timer_settime
  4.300.000218   0 10078   timer_gettime
  0.390.20   0  3863   gettimeofday
  0.350.18   0  6054   ioctl
  0.260.13   0  4196   select
  0.000.00   0  1593   rt_sigaction
-- --- --- - - 
100.000.005071 67988  5088 total

HPET:

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 90.200.011029   0 32437 22244 rt_sigtimedwait
  4.460.000545   0 44164   clock_gettime
  2.590.000317   0 12128   gettimeofday
  1.500.000184   0 10193   rt_sigaction
  1.100.000134   0 12461   select
  0.150.18   0  6060   ioctl
-- --- --- - - 
100.000.012227117443 22244 total

Unix:

% time seconds  usecs/call callserrors syscall
-- --- --- - - 
 83.290.012522   0 31652 21709 rt_sigtimedwait
  6.910.001039   0 43125   clock_gettime
  3.500.000526   0  6042   ioctl
  2.740.000412   0  9943   rt_sigaction
  1.980.000298   0 12183   select
  1.580.000238   0 11850

[Qemu-devel] Re: [kvm-devel] [PATCH 0/4] Rework alarm timer infrastrucure - take2

2007-08-20 Thread Luca Tettamanti
Il Sun, Aug 19, 2007 at 10:31:26PM +0300, Avi Kivity ha scritto: 
 Luca wrote:
  On 8/19/07, Luca Tettamanti [EMAIL PROTECTED] wrote:

  +static uint64_t qemu_next_deadline(void) {
  +uint64_t nearest_delta_us = ULLONG_MAX;
  +uint64_t vmdelta_us;
  
 
  Hum, I introduced a bug here... those vars should be signed.
 
  On the overhead introduced: how do you measure it?
 

 
 Run a 100Hz guest, measure cpu usage using something accurate like
 cyclesoak, with and without dynticks, with and without kvm.

Ok, here I've measured the CPU usage on the host when running an idle
guest.

At 100Hz

QEMU
hpet4.8%
dynticks5.1%

Note: I've taken the mean over a period of 20 secs, but the difference
between hpet and dynticks is well inside the variability of the test.

KVM
hpet2.2%
dynticks1.0%

Hum... here the numbers jumps a bit, but dynticks is always below hpet.

At 1000Hz:

QEMU
hpet5.5%
dynticks   11.7%

KVM
hpet3.4%
dynticks7.3%

No surprises here, you can see the additional 1k syscalls per second. On
the bright side, keep in mind that with a tickless guest and dynticks
I've seen as little as 50-60 timer ticks per second.

Hackbench (hackbench -pipe 50) inside the guest:

QEMU: impossible to measure, the variance of the results is much bigger
than difference between dynticks and hpet.

KVM: 
Around 0.8s slower in case on dynticks; variance of the results is
about 0.3s in both cases.

Luca
-- 
Chi parla in tono cortese, ma continua a prepararsi, potra` andare avanti;
 chi parla in tono bellicoso e avanza rapidamente dovra` ritirarsi 
Sun Tzu -- L'arte della guerra




[Qemu-devel] [PATCH 1/4] Rework alarm timer infrastrucure.

2007-08-17 Thread Luca Tettamanti
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.

Signed-off-by: Luca Tettamanti [EMAIL PROTECTED]

---
 vl.c |  287 +++
 vl.h |1 
 2 files changed, 185 insertions(+), 103 deletions(-)

Index: qemu/vl.c
===
--- qemu.orig/vl.c  2007-08-17 16:48:32.0 +0200
+++ qemu/vl.c   2007-08-18 00:40:25.0 +0200
@@ -781,18 +781,58 @@
 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)
 {
@@ -1009,7 +1049,8 @@
 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) {
@@ -1030,10 +1071,27 @@
 
 #define RTC_FREQ 1024
 
-static int rtc_fd;
+static void enable_sigio_timer(int fd)
+{
+struct sigaction act;
 
-static int start_rtc_timer(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(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;
+
 TFR(rtc_fd = open(/dev/rtc, O_RDONLY));
 if (rtc_fd  0)
 return -1;
@@ -1048,117 +1106,142 @@
 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;
+
+/* 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;
 
-static void init_timer_alarm(void)
+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

[Qemu-devel] [PATCH 0/4] Rework alarm timer infrastrucure - take 2

2007-08-17 Thread 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 have been rebased on QEMU
CVS.

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.

Luca
-- 




[Qemu-devel] [PATCH 3/4] Add support for HPET periodic timer.

2007-08-17 Thread Luca Tettamanti
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.

Signed-off-by: Luca Tettamanti [EMAIL PROTECTED]

---
 vl.c |   57 -
 1 file changed, 56 insertions(+), 1 deletion(-)

Index: qemu/vl.c
===
--- qemu.orig/vl.c  2007-08-17 17:39:21.0 +0200
+++ qemu/vl.c   2007-08-18 00:40:16.0 +0200
@@ -56,6 +56,7 @@
 #include pty.h
 #include malloc.h
 #include linux/rtc.h
+#include linux/hpet.h
 #include linux/ppdev.h
 #include linux/parport.h
 #else
@@ -809,6 +810,9 @@
 
 #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);
 
@@ -818,7 +822,9 @@
 
 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
@@ -1153,6 +1159,55 @@
 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;

-- 




[Qemu-devel] [PATCH 4/4] Add support for dynamic ticks.

2007-08-17 Thread Luca Tettamanti
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]

Signed-off-by: Luca Tettamanti [EMAIL PROTECTED]

---
 configure |5 ++
 vl.c  |  149 +++---
 2 files changed, 148 insertions(+), 6 deletions(-)

Index: qemu/vl.c
===
--- qemu.orig/vl.c  2007-08-17 17:45:00.0 +0200
+++ qemu/vl.c   2007-08-18 00:38:03.0 +0200
@@ -784,12 +784,42 @@
 
 struct qemu_alarm_timer {
 char const *name;
+unsigned int flags;
 
 int (*start)(struct qemu_alarm_timer *t);
 void (*stop)(struct qemu_alarm_timer *t);
+void (*rearm)(struct qemu_alarm_timer *t);
 void *priv;
 };
 
+#define ALARM_FLAG_DYNTICKS  0x1
+
+#ifdef DYNAMIC_TICKS
+
+static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
+{
+return t-flags  ALARM_FLAG_DYNTICKS;
+}
+
+static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) {
+if (!alarm_has_dynticks(t))
+return;
+
+t-rearm(t);
+}
+
+#else /* DYNAMIC_TICKS */
+
+static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
+{
+return 0;
+}
+
+static void qemu_rearm_alarm_timer(void) {
+}
+
+#endif /* DYNAMIC_TICKS */
+
 static struct qemu_alarm_timer *alarm_timer;
 
 #ifdef _WIN32
@@ -808,6 +838,14 @@
 static int unix_start_timer(struct qemu_alarm_timer *t);
 static void unix_stop_timer(struct qemu_alarm_timer *t);
 
+#ifdef DYNAMIC_TICKS
+
+static int dynticks_start_timer(struct qemu_alarm_timer *t);
+static void dynticks_stop_timer(struct qemu_alarm_timer *t);
+static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
+
+#endif
+
 #ifdef __linux__
 
 static int hpet_start_timer(struct qemu_alarm_timer *t);
@@ -821,16 +859,19 @@
 #endif /* _WIN32 */
 
 static struct qemu_alarm_timer alarm_timers[] = {
+#ifndef _WIN32
+#ifdef DYNAMIC_TICKS
+{dynticks, ALARM_FLAG_DYNTICKS, dynticks_start_timer, 
dynticks_stop_timer, dynticks_rearm_timer, NULL},
+#endif
 #ifdef __linux__
 /* HPET - if available - is preferred */
-{hpet, hpet_start_timer, hpet_stop_timer, NULL},
+{hpet, 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
 /* ...otherwise try RTC */
-{rtc, rtc_start_timer, rtc_stop_timer, NULL},
+{rtc, 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
 #endif
-#ifndef _WIN32
-{unix, unix_start_timer, unix_stop_timer, NULL},
+{unix, 0, unix_start_timer, unix_stop_timer, NULL, NULL},
 #else
-{win32, win32_start_timer, win32_stop_timer, alarm_win32_data},
+{win32, 0, win32_start_timer, win32_stop_timer, NULL, alarm_win32_data},
 #endif
 {NULL, }
 };
@@ -949,6 +990,8 @@
 }
 pt = t-next;
 }
+
+qemu_rearm_alarm_timer(alarm_timer);
 }
 
 /* modify the current timer so that it will be fired when current_time
@@ -1008,6 +1051,7 @@
 /* run the callback (the timer list can be modified) */
 ts-cb(ts-opaque);
 }
+qemu_rearm_alarm_timer(alarm_timer);
 }
 
 int64_t qemu_get_clock(QEMUClock *clock)
@@ -1115,7 +1159,8 @@
 last_clock = ti;
 }
 #endif
-if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
+if (alarm_has_dynticks(alarm_timer) ||
+qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
qemu_get_clock(vm_clock)) ||
 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
qemu_get_clock(rt_clock))) {
@@ -1243,6 +1288,97 @@
 
 #endif /* !defined(__linux__) */
 
+#ifdef DYNAMIC_TICKS
+static int dynticks_start_timer(struct qemu_alarm_timer *t)
+{
+struct sigevent ev;
+timer_t host_timer;
+struct sigaction act;
+
+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);
+
+ev.sigev_value.sival_int = 0;
+ev.sigev_notify = SIGEV_SIGNAL;
+ev.sigev_signo = SIGALRM;
+
+if (timer_create(CLOCK_REALTIME, ev, host_timer)) {
+perror(timer_create);
+
+/* disable dynticks */
+fprintf(stderr, Dynamic Ticks disabled\n);
+
+return -1;
+}
+
+t-priv = (void *)host_timer;
+
+return 0;
+}
+
+static void dynticks_stop_timer(struct qemu_alarm_timer *t)
+{
+timer_t host_timer = (timer_t)t-priv;
+
+timer_delete(host_timer);
+}
+
+static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
+{
+timer_t host_timer = (timer_t)t-priv;
+struct itimerspec timeout;
+int64_t nearest_delta_us = INT64_MAX;
+
+if (active_timers[QEMU_TIMER_REALTIME] ||
+active_timers[QEMU_TIMER_VIRTUAL]) {
+int64_t vmdelta_us, current_us

[Qemu-devel] [PATCH 2/4] Add -clock option.

2007-08-17 Thread Luca Tettamanti
Allow user to override the list of available alarm timers and their
priority. The format of the options is -clock clk1,clk2,...

Signed-off-by: Luca Tettamanti [EMAIL PROTECTED]

---
 vl.c |   72 +++
 1 file changed, 72 insertions(+)

Index: qemu/vl.c
===
--- qemu.orig/vl.c  2007-08-17 17:31:09.0 +0200
+++ qemu/vl.c   2007-08-18 00:40:22.0 +0200
@@ -829,6 +829,71 @@
 {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;
 
@@ -6791,6 +6856,8 @@
 #ifdef TARGET_SPARC
-prom-env variable=value  set OpenBIOS nvram variables\n
 #endif
+   -clock  force the use of the given methods for timer 
alarm.\n
+   To see what timers are available use -clock help\n
\n
During emulation, the following keys are useful:\n
ctrl-alt-f  toggle full screen\n
@@ -6888,6 +6955,7 @@
 QEMU_OPTION_name,
 QEMU_OPTION_prom_env,
 QEMU_OPTION_old_param,
+QEMU_OPTION_clock,
 };
 
 typedef struct QEMUOption {
@@ -6992,6 +7060,7 @@
 #if defined(TARGET_ARM)
 { old-param, 0, QEMU_OPTION_old_param },
 #endif
+{ clock, HAS_ARG, QEMU_OPTION_clock },
 { NULL },
 };
 
@@ -7771,6 +7840,9 @@
 case QEMU_OPTION_old_param:
 old_param = 1;
 #endif
+case QEMU_OPTION_clock:
+configure_alarms(optarg);
+break;
 }
 }
 }

-- 




[Qemu-devel] [PATCH/RFC 2/4] Add -clock option.

2007-08-16 Thread Luca Tettamanti
Allow user to override the list of available alarm timers and their
priority. The format of the options is -clock clk1,clk2,...

Signed-off-by: Luca Tettamanti [EMAIL PROTECTED]
---
 qemu/vl.c |   90 --
 1 files changed, 72 insertions(+), 18 deletions(-)

diff --git a/qemu/vl.c b/qemu/vl.c
index 33443ca..f0b4896 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -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
-tdfinject 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;
-- 
1.5.2.4





[Qemu-devel] [PATCH/RFC 0/4] Rework alarm timer infrastrucure.

2007-08-16 Thread 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.

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.




[Qemu-devel] [PATCH/RFC 1/4] Rework alarm timer infrastrucure.

2007-08-16 Thread Luca Tettamanti
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.

Signed-off-by: Luca Tettamanti [EMAIL PROTECTED]
---
 qemu/vl.c |  292 +--
 1 files changed, 189 insertions(+), 103 deletions(-)

diff --git a/qemu/vl.c b/qemu/vl.c
index 5360ed7..33443ca 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -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

[Qemu-devel] [PATCH/RFC 4/4] Add support for dynamic ticks.

2007-08-16 Thread Luca Tettamanti
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]

Signed-off-by: Luca Tettamanti [EMAIL PROTECTED]
---
 qemu/configure |5 ++
 qemu/vl.c  |  149 --
 2 files changed, 148 insertions(+), 6 deletions(-)

diff --git a/qemu/configure b/qemu/configure
index 365b7fb..38373db 100755
--- a/qemu/configure
+++ b/qemu/configure
@@ -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
diff --git a/qemu/vl.c b/qemu/vl.c
index 0373beb..096729d 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -748,12 +748,42 @@ struct QEMUTimer {
 
 struct qemu_alarm_timer {
 char const *name;
+unsigned int flags;
 
 int (*start)(struct qemu_alarm_timer *t);
 void (*stop)(struct qemu_alarm_timer *t);
+void (*rearm)(struct qemu_alarm_timer *t);
 void *priv;
 };
 
+#define ALARM_FLAG_DYNTICKS  0x1
+
+#ifdef DYNAMIC_TICKS
+
+static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
+{
+return t-flags  ALARM_FLAG_DYNTICKS;
+}
+
+static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) {
+if (!alarm_has_dynticks(t))
+return;
+
+t-rearm(t);
+}
+
+#else /* DYNAMIC_TICKS */
+
+static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
+{
+return 0;
+}
+
+static void qemu_rearm_alarm_timer(void) {
+}
+
+#endif /* DYNAMIC_TICKS */
+
 static struct qemu_alarm_timer *alarm_timer;
 
 #ifdef _WIN32
@@ -772,6 +802,14 @@ static void win32_stop_timer(struct qemu_alarm_timer *t);
 static int unix_start_timer(struct qemu_alarm_timer *t);
 static void unix_stop_timer(struct qemu_alarm_timer *t);
 
+#ifdef DYNAMIC_TICKS
+
+static int dynticks_start_timer(struct qemu_alarm_timer *t);
+static void dynticks_stop_timer(struct qemu_alarm_timer *t);
+static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
+
+#endif
+
 #ifdef __linux__
 
 static int hpet_start_timer(struct qemu_alarm_timer *t);
@@ -785,16 +823,19 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t);
 #endif /* _WIN32 */
 
 static struct qemu_alarm_timer alarm_timers[] = {
+#ifndef _WIN32
+#ifdef DYNAMIC_TICKS
+{dynticks, ALARM_FLAG_DYNTICKS, dynticks_start_timer, 
dynticks_stop_timer, dynticks_rearm_timer, NULL},
+#endif
 #ifdef __linux__
 /* HPET - if available - is preferred */
-{hpet, hpet_start_timer, hpet_stop_timer, NULL},
+{hpet, 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
 /* ...otherwise try RTC */
-{rtc, rtc_start_timer, rtc_stop_timer, NULL},
+{rtc, 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
 #endif
-#ifndef _WIN32
-{unix, unix_start_timer, unix_stop_timer, NULL},
+{unix, 0, unix_start_timer, unix_stop_timer, NULL, NULL},
 #else
-{win32, win32_start_timer, win32_stop_timer, alarm_win32_data},
+{win32, 0, win32_start_timer, win32_stop_timer, NULL, alarm_win32_data},
 #endif
 {NULL, }
 };
@@ -913,6 +954,8 @@ void qemu_del_timer(QEMUTimer *ts)
 }
 pt = t-next;
 }
+
+qemu_rearm_alarm_timer(alarm_timer);
 }
 
 /* modify the current timer so that it will be fired when current_time
@@ -972,6 +1015,7 @@ static void qemu_run_timers(QEMUTimer **ptimer_head, 
int64_t current_time)
 /* run the callback (the timer list can be modified) */
 ts-cb(ts-opaque);
 }
+qemu_rearm_alarm_timer(alarm_timer);
 }
 
 int64_t qemu_get_clock(QEMUClock *clock)
@@ -1079,7 +1123,8 @@ static void host_alarm_handler(int host_signum)
 last_clock = ti;
 }
 #endif
-if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
+if (alarm_has_dynticks(alarm_timer) ||
+qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
qemu_get_clock(vm_clock)) ||
 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
qemu_get_clock(rt_clock))) {
@@ -1207,6 +1252,97 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t)
 
 #endif /* !defined(__linux__) */
 
+#ifdef DYNAMIC_TICKS
+static int dynticks_start_timer(struct qemu_alarm_timer *t)
+{
+struct sigevent ev;
+timer_t host_timer;
+struct sigaction act;
+
+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);
+
+ev.sigev_value.sival_int = 0;
+ev.sigev_notify = SIGEV_SIGNAL

[Qemu-devel] [PATCH/RFC 3/4] Add support for HPET periodic timer.

2007-08-16 Thread Luca Tettamanti
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.

Signed-off-by: Luca Tettamanti [EMAIL PROTECTED]
---
 qemu/vl.c |   57 ++-
 1 files changed, 56 insertions(+), 1 deletions(-)

diff --git a/qemu/vl.c b/qemu/vl.c
index f0b4896..0373beb 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -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;
-- 
1.5.2.4





[Qemu-devel] Re: [kvm-devel] [PATCH] Dynamic ticks

2007-08-13 Thread Luca Tettamanti
Il Mon, Aug 13, 2007 at 05:42:55PM +0300, Dan Kenigsberg ha scritto: 
 Dynamic ticks in Qemu: have a SIGALRM generated only when it is
 needed, instead of every 1 millisecond. This patch requires that the
 host supports high resolution timers, since it arms a POSIX timer to the
 nearest Qemu timer's expiry time (which might be rather near).
 
 I tried to send a previous version of this patch yesterday, but luckily
 it seems to have been eaten by qemu-devel list. I'd be happy to hear
 your comments about it.

I like it ;) I have some comments (and a reworked patch at the end):

 Index: vl.c
 ===
 RCS file: /sources/qemu/qemu/vl.c,v
 retrieving revision 1.323
 diff -u -r1.323 vl.c
 --- vl.c  29 Jul 2007 17:57:25 -  1.323
 +++ vl.c  13 Aug 2007 14:18:19 -
 @@ -793,6 +793,15 @@
  /* frequency of the times() clock tick */
  static int timer_freq;
  #endif
 +#ifdef DYNAMIC_TICKS
 +/* If DYNAMIC_TICKS is defined (and use_dynamic_ticks selected) 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. */
 +static timer_t host_timer;
 +static void rearm_host_timer(void);
 +static int use_dynamic_ticks = 1;
 +#endif

I'd make use_dynamic_ticks a static inline helper, in this way gcc will
still optimize it away when not need and you can remove a lot of #ifdefs
from the code.

  
  QEMUClock *qemu_new_clock(int type)
  {
 @@ -838,6 +847,10 @@
  }
  pt = t-next;
  }
 +#ifdef DYNAMIC_TICKS
 +if (use_dynamic_ticks)
 +rearm_host_timer();
 +#endif

Like here

  }
  
  /* modify the current timer so that it will be fired when current_time
 @@ -897,6 +910,7 @@
  /* run the callback (the timer list can be modified) */
  ts-cb(ts-opaque);
  }
 +rearm_host_timer();
  }
  
  int64_t qemu_get_clock(QEMUClock *clock)
 @@ -1004,7 +1018,12 @@
  last_clock = ti;
  }
  #endif
 -if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
 +
 +if (
 +#ifdef DYNAMIC_TICKS
 +use_dynamic_ticks ||
 +#endif
 +qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
 qemu_get_clock(vm_clock)) ||
  qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
 qemu_get_clock(rt_clock))) {

and here (this one is pretty ugly btw)

 @@ -1109,21 +1128,37 @@
  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);
 +#ifdef DYNAMIC_TICKS
 +if (use_dynamic_ticks) {
 +struct sigevent ev;
 +ev.sigev_value.sival_int = 0;
 +ev.sigev_notify = SIGEV_SIGNAL;
 +ev.sigev_signo = SIGALRM;
 +if (timer_create(CLOCK_REALTIME, ev, host_timer))
 +perror(timer_create);

Should this fail you end up with a non-working QEMU. It's pretty easy to
recover though, running this code:

 +} else
 +#endif /* DYNAMIC_TICKS */
 +{
 +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);
 +}
  
  #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) {
 +if (
 +#ifdef DYNAMIC_TICKS
 +!use_dynamic_ticks 

helper ;)

 +#endif
 +(itv.it_interval.tv_usec  1000 || 1)) {

Plus, in this way you change the behaviour from always try RTC under
Linux to don't use RTC is dynticks is enabled.
Is this what you really want?

Furthermore: I'm not sure about the cost of reprogramming the CMOS RTC,
but with HPET should be feasible to program the timer in one-shot
mode.

  /* try to use /dev/rtc to have a faster timer */
  if (start_rtc_timer()  0)
  goto use_itimer;
 @@ -6287,6 +6322,10 @@
  

[Qemu-devel] PIIX/IDE: ports disabled in PCI config space?

2007-06-04 Thread Luca Tettamanti
Hello,
I'm testing the new Fedora7 under KVM. As you may know Fedora has
migrated to the new libata drivers.

ata_piix is unhappy with the PIIX IDE controller provided by QEmu/KVM:

libata version 2.20 loaded.
ata_piix :00:01.1: version 2.10ac1
PCI: Setting latency timer of device :00:01.1 to 64
ata1: PATA max MWDMA2 cmd 0x000101f0 ctl 0x000103f6 bmdma 0x00011400 irq 14
ata2: PATA max MWDMA2 cmd 0x00010170 ctl 0x00010376 bmdma 0x00011408 irq 15
scsi0 : ata_piix
ata1: port disabled. ignoring.
scsi1 : ata_piix
ata2: port disabled. ignoring.

The port disabled messages are generated by piix_pata_prereset
(called by piix_pata_error_handler), see drivers/ata/ata-piix.c.
piix_pata_prereset checks PCI config space to see whether the port is
active or not:

static int piix_pata_prereset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap-host-dev);

if (!pci_test_config_bits(pdev, piix_enable_bits[ap-port_no]))
return -ENOENT;

return ata_std_prereset(ap, deadline);
}

with:

static struct pci_bits piix_enable_bits[] = {
{ 0x41U, 1U, 0x80UL, 0x80UL },  /* port 0 */
{ 0x43U, 1U, 0x80UL, 0x80UL },  /* port 1 */
};

which means that it will read 1 byte at offset 0x41 (or 0x43), mask it
with 0x80 and the result shall be 0x80 (i.e. it checks bit 7).

Bit 7 in Intel docs is described in this way:

IDE Decode Enable (IDE). 1=Enable; 0=Disable. When enabled, I/O
 transactions on PCI targeting the IDE ATA register blocks (command block
 and control block) are positively decoded on PCI and driven on the IDE
 interface. When disabled, these accesses are subtractively decoded to
 ISA.

Now this is config space of the IDE controller:

00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II] 
(prog-if 80 [Master])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- 
Stepping- SERR- FastB2B-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium TAbort- 
TAbort- MAbort- SERR- PERR-
Latency: 64
Region 0: [virtual] Memory at 01f0 (32-bit, non-prefetchable) 
[size=8]
Region 1: [virtual] Memory at 03f0 (type 3, non-prefetchable) 
[size=1]
Region 2: [virtual] Memory at 0170 (32-bit, non-prefetchable) 
[size=8]
Region 3: [virtual] Memory at 0370 (type 3, non-prefetchable) 
[size=1]
Region 4: I/O ports at 1400 [size=16]
00: 86 80 10 70 07 00 80 02 00 80 01 01 00 40 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 01 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   ^^^^
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

As you can see those 2 bytes are 0, and the libata driver considers them
disabled (the legacy driver works fine).

The following patch fixes the problem (i.e. ata_piix finds both the HD
and the cdrom):

--- a/hw/ide.c  2007-06-04 19:34:25.0 +0200
+++ b/hw/ide.c  2007-06-04 21:45:28.0 +0200
@@ -2586,6 +2586,8 @@ static void piix3_reset(PCIIDEState *d)
 pci_conf[0x06] = 0x80; /* FBC */
 pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
 pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
+pci_conf[0x41] = 0x80; // enable port 0
+pci_conf[0x43] = 0x80; // enable port 1
 }
 
 void pci_piix_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)


It has been run-time tested with KVM-27. Applies cleanly to qemu 0.9 and
with offset to qemu-snapshot (I've not tested it though).

Luca
-- 
This message will self destruct in 5 seconds.