diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 07e86a8..99e20d1 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -293,17 +293,19 @@ ret:
 static int add_del_listener(pid_t pid, cpumask_t *maskp, int isadd)
 {
 	struct listener_list *listeners;
-	struct listener *s, *tmp;
+	struct listener *s, *tmp, *s2;
 	unsigned int cpu;
 	cpumask_t mask = *maskp;
 
 	if (!cpus_subset(mask, cpu_possible_map))
 		return -EINVAL;
 
+	s = NULL;
 	if (isadd == REGISTER) {
 		for_each_cpu_mask(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;
@@ -312,9 +314,16 @@ static int add_del_listener(pid_t pid, cpumask_t *maskp, 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;
 	}
 
