Commit 86de37f0 authored by Rajesh Venkatasubramanian's avatar Rajesh Venkatasubramanian Committed by Linus Torvalds

[PATCH] prio_tree: iterator + vma_prio_tree_next cleanup

Currently we have:

	while ((vma = vma_prio_tree_next(vma, root, &iter,
                                        begin, end)) != NULL)
		do_something_with(vma);

Then iter,root,begin,end are all transfered unchanged to various functions.
 This patch hides them in struct iter instead.

It slightly lessens source, code size, and stack usage.  Patch compiles and
tested lightly.
Signed-off-by: default avatarOleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: default avatarRajesh Venkatasubramanian <vrajesh@umich.edu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e66c6753
...@@ -80,7 +80,7 @@ static void __flush_dcache_page(struct page *page) ...@@ -80,7 +80,7 @@ static void __flush_dcache_page(struct page *page)
{ {
struct address_space *mapping = page_mapping(page); struct address_space *mapping = page_mapping(page);
struct mm_struct *mm = current->active_mm; struct mm_struct *mm = current->active_mm;
struct vm_area_struct *mpnt = NULL; struct vm_area_struct *mpnt;
struct prio_tree_iter iter; struct prio_tree_iter iter;
unsigned long offset; unsigned long offset;
pgoff_t pgoff; pgoff_t pgoff;
...@@ -97,8 +97,7 @@ static void __flush_dcache_page(struct page *page) ...@@ -97,8 +97,7 @@ static void __flush_dcache_page(struct page *page)
pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
flush_dcache_mmap_lock(mapping); flush_dcache_mmap_lock(mapping);
while ((mpnt = vma_prio_tree_next(mpnt, &mapping->i_mmap, vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
&iter, pgoff, pgoff)) != NULL) {
/* /*
* If this VMA is not in our MM, we can ignore it. * If this VMA is not in our MM, we can ignore it.
*/ */
...@@ -128,7 +127,7 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, ...@@ -128,7 +127,7 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
{ {
struct address_space *mapping = page_mapping(page); struct address_space *mapping = page_mapping(page);
struct mm_struct *mm = vma->vm_mm; struct mm_struct *mm = vma->vm_mm;
struct vm_area_struct *mpnt = NULL; struct vm_area_struct *mpnt;
struct prio_tree_iter iter; struct prio_tree_iter iter;
unsigned long offset; unsigned long offset;
pgoff_t pgoff; pgoff_t pgoff;
...@@ -145,8 +144,7 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, ...@@ -145,8 +144,7 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
* cache coherency. * cache coherency.
*/ */
flush_dcache_mmap_lock(mapping); flush_dcache_mmap_lock(mapping);
while ((mpnt = vma_prio_tree_next(mpnt, &mapping->i_mmap, vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
&iter, pgoff, pgoff)) != NULL) {
/* /*
* If this VMA is not in our MM, we can ignore it. * If this VMA is not in our MM, we can ignore it.
* Note that we intentionally mask out the VMA * Note that we intentionally mask out the VMA
......
...@@ -245,7 +245,7 @@ void disable_sr_hashing(void) ...@@ -245,7 +245,7 @@ void disable_sr_hashing(void)
void flush_dcache_page(struct page *page) void flush_dcache_page(struct page *page)
{ {
struct address_space *mapping = page_mapping(page); struct address_space *mapping = page_mapping(page);
struct vm_area_struct *mpnt = NULL; struct vm_area_struct *mpnt;
struct prio_tree_iter iter; struct prio_tree_iter iter;
unsigned long offset; unsigned long offset;
unsigned long addr; unsigned long addr;
...@@ -272,8 +272,7 @@ void flush_dcache_page(struct page *page) ...@@ -272,8 +272,7 @@ void flush_dcache_page(struct page *page)
* to flush one address here for them all to become coherent */ * to flush one address here for them all to become coherent */
flush_dcache_mmap_lock(mapping); flush_dcache_mmap_lock(mapping);
while ((mpnt = vma_prio_tree_next(mpnt, &mapping->i_mmap, vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
&iter, pgoff, pgoff)) != NULL) {
offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
addr = mpnt->vm_start + offset; addr = mpnt->vm_start + offset;
......
...@@ -272,11 +272,10 @@ static void hugetlbfs_drop_inode(struct inode *inode) ...@@ -272,11 +272,10 @@ static void hugetlbfs_drop_inode(struct inode *inode)
static inline void static inline void
hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff) hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
{ {
struct vm_area_struct *vma = NULL; struct vm_area_struct *vma;
struct prio_tree_iter iter; struct prio_tree_iter iter;
while ((vma = vma_prio_tree_next(vma, root, &iter, vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) {
h_pgoff, ULONG_MAX)) != NULL) {
unsigned long h_vm_pgoff; unsigned long h_vm_pgoff;
unsigned long v_length; unsigned long v_length;
unsigned long v_offset; unsigned long v_offset;
......
...@@ -602,9 +602,12 @@ extern void si_meminfo_node(struct sysinfo *val, int nid); ...@@ -602,9 +602,12 @@ extern void si_meminfo_node(struct sysinfo *val, int nid);
void vma_prio_tree_add(struct vm_area_struct *, struct vm_area_struct *old); void vma_prio_tree_add(struct vm_area_struct *, struct vm_area_struct *old);
void vma_prio_tree_insert(struct vm_area_struct *, struct prio_tree_root *); void vma_prio_tree_insert(struct vm_area_struct *, struct prio_tree_root *);
void vma_prio_tree_remove(struct vm_area_struct *, struct prio_tree_root *); void vma_prio_tree_remove(struct vm_area_struct *, struct prio_tree_root *);
struct vm_area_struct *vma_prio_tree_next( struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma,
struct vm_area_struct *, struct prio_tree_root *, struct prio_tree_iter *iter);
struct prio_tree_iter *, pgoff_t begin, pgoff_t end);
#define vma_prio_tree_foreach(vma, iter, root, begin, end) \
for (prio_tree_iter_init(iter, root, begin, end), vma = NULL; \
(vma = vma_prio_tree_next(vma, iter)); )
static inline void vma_nonlinear_insert(struct vm_area_struct *vma, static inline void vma_nonlinear_insert(struct vm_area_struct *vma,
struct list_head *list) struct list_head *list)
......
...@@ -17,8 +17,20 @@ struct prio_tree_iter { ...@@ -17,8 +17,20 @@ struct prio_tree_iter {
unsigned long mask; unsigned long mask;
unsigned long value; unsigned long value;
int size_level; int size_level;
struct prio_tree_root *root;
pgoff_t r_index;
pgoff_t h_index;
}; };
static inline void prio_tree_iter_init(struct prio_tree_iter *iter,
struct prio_tree_root *root, pgoff_t r_index, pgoff_t h_index)
{
iter->root = root;
iter->r_index = r_index;
iter->h_index = h_index;
}
#define INIT_PRIO_TREE_ROOT(ptr) \ #define INIT_PRIO_TREE_ROOT(ptr) \
do { \ do { \
(ptr)->prio_tree_node = NULL; \ (ptr)->prio_tree_node = NULL; \
......
...@@ -1123,12 +1123,12 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, ...@@ -1123,12 +1123,12 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
static inline void unmap_mapping_range_list(struct prio_tree_root *root, static inline void unmap_mapping_range_list(struct prio_tree_root *root,
struct zap_details *details) struct zap_details *details)
{ {
struct vm_area_struct *vma = NULL; struct vm_area_struct *vma;
struct prio_tree_iter iter; struct prio_tree_iter iter;
pgoff_t vba, vea, zba, zea; pgoff_t vba, vea, zba, zea;
while ((vma = vma_prio_tree_next(vma, root, &iter, vma_prio_tree_foreach(vma, &iter, root,
details->first_index, details->last_index)) != NULL) { details->first_index, details->last_index) {
vba = vma->vm_pgoff; vba = vma->vm_pgoff;
vea = vba + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) - 1; vea = vba + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) - 1;
/* Assume for now that PAGE_CACHE_SHIFT == PAGE_SHIFT */ /* Assume for now that PAGE_CACHE_SHIFT == PAGE_SHIFT */
......
...@@ -312,9 +312,7 @@ static void prio_tree_remove(struct prio_tree_root *root, ...@@ -312,9 +312,7 @@ static void prio_tree_remove(struct prio_tree_root *root,
* 'm' is the number of prio_tree_nodes that overlap the interval X. * 'm' is the number of prio_tree_nodes that overlap the interval X.
*/ */
static struct prio_tree_node *prio_tree_left( static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
struct prio_tree_root *root, struct prio_tree_iter *iter,
unsigned long radix_index, unsigned long heap_index,
unsigned long *r_index, unsigned long *h_index) unsigned long *r_index, unsigned long *h_index)
{ {
if (prio_tree_left_empty(iter->cur)) if (prio_tree_left_empty(iter->cur))
...@@ -322,7 +320,7 @@ static struct prio_tree_node *prio_tree_left( ...@@ -322,7 +320,7 @@ static struct prio_tree_node *prio_tree_left(
GET_INDEX(iter->cur->left, *r_index, *h_index); GET_INDEX(iter->cur->left, *r_index, *h_index);
if (radix_index <= *h_index) { if (iter->r_index <= *h_index) {
iter->cur = iter->cur->left; iter->cur = iter->cur->left;
iter->mask >>= 1; iter->mask >>= 1;
if (iter->mask) { if (iter->mask) {
...@@ -336,7 +334,7 @@ static struct prio_tree_node *prio_tree_left( ...@@ -336,7 +334,7 @@ static struct prio_tree_node *prio_tree_left(
iter->mask = ULONG_MAX; iter->mask = ULONG_MAX;
} else { } else {
iter->size_level = 1; iter->size_level = 1;
iter->mask = 1UL << (root->index_bits - 1); iter->mask = 1UL << (iter->root->index_bits - 1);
} }
} }
return iter->cur; return iter->cur;
...@@ -345,9 +343,7 @@ static struct prio_tree_node *prio_tree_left( ...@@ -345,9 +343,7 @@ static struct prio_tree_node *prio_tree_left(
return NULL; return NULL;
} }
static struct prio_tree_node *prio_tree_right( static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
struct prio_tree_root *root, struct prio_tree_iter *iter,
unsigned long radix_index, unsigned long heap_index,
unsigned long *r_index, unsigned long *h_index) unsigned long *r_index, unsigned long *h_index)
{ {
unsigned long value; unsigned long value;
...@@ -360,12 +356,12 @@ static struct prio_tree_node *prio_tree_right( ...@@ -360,12 +356,12 @@ static struct prio_tree_node *prio_tree_right(
else else
value = iter->value | iter->mask; value = iter->value | iter->mask;
if (heap_index < value) if (iter->h_index < value)
return NULL; return NULL;
GET_INDEX(iter->cur->right, *r_index, *h_index); GET_INDEX(iter->cur->right, *r_index, *h_index);
if (radix_index <= *h_index) { if (iter->r_index <= *h_index) {
iter->cur = iter->cur->right; iter->cur = iter->cur->right;
iter->mask >>= 1; iter->mask >>= 1;
iter->value = value; iter->value = value;
...@@ -380,7 +376,7 @@ static struct prio_tree_node *prio_tree_right( ...@@ -380,7 +376,7 @@ static struct prio_tree_node *prio_tree_right(
iter->mask = ULONG_MAX; iter->mask = ULONG_MAX;
} else { } else {
iter->size_level = 1; iter->size_level = 1;
iter->mask = 1UL << (root->index_bits - 1); iter->mask = 1UL << (iter->root->index_bits - 1);
} }
} }
return iter->cur; return iter->cur;
...@@ -405,10 +401,10 @@ static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter) ...@@ -405,10 +401,10 @@ static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
return iter->cur; return iter->cur;
} }
static inline int overlap(unsigned long radix_index, unsigned long heap_index, static inline int overlap(struct prio_tree_iter *iter,
unsigned long r_index, unsigned long h_index) unsigned long r_index, unsigned long h_index)
{ {
return heap_index >= r_index && radix_index <= h_index; return iter->h_index >= r_index && iter->r_index <= h_index;
} }
/* /*
...@@ -418,35 +414,33 @@ static inline int overlap(unsigned long radix_index, unsigned long heap_index, ...@@ -418,35 +414,33 @@ static inline int overlap(unsigned long radix_index, unsigned long heap_index,
* heap_index]. Note that always radix_index <= heap_index. We do a pre-order * heap_index]. Note that always radix_index <= heap_index. We do a pre-order
* traversal of the tree. * traversal of the tree.
*/ */
static struct prio_tree_node *prio_tree_first(struct prio_tree_root *root, static struct prio_tree_node *prio_tree_first(struct prio_tree_iter *iter)
struct prio_tree_iter *iter, unsigned long radix_index,
unsigned long heap_index)
{ {
struct prio_tree_root *root;
unsigned long r_index, h_index; unsigned long r_index, h_index;
INIT_PRIO_TREE_ITER(iter); INIT_PRIO_TREE_ITER(iter);
root = iter->root;
if (prio_tree_empty(root)) if (prio_tree_empty(root))
return NULL; return NULL;
GET_INDEX(root->prio_tree_node, r_index, h_index); GET_INDEX(root->prio_tree_node, r_index, h_index);
if (radix_index > h_index) if (iter->r_index > h_index)
return NULL; return NULL;
iter->mask = 1UL << (root->index_bits - 1); iter->mask = 1UL << (root->index_bits - 1);
iter->cur = root->prio_tree_node; iter->cur = root->prio_tree_node;
while (1) { while (1) {
if (overlap(radix_index, heap_index, r_index, h_index)) if (overlap(iter, r_index, h_index))
return iter->cur; return iter->cur;
if (prio_tree_left(root, iter, radix_index, heap_index, if (prio_tree_left(iter, &r_index, &h_index))
&r_index, &h_index))
continue; continue;
if (prio_tree_right(root, iter, radix_index, heap_index, if (prio_tree_right(iter, &r_index, &h_index))
&r_index, &h_index))
continue; continue;
break; break;
...@@ -459,21 +453,16 @@ static struct prio_tree_node *prio_tree_first(struct prio_tree_root *root, ...@@ -459,21 +453,16 @@ static struct prio_tree_node *prio_tree_first(struct prio_tree_root *root,
* *
* Get the next prio_tree_node that overlaps with the input interval in iter * Get the next prio_tree_node that overlaps with the input interval in iter
*/ */
static struct prio_tree_node *prio_tree_next(struct prio_tree_root *root, static struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
struct prio_tree_iter *iter, unsigned long radix_index,
unsigned long heap_index)
{ {
unsigned long r_index, h_index; unsigned long r_index, h_index;
repeat: repeat:
while (prio_tree_left(root, iter, radix_index, while (prio_tree_left(iter, &r_index, &h_index))
heap_index, &r_index, &h_index)) { if (overlap(iter, r_index, h_index))
if (overlap(radix_index, heap_index, r_index, h_index))
return iter->cur; return iter->cur;
}
while (!prio_tree_right(root, iter, radix_index, while (!prio_tree_right(iter, &r_index, &h_index)) {
heap_index, &r_index, &h_index)) {
while (!prio_tree_root(iter->cur) && while (!prio_tree_root(iter->cur) &&
iter->cur->parent->right == iter->cur) iter->cur->parent->right == iter->cur)
prio_tree_parent(iter); prio_tree_parent(iter);
...@@ -484,7 +473,7 @@ static struct prio_tree_node *prio_tree_next(struct prio_tree_root *root, ...@@ -484,7 +473,7 @@ static struct prio_tree_node *prio_tree_next(struct prio_tree_root *root,
prio_tree_parent(iter); prio_tree_parent(iter);
} }
if (overlap(radix_index, heap_index, r_index, h_index)) if (overlap(iter, r_index, h_index))
return iter->cur; return iter->cur;
goto repeat; goto repeat;
...@@ -622,8 +611,7 @@ void vma_prio_tree_remove(struct vm_area_struct *vma, ...@@ -622,8 +611,7 @@ void vma_prio_tree_remove(struct vm_area_struct *vma,
* page in the given range of contiguous file pages. * page in the given range of contiguous file pages.
*/ */
struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma, struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma,
struct prio_tree_root *root, struct prio_tree_iter *iter, struct prio_tree_iter *iter)
pgoff_t begin, pgoff_t end)
{ {
struct prio_tree_node *ptr; struct prio_tree_node *ptr;
struct vm_area_struct *next; struct vm_area_struct *next;
...@@ -632,7 +620,7 @@ struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma, ...@@ -632,7 +620,7 @@ struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma,
/* /*
* First call is with NULL vma * First call is with NULL vma
*/ */
ptr = prio_tree_first(root, iter, begin, end); ptr = prio_tree_first(iter);
if (ptr) { if (ptr) {
next = prio_tree_entry(ptr, struct vm_area_struct, next = prio_tree_entry(ptr, struct vm_area_struct,
shared.prio_tree_node); shared.prio_tree_node);
...@@ -657,7 +645,7 @@ struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma, ...@@ -657,7 +645,7 @@ struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma,
} }
} }
ptr = prio_tree_next(root, iter, begin, end); ptr = prio_tree_next(iter);
if (ptr) { if (ptr) {
next = prio_tree_entry(ptr, struct vm_area_struct, next = prio_tree_entry(ptr, struct vm_area_struct,
shared.prio_tree_node); shared.prio_tree_node);
......
...@@ -277,15 +277,14 @@ static inline int page_referenced_file(struct page *page) ...@@ -277,15 +277,14 @@ static inline int page_referenced_file(struct page *page)
unsigned int mapcount = page->mapcount; unsigned int mapcount = page->mapcount;
struct address_space *mapping = page->mapping; struct address_space *mapping = page->mapping;
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct vm_area_struct *vma = NULL; struct vm_area_struct *vma;
struct prio_tree_iter iter; struct prio_tree_iter iter;
int referenced = 0; int referenced = 0;
if (!spin_trylock(&mapping->i_mmap_lock)) if (!spin_trylock(&mapping->i_mmap_lock))
return 0; return 0;
while ((vma = vma_prio_tree_next(vma, &mapping->i_mmap, vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
&iter, pgoff, pgoff)) != NULL) {
if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE)) if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE))
== (VM_LOCKED|VM_MAYSHARE)) { == (VM_LOCKED|VM_MAYSHARE)) {
referenced++; referenced++;
...@@ -658,7 +657,7 @@ static inline int try_to_unmap_file(struct page *page) ...@@ -658,7 +657,7 @@ static inline int try_to_unmap_file(struct page *page)
{ {
struct address_space *mapping = page->mapping; struct address_space *mapping = page->mapping;
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct vm_area_struct *vma = NULL; struct vm_area_struct *vma;
struct prio_tree_iter iter; struct prio_tree_iter iter;
int ret = SWAP_AGAIN; int ret = SWAP_AGAIN;
unsigned long cursor; unsigned long cursor;
...@@ -669,8 +668,7 @@ static inline int try_to_unmap_file(struct page *page) ...@@ -669,8 +668,7 @@ static inline int try_to_unmap_file(struct page *page)
if (!spin_trylock(&mapping->i_mmap_lock)) if (!spin_trylock(&mapping->i_mmap_lock))
return ret; return ret;
while ((vma = vma_prio_tree_next(vma, &mapping->i_mmap, vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
&iter, pgoff, pgoff)) != NULL) {
ret = try_to_unmap_one(page, vma); ret = try_to_unmap_one(page, vma);
if (ret == SWAP_FAIL || !page->mapcount) if (ret == SWAP_FAIL || !page->mapcount)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment