bikeshed time.

pmap_is_direct_mapped() returns a boolean (int) value explaining whether
or not a given virtual address is part of the direct map for that arch.

I'd like this interface so km_alloc can do the direct-map-if-contig
mapping behaviour. This does not do m88k, hppa* and vax because I can't
find a nice define that explains where the direct segment might end.


Diff includes the km_alloc change so you can see why I want it.

Any objections to the idea? Pointers as to how to do the other archs?

-0-

diff --git a/arch/alpha/include/pmap.h b/arch/alpha/include/pmap.h
index f85520b..3d9feaa 100644
--- a/arch/alpha/include/pmap.h
+++ b/arch/alpha/include/pmap.h
@@ -198,6 +198,8 @@ extern      pt_entry_t *VPT;                /* Virtual Page 
Table */
  */
 #define        pmap_map_direct(pg)     ALPHA_PHYS_TO_K0SEG(VM_PAGE_TO_PHYS(pg))
 #define        pmap_unmap_direct(va)   
PHYS_TO_VM_PAGE(ALPHA_K0SEG_TO_PHYS((va)))
+#define pmap_is_direct_mapped(va)      (kva >= ALPHA_K0SEG_BASE &&     \
+                                           kva <= ALPHA_k0SEG_END)
 #define        __HAVE_PMAP_DIRECT
 
 paddr_t vtophys(vaddr_t);
diff --git a/arch/amd64/include/pmap.h b/arch/amd64/include/pmap.h
index e06158f..99c6d85 100644
--- a/arch/amd64/include/pmap.h
+++ b/arch/amd64/include/pmap.h
@@ -561,6 +561,8 @@ kvtopte(vaddr_t va)
 #define PMAP_DIRECT_UNMAP(va)  ((paddr_t)va - PMAP_DIRECT_BASE)
 #define pmap_map_direct(pg)    PMAP_DIRECT_MAP(VM_PAGE_TO_PHYS(pg))
 #define pmap_unmap_direct(va)  PHYS_TO_VM_PAGE(PMAP_DIRECT_UNMAP(va))
+#define pmap_is_direct_mapped(va)      (va >= PMAP_DIRECT_BASE &&      \
+                                           va <= PMAP_DIRECT_END)
 
 #define __HAVE_PMAP_DIRECT
 
diff --git a/arch/mips64/include/pmap.h b/arch/mips64/include/pmap.h
index 9856238..78736b6 100644
--- a/arch/mips64/include/pmap.h
+++ b/arch/mips64/include/pmap.h
@@ -166,6 +166,7 @@ void pmap_update_kernel_page(vaddr_t, pt_entry_t);
 #define        __HAVE_PMAP_DIRECT
 vaddr_t        pmap_map_direct(vm_page_t);
 vm_page_t pmap_unmap_direct(vaddr_t);
+#define pmap_is_direct_mapped(va)      IS_XKPHYS(va)
 #endif
 
 #endif /* _KERNEL */
diff --git a/arch/powerpc/include/pmap.h b/arch/powerpc/include/pmap.h
index e312669..96893e8 100644
--- a/arch/powerpc/include/pmap.h
+++ b/arch/powerpc/include/pmap.h
@@ -122,6 +122,7 @@ boolean_t pteclrbits(struct vm_page *pg, u_int mask, u_int 
clear);
  */
 #define pmap_map_direct(pg)            ((vaddr_t)VM_PAGE_TO_PHYS(pg))
 #define pmap_unmap_direct(va)          PHYS_TO_VM_PAGE((paddr_t)va)
+#define pmap_is_direct_mapped(va)      (va >= 0 && va <= 0x80000000)
 #define        __HAVE_PMAP_DIRECT
 
 void pmap_bootstrap(u_int kernelstart, u_int kernelend);
diff --git a/arch/sh/include/pmap.h b/arch/sh/include/pmap.h
index 25d4a76..7d17604 100644
--- a/arch/sh/include/pmap.h
+++ b/arch/sh/include/pmap.h
@@ -93,6 +93,8 @@ vaddr_t       pmap_prefer_offset(vaddr_t);
 #define        __HAVE_PMAP_DIRECT
 vaddr_t        pmap_map_direct(vm_page_t);
 vm_page_t pmap_unmap_direct(vaddr_t);
+#define pmap_is_direct_mapped(va)      (va >= SH3_P1SEG_BASE &&        \
+                                           va <= SH3_P2SEG_END)
 
 /* MD pmap utils. */
 pt_entry_t *__pmap_pte_lookup(pmap_t, vaddr_t);
diff --git a/arch/vax/include/pmap.h b/arch/vax/include/pmap.h
index c07cb92..d63f2ce 100644
--- a/arch/vax/include/pmap.h
+++ b/arch/vax/include/pmap.h
@@ -104,6 +104,8 @@ extern      struct pmap kernel_pmap_store;
  */
 #define pmap_map_direct(pg)    (VM_PAGE_TO_PHYS(pg) | KERNBASE)
 #define pmap_unmap_direct(va) PHYS_TO_VM_PAGE((va) & ~KERNBASE)
+extern vaddr_t virtual_avail;
+#define pmap_is_direct_mapped(va)      (kva >= virtual_avail)
 #define        __HAVE_PMAP_DIRECT
 
 #define PMAP_STEAL_MEMORY
diff --git a/uvm/uvm_km.c b/uvm/uvm_km.c
index 4db83ce..d1c059a 100644
--- a/uvm/uvm_km.c
+++ b/uvm/uvm_km.c
@@ -876,17 +876,9 @@ km_alloc(size_t sz, const struct kmem_va_mode *kv,
        }
 
 #ifdef __HAVE_PMAP_DIRECT
-       if (kv->kv_align || kv->kv_executable)
+       /* malloc isn't smart enough for direct mapping */
+       if (kv->kv_align || kv->kv_executable || kv == &kv_intrsafe)
                goto alloc_va;
-#if 1
-       /*
-        * For now, only do DIRECT mappings for single page
-        * allocations, until we figure out a good way to deal
-        * with contig allocations in km_free.
-        */
-       if (!kv->kv_singlepage)
-               goto alloc_va;
-#endif
        /*
         * Dubious optimization. If we got a contig segment, just map it
         * through the direct map.
@@ -995,11 +987,14 @@ km_free(void *v, size_t sz, const struct kmem_va_mode *kv,
                goto free_va;
        }
 
-       if (kv->kv_singlepage) {
 #ifdef __HAVE_PMAP_DIRECT
-               pg = pmap_unmap_direct(va);
-               uvm_pagefree(pg);
+       if (kv->kv_singlepage || pmap_is_direct_mapped(va)) {
+               for (va = sva; va < eva; va += PAGE_SIZE)
+                       uvm_pagefree(pmap_unmap_direct(va));
+               return;
+       }
 #else
+       if (kv->kv_singlepage) {
                struct uvm_km_free_page *fp = v;
                mtx_enter(&uvm_km_pages.mtx);
                fp->next = uvm_km_pages.freelist;
@@ -1007,9 +1002,9 @@ km_free(void *v, size_t sz, const struct kmem_va_mode *kv,
                if (uvm_km_pages.freelistlen++ > 16)
                        wakeup(&uvm_km_pages.km_proc);
                mtx_leave(&uvm_km_pages.mtx);
-#endif
                return;
        }
+#endif
 
        if (kp->kp_pageable) {
                pmap_remove(pmap_kernel(), sva, eva);

-- 
You should never wear your best trousers when you go out to fight for
freedom and liberty.
                -- Henrik Ibsen

Reply via email to