Subject: Re: found anoncvs problem . . .
To: tech-kern@NetBSD.ORG, Jason Thorpe <thorpej@nas.nasa.gov>
From: Christian E. Hopps <chopps@water.emich.edu>
List: tech-kern
Date: 12/30/1995 16:10:28
Note: I have cross-posted this to tech-kern as some of it might be of interest to non-m68k ports...

At 2:12 AM 12/5/95, Jason Thorpe wrote:
>On Mon, 4 Dec 95 21:58:15 CST 
> Chuck Cranor <chuck@maria.wustl.edu> wrote:
>
> >     it seems to me that we need to somehow limit maxproc to be
> > less than or equal to sizeof(pt_map)/sizeof(user page table) to
> > avoid this hang, in the general case.  where should this be done?
> > comments?   
>
>Chuck, as you and I discussed privately, I'd much rather have fork() 
>return EAGAIN than just see and random hang.  "Truncating" seems to be 
>safe; it's used to initialize some hash tables, etc., but then, AFAICT, 
>is basically only used to check if fork() should fail.  Seeing as how 
>sysctl(2) can raise it, I certainly think it should be safe for 
>pmap_init() to lower it.  Attached below is the patch I plan on 
>committing to the NetBSD/hp300 pmap.c unless someone else has a better 
>idea that's relatively feasible.  (Note, I have a pending PR on this 
>that's O(1.5 years) old, so I'm somewhat motivated to get some sort of fix 
>into the tree :-).

Sorry for taking so long to comment...

The patch that you listed (and people used) is very wastefull.  If your going to change 'maxproc' you should do it earlier than you do.  Understand that the KPT pages (kernel page table pages) are wired for eternity i.e. you remove enough physical memory for all the KPT pages and never free it.  KPT pages are responsible for mapping the user page tables.  The number of KPT pages is directly (look at pmap.c) related to 'maxproc' so if you allocate them and then lower 'maxproc' you've wasted valuable physical ram.

Regarding sysctl: So much is allocated at boot time based on the value of 'maxproc' its just wrong to allow the user/root to set maxproc above what it was at boot time.  We must either allocate things on some other variable or disallow setting 'maxproc' above what it was at boot time.

Regarding USRSTACK :)

Notice that the amiga port uses a much smaller USRSTACK than the hp300.  This was originally done by Markus Wild so as to be more compatible with SunOS.  I was going to change it (not seeing the large benifit in this compatibility) and then I discovered how usefull it was to leave it lower.  It free's up a bunch of phsycial memory for the system to use.  I'll demonstrate, first the amiga and hp300 pte.h constants (I list the amiga defines so you can better see the relationships they are the same for the hp300):

#define USRSTACK        0x0E000000
#define VM_MAXUSER_ADDRESS      ((vm_offset_t)(USRSTACK))

#define AMIGA_UPTSIZE           roundup(VM_MAXUSER_ADDRESS / NPTEPG, NBPG)
#define AMIGA_UPTBASE           0x10000000
#define AMIGA_UPTMAXSIZE \
    roundup((AMIGA_MAX_COREUPT * AMIGA_UPTSIZE), NBPG)
#define AMIGA_MAX_KPTSIZE \

#define HP_MAX_PTSIZE   0x400000        /* max size of UPT */
#define HP_MAX_KPTSIZE  0x100000        /* max memory to allocate to KPT */
#define HP_PTBASE       0x10000000      /* UPT map base address */
#define HP_PTMAXSIZE    0x70000000      /* UPT map maximum size */

#define USRSTACK        (-HIGHPAGES*NBPG)       /* Start of user stack */
#define VM_MAX_KERNEL_ADDRESS   ((vm_offset_t)0xFFFFF000)

(NPTEG is 0x400 on the hp300 and 0x800 on the amiga becuase they use 4k and 8k pages)

Say the user requests maxusers of 16 thats 16 * 16 + 20 or a maxproc of 276.  Thus the number of KPT pages is
amiga: howmany(((maxproc + 16) * AMIGA_UPTSIZE / NPTEPG), NBPG);
amiga: howmany((292 * AMIGA_UPTSIZE / NPTEPG), NBPG);
amiga: howmany((292 * USRSTACK / NPTEPG / NPTEPG), NBPG);
amiga: howmany((292 * 56), NBPG);  /* thats 56 bytes per process */
amiga: howmany(16352, NBPG);
amiga: 2 pages or 16k.

hp300: howmany((292 * 0x400000 / NPTEPG), NBPG);
hp300: howmany((292 * 4k), NBPG);  /* thats 4k bytes per process */
hp300: howmany(1196032, NBPG);
hp300: 146 pages or 584k.

So the amiga gains 568k of that valuable commodity, pageable ram.
The other large benifit (and the one that ties this to the point of discussion) is that I can support a great many more processes.

With such a large USRSTACK on the hp300 the largest "maxproc" is 448.  Currently the amiga has a limit of 1024 procs (see MAX_CORE_UPT) and if I chose to use the same range as the hp300 for my page table map I would raise that to 16k processes (a ridiculous number for a single 040 or less system).

I not sure how pratical 448 processes on an hp300 is.  Is it possible to reach that number and still have a slightly usable system?

I think that there was some reason for the stack being so large on the hp300 (hpux compat?).  If not I recommend lowering it.  This may also be an issue for other non-m68k ports if they use similar algorithms.

Chris.

BTW when I first was looking at raising USRSTACK I was still using the hex constants from hp300 so even though I had a smaller stack I gained nothing from it.  At the time I was investigating why the amiga required so much physical ram wired down (app 1M) it was due to the KPT pages.  Needless to say I was very happy to gain 1M of physical ram from changes in a few hex constants to symbolic ones, perhaps there is a lesson somewhere in that.. :)