CONFIG_EXT2 controls the loading of the fs_type
[akaros.git] / kern / src / page_alloc.c
index 5262bae..dc83725 100644 (file)
 #include <pmap.h>
 #include <string.h>
 #include <kmalloc.h>
+#include <blockdev.h>
 
 #define l1 (available_caches.l1)
 #define l2 (available_caches.l2)
 #define l3 (available_caches.l3)
 
 static void __page_decref(page_t *CT(1) page);
-static void __page_incref(page_t *CT(1) page);
 static error_t __page_alloc_specific(page_t** page, size_t ppn);
 
 #ifdef __CONFIG_PAGE_COLORING__
@@ -68,8 +68,7 @@ static void __page_clear(page_t *SAFE page)
                *page = LIST_FIRST(&colored_page_free_list[i]);                     \
                LIST_REMOVE(*page, pg_link);                                        \
                __page_clear(*page);                                                \
-               /* Note the 0 initial value, due to how user pages are refcnt'd */  \
-               page_setref((*page), 0);                                            \
+               page_setref((*page), 1);                                            \
                return i;                                                           \
        }                                                                       \
        return -ENOMEM;
@@ -108,14 +107,13 @@ static error_t __page_alloc_specific(page_t** page, size_t ppn)
        *page = sp_page;
        LIST_REMOVE(*page, pg_link);
        __page_clear(*page);
-       /* Note the 0 initial value, due to how user pages are refcnt'd.  If you
-        * have a page, you need to kref_get it before you *use* it. */
-       page_setref(*page, 0);
+       page_setref(*page, 1);
        return 0;
 }
 
 /**
  * @brief Allocates a physical page from a pool of unused physical memory.
+ * Note, the page IS reference counted.
  *
  * Zeroes the page.
  *
@@ -141,6 +139,7 @@ error_t upage_alloc(struct proc* p, page_t** page, int zero)
        return ret;
 }
 
+/* Allocates a refcounted page of memory for the kernel's use */
 error_t kpage_alloc(page_t** page) 
 {
        ssize_t ret;
@@ -151,8 +150,6 @@ error_t kpage_alloc(page_t** page)
 
        if (ret >= 0) {
                global_next_color = ret;        
-               /* this is the "it's okay if it was 0" kref */
-               __kref_get(&(*page)->pg_kref, 1);
                ret = ESUCCESS;
        }
        spin_unlock_irqsave(&colored_page_free_list_lock);
@@ -198,7 +195,6 @@ void *get_cont_pages(size_t order, int flags)
        for(int i=0; i<npages; i++) {
                page_t* page;
                __page_alloc_specific(&page, first+i);
-               __kref_get(&page->pg_kref, 1);
        }
        spin_unlock_irqsave(&colored_page_free_list_lock);
        return ppn2kva(first);
@@ -241,7 +237,6 @@ error_t kpage_alloc_specific(page_t** page, size_t ppn)
 {
        spin_lock_irqsave(&colored_page_free_list_lock);
        __page_alloc_specific(page, ppn);
-       page_incref(*page);
        spin_unlock_irqsave(&colored_page_free_list_lock);
        return 0;
 }
@@ -259,11 +254,6 @@ int page_is_free(size_t ppn) {
  */
 void page_incref(page_t *page)
 {
-       __page_incref(page);
-}
-
-void __page_incref(page_t *page)
-{
        kref_get(&page->pg_kref, 1);
 }
 
@@ -288,6 +278,8 @@ static void page_release(struct kref *kref)
 {
        struct page *page = container_of(kref, struct page, pg_kref);
 
+       if (page->pg_flags & PG_BUFFER)
+               free_bhs(page);
        /* Probably issues with this, get rid of it on a future review */
        __page_clear(page);
        /* Give our page back to the free list.  The protections for this are that
@@ -308,7 +300,9 @@ void page_setref(page_t *page, size_t val)
 }
 
 /* Attempts to get a lock on the page for IO operations.  If it is already
- * locked, it will block the thread until it is unlocked. */
+ * locked, it will block the thread until it is unlocked.  Note that this is
+ * really a "sleep on some event", not necessarily the IO, but it is "the page
+ * is ready". */
 void lock_page(struct page *page)
 {
        /* TODO: (BLK) actually do something!  And this has a race!  Not a big deal
@@ -326,3 +320,32 @@ void unlock_page(struct page *page)
         * a basic interrupt...  */
        page->pg_flags &= ~PG_LOCKED;
 }
+
+void print_pageinfo(struct page *page)
+{
+       int i;
+       if (!page) {
+               printk("Null page\n");
+               return;
+       }
+       printk("Page %d (%08p), Flags: %08p Refcnt: %d\n", page2ppn(page), page2kva(page),
+              page->pg_flags, kref_refcnt(&page->pg_kref));
+       if (page->pg_mapping) {
+               printk("\tMapped into object %08p at index %d\n",
+                      page->pg_mapping->pm_host, page->pg_index);
+       }
+       if (page->pg_flags & PG_BUFFER) {
+               struct buffer_head *bh = (struct buffer_head*)page->pg_private;
+               i = 0;
+               while (bh) {
+                       printk("\tBH %d: buffer: %08p, sector: %d, nr_sector: %d\n", i,
+                              bh->bh_buffer, bh->bh_sector, bh->bh_nr_sector);
+                       i++;
+                       bh = bh->bh_next;
+               }
+               printk("\tPage is %sup to date\n",
+                      page->pg_flags & PG_UPTODATE ? "" : "not ");
+       }
+       printk("\tPage is %slocked\n", page->pg_flags & PG_LOCKED ? "" : "un");
+       printk("\tPage is %s\n", page->pg_flags & PG_DIRTY ? "dirty" : "clean");
+}