pm_load_page_nowait()
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 7 Feb 2014 06:02:10 +0000 (22:02 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sun, 9 Feb 2014 07:22:59 +0000 (23:22 -0800)
Will only return if the page cache has the page and is up to date.
Meaning, fill it, but don't block.

Some devices could have the ability to fill a page without blocking, so
we can add a PM op for that.

kern/include/pagemap.h
kern/src/pagemap.c

index c23155e..122f18f 100644 (file)
@@ -60,6 +60,8 @@ struct page_map_operations {
 /* Page cache functions */
 void pm_init(struct page_map *pm, struct page_map_operations *op, void *host);
 int pm_load_page(struct page_map *pm, unsigned long index, struct page **pp);
+int pm_load_page_nowait(struct page_map *pm, unsigned long index,
+                        struct page **pp);
 void pm_put_page(struct page *page);
 void pm_add_vmr(struct page_map *pm, struct vm_region *vmr);
 void pm_remove_vmr(struct page_map *pm, struct vm_region *vmr);
index 30d13c2..4a28841 100644 (file)
@@ -247,6 +247,21 @@ load_locked_page:
        return 0;
 }
 
+int pm_load_page_nowait(struct page_map *pm, unsigned long index,
+                        struct page **pp)
+{
+       struct page *page = pm_find_page(pm, index);
+       if (!page)
+               return -EAGAIN;
+       if (!(atomic_read(&page->pg_flags) & PG_UPTODATE)) {
+               /* TODO: could have a read_nowait pm_op */
+               pm_put_page(page);
+               return -EAGAIN;
+       }
+       *pp = page;
+       return 0;
+}
+
 static bool vmr_has_page_idx(struct vm_region *vmr, unsigned long pg_idx)
 {
        unsigned long nr_pgs = (vmr->vm_end - vmr->vm_base) >> PGSHIFT;