aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilad Ben-Yossef <gilad@benyossef.com>2012-03-28 14:42:45 -0700
committerSteven Rostedt <rostedt@rostedt.homelinux.com>2014-01-17 10:13:18 -0500
commit076adbef08819f460ec8eba0d9e02114ed71254d (patch)
tree996b92f026ab83c518b21a76362f3858b2d0d1ec
parent5aada3eed524213e6349815bb363e662edf924e3 (diff)
fs: only send IPI to invalidate LRU BH when needed
[ Upstream commit 42be35d0390b966253136a285f507f5ad00fd9e8 ] In several code paths, such as when unmounting a file system (but not only) we send an IPI to ask each cpu to invalidate its local LRU BHs. For multi-cores systems that have many cpus that may not have any LRU BH because they are idle or because they have not performed any file system accesses since last invalidation (e.g. CPU crunching on high perfomance computing nodes that write results to shared memory or only using filesystems that do not use the bh layer.) This can lead to loss of performance each time someone switches the KVM (the virtual keyboard and screen type, not the hypervisor) if it has a USB storage stuck in. This patch attempts to only send an IPI to cpus that have LRU BH. Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--fs/buffer.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 997b199bffca..36d49f1364de 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1425,10 +1425,23 @@ static void invalidate_bh_lru(void *arg)
}
put_cpu_var(bh_lrus);
}
+
+static bool has_bh_in_lru(int cpu, void *dummy)
+{
+ struct bh_lru *b = per_cpu_ptr(&bh_lrus, cpu);
+ int i;
+ for (i = 0; i < BH_LRU_SIZE; i++) {
+ if (b->bhs[i])
+ return 1;
+ }
+
+ return 0;
+}
+
void invalidate_bh_lrus(void)
{
- on_each_cpu(invalidate_bh_lru, NULL, 1);
+ on_each_cpu_cond(has_bh_in_lru, invalidate_bh_lru, NULL, 1, GFP_KERNEL);
}
EXPORT_SYMBOL_GPL(invalidate_bh_lrus);