summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2011-08-01 07:27:33 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2011-08-01 07:27:33 -0400
commit6c9e3addce876b5cd708dcc1000c1aa52ec3284c (patch)
tree91b37350a3b010784b3b8e69238759778e06f6db
parent7423cb454e855defd4da22fba789ea5ed638000a (diff)
downloadlongterm-queue-2.6.34-6c9e3addce876b5cd708dcc1000c1aa52ec3284c.tar.gz
add taskstats leak fix patch
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--queue/series5
-rw-r--r--queue/taskstats-don-t-allow-duplicate-entries-in-listener-.patch79
2 files changed, 84 insertions, 0 deletions
diff --git a/queue/series b/queue/series
index 4798144..469fef7 100644
--- a/queue/series
+++ b/queue/series
@@ -69,3 +69,8 @@ nfs4-Ensure-that-ACL-pages-sent-over-NFS-were-not-al.patch
# Content taken from v2.6.32.41
dccp-handle-invalid-feature-options-length.patch
+
+# Content taken from v2.6.32.42
+
+# Content taken from v2.6.32.43
+taskstats-don-t-allow-duplicate-entries-in-listener-.patch
diff --git a/queue/taskstats-don-t-allow-duplicate-entries-in-listener-.patch b/queue/taskstats-don-t-allow-duplicate-entries-in-listener-.patch
new file mode 100644
index 0000000..0c6c3d8
--- /dev/null
+++ b/queue/taskstats-don-t-allow-duplicate-entries-in-listener-.patch
@@ -0,0 +1,79 @@
+From 1520b6af793b21ab1fe48a49f7fbe72202c8ba41 Mon Sep 17 00:00:00 2001
+From: Vasiliy Kulikov <segoon@openwall.com>
+Date: Mon, 27 Jun 2011 16:18:11 -0700
+Subject: [PATCH] taskstats: don't allow duplicate entries in listener mode
+
+commit 26c4caea9d697043cc5a458b96411b86d7f6babd upstream.
+
+Currently a single process may register exit handlers unlimited times.
+It may lead to a bloated listeners chain and very slow process
+terminations.
+
+Eg after 10KK sent TASKSTATS_CMD_ATTR_REGISTER_CPUMASKs ~300 Mb of
+kernel memory is stolen for the handlers chain and "time id" shows 2-7
+seconds instead of normal 0.003. It makes it possible to exhaust all
+kernel memory and to eat much of CPU time by triggerring numerous exits
+on a single CPU.
+
+The patch limits the number of times a single process may register
+itself on a single CPU to one.
+
+One little issue is kept unfixed - as taskstats_exit() is called before
+exit_files() in do_exit(), the orphaned listener entry (if it was not
+explicitly deregistered) is kept until the next someone's exit() and
+implicit deregistration in send_cpu_listeners(). So, if a process
+registered itself as a listener exits and the next spawned process gets
+the same pid, it would inherit taskstats attributes.
+
+Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
+Cc: Balbir Singh <bsingharora@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+
+diff --git a/kernel/taskstats.c b/kernel/taskstats.c
+index 11281d5..5e21645 100644
+--- a/kernel/taskstats.c
++++ b/kernel/taskstats.c
+@@ -292,16 +292,18 @@ ret:
+ static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd)
+ {
+ struct listener_list *listeners;
+- struct listener *s, *tmp;
++ struct listener *s, *tmp, *s2;
+ unsigned int cpu;
+
+ if (!cpumask_subset(mask, cpu_possible_mask))
+ return -EINVAL;
+
++ s = NULL;
+ if (isadd == REGISTER) {
+ for_each_cpu(cpu, mask) {
+- s = kmalloc_node(sizeof(struct listener), GFP_KERNEL,
+- cpu_to_node(cpu));
++ if (!s)
++ s = kmalloc_node(sizeof(struct listener),
++ GFP_KERNEL, cpu_to_node(cpu));
+ if (!s)
+ goto cleanup;
+ s->pid = pid;
+@@ -310,9 +312,16 @@ static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd)
+
+ listeners = &per_cpu(listener_array, cpu);
+ down_write(&listeners->sem);
++ list_for_each_entry_safe(s2, tmp, &listeners->list, list) {
++ if (s2->pid == pid)
++ goto next_cpu;
++ }
+ list_add(&s->list, &listeners->list);
++ s = NULL;
++next_cpu:
+ up_write(&listeners->sem);
+ }
++ kfree(s);
+ return 0;
+ }
+
+--
+1.7.4.4
+