Subject: pmap_zero_page() and TLB
To: None <port-i386@netbsd.org>
From: Jason R Thorpe <thorpej@zembu.com>
List: port-i386
Date: 10/05/2000 16:41:53
Folks...

So, I just heard for the first time today that some people hare having
K6 issues wrt. zero page idling -- wasn't aware of that.  So, this goes
back to the problems we saw with the Cyrix CPUs.  I think the way the
pmap is doing TLB invalidation is a little sketchy.

I've attached a diff that I'd like people with Cyrix CPUs to try.  It's
relative to the 1.5 branch.  Please see if this works in the presence
of idle page zero'ing.

Thanks.

-- 
        -- Jason R. Thorpe <thorpej@zembu.com>

Index: pmap.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/pmap.c,v
retrieving revision 1.94.2.2
diff -c -r1.94.2.2 pmap.c
*** pmap.c	2000/09/21 14:20:24	1.94.2.2
--- pmap.c	2000/10/05 23:39:34
***************
*** 2067,2082 ****
  pmap_zero_page(pa)
  	paddr_t pa;
  {
- 	simple_lock(&pmap_zero_page_lock);
- #ifdef DIAGNOSTIC
- 	if (*zero_pte)
- 		panic("pmap_zero_page: lock botch");
- #endif
  
  	*zero_pte = (pa & PG_FRAME) | PG_V | PG_RW;	/* map in */
  	memset(zerop, 0, NBPG);				/* zero */
- 	*zero_pte = 0;				/* zap! */
- 	pmap_update_pg((vaddr_t)zerop);		/* flush TLB */
  	simple_unlock(&pmap_zero_page_lock);
  }
  
--- 2067,2077 ----
  pmap_zero_page(pa)
  	paddr_t pa;
  {
  
+ 	simple_lock(&pmap_zero_page_lock);
  	*zero_pte = (pa & PG_FRAME) | PG_V | PG_RW;	/* map in */
+ 	pmap_update_pg((vaddr_t)zerop);			/* flush TLB */
  	memset(zerop, 0, NBPG);				/* zero */
  	simple_unlock(&pmap_zero_page_lock);
  }
  
***************
*** 2088,2104 ****
  pmap_zero_page_uncached(pa)
  	paddr_t pa;
  {
- 	simple_lock(&pmap_zero_page_lock);
- #ifdef DIAGNOSTIC
- 	if (*zero_pte)
- 		panic("pmap_zero_page_uncached: lock botch");
- #endif
  
  	*zero_pte = (pa & PG_FRAME) | PG_V | PG_RW |	/* map in */
  	    ((cpu_class != CPUCLASS_386) ? PG_N : 0);
- 	memset(zerop, 0, NBPG);				/* zero */
- 	*zero_pte = 0;					/* zap! */
  	pmap_update_pg((vaddr_t)zerop);			/* flush TLB */
  	simple_unlock(&pmap_zero_page_lock);
  }
  
--- 2083,2094 ----
  pmap_zero_page_uncached(pa)
  	paddr_t pa;
  {
  
+ 	simple_lock(&pmap_zero_page_lock);
  	*zero_pte = (pa & PG_FRAME) | PG_V | PG_RW |	/* map in */
  	    ((cpu_class != CPUCLASS_386) ? PG_N : 0);
  	pmap_update_pg((vaddr_t)zerop);			/* flush TLB */
+ 	memset(zerop, 0, NBPG);				/* zero */
  	simple_unlock(&pmap_zero_page_lock);
  }