[patch][rfc] radix-tree: be a nice citizen

Nick Piggin
2007-08-29T08:50:39Z

ISTR that last time I sent you a patch to do the same thing, you
had some objections. I can't remember what they were though, but
I guess you didn't end up merging it.

I was reminded by the problem after seeing an atomic allocation
failure trace from pagecache radix tree inesrtion.

Most pagecache (and some other) radix tree insertions have the great
opportunity to preallocate a few nodes with relaxed gfp flags. But
the preallocation is squandered when it comes time to allocate a node,
we default to first attempting a GFP_ATOMIC allocation -- that doesn't
normally fail, but it can eat into atomic memory reserves that we
don't need to be using.

Signed-off-by: Nick Piggin <npiggin@suse.de>

---
Index: linux-2.6/lib/radix-tree.c
===================================================================
--- linux-2.6.orig/lib/radix-tree.c
+++ linux-2.6/lib/radix-tree.c
@@ -90,11 +90,10 @@ static inline gfp_t root_gfp_mask(struct
static struct radix_tree_node *
radix_tree_node_alloc(struct radix_tree_root *root)
{
- struct radix_tree_node *ret;
+ struct radix_tree_node *ret = NULL;
gfp_t gfp_mask = root_gfp_mask(root);

- ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
- if (ret == NULL && !(gfp_mask & __GFP_WAIT)) {
+ if (!(gfp_mask & __GFP_WAIT)) {
struct radix_tree_preload *rtp;

rtp = &__get_cpu_var(radix_tree_preloads);
@@ -104,6 +103,8 @@ radix_tree_node_alloc(struct radix_tree_
rtp->nr--;
}
}
+ if (ret == NULL)
+ ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
BUG_ON(radix_tree_is_direct_ptr(ret));
return ret;
}