Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] taskstats: cleanup ->signal->stats allocation

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.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Shailabh Nagar <nagar@watson.ibm.com>
Cc: Jay Lan <jlan@engr.sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Oleg Nesterov and committed by
Linus Torvalds
34ec1234 115085ea

+25 -26
-24
include/linux/taskstats_kern.h
··· 20 20 sig->stats = NULL; 21 21 } 22 22 23 - static inline void taskstats_tgid_alloc(struct task_struct *tsk) 24 - { 25 - struct signal_struct *sig = tsk->signal; 26 - struct taskstats *stats; 27 - 28 - if (sig->stats != NULL) 29 - return; 30 - 31 - /* No problem if kmem_cache_zalloc() fails */ 32 - stats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); 33 - 34 - spin_lock_irq(&tsk->sighand->siglock); 35 - if (!sig->stats) { 36 - sig->stats = stats; 37 - stats = NULL; 38 - } 39 - spin_unlock_irq(&tsk->sighand->siglock); 40 - 41 - if (stats) 42 - kmem_cache_free(taskstats_cache, stats); 43 - } 44 - 45 23 static inline void taskstats_tgid_free(struct signal_struct *sig) 46 24 { 47 25 if (sig->stats) ··· 32 54 static inline void taskstats_exit(struct task_struct *tsk, int group_dead) 33 55 {} 34 56 static inline void taskstats_tgid_init(struct signal_struct *sig) 35 - {} 36 - static inline void taskstats_tgid_alloc(struct task_struct *tsk) 37 57 {} 38 58 static inline void taskstats_tgid_free(struct signal_struct *sig) 39 59 {}
-1
kernel/fork.c
··· 847 847 if (clone_flags & CLONE_THREAD) { 848 848 atomic_inc(&current->signal->count); 849 849 atomic_inc(&current->signal->live); 850 - taskstats_tgid_alloc(current); 851 850 return 0; 852 851 } 853 852 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
+25 -1
kernel/taskstats.c
··· 412 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 439 /* Send pid data out on exit */ 416 440 void taskstats_exit(struct task_struct *tsk, int group_dead) 417 441 { ··· 457 433 size = nla_total_size(sizeof(u32)) + 458 434 nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); 459 435 460 - is_thread_group = (tsk->signal->stats != NULL); 436 + is_thread_group = !!taskstats_tgid_alloc(tsk); 461 437 if (is_thread_group) { 462 438 /* PID + STATS + TGID + STATS */ 463 439 size = 2 * size;