diff options
| author | Oleg Nesterov <oleg@redhat.com> | 2011-08-03 16:21:04 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-03 14:25:20 -1000 | 
| commit | dfc428b656c4693a2334a8d9865b430beddb562a (patch) | |
| tree | ad8aa91d2e3c5e9cedc5f4efb2e04a86b4a0784e | |
| parent | 12b3e038e5bb4860c17d001e92a6fa9964c0a7b9 (diff) | |
| download | olio-linux-3.10-dfc428b656c4693a2334a8d9865b430beddb562a.tar.xz olio-linux-3.10-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.c | 16 | 
1 files changed, 7 insertions, 9 deletions
| diff --git a/kernel/taskstats.c b/kernel/taskstats.c index d1db2880d1c..a09a54936f1 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;  	} |