Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 06 Mar 2008 21:38:23 +0100
From:      =?iso-8859-1?b?RnLpZOlyaWM=?= PRACA <frederic.praca@freebsd-fr.org>
To:        John Baldwin <jhb@freebsd.org>
Cc:        freebsd-hackers@freebsd.org, anholt@FreeBSD.org
Subject:   Re: Kernel crash on Asus A7N8X-X
Message-ID:  <1204835903.47d0563ff0717@imp.free.fr>
In-Reply-To: <200803060844.10772.jhb@freebsd.org>
References:  <1204671599.47cdd46f6b1e2@imp.free.fr> <200803060831.27056.jhb@freebsd.org> <200803060844.10772.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Selon John Baldwin <jhb@freebsd.org>:

> On Thursday 06 March 2008 08:31:26 am John Baldwin wrote:
> > The Linux AGP driver has the same code.  It appears to be forcing a read of
> > the TLB registers to force prior writes to clear the TLB entries to flush
> > perhaps?  I'm not sure why you are getting a panic.  What kind of fault did
> > you get?  (The original kernel panic messages would be needed.)
>
> Actually, it looks like you have a 64MB aperture and with either a 32MB or
> 64MB aperture this loop runs off the end of the GATT (GATT has 16384 entries
> * 4 bytes == 64k == 16 pages on x86) so if it dies before it starts the next
> loop that might explain it.  The patch below makes it walk the full GATT
> reading the first word from each page to force a flush w/o walking off the
> end of the GATT.
>
> Actually, this is what appears to have happened:
>
> (gdb) set $start = 0xd4d05000  (ag_virtual)
> (gdb) set $fva = 3570491392    (eva in trap_pfault() frame)
> (gdb) p ($fva - $start) / 4
> $2 = 17408
>
> That's well over your current ag_entries of 16384.  Try this patch (note
> Linux's in-kernel agp driver has the same bug):
>
> Index: agp_nvidia.c
> ===================================================================
> RCS file: /host/cvs/usr/cvs/src/sys/dev/agp/agp_nvidia.c,v
> retrieving revision 1.13
> diff -u -r1.13 agp_nvidia.c
> --- agp_nvidia.c	12 Nov 2007 21:51:37 -0000	1.13
> +++ agp_nvidia.c	6 Mar 2008 13:37:43 -0000
> @@ -347,7 +347,7 @@
>  	struct agp_nvidia_softc *sc;
>  	u_int32_t wbc_reg, temp;
>  	volatile u_int32_t *ag_virtual;
> -	int i;
> +	int i, pages;
>
>  	sc = (struct agp_nvidia_softc *)device_get_softc(dev);
>
> @@ -373,9 +373,10 @@
>  	ag_virtual = (volatile u_int32_t *)sc->gatt->ag_virtual;
>
>  	/* Flush TLB entries. */
> -	for(i = 0; i < 32 + 1; i++)
> +	pages = sc->gatt->ag_entries * sizeof(u_int32_t) / PAGE_SIZE;
> +	for(i = 0; i < pages; i++)
>  		temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)];
> -	for(i = 0; i < 32 + 1; i++)
> +	for(i = 0; i < pages; i++)
>  		temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)];
>
>  	return (0);
>
> --
> John Baldwin

Thanks a lot John, this code works. I have been able to launch X w/o crashing
the kernel.

Fred



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