Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-05-22 08:10:33 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-05-22 08:10:33 -0700
commitad9beb315728e494dd66943054426fd550fe44b8 (patch)
treea0bcd982b1e79fdff8d0db3be90dbc12a0809a1e
parent17e8935ff8a2dee9c34add6784d0a073d3e79c66 (diff)
[PATCH] partial prefetch for vma_prio_tree_next
From: Rajesh Venkatasubramanian <vrajesh@umich.edu> This patch adds prefetches for walking a vm_set.list. Adding prefetches for prio tree traversals is tricky and may lead to cache trashing. So this patch just adds prefetches only when walking a vm_set.list. I haven't done any benchmarks to show that this patch improves performance. However, this patch should help to improve performance when vm_set.lists are long, e.g., libc. Since we only prefetch vmas that are guaranteed to be used in the near future, this patch should not result in cache trashing, theoretically. I didn't add any NULL checks before prefetching because prefetch.h clearly says prefetch(0) is okay.
-rw-r--r--mm/prio_tree.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/mm/prio_tree.c b/mm/prio_tree.c
index 605483e04485..a2a7e6b2dba2 100644
--- a/mm/prio_tree.c
+++ b/mm/prio_tree.c
@@ -628,28 +628,37 @@ 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);
- if (ptr)
- return prio_tree_entry(ptr, struct vm_area_struct,
+ if (ptr) {
+ next = prio_tree_entry(ptr, struct vm_area_struct,
shared.prio_tree_node);
- else
+ prefetch(next->shared.vm_set.head);
+ return next;
+ } else
return NULL;
}
if (vma->shared.vm_set.parent) {
- if (vma->shared.vm_set.head)
- return vma->shared.vm_set.head;
+ if (vma->shared.vm_set.head) {
+ next = vma->shared.vm_set.head;
+ prefetch(next->shared.vm_set.list.next);
+ return next;
+ }
} else {
next = list_entry(vma->shared.vm_set.list.next,
struct vm_area_struct, shared.vm_set.list);
- if (!next->shared.vm_set.head)
+ if (!next->shared.vm_set.head) {
+ prefetch(next->shared.vm_set.list.next);
return next;
+ }
}
ptr = prio_tree_next(root, iter, begin, end);
- if (ptr)
- return prio_tree_entry(ptr, struct vm_area_struct,
+ if (ptr) {
+ next = prio_tree_entry(ptr, struct vm_area_struct,
shared.prio_tree_node);
- else
+ prefetch(next->shared.vm_set.head);
+ return next;
+ } else
return NULL;
}
EXPORT_SYMBOL(vma_prio_tree_next);