Add a bulk interface to sem_down()
[akaros.git] / kern / src / page_alloc.c
index 8a3814f..4fd1943 100644 (file)
@@ -95,19 +95,24 @@ void kpages_free(void *addr, size_t size)
        arena_free(kpages_arena, addr, size);
 }
 
+/* Returns naturally aligned, contiguous pages of amount PGSIZE << order.  Linux
+ * code might assume its allocations are aligned. (see dma_alloc_coherent and
+ * bnx2x). */
 void *get_cont_pages(size_t order, int flags)
 {
-       return kpages_alloc(PGSIZE << order, flags);
+       return arena_xalloc(kpages_arena, PGSIZE << order, PGSIZE << order,
+                           0, 0, NULL, NULL, flags);
 }
 
 void free_cont_pages(void *buf, size_t order)
 {
-       kpages_free(buf, PGSIZE << order);
+       arena_xfree(kpages_arena, buf, PGSIZE << order);
 }
 
 /* Frees the page */
 void page_decref(page_t *page)
 {
+       assert(!page_is_pagemap(page));
        kpages_free(page2kva(page), PGSIZE);
 }
 
@@ -129,3 +134,29 @@ void unlock_page(struct page *page)
        atomic_and(&page->pg_flags, ~PG_LOCKED);
        sem_up(&page->pg_sem);
 }
+
+static void *__jumbo_pml2_alloc(struct arena *a, size_t size, int flags)
+{
+       return arena_xalloc(a, size, PML2_PTE_REACH, 0, 0, NULL, NULL, flags);
+}
+
+static struct arena *jumbo_pml2_arena;
+
+/* Just for example; we could add qcaches too.  Do this after kmalloc_init(). */
+void jumbo_arena_init(void)
+{
+       jumbo_pml2_arena = arena_create("jumbo_pml2", NULL, 0, PML2_PTE_REACH,
+                                       __jumbo_pml2_alloc, arena_xfree,
+                                       base_arena, 0, MEM_WAIT);
+       assert(jumbo_pml2_arena);
+}
+
+void *jumbo_page_alloc(size_t nr, int flags)
+{
+       return arena_alloc(jumbo_pml2_arena, nr * PML2_PTE_REACH, flags);
+}
+
+void jumbo_page_free(void *buf, size_t nr)
+{
+       arena_free(jumbo_pml2_arena, buf, nr * PML2_PTE_REACH);
+}