Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Oleg Nesterov and committed by
Linus Torvalds
dfc428b6 12b3e038

+7 -9
+7 -9
kernel/taskstats.c
··· 291 291 if (!cpumask_subset(mask, cpu_possible_mask)) 292 292 return -EINVAL; 293 293 294 - s = NULL; 295 294 if (isadd == REGISTER) { 296 295 for_each_cpu(cpu, mask) { 297 - if (!s) 298 - s = kmalloc_node(sizeof(struct listener), 299 - GFP_KERNEL, cpu_to_node(cpu)); 296 + s = kmalloc_node(sizeof(struct listener), 297 + GFP_KERNEL, cpu_to_node(cpu)); 300 298 if (!s) 301 299 goto cleanup; 300 + 302 301 s->pid = pid; 303 - INIT_LIST_HEAD(&s->list); 304 302 s->valid = 1; 305 303 306 304 listeners = &per_cpu(listener_array, cpu); 307 305 down_write(&listeners->sem); 308 - list_for_each_entry_safe(s2, tmp, &listeners->list, list) { 306 + list_for_each_entry(s2, &listeners->list, list) { 309 307 if (s2->pid == pid) 310 - goto next_cpu; 308 + goto exists; 311 309 } 312 310 list_add(&s->list, &listeners->list); 313 311 s = NULL; 314 - next_cpu: 312 + exists: 315 313 up_write(&listeners->sem); 314 + kfree(s); /* nop if NULL */ 316 315 } 317 - kfree(s); 318 316 return 0; 319 317 } 320 318