diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2011-08-01 07:27:33 -0400 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2011-08-01 07:27:33 -0400 |
commit | 6c9e3addce876b5cd708dcc1000c1aa52ec3284c (patch) | |
tree | 91b37350a3b010784b3b8e69238759778e06f6db | |
parent | 7423cb454e855defd4da22fba789ea5ed638000a (diff) | |
download | longterm-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/series | 5 | ||||
-rw-r--r-- | queue/taskstats-don-t-allow-duplicate-entries-in-listener-.patch | 79 |
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 + |