From: Anders Melchiorsen <[EMAIL PROTECTED]> Without I/O signals, qemu is relying on periodic timer events to poll the I/O. That seems wrong, even though it works reasonably well because timers are so frequent. In KVM, timers are less frequent, and it does not work quite as well.
Here is a quick try at a more elaborate patch. It attaches a signal to all[1] file descriptors that will be used in select(). Also, it uses a dedicated SIGIO handler rather than piggybacking on the alarm handler, so alarm I/O is changed to use SIGALRM. I copied the handler function from the alarm case, quite frankly I do not quite understand what is going on. Also, I left _WIN32 out, since I have no idea how signals work there. [1] The slirp file descriptors are not included yet. Index: kvm-userspace.io/qemu/vl.c =================================================================== --- kvm-userspace.io.orig/qemu/vl.c +++ kvm-userspace.io/qemu/vl.c @@ -1177,6 +1177,25 @@ static int timer_load(QEMUFile *f, void return 0; } +#ifndef _WIN32 +static void host_io_handler(int host_signum) +{ + CPUState *env = next_cpu; + + if (env) { + /* stop the currently executing cpu because io occured */ + cpu_interrupt(env, CPU_INTERRUPT_EXIT); +#ifdef USE_KQEMU + if (env->kqemu_enabled) { + kqemu_cpu_interrupt(env); + } +#endif + } + + event_pending = 1; +} +#endif + #ifdef _WIN32 void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) @@ -1270,7 +1289,20 @@ static uint64_t qemu_next_deadline(void) #define RTC_FREQ 1024 -static void enable_sigio_timer(int fd) +static void enable_sigio(int fd) +{ + struct sigaction act; + + sigfillset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = host_io_handler; + + sigaction(SIGIO, &act, NULL); + fcntl(fd, F_SETFL, O_ASYNC); + fcntl(fd, F_SETOWN, getpid()); +} + +static void enable_sigalrm(int fd) { struct sigaction act; @@ -1279,8 +1311,9 @@ static void enable_sigio_timer(int fd) act.sa_flags = 0; act.sa_handler = host_alarm_handler; - sigaction(SIGIO, &act, NULL); + sigaction(SIGALRM, &act, NULL); fcntl(fd, F_SETFL, O_ASYNC); + fcntl(fd, F_SETSIG, SIGALRM); fcntl(fd, F_SETOWN, getpid()); } @@ -1317,7 +1350,7 @@ static int hpet_start_timer(struct qemu_ if (r < 0) goto fail; - enable_sigio_timer(fd); + enable_sigalrm(fd); t->priv = (void *)(long)fd; return 0; @@ -1355,7 +1388,7 @@ static int rtc_start_timer(struct qemu_a return -1; } - enable_sigio_timer(rtc_fd); + enable_sigalrm(rtc_fd); t->priv = (void *)(long)rtc_fd; @@ -4029,7 +4062,6 @@ static TAPState *net_tap_fd_init(VLANSta return NULL; s->fd = fd; s->no_poll = 0; - enable_sigio_timer(fd); s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s); qemu_set_fd_handler2(s->fd, tap_read_poll, tap_send, NULL, s); snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd); @@ -5661,6 +5693,10 @@ int qemu_set_fd_handler2(int fd, return -1; ioh->next = first_io_handler; first_io_handler = ioh; +#ifndef _WIN32 + enable_sigio(fd); +#endif + found: ioh->fd = fd; ioh->fd_read_poll = fd_read_poll; -- ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel