diff options
Diffstat (limited to 'kernel/taskstats.c')
| -rw-r--r-- | kernel/taskstats.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 6d7dc4ec4aa5..888adbcca30c 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
| @@ -290,18 +290,17 @@ ret: | |||
| 290 | return; | 290 | return; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | static int add_del_listener(pid_t pid, cpumask_t *maskp, int isadd) | 293 | static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) |
| 294 | { | 294 | { |
| 295 | struct listener_list *listeners; | 295 | struct listener_list *listeners; |
| 296 | struct listener *s, *tmp; | 296 | struct listener *s, *tmp; |
| 297 | unsigned int cpu; | 297 | unsigned int cpu; |
| 298 | cpumask_t mask = *maskp; | ||
| 299 | 298 | ||
| 300 | if (!cpus_subset(mask, cpu_possible_map)) | 299 | if (!cpumask_subset(mask, cpu_possible_mask)) |
| 301 | return -EINVAL; | 300 | return -EINVAL; |
| 302 | 301 | ||
| 303 | if (isadd == REGISTER) { | 302 | if (isadd == REGISTER) { |
| 304 | for_each_cpu_mask_nr(cpu, mask) { | 303 | for_each_cpu(cpu, mask) { |
| 305 | s = kmalloc_node(sizeof(struct listener), GFP_KERNEL, | 304 | s = kmalloc_node(sizeof(struct listener), GFP_KERNEL, |
| 306 | cpu_to_node(cpu)); | 305 | cpu_to_node(cpu)); |
| 307 | if (!s) | 306 | if (!s) |
| @@ -320,7 +319,7 @@ static int add_del_listener(pid_t pid, cpumask_t *maskp, int isadd) | |||
| 320 | 319 | ||
| 321 | /* Deregister or cleanup */ | 320 | /* Deregister or cleanup */ |
| 322 | cleanup: | 321 | cleanup: |
| 323 | for_each_cpu_mask_nr(cpu, mask) { | 322 | for_each_cpu(cpu, mask) { |
| 324 | listeners = &per_cpu(listener_array, cpu); | 323 | listeners = &per_cpu(listener_array, cpu); |
| 325 | down_write(&listeners->sem); | 324 | down_write(&listeners->sem); |
| 326 | list_for_each_entry_safe(s, tmp, &listeners->list, list) { | 325 | list_for_each_entry_safe(s, tmp, &listeners->list, list) { |
| @@ -335,7 +334,7 @@ cleanup: | |||
| 335 | return 0; | 334 | return 0; |
| 336 | } | 335 | } |
| 337 | 336 | ||
| 338 | static int parse(struct nlattr *na, cpumask_t *mask) | 337 | static int parse(struct nlattr *na, struct cpumask *mask) |
| 339 | { | 338 | { |
| 340 | char *data; | 339 | char *data; |
| 341 | int len; | 340 | int len; |
| @@ -428,23 +427,33 @@ err: | |||
| 428 | 427 | ||
| 429 | static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | 428 | static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) |
| 430 | { | 429 | { |
| 431 | int rc = 0; | 430 | int rc; |
| 432 | struct sk_buff *rep_skb; | 431 | struct sk_buff *rep_skb; |
| 433 | struct taskstats *stats; | 432 | struct taskstats *stats; |
| 434 | size_t size; | 433 | size_t size; |
| 435 | cpumask_t mask; | 434 | cpumask_var_t mask; |
| 435 | |||
| 436 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | ||
| 437 | return -ENOMEM; | ||
| 436 | 438 | ||
| 437 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], &mask); | 439 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); |
| 438 | if (rc < 0) | 440 | if (rc < 0) |
| 439 | return rc; | 441 | goto free_return_rc; |
| 440 | if (rc == 0) | 442 | if (rc == 0) { |
| 441 | return add_del_listener(info->snd_pid, &mask, REGISTER); | 443 | rc = add_del_listener(info->snd_pid, mask, REGISTER); |
| 444 | goto free_return_rc; | ||
| 445 | } | ||
| 442 | 446 | ||
| 443 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], &mask); | 447 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); |
| 444 | if (rc < 0) | 448 | if (rc < 0) |
| 449 | goto free_return_rc; | ||
| 450 | if (rc == 0) { | ||
| 451 | rc = add_del_listener(info->snd_pid, mask, DEREGISTER); | ||
| 452 | free_return_rc: | ||
| 453 | free_cpumask_var(mask); | ||
| 445 | return rc; | 454 | return rc; |
| 446 | if (rc == 0) | 455 | } |
| 447 | return add_del_listener(info->snd_pid, &mask, DEREGISTER); | 456 | free_cpumask_var(mask); |
| 448 | 457 | ||
| 449 | /* | 458 | /* |
| 450 | * Size includes space for nested attributes | 459 | * Size includes space for nested attributes |
