summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2011-08-03 16:21:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-08-03 14:25:20 -1000
commitdfc428b656c4693a2334a8d9865b430beddb562a (patch)
treead8aa91d2e3c5e9cedc5f4efb2e04a86b4a0784e
parent12b3e038e5bb4860c17d001e92a6fa9964c0a7b9 (diff)
downloadlinux-dfc428b656c4693a2334a8d9865b430beddb562a.tar.gz
linux-dfc428b656c4693a2334a8d9865b430beddb562a.tar.bz2
linux-dfc428b656c4693a2334a8d9865b430beddb562a.zip
taskstats: add_del_listener() shouldn't use the wrong node
1. Commit 26c4caea9d69 "don't allow duplicate entries in listener mode" changed add_del_listener(REGISTER) so that "next_cpu:" can reuse the listener allocated for the previous cpu, this doesn't look exactly right even if minor. Change the code to kfree() in the already-registered case, this case is unlikely anyway so the extra kmalloc_node() shouldn't hurt but looke more correct and clean. 2. use the plain list_for_each_entry() instead of _safe() to scan listeners->list. 3. Remove the unneeded INIT_LIST_HEAD(&s->list), we are going to list_add(&s->list). Signed-off-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Vasiliy Kulikov <segoon@openwall.com> Cc: Balbir Singh <bsingharora@gmail.com> Reviewed-by: Jerome Marchand <jmarchan@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/taskstats.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index d1db2880d1cf..a09a54936f19 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -291,30 +291,28 @@ static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd)
if (!cpumask_subset(mask, cpu_possible_mask))
return -EINVAL;
- s = NULL;
if (isadd == REGISTER) {
for_each_cpu(cpu, mask) {
- if (!s)
- s = kmalloc_node(sizeof(struct listener),
- GFP_KERNEL, cpu_to_node(cpu));
+ s = kmalloc_node(sizeof(struct listener),
+ GFP_KERNEL, cpu_to_node(cpu));
if (!s)
goto cleanup;
+
s->pid = pid;
- INIT_LIST_HEAD(&s->list);
s->valid = 1;
listeners = &per_cpu(listener_array, cpu);
down_write(&listeners->sem);
- list_for_each_entry_safe(s2, tmp, &listeners->list, list) {
+ list_for_each_entry(s2, &listeners->list, list) {
if (s2->pid == pid)
- goto next_cpu;
+ goto exists;
}
list_add(&s->list, &listeners->list);
s = NULL;
-next_cpu:
+exists:
up_write(&listeners->sem);
+ kfree(s); /* nop if NULL */
}
- kfree(s);
return 0;
}