Allocate ->signal->stats on demand in taskstats_exit(), this allows us to remove taskstats_tgid_alloc() (the last non-trivial inline) from taskstat's public interface.
Showing the changes to kernel/taskstats.c (1 of 3 files). Show all
Unified · Split
| @@ -412,6 +412,30 @@ err: · 411 unmodified lines | |||
| 412 | return rc; | 412 | return rc; |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) | ||
| 416 | { | ||
| 417 | struct signal_struct *sig = tsk->signal; | ||
| 418 | struct taskstats *stats; | ||
| 419 | |||
| 420 | if (sig->stats || thread_group_empty(tsk)) | ||
| 421 | goto ret; | ||
| 422 | |||
| 423 | /* No problem if kmem_cache_zalloc() fails */ | ||
| 424 | stats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); | ||
| 425 | |||
| 426 | spin_lock_irq(&tsk->sighand->siglock); | ||
| 427 | if (!sig->stats) { | ||
| 428 | sig->stats = stats; | ||
| 429 | stats = NULL; | ||
| 430 | } | ||
| 431 | spin_unlock_irq(&tsk->sighand->siglock); | ||
| 432 | |||
| 433 | if (stats) | ||
| 434 | kmem_cache_free(taskstats_cache, stats); | ||
| 435 | ret: | ||
| 436 | return sig->stats; | ||
| 437 | } | ||
| 438 | |||
| 415 | /* Send pid data out on exit */ | 439 | /* Send pid data out on exit */ |
| 416 | void taskstats_exit(struct task_struct *tsk, int group_dead) | 440 | void taskstats_exit(struct task_struct *tsk, int group_dead) |
| 417 | { | 441 | { |
| @@ -433,7 +457,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) · 15 unmodified lines | |||
| 433 | size = nla_total_size(sizeof(u32)) + | 457 | size = nla_total_size(sizeof(u32)) + |
| 434 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | 458 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); |
| 435 | 459 | ||
| 436 | is_thread_group = (tsk->signal->stats != NULL); | 460 | is_thread_group = !!taskstats_tgid_alloc(tsk); |
| 437 | if (is_thread_group) { | 461 | if (is_thread_group) { |
| 438 | /* PID + STATS + TGID + STATS */ | 462 | /* PID + STATS + TGID + STATS */ |
| 439 | size = 2 * size; | 463 | size = 2 * size; |