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