Convert calls of get_cont_pages() to kpages_alloc
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 23 Nov 2016 16:58:18 +0000 (11:58 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 29 Nov 2016 16:27:40 +0000 (11:27 -0500)
get_cont_pages() and its 'order' interface are a mess.  Just ask for how
much memory you want, and let the allocator figure it out.

Also, get_cont_pages_node() was just pretending to do something
NUMA-related.  Remove it for now, and we can 'do the right thing' when we
figure it all out.

Linux code can still use get_cont_pages().  The semantics of that will
change shortly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/pmap64.c
kern/arch/x86/ros/vmx.h
kern/arch/x86/vmm/intel/vmx.c
kern/include/kmalloc.h
kern/include/page_alloc.h
kern/src/env.c
kern/src/kmalloc.c
kern/src/kthread.c
kern/src/page_alloc.c
kern/src/process.c

index 09469a9..4fd7ae7 100644 (file)
@@ -102,7 +102,7 @@ static kpte_t *__pml_walk(kpte_t *pml, uintptr_t va, int flags, int pml_shift)
        if (!kpte_is_present(kpte)) {
                if (!(flags & PG_WALK_CREATE))
                        return NULL;
-               new_pml_kva = get_cont_pages(1, MEM_WAIT);
+               new_pml_kva = kpages_alloc(2 * PGSIZE, MEM_WAIT);
                memset(new_pml_kva, 0, PGSIZE * 2);
                /* Might want better error handling (we're probably out of memory) */
                if (!new_pml_kva)
@@ -371,7 +371,7 @@ int unmap_segment(pgdir_t pgdir, uintptr_t va, size_t size)
                                        return 0;
                        }
                }
-               free_cont_pages(KADDR(PTE_ADDR(*kpte)), 1);
+               kpages_free(KADDR(PTE_ADDR(*kpte)), 2 * PGSIZE);
                *kpte = 0;
                return 0;
        }
@@ -533,7 +533,7 @@ void env_pagetable_free(struct proc *p)
 {
        unmap_segment(p->env_pgdir, 0, UVPT - 0);
        /* the page directory is not a PTE, so it never was freed */
-       free_cont_pages(pgdir_get_kpt(p->env_pgdir), 1);
+       kpages_free(pgdir_get_kpt(p->env_pgdir), 2 * PGSIZE);
        tlbflush();
 }
 
@@ -626,7 +626,7 @@ int arch_pgdir_setup(pgdir_t boot_copy, pgdir_t *new_pd)
        kpte_t *kpt;
        epte_t *ept;
 
-       kpt = get_cont_pages(1, MEM_WAIT);
+       kpt = kpages_alloc(2 * PGSIZE, MEM_WAIT);
        memcpy(kpt, boot_copy.kpte, PGSIZE);
        ept = kpte_to_epte(kpt);
        memset(ept, 0, PGSIZE);
index c1650d1..e0a008e 100644 (file)
@@ -665,7 +665,6 @@ extern struct vmx_capability vmx_capability;
 
 struct vmcs_config {
        int size;
-       int order;
        uint32_t revision_id;
        uint32_t pin_based_exec_ctrl;
        uint32_t cpu_based_exec_ctrl;
index 6ba7212..fe08a47 100644 (file)
 #define currentcpu (&per_cpu_info[core_id()])
 
 static unsigned long *msr_bitmap;
-#define VMX_IO_BITMAP_ORDER            4       /* 64 KB */
-#define VMX_IO_BITMAP_SZ               (1 << (VMX_IO_BITMAP_ORDER + PGSHIFT))
+#define VMX_IO_BITMAP_SZ               (1 << 16) /* 64 KB */
 static unsigned long *io_bitmap;
 
 int x86_ept_pte_fix_ups = 0;
@@ -676,7 +675,6 @@ setup_vmcs_config(void *p)
        }
 
        vmcs_conf->size = vmx_msr_high & 0x1fff;
-       vmcs_conf->order = LOG2_UP(nr_pages(vmcs_config.size));
        vmcs_conf->revision_id = (uint32_t) vmx_msr;
 
        /* Read in the caps for runtime checks.  This MSR is only available if
@@ -690,10 +688,10 @@ static struct vmcs *__vmx_alloc_vmcs(int node)
 {
        struct vmcs *vmcs;
 
-       vmcs = get_cont_pages_node(node, vmcs_config.order, MEM_WAIT);
+       vmcs = kpages_alloc(vmcs_config.size, MEM_WAIT);
        if (!vmcs)
-               error(ENOMEM, "__vmx_alloc_vmcs: Could not get %d contig pages",
-                     vmcs_config.order);
+               error(ENOMEM, "__vmx_alloc_vmcs: Could not get %d contig bytes",
+                     vmcs_config.size);
        memset(vmcs, 0, vmcs_config.size);
        vmcs->revision_id = vmcs_config.revision_id; /* vmcs revision id */
        printd("%d: set rev id %d\n", core_id(), vmcs->revision_id);
@@ -719,7 +717,7 @@ vmx_alloc_vmcs(void)
 static void
 vmx_free_vmcs(struct vmcs *vmcs)
 {
-       free_cont_pages(vmcs, vmcs_config.order);
+       kpages_free(vmcs, vmcs_config.size);
 }
 
 /*
@@ -1316,8 +1314,7 @@ int intel_vmm_init(void) {
                printk("Could not allocate msr_bitmap\n");
                return -ENOMEM;
        }
-       io_bitmap = (unsigned long *)get_cont_pages(VMX_IO_BITMAP_ORDER,
-                                                   MEM_WAIT);
+       io_bitmap = (unsigned long *)kpages_alloc(VMX_IO_BITMAP_SZ, MEM_WAIT);
        if (!io_bitmap) {
                printk("Could not allocate msr_bitmap\n");
                kfree(msr_bitmap);
index bd6da19..f944f8b 100644 (file)
@@ -53,7 +53,7 @@ void *debug_canary;
 struct kmalloc_tag {
        union {
                struct kmem_cache *my_cache;
-               size_t num_pages;
+               size_t amt_alloc;
                uint64_t unused_force_align;
        };
        struct kref kref;
index 3852d9d..9e776da 100644 (file)
@@ -70,7 +70,6 @@ void *kpages_zalloc(size_t size, int flags);
 void kpages_free(void *addr, size_t size);
 
 void *get_cont_pages(size_t order, int flags);
-void *get_cont_pages_node(int node, size_t order, int flags);
 void free_cont_pages(void *buf, size_t order);
 
 void page_decref(page_t *page);
index 5b51952..e47f76b 100644 (file)
@@ -44,9 +44,9 @@ int env_setup_vm(env_t *e)
        /* These need to be contiguous, so the kernel can alias them.  Note the
         * pages return with a refcnt, but it's okay to insert them since we free
         * them manually when the process is cleaned up. */
-       if (!(e->procinfo = get_cont_pages(LOG2_UP(PROCINFO_NUM_PAGES), 0)))
+       if (!(e->procinfo = kpages_alloc(PROCINFO_NUM_PAGES * PGSIZE, MEM_WAIT)))
                goto env_setup_vm_error_i;
-       if (!(e->procdata = get_cont_pages(LOG2_UP(PROCDATA_NUM_PAGES), 0)))
+       if (!(e->procdata = kpages_alloc(PROCDATA_NUM_PAGES * PGSIZE, MEM_WAIT)))
                goto env_setup_vm_error_d;
        /* Normally we would 0 the pages here.  We handle it in proc_init_proc*.
         * Do not start the process without calling those. */
@@ -82,9 +82,9 @@ int env_setup_vm(env_t *e)
        return 0;
 
 env_setup_vm_error:
-       free_cont_pages(e->procdata, LOG2_UP(PROCDATA_NUM_PAGES));
+       kpages_free(e->procdata, PROCDATA_NUM_PAGES * PGSIZE);
 env_setup_vm_error_d:
-       free_cont_pages(e->procinfo, LOG2_UP(PROCINFO_NUM_PAGES));
+       kpages_free(e->procinfo, PROCINFO_NUM_PAGES * PGSIZE);
 env_setup_vm_error_i:
        env_user_mem_free(e, 0, UVPT);
        env_pagetable_free(e);
index a5b51cf..1a598d2 100644 (file)
@@ -55,15 +55,17 @@ void *kmalloc(size_t size, int flags)
                cache_id = LOG2_UP(ksize) - LOG2_UP(KMALLOC_SMALLEST);
        // if we don't have a cache to handle it, alloc cont pages
        if (cache_id >= NUM_KMALLOC_CACHES) {
-               size_t num_pgs = ROUNDUP(size + sizeof(struct kmalloc_tag), PGSIZE) /
-                                          PGSIZE;
-               buf = get_cont_pages(LOG2_UP(num_pgs), flags);
+               /* The arena allocator will round up too, but we want to know in advance
+                * so that krealloc can avoid extra allocations. */
+               size_t amt_alloc = ROUNDUP(size + sizeof(struct kmalloc_tag), PGSIZE);
+
+               buf = kpages_alloc(amt_alloc, flags);
                if (!buf)
                        panic("Kmalloc failed!  Handle me!");
                // fill in the kmalloc tag
                struct kmalloc_tag *tag = buf;
                tag->flags = KMALLOC_TAG_PAGES;
-               tag->num_pages = num_pgs;
+               tag->amt_alloc = amt_alloc;
                tag->canary = KMALLOC_CANARY;
                kref_init(&tag->kref, __kfree_release, 1);
                return buf + sizeof(struct kmalloc_tag);
@@ -167,8 +169,7 @@ void *krealloc(void* buf, size_t size, int flags)
                if ((tag->flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_CACHE) {
                        osize = tag->my_cache->obj_size - sizeof(struct kmalloc_tag);
                } else if ((tag->flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_PAGES) {
-                       osize = LOG2_UP(tag->num_pages) * PGSIZE
-                               - sizeof(struct kmalloc_tag);
+                       osize = tag->amt_alloc - sizeof(struct kmalloc_tag);
                } else {
                        panic("Probably a bad tag, flags %p\n", tag->flags);
                }
@@ -220,7 +221,7 @@ static void __kfree_release(struct kref *kref)
        if ((tag->flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_CACHE)
                kmem_cache_free(tag->my_cache, tag);
        else if ((tag->flags & KMALLOC_FLAG_MASK) == KMALLOC_TAG_PAGES)
-               free_cont_pages(tag, LOG2_UP(tag->num_pages));
+               kpages_free(tag, tag->amt_alloc);
        else
                panic("Bad flag 0x%x in %s", tag->flags, __FUNCTION__);
 }
index dcd56b9..0aef2a2 100644 (file)
@@ -12,6 +12,7 @@
 #include <smp.h>
 #include <schedule.h>
 #include <kstack.h>
+#include <kmalloc.h>
 #include <arch/uaccess.h>
 
 uintptr_t get_kstack(void)
@@ -20,7 +21,7 @@ uintptr_t get_kstack(void)
        if (KSTKSIZE == PGSIZE)
                stackbot = (uintptr_t)kpage_alloc_addr();
        else
-               stackbot = (uintptr_t)get_cont_pages(KSTKSHIFT - PGSHIFT, 0);
+               stackbot = (uintptr_t)kpages_alloc(KSTKSIZE, MEM_ATOMIC);
        assert(stackbot);
        return stackbot + KSTKSIZE;
 }
@@ -31,7 +32,7 @@ void put_kstack(uintptr_t stacktop)
        if (KSTKSIZE == PGSIZE)
                page_decref(kva2page((void*)stackbot));
        else
-               free_cont_pages((void*)stackbot, KSTKSHIFT - PGSHIFT);
+               kpages_free((void*)stackbot, KSTKSIZE);
 }
 
 uintptr_t *kstack_bottom_addr(uintptr_t stacktop)
index 6747a44..8a3814f 100644 (file)
@@ -100,11 +100,6 @@ void *get_cont_pages(size_t order, int flags)
        return kpages_alloc(PGSIZE << order, flags);
 }
 
-void *get_cont_pages_node(int node, size_t order, int flags)
-{
-       return get_cont_pages(order, flags);
-}
-
 void free_cont_pages(void *buf, size_t order)
 {
        kpages_free(buf, PGSIZE << order);
index d54001f..60171ba 100644 (file)
@@ -515,8 +515,8 @@ static void __proc_free(struct kref *kref)
         * clear the PTEs of the upper stuff (UMAPTOP to UVPT), but we shouldn't
         * need to. */
        env_user_mem_walk(p, 0, UMAPTOP, __cb_assert_no_pg, 0);
-       free_cont_pages(p->procinfo, LOG2_UP(PROCINFO_NUM_PAGES));
-       free_cont_pages(p->procdata, LOG2_UP(PROCDATA_NUM_PAGES));
+       kpages_free(p->procinfo, PROCINFO_NUM_PAGES * PGSIZE);
+       kpages_free(p->procdata, PROCDATA_NUM_PAGES * PGSIZE);
 
        env_pagetable_free(p);
        arch_pgdir_clear(&p->env_pgdir);