NKPT comments are misleading

Ruslan Ermilov ru at FreeBSD.org
Sat Nov 11 13:25:15 PST 2006


Hi,

I've been recently playing with loading i386 kernels with an
unusually large code segment (like 74MB ;).  I ended up
bumping a NKPT following suggestion from jhb@, but these
comments didn't look sane to me.

: amd64/include/pmap.h-/* Initial number of kernel page tables */
: amd64/include/pmap.h:#ifndef NKPT
: amd64/include/pmap.h:#define    NKPT            240     /* Enough for 16GB (2MB page tables) */
: amd64/include/pmap.h-#endif
: --
: i386/include/pmap.h-/* Actual number of kernel page tables */
: i386/include/pmap.h:#ifndef NKPT
: i386/include/pmap.h-#ifdef PAE
: i386/include/pmap.h:#define     NKPT            240     /* Enough for 16GB (2MB page tables) */
: i386/include/pmap.h-#else
: i386/include/pmap.h:#define     NKPT            30      /* Enough for 4GB (4MB page tables) */
: i386/include/pmap.h-#endif
: i386/include/pmap.h-#endif

On FreeBSD6/amd64, "struct vm_page" is 112 bytes, so to map 16GB
of RAM we'd need to map a vm_page_array of size (16G/4K)*112=448M,
and that requires 448M/2MB = 224 page tables.  Add to that the
kernelsize/2MB to map a kernel, plus some minor extra, and you get
the required NKPT value.  So the comment is mostly right for
FreeBSD6/amd64.

But on FreeBSD7/amd64 "struct vm_page" is already 120 bytes, and
on FreeBSD7/i386 it's 72/76 for non-PAE/PAE, and 68/72 for FreeBSD6.
The actual numbers are:

: FreeBSD6/amd64 requires 224 PTs to map 16G of RAM
: FreeBSD7/amd64 requires 240 PTs to map 16G of RAM
: FreeBSD7/i386 non-PAE requires 18 PTs to map 4G of RAM
: FreeBSD7/i386 PAE requires 152 PTs to map 16G of RAM
: FreeBSD7/i386 non-PAE requires 17 PTs to map 4G of RAM
: FreeBSD7/i386 PAE requires 144 PTs to map 16G of RAM

As you can see, the comments in i386/include/pmap.h don't make
much sense, neither none of four combination of FreeBSD6/7 and
PAE/non-PAE.  This is because (I think) it was blindly copied
from AMD64 incorrectly assuming "struct vm_page" has the same
size.

Also, for i386 it says "actual number of kernel page tables"
where it should say "initial number of kernel page tables";
the actual number of page tables (nkpt) can later grow if
necessary.

The comments are also applicable to a normal-sized kernels
only.  E.g., mapping a 7M i386 non-PAE kernel only requires
2 PTs, but a 74M kernel already "eats" 19 PTs.  (It requires
less by using 4M pages when PSE is in use, but the rest is
still wasted because vtopte() doesn't "know" about PSE.)
So, these comments don't account for the possible larger
kernel size, or assume a default kernel size.  In the latter
case, this should be documented.  The i386/non-PAE is
especially fragile.


Cheers,
-- 
Ruslan Ermilov
ru at FreeBSD.org
FreeBSD committer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-amd64/attachments/20061111/f6dc0880/attachment.pgp


More information about the freebsd-amd64 mailing list