On Tue, 23 Sep 2008 11:10:17 +0200
Nick Piggin <[EMAIL PROTECTED]> 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


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to