aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2004-03-18 16:04:13 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-03-18 16:04:13 -0800
commit279ce7b25799360a650473ce5cd89b8103faf8f0 (patch)
tree49a4930d9c28f80f41d6c29e34319a216f9a6174 /lib
parent9bd3badff4e7b97209961875014053d6a292af99 (diff)
downloadhistory-279ce7b25799360a650473ce5cd89b8103faf8f0.tar.gz
[PATCH] Hotplug CPUs: Other CPU_DEAD Notifiers
Various files keep per-cpu caches which need to be freed/moved when a CPU goes down. All under CONFIG_HOTPLUG_CPU ifdefs. scsi.c: drain dead cpu's scsi_done_q onto this cpu. buffer.c: brelse the bh_lrus queue for dead cpu. timer.c: migrate timers from dead cpu, being careful of lock order vs __mod_timer. radix_tree.c: free dead cpu's radix_tree_preloads page_alloc.c: empty dead cpu's nr_pagecache_local into nr_pagecache, and free pages on cpu's local cache. slab.c: stop reap_timer for dead cpu, adjust each cache's free limit, and free each slab cache's per-cpu block. swap.c: drain dead cpu's lru_add_pvecs into ours, and empty its committed_space counter into global counter. dev.c: drain device queues from dead cpu into this one. flow.c: drain dead cpu's flow cache.
Diffstat (limited to 'lib')
-rw-r--r--lib/radix-tree.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index cdfb8c6a97f1d5..70ad32ff37ca9c 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -24,6 +24,8 @@
#include <linux/radix-tree.h>
#include <linux/percpu.h>
#include <linux/slab.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
#include <linux/gfp.h>
#include <linux/string.h>
@@ -420,6 +422,28 @@ static __init void radix_tree_init_maxindex(void)
height_to_maxindex[i] = __maxindex(i);
}
+#ifdef CONFIG_HOTPLUG_CPU
+static int radix_tree_callback(struct notifier_block *nfb,
+ unsigned long action,
+ void *hcpu)
+{
+ int cpu = (long)hcpu;
+ struct radix_tree_preload *rtp;
+
+ /* Free per-cpu pool of perloaded nodes */
+ if (action == CPU_DEAD) {
+ rtp = &per_cpu(radix_tree_preloads, cpu);
+ while (rtp->nr) {
+ kmem_cache_free(radix_tree_node_cachep,
+ rtp->nodes[rtp->nr-1]);
+ rtp->nodes[rtp->nr-1] = NULL;
+ rtp->nr--;
+ }
+ }
+ return NOTIFY_OK;
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
void __init radix_tree_init(void)
{
radix_tree_node_cachep = kmem_cache_create("radix_tree_node",
@@ -428,4 +452,5 @@ void __init radix_tree_init(void)
if (!radix_tree_node_cachep)
panic ("Failed to create radix_tree_node cache\n");
radix_tree_init_maxindex();
+ hotcpu_notifier(radix_tree_callback, 0);
}