diff options
Diffstat (limited to 'kernel/taskstats.c')
| -rw-r--r-- | kernel/taskstats.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 9ffea360a778..e19ce1454ee1 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
| 29 | #include <linux/file.h> | 29 | #include <linux/file.h> |
| 30 | #include <net/genetlink.h> | 30 | #include <net/genetlink.h> |
| 31 | #include <asm/atomic.h> | 31 | #include <linux/atomic.h> |
| 32 | 32 | ||
| 33 | /* | 33 | /* |
| 34 | * Maximum length of a cpumask that can be specified in | 34 | * Maximum length of a cpumask that can be specified in |
| @@ -285,7 +285,7 @@ ret: | |||
| 285 | static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) | 285 | static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) |
| 286 | { | 286 | { |
| 287 | struct listener_list *listeners; | 287 | struct listener_list *listeners; |
| 288 | struct listener *s, *tmp; | 288 | struct listener *s, *tmp, *s2; |
| 289 | unsigned int cpu; | 289 | unsigned int cpu; |
| 290 | 290 | ||
| 291 | if (!cpumask_subset(mask, cpu_possible_mask)) | 291 | if (!cpumask_subset(mask, cpu_possible_mask)) |
| @@ -293,18 +293,25 @@ static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) | |||
| 293 | 293 | ||
| 294 | if (isadd == REGISTER) { | 294 | if (isadd == REGISTER) { |
| 295 | for_each_cpu(cpu, mask) { | 295 | for_each_cpu(cpu, mask) { |
| 296 | s = kmalloc_node(sizeof(struct listener), GFP_KERNEL, | 296 | s = kmalloc_node(sizeof(struct listener), |
| 297 | cpu_to_node(cpu)); | 297 | GFP_KERNEL, cpu_to_node(cpu)); |
| 298 | if (!s) | 298 | if (!s) |
| 299 | goto cleanup; | 299 | goto cleanup; |
| 300 | |||
| 300 | s->pid = pid; | 301 | s->pid = pid; |
| 301 | INIT_LIST_HEAD(&s->list); | ||
| 302 | s->valid = 1; | 302 | s->valid = 1; |
| 303 | 303 | ||
| 304 | listeners = &per_cpu(listener_array, cpu); | 304 | listeners = &per_cpu(listener_array, cpu); |
| 305 | down_write(&listeners->sem); | 305 | down_write(&listeners->sem); |
| 306 | list_for_each_entry(s2, &listeners->list, list) { | ||
| 307 | if (s2->pid == pid && s2->valid) | ||
| 308 | goto exists; | ||
| 309 | } | ||
| 306 | list_add(&s->list, &listeners->list); | 310 | list_add(&s->list, &listeners->list); |
| 311 | s = NULL; | ||
| 312 | exists: | ||
| 307 | up_write(&listeners->sem); | 313 | up_write(&listeners->sem); |
| 314 | kfree(s); /* nop if NULL */ | ||
| 308 | } | 315 | } |
| 309 | return 0; | 316 | return 0; |
| 310 | } | 317 | } |
