diff options
author | Hugh Dickins <hughd@google.com> | 2011-08-03 19:21:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-03 20:25:24 -0400 |
commit | e504f3fdd63d486d45b18009e5a65f2e329acb0a (patch) | |
tree | 2d02a5c29a922fae626a69cd0fc92cae37d7918e /include/linux | |
parent | 31475dd611209413bace21651a400afb91d0bd9d (diff) |
tmpfs radix_tree: locate_item to speed up swapoff
We have already acknowledged that swapoff of a tmpfs file is slower than
it was before conversion to the generic radix_tree: a little slower
there will be acceptable, if the hotter paths are faster.
But it was a shock to find swapoff of a 500MB file 20 times slower on my
laptop, taking 10 minutes; and at that rate it significantly slows down
my testing.
Now, most of that turned out to be overhead from PROVE_LOCKING and
PROVE_RCU: without those it was only 4 times slower than before; and
more realistic tests on other machines don't fare as badly.
I've tried a number of things to improve it, including tagging the swap
entries, then doing lookup by tag: I'd expected that to halve the time,
but in practice it's erratic, and often counter-productive.
The only change I've so far found to make a consistent improvement, is
to short-circuit the way we go back and forth, gang lookup packing
entries into the array supplied, then shmem scanning that array for the
target entry. Scanning in place doubles the speed, so it's now only
twice as slow as before (or three times slower when the PROVEs are on).
So, add radix_tree_locate_item() as an expedient, once-off,
single-caller hack to do the lookup directly in place. #ifdef it on
CONFIG_SHMEM and CONFIG_SWAP, as much to document its limited
applicability as save space in other configurations. And, sadly,
#include sched.h for cond_resched().
Signed-off-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/radix-tree.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index b7edf8251455..9d4539c52e53 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h | |||
@@ -252,6 +252,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
252 | unsigned long nr_to_tag, | 252 | unsigned long nr_to_tag, |
253 | unsigned int fromtag, unsigned int totag); | 253 | unsigned int fromtag, unsigned int totag); |
254 | int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag); | 254 | int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag); |
255 | unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item); | ||
255 | 256 | ||
256 | static inline void radix_tree_preload_end(void) | 257 | static inline void radix_tree_preload_end(void) |
257 | { | 258 | { |