diff options
author | Andrew Morton <akpm@osdl.org> | 2004-05-22 08:10:33 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-05-22 08:10:33 -0700 |
commit | ad9beb315728e494dd66943054426fd550fe44b8 (patch) | |
tree | a0bcd982b1e79fdff8d0db3be90dbc12a0809a1e /mm | |
parent | 17e8935ff8a2dee9c34add6784d0a073d3e79c66 (diff) | |
download | history-ad9beb315728e494dd66943054426fd550fe44b8.tar.gz |
[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.
Diffstat (limited to 'mm')
-rw-r--r-- | mm/prio_tree.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/mm/prio_tree.c b/mm/prio_tree.c index 605483e044851b..a2a7e6b2dba2c4 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); |