From: KAMEZAWA H. <kam...@jp...> - 2008-09-25 09:11:31
|
On Tue, 23 Sep 2008 11:10:17 +0200 Nick Piggin <np...@su...> wrote: > +void *pageable_vmap_object(pgobj_t *object, unsigned long start, unsigned long end) > +{ > + struct file *filp = (struct file *)object; > + struct address_space *mapping = filp->f_dentry->d_inode->i_mapping; > + unsigned int offset = start & ~PAGE_CACHE_MASK; > + pgoff_t first, last, i; > + struct page **pages; > + int nr; > + void *ret; > + > + BUG_ON(start >= end); > + > + first = start / PAGE_SIZE; > + last = DIV_ROUND_UP(end, PAGE_SIZE); > + nr = last - first; > + > +#ifndef CONFIG_HIGHMEM > + if (nr == 1) { > + struct page *page; > + > + rcu_read_lock(); > + page = radix_tree_lookup(&mapping->page_tree, first); > + rcu_read_unlock(); > + BUG_ON(!page); > + BUG_ON(page_count(page) < 2); > + > + ret = page_address(page); > + > + goto out; > + } > +#endif > + > + pages = kmalloc(sizeof(struct page *) * nr, GFP_KERNEL); > + if (!pages) > + return NULL; > + > + for (i = first; i < last; i++) { > + struct page *page; > + > + rcu_read_lock(); > + page = radix_tree_lookup(&mapping->page_tree, i); > + rcu_read_unlock(); > + BUG_ON(!page); > + BUG_ON(page_count(page) < 2); > + > + pages[i] = page; > + } > + > + ret = vmap(pages, nr, VM_MAP, PAGE_KERNEL); > + kfree(pages); > + if (!ret) > + return NULL; > + > +out: > + return ret + offset; > +} > + > +void pageable_vunmap_object(pgobj_t *object, void *ptr, unsigned long start, unsigned long end) > +{ > +#ifndef CONFIG_HIGHMEM > + pgoff_t first, last; > + int nr; > + > + BUG_ON(start >= end); > + > + first = start / PAGE_SIZE; > + last = DIV_ROUND_UP(end, PAGE_SIZE); > + nr = last - first; > + if (nr == 1) > + return; > +#endif > + > + vunmap((void *)((unsigned long)ptr & PAGE_CACHE_MASK)); > +} > + Some questions.. - could you use GFP_HIGHUSER rather than GFP_HIGHUSER_MOVABLE ? I think setting mapping_gfp_mask() (address_space->flags) to appropriate value is enough. - Can we mlock pages while it's vmapped ? (or Reserve and remove from LRU) Then, new split-lru can ignore these pages while there are mapped. over-killing ? - Doesn't we need to increase page->mapcount ? - memory resource contorller should account these pages ? (Maybe this is question to myself....) Thanks, -Kame |