aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/taskstats.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 7d793d6b1e90..d2a41339f37b 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -343,6 +343,25 @@ static int parse(struct nlattr *na, cpumask_t *mask)
343 return ret; 343 return ret;
344} 344}
345 345
346static int mk_reply(struct sk_buff *skb, int type, u32 pid, struct taskstats *stats)
347{
348 struct nlattr *na;
349 int aggr;
350
351 aggr = TASKSTATS_TYPE_AGGR_TGID;
352 if (type == TASKSTATS_TYPE_PID)
353 aggr = TASKSTATS_TYPE_AGGR_PID;
354
355 na = nla_nest_start(skb, aggr);
356 NLA_PUT_U32(skb, type, pid);
357 NLA_PUT_TYPE(skb, struct taskstats, TASKSTATS_TYPE_STATS, *stats);
358 nla_nest_end(skb, na);
359
360 return 0;
361nla_put_failure:
362 return -1;
363}
364
346static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) 365static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
347{ 366{
348 int rc = 0; 367 int rc = 0;
@@ -350,7 +369,6 @@ static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
350 struct taskstats stats; 369 struct taskstats stats;
351 void *reply; 370 void *reply;
352 size_t size; 371 size_t size;
353 struct nlattr *na;
354 cpumask_t mask; 372 cpumask_t mask;
355 373
356 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], &mask); 374 rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], &mask);
@@ -382,27 +400,21 @@ static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
382 if (rc < 0) 400 if (rc < 0)
383 goto err; 401 goto err;
384 402
385 na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID); 403 if (mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid, &stats))
386 NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, pid); 404 goto nla_put_failure;
387 NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
388 stats);
389 } else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) { 405 } else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) {
390 u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); 406 u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]);
391 rc = fill_tgid(tgid, NULL, &stats); 407 rc = fill_tgid(tgid, NULL, &stats);
392 if (rc < 0) 408 if (rc < 0)
393 goto err; 409 goto err;
394 410
395 na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID); 411 if (mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid, &stats))
396 NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, tgid); 412 goto nla_put_failure;
397 NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
398 stats);
399 } else { 413 } else {
400 rc = -EINVAL; 414 rc = -EINVAL;
401 goto err; 415 goto err;
402 } 416 }
403 417
404 nla_nest_end(rep_skb, na);
405
406 return send_reply(rep_skb, info->snd_pid); 418 return send_reply(rep_skb, info->snd_pid);
407 419
408nla_put_failure: 420nla_put_failure:
@@ -446,7 +458,6 @@ void taskstats_exit(struct task_struct *tsk, int group_dead)
446 void *reply; 458 void *reply;
447 size_t size; 459 size_t size;
448 int is_thread_group; 460 int is_thread_group;
449 struct nlattr *na;
450 461
451 if (!family_registered) 462 if (!family_registered)
452 return; 463 return;
@@ -481,27 +492,17 @@ void taskstats_exit(struct task_struct *tsk, int group_dead)
481 if (rc < 0) 492 if (rc < 0)
482 goto err_skb; 493 goto err_skb;
483 494
484 na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID); 495 if (mk_reply(rep_skb, TASKSTATS_TYPE_PID, tsk->pid, tidstats))
485 NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, (u32)tsk->pid); 496 goto nla_put_failure;
486 NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
487 *tidstats);
488 nla_nest_end(rep_skb, na);
489
490 if (!is_thread_group)
491 goto send;
492 497
493 /* 498 /*
494 * Doesn't matter if tsk is the leader or the last group member leaving 499 * Doesn't matter if tsk is the leader or the last group member leaving
495 */ 500 */
496 if (!group_dead) 501 if (!is_thread_group || !group_dead)
497 goto send; 502 goto send;
498 503
499 na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID); 504 if (mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tsk->tgid, tsk->signal->stats))
500 NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, (u32)tsk->tgid); 505 goto nla_put_failure;
501 /* No locking needed for tsk->signal->stats since group is dead */
502 NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
503 *tsk->signal->stats);
504 nla_nest_end(rep_skb, na);
505 506
506send: 507send:
507 send_cpu_listeners(rep_skb, listeners); 508 send_cpu_listeners(rep_skb, listeners);