aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/taskstats.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/taskstats.c')
-rw-r--r--kernel/taskstats.c118
1 files changed, 78 insertions, 40 deletions
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 5a651aa63d61..9970cae04f15 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -430,39 +430,46 @@ err:
430 return rc; 430 return rc;
431} 431}
432 432
433static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) 433static int cmd_attr_register_cpumask(struct genl_info *info)
434{ 434{
435 int rc;
436 struct sk_buff *rep_skb;
437 struct taskstats *stats;
438 size_t size;
439 cpumask_var_t mask; 435 cpumask_var_t mask;
436 int rc;
440 437
441 if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 438 if (!alloc_cpumask_var(&mask, GFP_KERNEL))
442 return -ENOMEM; 439 return -ENOMEM;
443
444 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); 440 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask);
445 if (rc < 0) 441 if (rc < 0)
446 goto free_return_rc; 442 goto out;
447 if (rc == 0) { 443 rc = add_del_listener(info->snd_pid, mask, REGISTER);
448 rc = add_del_listener(info->snd_pid, mask, REGISTER); 444out:
449 goto free_return_rc; 445 free_cpumask_var(mask);
450 } 446 return rc;
447}
451 448
449static int cmd_attr_deregister_cpumask(struct genl_info *info)
450{
451 cpumask_var_t mask;
452 int rc;
453
454 if (!alloc_cpumask_var(&mask, GFP_KERNEL))
455 return -ENOMEM;
452 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); 456 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask);
453 if (rc < 0) 457 if (rc < 0)
454 goto free_return_rc; 458 goto out;
455 if (rc == 0) { 459 rc = add_del_listener(info->snd_pid, mask, DEREGISTER);
456 rc = add_del_listener(info->snd_pid, mask, DEREGISTER); 460out:
457free_return_rc:
458 free_cpumask_var(mask);
459 return rc;
460 }
461 free_cpumask_var(mask); 461 free_cpumask_var(mask);
462 return rc;
463}
464
465static int cmd_attr_pid(struct genl_info *info)
466{
467 struct taskstats *stats;
468 struct sk_buff *rep_skb;
469 size_t size;
470 u32 pid;
471 int rc;
462 472
463 /*
464 * Size includes space for nested attributes
465 */
466 size = nla_total_size(sizeof(u32)) + 473 size = nla_total_size(sizeof(u32)) +
467 nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); 474 nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
468 475
@@ -471,33 +478,64 @@ free_return_rc:
471 return rc; 478 return rc;
472 479
473 rc = -EINVAL; 480 rc = -EINVAL;
474 if (info->attrs[TASKSTATS_CMD_ATTR_PID]) { 481 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]);
475 u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]); 482 stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid);
476 stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid); 483 if (!stats)
477 if (!stats) 484 goto err;
478 goto err; 485
479 486 rc = fill_pid(pid, NULL, stats);
480 rc = fill_pid(pid, NULL, stats); 487 if (rc < 0)
481 if (rc < 0) 488 goto err;
482 goto err; 489 return send_reply(rep_skb, info);
483 } else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) { 490err:
484 u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); 491 nlmsg_free(rep_skb);
485 stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid); 492 return rc;
486 if (!stats) 493}
487 goto err; 494
488 495static int cmd_attr_tgid(struct genl_info *info)
489 rc = fill_tgid(tgid, NULL, stats); 496{
490 if (rc < 0) 497 struct taskstats *stats;
491 goto err; 498 struct sk_buff *rep_skb;
492 } else 499 size_t size;
500 u32 tgid;
501 int rc;
502
503 size = nla_total_size(sizeof(u32)) +
504 nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
505
506 rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size);
507 if (rc < 0)
508 return rc;
509
510 rc = -EINVAL;
511 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]);
512 stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid);
513 if (!stats)
493 goto err; 514 goto err;
494 515
516 rc = fill_tgid(tgid, NULL, stats);
517 if (rc < 0)
518 goto err;
495 return send_reply(rep_skb, info); 519 return send_reply(rep_skb, info);
496err: 520err:
497 nlmsg_free(rep_skb); 521 nlmsg_free(rep_skb);
498 return rc; 522 return rc;
499} 523}
500 524
525static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
526{
527 if (info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK])
528 return cmd_attr_register_cpumask(info);
529 else if (info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK])
530 return cmd_attr_deregister_cpumask(info);
531 else if (info->attrs[TASKSTATS_CMD_ATTR_PID])
532 return cmd_attr_pid(info);
533 else if (info->attrs[TASKSTATS_CMD_ATTR_TGID])
534 return cmd_attr_tgid(info);
535 else
536 return -EINVAL;
537}
538
501static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) 539static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk)
502{ 540{
503 struct signal_struct *sig = tsk->signal; 541 struct signal_struct *sig = tsk->signal;