Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Aug 2004 16:26:41 +0900
From:      Pyun YongHyeon <yongari@kt-is.co.kr>
To:        Ken Smith <kensmith@cse.Buffalo.EDU>
Cc:        sparc64@freebsd.org
Subject:   Re: Insta-panic with recent -current on Ultra10
Message-ID:  <20040818072641.GB8375@kt-is.co.kr>
In-Reply-To: <20040818052628.GA8375@kt-is.co.kr>
References:  <200408170909.i7H99taL082002@postoffice.e-easy.com.au> <20040817115518.W68839@ury.york.ac.uk> <20040818010554.GB5194@electra.cse.Buffalo.EDU> <20040818052628.GA8375@kt-is.co.kr>

next in thread | previous in thread | raw e-mail | index | archive | help

--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Aug 18, 2004 at 02:26:28PM +0900, To Ken Smith wrote:
 > On Tue, Aug 17, 2004 at 09:05:54PM -0400, Ken Smith wrote:
 >  > On Tue, Aug 17, 2004 at 11:56:11AM +0100, Gavin Atkinson wrote:
 >  > > On Tue, 17 Aug 2004, Chris Knight wrote:
 >  > > > I'm getting the following panic on a kernel built from CURRENT
 >  > > > as of 17/08/2004 0100 AEST (+10).
 >  > > > A kernel from the 13/08/2004 0100 AEST (+10) works fine.
 >  > > > In the process of rebuilding the kernel so I can get some more
 >  > > > details...
 >  > > 
 >  > > I've seen exactly this panic from a kernel dated 15th. Just another
 >  > > datapoint.
 >  > 
 >  > Ok, I can reproduce this on a kernel from today:
 >  > 
 >  > acd0: CDRW <CRD-8322B/1.06> at ata3-master PIO4
 >  > Mounting root from ufs:/dev/ad0a
 >  > IOMMU fault virtual address 0xc0620000
 >  > panic: pcib: uncorrectable DMA error AFAR 0x3f867880 AFSR 0x270000ff00000000
 >  > cpuid = 0;
 >  > KDB: enter: panic
 >  > [thread 100042]
 >  > Stopped at      kdb_enter+0x38: ta              %xcc, 1
 >  > db> tr
 >  > panic() at panic+0x1a8
 >  > psycho_ue() at psycho_ue+0x60
 >  > intr_fast() at intr_fast+0x88
 >  > -- interrupt level=0xd pil=0 %o7=0xc02b474c --
 >  > spitfire_block_zero() at spitfire_block_zero+0x74
 >  > vm_pagezero() at vm_pagezero+0x1b8
 >  > fork_exit() at fork_exit+0x9c
 >  > fork_trampoline() at fork_trampoline+0x8
 >  > db>
 >  > 
 >  > And a kernel from the 10th does not appear to have the problem.  I'll
 >  > do a little playing with CVS to see if I can locate exactly what commit
 >  > does it.
 >  > 
 > 
 > [CCed to sos]
 > 
 > Backing out sos@ committment for PRD table fixed the issue.
 > Working revisions are
 > ata-all.h rev. 1.80
 > ata-chipset.c rev. 1.79
 > ata-dma.c rev. 1.128
 > 

The following patch seems to fix the issue on AXe.

Regards,
Pyun YongHyeon
-- 
Pyun YongHyeon <http://www.kr.freebsd.org/~yongari>;

--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ata.patch"

--- ata-chipset.c.orig	Mon Aug 16 20:29:47 2004
+++ ata-chipset.c	Wed Aug 18 16:15:48 2004
@@ -1578,7 +1578,7 @@
 	    wordp[idx++] = htole32(prd[i].count & ~ATA_DMA_EOT);
 	    length += (prd[i].count & ~ATA_DMA_EOT);
 	} while (!(prd[i++].count & ATA_DMA_EOT));
-	wordp[idx - 1] |= htole32(ATA_DMA_EOT);
+	wordp[idx - 1] = htole32(ATA_DMA_EOT | wordp[idx - 1]);
 
 	wordp = (u_int32_t *)
 	    (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_LSG_OFFSET);
--- ata-dma.c.orig	Mon Aug 16 20:29:47 2004
+++ ata-dma.c	Wed Aug 18 16:06:45 2004
@@ -57,6 +57,7 @@
 static MALLOC_DEFINE(M_ATADMA, "ATA DMA", "ATA driver DMA");
 
 /* misc defines */
+#define MAXSEGSZ	PAGE_SIZE
 #define MAXTABSZ	PAGE_SIZE
 #define MAXWSPCSZ	PAGE_SIZE
 #define MAXCTLDMASZ	(2 * (MAXTABSZ + MAXPHYS))
@@ -199,16 +200,25 @@
 {
     struct ata_dmasetprd_args *args = xsc;
     struct ata_dma_prdentry *prd = args->dmatab;
-    int i;
+    bus_size_t cnt;
+    u_int32_t lastcount;
+    int i, j;
 
     if ((args->error = error))
 	return;
-
+    lastcount = j = 0;
     for (i = 0; i < nsegs; i++) {
-	prd[i].addr = htole32(segs[i].ds_addr);
-	prd[i].count = htole32(segs[i].ds_len);
+	/*
+	 * A maximum segment size was specified for bus_dma_tag_create, but
+	 * some busdma code does not seem to honor this, so fix up if needed.
+	 */
+	for (cnt = 0; cnt < segs[i].ds_len; cnt += MAXSEGSZ, j++) {
+	    prd[j].addr = htole32(segs[i].ds_addr + cnt);
+	    lastcount = ulmin(segs[i].ds_len - cnt, MAXSEGSZ) & 0xffff;
+	    prd[j].count = htole32(lastcount);
+	}
     }
-    prd[i - 1].count |= htole32(ATA_DMA_EOT);
+    prd[j - 1].count = htole32(ATA_DMA_EOT | lastcount);
 }
 
 static int

--y0ulUmNC+osPPQO6--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040818072641.GB8375>