Track errno and errstr in the kthread
[akaros.git] / kern / include / page_alloc.h
index a947e88..9e776da 100644 (file)
@@ -1,20 +1,20 @@
-/* Copyright (c) 2009, 2010 The Regents of the University  of California. 
- * See the COPYRIGHT files at the top of this source tree for full 
+/* Copyright (c) 2009, 2010 The Regents of the University  of California.
+ * See the COPYRIGHT files at the top of this source tree for full
  * license information.
- * 
- * Kevin Klues <klueska@cs.berkeley.edu>    
+ *
+ * Kevin Klues <klueska@cs.berkeley.edu>
  * Barret Rhoden <brho@cs.berkeley.edu> */
-#ifndef PAGE_ALLOC_H
-#define PAGE_ALLOC_H
+
+#pragma once
 
 #include <atomic.h>
 #include <sys/queue.h>
 #include <error.h>
 #include <arch/mmu.h>
-#include <colored_page_alloc.h>
 #include <process.h>
 #include <kref.h>
+#include <kthread.h>
+#include <multiboot.h>
 
 struct page_map;               /* preprocessor games */
 
@@ -22,52 +22,65 @@ struct page_map;            /* preprocessor games */
 struct page;
 typedef size_t ppn_t;
 typedef struct page page_t;
-typedef LIST_HEAD(PageList, page) page_list_t;
-typedef LIST_ENTRY(page) page_list_entry_t;
+typedef BSD_LIST_HEAD(PageList, page) page_list_t;
+typedef BSD_LIST_ENTRY(page) page_list_entry_t;
 
 /* Per-page flag bits related to their state in the page cache */
 #define PG_LOCKED              0x001   /* involved in an IO op */
 #define PG_UPTODATE            0x002   /* page map, filled with file data */
 #define PG_DIRTY               0x004   /* page map, data is dirty */
+#define PG_BUFFER              0x008   /* is a buffer page, has BHs */
+#define PG_PAGEMAP             0x010   /* belongs to a page map */
+#define PG_REMOVAL             0x020   /* Working flag for page map removal */
 
-/* TODO: this struct is not protected from concurrent operations in any
- * function.  We may want a lock, but a better thing would be a good use of
- * reference counting and atomic operations. */
+/* TODO: this struct is not protected from concurrent operations in some
+ * functions.  If you want to lock on it, use the spinlock in the semaphore.
+ * This structure is getting pretty big (and we're wasting RAM).  If it becomes
+ * an issue, we can dynamically allocate some of these things when we're a
+ * buffer page (in a page mapping) */
 struct page {
-       LIST_ENTRY(page)                        pg_link;        /* membership in various lists */
-       struct kref                                     pg_kref;
-       unsigned int                            pg_flags;
-       struct page_map                         *pg_mapping;
+       BSD_LIST_ENTRY(page)            pg_link;        /* membership in various lists */
+       atomic_t                                        pg_flags;
+       struct page_map                         *pg_mapping; /* for debugging... */
        unsigned long                           pg_index;
+       void                                            **pg_tree_slot;
+       void                                            *pg_private;    /* type depends on page usage */
+       struct semaphore                        pg_sem;         /* for blocking on IO */
+       uint64_t                                gpa;            /* physical address in guest */
+
+       bool                                            pg_is_free;     /* TODO: will remove */
 };
 
 /******** Externally visible global variables ************/
-extern uint8_t* global_cache_colors_map;
-extern spinlock_t colored_page_free_list_lock;
-extern page_list_t LCKD(&colored_page_free_list_lock) * RO CT(llc_num_colors)
-    colored_page_free_list;
+extern spinlock_t page_list_lock;
+extern page_list_t page_free_list;
 
 /*************** Functional Interface *******************/
-void page_alloc_init(void);
-void colored_page_alloc_init(void);
+void base_arena_init(struct multiboot_info *mbi);
 
-error_t upage_alloc(struct proc* p, page_t *SAFE *page, int zero);
-error_t kpage_alloc(page_t *SAFE *page);
-error_t upage_alloc_specific(struct proc* p, page_t *SAFE *page, size_t ppn);
-error_t kpage_alloc_specific(page_t *SAFE *page, size_t ppn);
-error_t colored_upage_alloc(uint8_t* map, page_t *SAFE *page, size_t color);
-error_t page_free(page_t *SAFE page);
+error_t upage_alloc(struct proc *p, page_t **page, bool zero);
+error_t kpage_alloc(page_t **page);
+void *kpage_alloc_addr(void);
+void *kpage_zalloc_addr(void);
 
-void *CT(1 << order) get_cont_pages(size_t order, int flags);
+/* Direct allocation from the kpages arena (instead of kmalloc).  These will
+ * give you PGSIZE quantum. */
+void *kpages_alloc(size_t size, int flags);
+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 free_cont_pages(void *buf, size_t order);
 
-void page_incref(page_t *SAFE page);
-void page_decref(page_t *SAFE page);
-void page_setref(page_t *SAFE page, size_t val);
+void page_decref(page_t *page);
 
 int page_is_free(size_t ppn);
 void lock_page(struct page *page);
 void unlock_page(struct page *page);
+void print_pageinfo(struct page *page);
+static inline bool page_is_pagemap(struct page *page);
 
-#endif //PAGE_ALLOC_H
-
+static inline bool page_is_pagemap(struct page *page)
+{
+       return atomic_read(&page->pg_flags) & PG_PAGEMAP ? true : false;
+}