Commit ad9beb31 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[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.
parent 17e8935f
...@@ -628,28 +628,37 @@ struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma, ...@@ -628,28 +628,37 @@ 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(root, iter, begin, end);
if (ptr) if (ptr) {
return 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);
else prefetch(next->shared.vm_set.head);
return next;
} else
return NULL; return NULL;
} }
if (vma->shared.vm_set.parent) { if (vma->shared.vm_set.parent) {
if (vma->shared.vm_set.head) if (vma->shared.vm_set.head) {
return vma->shared.vm_set.head; next = vma->shared.vm_set.head;
prefetch(next->shared.vm_set.list.next);
return next;
}
} else { } else {
next = list_entry(vma->shared.vm_set.list.next, next = list_entry(vma->shared.vm_set.list.next,
struct vm_area_struct, shared.vm_set.list); 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; return next;
}
} }
ptr = prio_tree_next(root, iter, begin, end); ptr = prio_tree_next(root, iter, begin, end);
if (ptr) if (ptr) {
return 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);
else prefetch(next->shared.vm_set.head);
return next;
} else
return NULL; return NULL;
} }
EXPORT_SYMBOL(vma_prio_tree_next); EXPORT_SYMBOL(vma_prio_tree_next);
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