From owner-freebsd-bugs@FreeBSD.ORG Sat Aug 25 03:40:01 2007 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F2F5C16A41A for ; Sat, 25 Aug 2007 03:40:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id D4FCD13C480 for ; Sat, 25 Aug 2007 03:40:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.1/8.14.1) with ESMTP id l7P3e1ka026753 for ; Sat, 25 Aug 2007 03:40:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.1/8.14.1/Submit) id l7P3e1uu026752; Sat, 25 Aug 2007 03:40:01 GMT (envelope-from gnats) Resent-Date: Sat, 25 Aug 2007 03:40:01 GMT Resent-Message-Id: <200708250340.l7P3e1uu026752@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Arthur Hartwig Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 616E216A418 for ; Sat, 25 Aug 2007 03:30:17 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 536B513C469 for ; Sat, 25 Aug 2007 03:30:17 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.1/8.14.1) with ESMTP id l7P3UHEO037002 for ; Sat, 25 Aug 2007 03:30:17 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.1/8.14.1/Submit) id l7P3UHFF037001; Sat, 25 Aug 2007 03:30:17 GMT (envelope-from nobody) Message-Id: <200708250330.l7P3UHFF037001@www.freebsd.org> Date: Sat, 25 Aug 2007 03:30:17 GMT From: Arthur Hartwig To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/115801: Writing of crash dumps is unreliable X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 25 Aug 2007 03:40:02 -0000 >Number: 115801 >Category: kern >Synopsis: Writing of crash dumps is unreliable >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Aug 25 03:40:01 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Arthur Hartwig >Release: 6.2 >Organization: Nokia >Environment: >Description: In ata_start() in ata-queue.c if the variable dumping is non-zero the code loops calling ata_interrupt() until it returns non-zero. Unfortunately it is possible for hardware interrupt to occur while in this loop and process the completion with the consequence that the completion is not seen in the loop in ata_start(). >How-To-Repeat: >Fix: Suggested fix: On initiating a dump, remove the device interrupt handler to ensure that ata_interrupt() is not called as a consequence of a hardware interrupt while in the afore mentioned loop in ata_start(). Note it is not sufficient to disable interrupts on the device because the device interrupt line might be shared by other devices (particularly true with recent Intel chipsets) and the ATA interrupt handler will be called when other devices interrupt. This fix has proved reliable on a number of systems based on Intel E7520 and P5000 chipsets. In ad_dump() in ata-disk.c, change *** 953,963 **** --- 953,975 ---- ad_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) { struct disk *dp = arg; struct bio bp; + static int first_call = 1; + int ret; + + if (first_call) { + device_t dev = device_get_parent((device_t)(dp->d_drv1)); + struct ata_channel *ch = device_get_softc(dev); + + if ((ret = bus_teardown_intr(dev, ch->r_irq, ch->ih))) { + printf("Failed to deregister interrupt handler: %d\n", ret); + } + first_call--; + } /* length zero is special and really means flush buffers to media */ if (!length) { struct ata_device *atadev = device_get_softc(dp->d_drv1); int error = 0; >Release-Note: >Audit-Trail: >Unformatted: