Subject: Re: vm_fault on i386...
To: Matthias Drochner <drochner@zelux6.zel.kfa-juelich.de>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: port-i386
Date: 06/18/1997 13:19:22
On Wed, 18 Jun 1997 20:31:41 +0200 (MET DST) 
 Matthias Drochner <drochner@zelux6.zel.kfa-juelich.de> wrote:

 > Excerpts from netbsd: 18-Jun-97 Re: vm_fault on i386... Jason
 > Thorpe@nas.nasa.go (1240)
 > 
 > >  > root@wraith# vm_fault(0xf880d100,0,1,0) -> 5
 > >  > kernal: page fault trap, code = 0
 > >  > stopped at _pmap_changebit + 0x83: movl 0(%edx),%eax
 > 
 > I've seen similar errors.
 > The reason was that pde's disappeared magically.

Oh my.  That's .... special.

 > This seemed to be triggered by a combination of heavy DMA
 > activity (locked pages + tsleep()) and process creation /
 > termination.
 > Nasty race condition -  couldn't track it down at this time.

Yah, I've suspected that the problem Bill Sommerfeld is seeing is
a race condition, as well as the machine check problem on the Alpha.

Unfortunately, I have not been able to reproduce it locally... I would
appreciate any help I can get from you guys to find this...

In any case, if you're seeing this problem, I'd appreciate it if you
could try the following patch, and see if it helps any... It essentially
prevents the dma map loading code from being interrupted by anything that
might frob VM structures...  This is not a good long term fix, but it
might give us a better idea about where the bug lies...

Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                               Home: 408.866.1912
NAS: M/S 258-6                                          Work: 415.604.0935
Moffett Field, CA 94035                                Pager: 415.428.6939

Index: i386/machdep.c
===================================================================
RCS file: /mastersrc/netbsd/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.81
diff -c -r1.81 machdep.c
*** machdep.c	1997/06/13 01:15:23	1.81
--- machdep.c	1997/06/18 19:53:39
***************
*** 2033,2038 ****
--- 2033,2039 ----
  	caddr_t vaddr = buf;
  	int first, seg;
  	pmap_t pmap;
+ 	int s;
  
  	/*
  	 * Make sure that on error condition we return "no valid mappings".
***************
*** 2046,2051 ****
--- 2047,2054 ----
  	 * XXX Need to implement "don't dma across this boundry".
  	 */
  
+ 	s = splimp();
+ 
  	if (p != NULL)
  		pmap = p->p_vmspace->vm_map.pmap;
  	else
***************
*** 2089,2094 ****
--- 2092,2099 ----
  		vaddr += sgsize;
  		buflen -= sgsize;
  	}
+ 
+ 	splx(s);
  
  	/*
  	 * Did we fit?
Index: isa/isa_machdep.c
===================================================================
RCS file: /mastersrc/netbsd/src/sys/arch/i386/isa/isa_machdep.c,v
retrieving revision 1.36
diff -c -r1.36 isa_machdep.c
*** isa_machdep.c	1997/06/13 01:15:39	1.36
--- isa_machdep.c	1997/06/18 20:05:20
***************
*** 622,631 ****
  	int flags;
  {
  	struct i386_isa_dma_cookie *cookie = map->_dm_cookie;
! 	int error;
  
  	STAT_INCR(isa_dma_stats_loads);
  
  	/*
  	 * Check to see if we might need to bounce the transfer.
  	 */
--- 622,633 ----
  	int flags;
  {
  	struct i386_isa_dma_cookie *cookie = map->_dm_cookie;
! 	int error, s;
  
  	STAT_INCR(isa_dma_stats_loads);
  
+ 	s = splimp();
+ 
  	/*
  	 * Check to see if we might need to bounce the transfer.
  	 */
***************
*** 635,643 ****
  		 * threshold.  If they are, don't bother bouncing.
  		 */
  		if (_isa_dma_check_buffer(buf, buflen,
! 		    map->_dm_segcnt, map->_dm_boundary, p) == 0)
! 			return (_bus_dmamap_load(t, map, buf, buflen,
! 			    p, flags));
  
  		STAT_INCR(isa_dma_stats_bounces);
  
--- 637,647 ----
  		 * threshold.  If they are, don't bother bouncing.
  		 */
  		if (_isa_dma_check_buffer(buf, buflen,
! 		    map->_dm_segcnt, map->_dm_boundary, p) == 0) {
! 			error = _bus_dmamap_load(t, map, buf, buflen,
! 			    p, flags);
! 			goto out;
! 		}
  
  		STAT_INCR(isa_dma_stats_bounces);
  
***************
*** 648,654 ****
  			error = _isa_dma_alloc_bouncebuf(t, map, buflen,
  			    flags);
  			if (error)
! 				return (error);
  		}
  
  		/*
--- 652,658 ----
  			error = _isa_dma_alloc_bouncebuf(t, map, buflen,
  			    flags);
  			if (error)
! 				goto out;
  		}
  
  		/*
***************
*** 678,683 ****
--- 682,689 ----
  		error = _bus_dmamap_load(t, map, buf, buflen, p, flags); 
  	}
  
+  out:
+ 	splx(s);
  	return (error);
  }
  
***************
*** 735,740 ****
--- 741,749 ----
  	bus_dmamap_t map;
  {
  	struct i386_isa_dma_cookie *cookie = map->_dm_cookie;
+ 	int s;
+ 
+ 	s = splimp();
  
  	/*
  	 * If we have bounce pages, free them, unless they're
***************
*** 750,755 ****
--- 759,765 ----
  	 * Do the generic bits of the unload.
  	 */
  	_bus_dmamap_unload(t, map);
+ 	splx(s);
  }
  
  /*