Subject: adventures in pmap
To: None <port-arm@netbsd.org>
From: Chris Gilbert <chris@paradox.demon.co.uk>
List: port-arm
Date: 08/12/2002 03:12:30
Evening (or rather morning)

While looking over the pmap code I noticed that every time we fork a process
we pretty much bzero most of the 16k L1 table, thinking this was inefficient
I decided to fiddle with the code in pmap, mostly with a view to start work
on freeing ptp's when we're finished with them, which means that on process
exit the only pages in the L1 would be the kernel ones, as the rest are
pmap_removed, which means that the l1pt will have been cleanded up, and
wouldn't need to be bzero'd, reducing the process creation overhead
(especially as most processes have maybe 3 ptp's, so only have 12 entries in
the l1pt, so 16k is rather overkill if only 48 bytes had to be cleared.)

However I stumbled at the first block, it seems that some processes
(savecore, gdb, fsck) are mapping memory in somehow, but not creating a user
manged ptp for it, I'm wondering if anyone can suggest how?

to see the effect, try the patch at the end, in theory it shouldn't change
much, but it seems that something is fiddling it mappings but not telling
the pmap.

I'm probably missing something obvious, but I've no idea what.  I'm guessing
it all works normally, as the panic I get traces back to the the data abort
handler, so
something is meant to be there, and finds it's way into place, I just
assumed that anything within normal memory would have an associated ptp.

I'll start investigating this further, unless anyone has a suggestion on
this (other than rewrite the pmap)

Chris

Index: pmap.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/arm/arm32/pmap.c,v
retrieving revision 1.108
diff -u -p -r1.108 pmap.c
--- pmap.c      2002/08/10 00:48:35     1.108
+++ pmap.c      2002/08/12 01:54:25
@@ -2567,6 +2585,7 @@ pmap_enter(struct pmap *pmap, vaddr_t va
        struct vm_page *pg;
        struct pv_entry *pve;
        int error, nflags;
+       struct vm_page *ptp = NULL;

        PDEBUG(5, printf("pmap_enter: V%08lx P%08lx in pmap %p prot=%08x,
wired = %d\n",
            va, pa, pmap, prot, wired));
@@ -2602,21 +2621,19 @@ pmap_enter(struct pmap *pmap, vaddr_t va
         * address, allocate one.
         */
        ptes = pmap_map_ptes(pmap);             /* locks pmap */
-       if (pmap_pde_v(pmap_pde(pmap, va)) == 0) {
-               struct vm_page *ptp;
-
-               /* kernel should be pre-grown */
-               KASSERT(pmap != pmap_kernel());

-               /* if failure is allowed then don't try too hard */
-               ptp = pmap_get_ptp(pmap, va & L1_S_FRAME);
-               if (ptp == NULL) {
-                       if (flags & PMAP_CANFAIL) {
-                               error = ENOMEM;
-                               goto out;
-                       }
-                       panic("pmap_enter: get ptp failed");
+       /* kernel should be pre-grown */
+       if (pmap != pmap_kernel())
+       {
+           /* if failure is allowed then don't try too hard */
+           ptp = pmap_get_ptp(pmap, va & L1_S_FRAME);
+           if (ptp == NULL) {
+               if (flags & PMAP_CANFAIL) {
+                   error = ENOMEM;
+                   goto out;
                }
+               panic("pmap_enter: get ptp failed");
+           }