From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=45965 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q8VzG-00028X-Se for qemu-devel@nongnu.org; Sat, 09 Apr 2011 07:05:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q8VzF-0005LI-An for qemu-devel@nongnu.org; Sat, 09 Apr 2011 07:05:54 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:39944) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q8VzE-0005Ks-Rf for qemu-devel@nongnu.org; Sat, 09 Apr 2011 07:05:53 -0400 Date: Sat, 9 Apr 2011 20:05:49 +0900 From: Isaku Yamahata Message-ID: <20110409110549.GA23309@valinux.co.jp> References: <20110403195314.GB23034@volta.aurel32.net> <20110403234207.GD11748@valinux.co.jp> <20110404021511.GF11748@valinux.co.jp> <4DA01AF2.3040309@web.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4DA01AF2.3040309@web.de> Subject: [Qemu-devel] Re: [PATCH] ioapic: when switches to level trigger mode, interrupts raised repeatedly. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Jan Kiszka Cc: qemu-devel@nongnu.org, Aurelien Jarno On Sat, Apr 09, 2011 at 10:38:10AM +0200, Jan Kiszka wrote: > On 2011-04-04 04:15, Isaku Yamahata wrote: > > On Mon, Apr 04, 2011 at 08:42:07AM +0900, Isaku Yamahata wrote: > >> > Thank you for applying. But I found that the patch is wrong and > >> > I'm preparing the new one. Can you please revert it? > > Here is the corrected patch. The first wrong patch clears the interrupts > > bit unconditionally. Which caused losing interrupt. > > > > From 5ed177d35ab14f3b070a0eba2c49400279a3a14b Mon Sep 17 00:00:00 2001 > > Message-Id: <5ed177d35ab14f3b070a0eba2c49400279a3a14b.1301883258.git.yamahata@valinux.co.jp> > > In-Reply-To: > > References: > > From: Isaku Yamahata > > Date: Wed, 16 Mar 2011 14:00:13 +0900 > > Subject: [PATCH 01/30] ioapic: when switches to level trigger mode, interrupts raised repeatedly. > > > > - the trigger mode is edge at first by reset. > > - During initializatoin, the interrupt is raised as edge which is masked. > > The corresponding bit of irr is set. > > ...and that is the actual problem. The spec says: "Interrupt Mask?R/W. > When this bit is 1, the interrupt signal is masked. Edge-sensitive > interrupts signaled on a masked interrupt pin are ignored (i.e., not > delivered or held pending)." > > So this should do the trick in a correct way (untested, please > validate): Thank you for referring the spec. It works. Here's the updated patch with your signed-off-by and my tested-by. >>From a6c92855357a24da6a0d8d6e76dcca735a4be885 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Isaku Yamahata Date: Wed, 16 Mar 2011 14:00:13 +0900 Subject: [PATCH] ioapic: when switches to level trigger mode, interrupts raised repeatedly. - the trigger mode is edge at first by reset. - During initializatoin, the interrupt is raised as edge which is masked. The corresponding bit of irr is set. the bit must not be set when masked - Then the mode is switched to level and it's unmasked with the same write. - the bit of irr is set, so the interrupt is raised repeatedly by ioapic_service(). - OS considers that the irq line is broken and falls back to polling mode. >>From the specification, the masked edge triggered interrupt must be ingored as follows. 3.4.2 I/O redirection table registers: Interrupt Mask Edge-sensitive interrupts signaled on a masked interrupt pin are ignored (i.e., not delivered or held pending). > Bringing up interface eth0: > Determining IP information for eth0...irq 18: nobody cared (try booting with the "irqpoll" option) > Pid: 4126, comm: ip Not tainted 2.6.38-rc7 #1 > Call Trace: > [] ? __report_bad_irq+0x38/0x87 > [] ? note_interrupt+0x11f/0x188 > [] ? handle_fasteoi_irq+0xa7/0xd1 > [] ? handle_irq+0x83/0x8c > [] ? do_IRQ+0x48/0xaf > [] ? ret_from_intr+0x0/0xe > [] ? __do_softirq+0x4f/0x114 > [] ? call_softirq+0x1c/0x28 > [] ? do_softirq+0x33/0x68 > [] ? irq_exit+0x36/0x38 > [] ? smp_apic_timer_interrupt+0x88/0x96 > [] ? apic_timer_interrupt+0x13/0x20 > [] ? __ioapic_set_affinity+0x68/0x7c > [] ? _raw_spin_unlock_irqrestore+0x8/0xa > [] ? __setup_irq+0x224/0x2cb > [] ? e1000_intr+0x0/0x103 > [] ? request_threaded_irq+0xd1/0x114 > [] ? e1000_request_irq+0x34/0x63 > [] ? e1000_open+0x81/0x11f > [] ? call_netdevice_notifiers+0x45/0x4a > [] ? __dev_open+0x97/0xc4 > [] ? __dev_change_flags+0xb9/0x13d > [] ? dev_change_flags+0x1c/0x51 > [] ? devinet_ioctl+0x26e/0x594 > [] ? inet_ioctl+0x92/0xaa > [] ? T.1003+0x13/0x32 > [] ? sock_ioctl+0x1f2/0x1ff > [] ? do_vfs_ioctl+0x498/0x4e7 > [] ? sock_alloc_file+0xb3/0x115 > [] ? fd_install+0x31/0x5d > [] ? sys_ioctl+0x42/0x65 > [] ? system_call_fastpath+0x16/0x1b > handlers: > [] (e1000_intr+0x0/0x103) > Disabling IRQ #18 Signed-off-by: Jan Kiszka Tested-by: Isaku Yamahata --- hw/ioapic.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/ioapic.c b/hw/ioapic.c index 569327d..42c5037 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -160,8 +160,13 @@ static void ioapic_set_irq(void *opaque, int vector, int level) s->irr &= ~mask; } } else { - /* edge triggered */ - if (level) { + /* + * edge triggered + * 3.4.2 I/O redirection table registers: Interrupt Mask + * Edge-sensitive interrupts signaled on a masked interrupt pin + * are ignored (i.e., not delivered or held pending). + */ + if (level && !(entry & IOAPIC_LVT_MASKED)) { s->irr |= mask; ioapic_service(s); } -- 1.7.1.1 -- yamahata