Subject: Re: I just got a "panic: pmap_physpage_alloc: no pages available after 5 tries"
To: R. C. Dowdeswell <elric@imrryr.org>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: port-alpha
Date: 02/04/1999 11:47:06
On Wed, 03 Feb 1999 16:49:14 -0800 
 "R. C. Dowdeswell" <elric@mabelode.imrryr.org> wrote:

 > panic: pmap_physpage_alloc: no pages available after 5 tries
 > syncing disks... panic: lockmgr: locking against myself
 > 
 > I used to get this with 16MB RAM, a lot, and I thought that it was
 > because the minimum specs of the Alpha port were 32MB.  But now I
 > have 64MB, and got it.  The only thing that I was doing was running
 > a program that I'm guessing was running wild malloc(3)'ing memory
 > out of control.  (Yes, I am debugging it... :)

Please apply the following patch, which will give me some more info
so that I can figure out the best solution.

 > So, is this is well known problem, is there a solution, who would
 > be the best person to talk to about it?  I've looked for the code,
 > and note that it is in /sys/arch/alpha/alpha/pmap.c, but don't
 > really know how to go about fixing it.

I'm probably the right person to talk to, since a good portion of
the Alpha pmap code was written by me :-)

The problem is that it's running out of memory while trying to allocate
some important pmap data structure.  The patch I'm sending you will tell
me which one it is.

I know I need to make the pmap's memory allocation strategy a bit more
robust.  What is there worked for me in some test cases, but it's clearly
not great for all of them.

        -- Jason R. Thorpe <thorpej@nas.nasa.gov>

Index: alpha/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/alpha/pmap.c,v
retrieving revision 1.76
diff -c -r1.76 pmap.c
*** pmap.c	1998/12/18 19:52:11	1.76
--- pmap.c	1999/02/04 18:52:43
***************
*** 287,292 ****
--- 287,297 ----
  struct pool pmap_asngen_pool;
  
  /*
+  * Canonical names for PGU_* constants.
+  */
+ const char *pmap_pgu_strings[] = PGU_STRINGS;
+ 
+ /*
   * Address Space Numbers.
   *
   * On many implementations of the Alpha architecture, the TLB entries and
***************
*** 3181,3191 ****
  			pvh = pa_to_pvh(pa);
  			simple_lock(&pvh->pvh_slock);
  #ifdef DIAGNOSTIC
! 			if (pvh->pvh_usage != PGU_NORMAL)
! 				panic("pmap_physpage_alloc: in use?!");
! 			if (pvh->pvh_refcnt != 0)
! 				panic("pmap_physpage_alloc: page has "
! 				    "references");
  #endif
  			pvh->pvh_usage = usage;
  			simple_unlock(&pvh->pvh_slock);
--- 3186,3202 ----
  			pvh = pa_to_pvh(pa);
  			simple_lock(&pvh->pvh_slock);
  #ifdef DIAGNOSTIC
! 			if (pvh->pvh_usage != PGU_NORMAL) {
! 				printf("pmap_physpage_alloc: page 0x%lx is "
! 				    "in use (%s)\n", pa,
! 				    pmap_pgu_strings[pvh->pvh_usage]);
! 				goto die;
! 			}
! 			if (pvh->pvh_refcnt != 0) {
! 				printf("pmap_physpage_alloc: page 0x%lx has "
! 				    "%d references", pa, pvh->pvh_refcnt);
! 				goto die;
! 			}
  #endif
  			pvh->pvh_usage = usage;
  			simple_unlock(&pvh->pvh_slock);
***************
*** 3220,3226 ****
  	 * If we couldn't get any more pages after 5 tries, just
  	 * give up.
  	 */
! 	panic("pmap_physpage_alloc: no pages available after 5 tries");
  }
  
  /*
--- 3231,3240 ----
  	 * If we couldn't get any more pages after 5 tries, just
  	 * give up.
  	 */
! 	printf("pmap_physpage_alloc: no pages for %s page available after "
! 	    "5 tries", pmap_pgu_strings[usage]);
!  die:
! 	panic("pmap_physpage_alloc");
  }
  
  /*
Index: include/pmap.h
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/include/pmap.h,v
retrieving revision 1.24
diff -c -r1.24 pmap.h
*** pmap.h	1998/09/22 03:58:11	1.24
--- pmap.h	1999/02/04 18:52:43
***************
*** 153,158 ****
--- 153,167 ----
  
  #define	PGU_ISPTPAGE(pgu)	((pgu) >= PGU_L1PT)
  
+ #define	PGU_STRINGS							\
+ {									\
+ 	"normal",							\
+ 	"pvent",							\
+ 	"l1pt",								\
+ 	"l2pt",								\
+ 	"l3pt",								\
+ }
+ 
  struct pv_page_info {
  	TAILQ_ENTRY(pv_page) pgi_list;
  	LIST_HEAD(, pv_entry) pgi_freelist;