From 86de37f0de2be6b0c51c0210dd6533177353f864 Mon Sep 17 00:00:00 2001 From: Rajesh Venkatasubramanian Date: Sun, 22 Aug 2004 22:57:07 -0700 Subject: [PATCH] [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: Oleg Nesterov Signed-off-by: Rajesh Venkatasubramanian Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mm/fault-armv.c | 10 +++---- arch/parisc/kernel/cache.c | 5 ++-- fs/hugetlbfs/inode.c | 5 ++-- include/linux/mm.h | 9 ++++-- include/linux/prio_tree.h | 12 ++++++++ mm/memory.c | 6 ++-- mm/prio_tree.c | 60 +++++++++++++++----------------------- mm/rmap.c | 10 +++---- 8 files changed, 57 insertions(+), 60 deletions(-) diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index d03940c1b6970..b6225a35fea46 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -80,7 +80,7 @@ static void __flush_dcache_page(struct page *page) { struct address_space *mapping = page_mapping(page); struct mm_struct *mm = current->active_mm; - struct vm_area_struct *mpnt = NULL; + struct vm_area_struct *mpnt; struct prio_tree_iter iter; unsigned long offset; pgoff_t pgoff; @@ -97,8 +97,7 @@ static void __flush_dcache_page(struct page *page) pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); flush_dcache_mmap_lock(mapping); - while ((mpnt = vma_prio_tree_next(mpnt, &mapping->i_mmap, - &iter, pgoff, pgoff)) != NULL) { + vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) { /* * 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, { struct address_space *mapping = page_mapping(page); struct mm_struct *mm = vma->vm_mm; - struct vm_area_struct *mpnt = NULL; + struct vm_area_struct *mpnt; struct prio_tree_iter iter; unsigned long offset; pgoff_t pgoff; @@ -145,8 +144,7 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, * cache coherency. */ flush_dcache_mmap_lock(mapping); - while ((mpnt = vma_prio_tree_next(mpnt, &mapping->i_mmap, - &iter, pgoff, pgoff)) != NULL) { + vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) { /* * If this VMA is not in our MM, we can ignore it. * Note that we intentionally mask out the VMA diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index eadc88c5a3d8a..0703ab036826f 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -245,7 +245,7 @@ void disable_sr_hashing(void) void flush_dcache_page(struct page *page) { struct address_space *mapping = page_mapping(page); - struct vm_area_struct *mpnt = NULL; + struct vm_area_struct *mpnt; struct prio_tree_iter iter; unsigned long offset; unsigned long addr; @@ -272,8 +272,7 @@ void flush_dcache_page(struct page *page) * to flush one address here for them all to become coherent */ flush_dcache_mmap_lock(mapping); - while ((mpnt = vma_prio_tree_next(mpnt, &mapping->i_mmap, - &iter, pgoff, pgoff)) != NULL) { + vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) { offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; addr = mpnt->vm_start + offset; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 4ec4283159ea1..90c07ffb7800a 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -272,11 +272,10 @@ static void hugetlbfs_drop_inode(struct inode *inode) static inline void 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; - while ((vma = vma_prio_tree_next(vma, root, &iter, - h_pgoff, ULONG_MAX)) != NULL) { + vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) { unsigned long h_vm_pgoff; unsigned long v_length; unsigned long v_offset; diff --git a/include/linux/mm.h b/include/linux/mm.h index 0e30d4079c8a2..fc87162452946 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -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_insert(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 *, struct prio_tree_root *, - struct prio_tree_iter *, pgoff_t begin, pgoff_t end); +struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma, + struct prio_tree_iter *iter); + +#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, struct list_head *list) diff --git a/include/linux/prio_tree.h b/include/linux/prio_tree.h index 4ac5c62693ec5..6356a511f9ee7 100644 --- a/include/linux/prio_tree.h +++ b/include/linux/prio_tree.h @@ -17,8 +17,20 @@ struct prio_tree_iter { unsigned long mask; unsigned long value; 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) \ do { \ (ptr)->prio_tree_node = NULL; \ diff --git a/mm/memory.c b/mm/memory.c index 05ff4993852b0..57f869fc54ca0 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1123,12 +1123,12 @@ no_new_page: static inline void unmap_mapping_range_list(struct prio_tree_root *root, struct zap_details *details) { - struct vm_area_struct *vma = NULL; + struct vm_area_struct *vma; struct prio_tree_iter iter; pgoff_t vba, vea, zba, zea; - while ((vma = vma_prio_tree_next(vma, root, &iter, - details->first_index, details->last_index)) != NULL) { + vma_prio_tree_foreach(vma, &iter, root, + details->first_index, details->last_index) { vba = vma->vm_pgoff; vea = vba + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) - 1; /* Assume for now that PAGE_CACHE_SHIFT == PAGE_SHIFT */ diff --git a/mm/prio_tree.c b/mm/prio_tree.c index 7608735b39b81..a49ededace39a 100644 --- a/mm/prio_tree.c +++ b/mm/prio_tree.c @@ -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. */ -static struct prio_tree_node *prio_tree_left( - struct prio_tree_root *root, struct prio_tree_iter *iter, - unsigned long radix_index, unsigned long heap_index, +static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter, unsigned long *r_index, unsigned long *h_index) { if (prio_tree_left_empty(iter->cur)) @@ -322,7 +320,7 @@ static struct prio_tree_node *prio_tree_left( 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->mask >>= 1; if (iter->mask) { @@ -336,7 +334,7 @@ static struct prio_tree_node *prio_tree_left( iter->mask = ULONG_MAX; } else { iter->size_level = 1; - iter->mask = 1UL << (root->index_bits - 1); + iter->mask = 1UL << (iter->root->index_bits - 1); } } return iter->cur; @@ -345,9 +343,7 @@ static struct prio_tree_node *prio_tree_left( return NULL; } -static struct prio_tree_node *prio_tree_right( - struct prio_tree_root *root, struct prio_tree_iter *iter, - unsigned long radix_index, unsigned long heap_index, +static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter, unsigned long *r_index, unsigned long *h_index) { unsigned long value; @@ -360,12 +356,12 @@ static struct prio_tree_node *prio_tree_right( else value = iter->value | iter->mask; - if (heap_index < value) + if (iter->h_index < value) return NULL; 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->mask >>= 1; iter->value = value; @@ -380,7 +376,7 @@ static struct prio_tree_node *prio_tree_right( iter->mask = ULONG_MAX; } else { iter->size_level = 1; - iter->mask = 1UL << (root->index_bits - 1); + iter->mask = 1UL << (iter->root->index_bits - 1); } } return iter->cur; @@ -405,10 +401,10 @@ static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter) 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) { - 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, * heap_index]. Note that always radix_index <= heap_index. We do a pre-order * traversal of the tree. */ -static struct prio_tree_node *prio_tree_first(struct prio_tree_root *root, - struct prio_tree_iter *iter, unsigned long radix_index, - unsigned long heap_index) +static struct prio_tree_node *prio_tree_first(struct prio_tree_iter *iter) { + struct prio_tree_root *root; unsigned long r_index, h_index; INIT_PRIO_TREE_ITER(iter); + root = iter->root; if (prio_tree_empty(root)) return NULL; GET_INDEX(root->prio_tree_node, r_index, h_index); - if (radix_index > h_index) + if (iter->r_index > h_index) return NULL; iter->mask = 1UL << (root->index_bits - 1); iter->cur = root->prio_tree_node; while (1) { - if (overlap(radix_index, heap_index, r_index, h_index)) + if (overlap(iter, r_index, h_index)) return iter->cur; - if (prio_tree_left(root, iter, radix_index, heap_index, - &r_index, &h_index)) + if (prio_tree_left(iter, &r_index, &h_index)) continue; - if (prio_tree_right(root, iter, radix_index, heap_index, - &r_index, &h_index)) + if (prio_tree_right(iter, &r_index, &h_index)) continue; break; @@ -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 */ -static struct prio_tree_node *prio_tree_next(struct prio_tree_root *root, - struct prio_tree_iter *iter, unsigned long radix_index, - unsigned long heap_index) +static struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter) { unsigned long r_index, h_index; repeat: - while (prio_tree_left(root, iter, radix_index, - heap_index, &r_index, &h_index)) { - if (overlap(radix_index, heap_index, r_index, h_index)) + while (prio_tree_left(iter, &r_index, &h_index)) + if (overlap(iter, r_index, h_index)) return iter->cur; - } - while (!prio_tree_right(root, iter, radix_index, - heap_index, &r_index, &h_index)) { + while (!prio_tree_right(iter, &r_index, &h_index)) { while (!prio_tree_root(iter->cur) && iter->cur->parent->right == iter->cur) prio_tree_parent(iter); @@ -484,7 +473,7 @@ repeat: prio_tree_parent(iter); } - if (overlap(radix_index, heap_index, r_index, h_index)) + if (overlap(iter, r_index, h_index)) return iter->cur; goto repeat; @@ -622,8 +611,7 @@ void vma_prio_tree_remove(struct vm_area_struct *vma, * page in the given range of contiguous file pages. */ struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma, - struct prio_tree_root *root, struct prio_tree_iter *iter, - pgoff_t begin, pgoff_t end) + struct prio_tree_iter *iter) { struct prio_tree_node *ptr; struct vm_area_struct *next; @@ -632,7 +620,7 @@ struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma, /* * First call is with NULL vma */ - ptr = prio_tree_first(root, iter, begin, end); + ptr = prio_tree_first(iter); if (ptr) { next = prio_tree_entry(ptr, struct vm_area_struct, shared.prio_tree_node); @@ -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) { next = prio_tree_entry(ptr, struct vm_area_struct, shared.prio_tree_node); diff --git a/mm/rmap.c b/mm/rmap.c index 254cf12545d69..d4208d6d8eff4 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -277,15 +277,14 @@ static inline int page_referenced_file(struct page *page) unsigned int mapcount = page->mapcount; struct address_space *mapping = page->mapping; 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; int referenced = 0; if (!spin_trylock(&mapping->i_mmap_lock)) return 0; - while ((vma = vma_prio_tree_next(vma, &mapping->i_mmap, - &iter, pgoff, pgoff)) != NULL) { + vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE)) == (VM_LOCKED|VM_MAYSHARE)) { referenced++; @@ -658,7 +657,7 @@ static inline int try_to_unmap_file(struct page *page) { struct address_space *mapping = page->mapping; 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; int ret = SWAP_AGAIN; unsigned long cursor; @@ -669,8 +668,7 @@ static inline int try_to_unmap_file(struct page *page) if (!spin_trylock(&mapping->i_mmap_lock)) return ret; - while ((vma = vma_prio_tree_next(vma, &mapping->i_mmap, - &iter, pgoff, pgoff)) != NULL) { + vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { ret = try_to_unmap_one(page, vma); if (ret == SWAP_FAIL || !page->mapcount) goto out; -- 2.53.0