From nobody@FreeBSD.ORG Wed Nov 8 12:58:59 2000 Return-Path: Received: by hub.freebsd.org (Postfix, from userid 32767) id 651A737B479; Wed, 8 Nov 2000 12:58:59 -0800 (PST) Message-Id: <20001108205859.651A737B479@hub.freebsd.org> Date: Wed, 8 Nov 2000 12:58:59 -0800 (PST) From: twatson@chiaro.com Sender: nobody@FreeBSD.ORG To: freebsd-gnats-submit@FreeBSD.org Subject: IDE disk driver ad has defect when doing kernel dump using reboot -d on large memory system X-Send-Pr-Version: www-1.0 >Number: 22700 >Category: kern >Synopsis: IDE disk driver ad has defect when doing kernel dump using reboot -d on large memory system >Confidential: no >Severity: non-critical >Priority: low >Responsible: sos >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Nov 08 13:00:01 PST 2000 >Closed-Date: Tue Nov 14 01:05:16 PST 2000 >Last-Modified: Tue Nov 14 01:05:39 PST 2000 >Originator: Tom Watson >Release: FreeBSD 4.0 >Organization: Chiaro Networks, Ltd. >Environment: >Description: The function addump in file ata-disk.c is called with interrupts off to do a crashdump. This function calls ad_transfer to transfer a page size chunk. Ad_transfer calls timeout if panicstr is NULL. Not all dump situations result from a panic, e.g. "reboot -d", meaning panicstr isn't always NULL when doing a dump. The timeouts are never cleared by the interrupt handler since interrupts are disabled. Consequently, on large memory machines, the timeout table overflows and you panic during the crashdump with panic("timeout table full"). >How-To-Repeat: Do a "reboot -d" with crash dumps configured on a 256 MB. machine with IDE swap device. >Fix: I changed the ata-disk.c driver as follows (calling untimeout in addump): *** ata-disk.c Wed Nov 8 13:49:50 2000 --- ata-disk.c.orig Wed Nov 8 09:36:02 2000 *************** *** 293,299 **** request.donecount += request.currentsize; request.bytecount -= request.currentsize; DELAY(20); - untimeout((timeout_t *)ad_timeout, &request,request. timeout_handle); } if (addr % (1024 * 1024) == 0) { --- 293,298 ---- *************** *** 363,368 **** --- 362,370 ---- if (request->donecount == 0) { /* start timeout for this transfer */ + if (panicstr) + request->timeout_handle.callout = NULL; + else request->timeout_handle = timeout((timeout_t*)ad_timeout, request, 10 * hz); >Release-Note: >Audit-Trail: Responsible-Changed-From-To: freebsd-bugs->sos Responsible-Changed-By: dougb Responsible-Changed-When: Thu Nov 9 22:12:12 PST 2000 Responsible-Changed-Why: Soren is Mr. ATA http://www.freebsd.org/cgi/query-pr.cgi?pr=22700 State-Changed-From-To: open->closed State-Changed-By: sos State-Changed-When: Tue Nov 14 01:05:16 PST 2000 State-Changed-Why: fixed in 4.2 http://www.freebsd.org/cgi/query-pr.cgi?pr=22700 >Unformatted: