mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	[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>
This commit is contained in:
		
							parent
							
								
									115085ea07
								
							
						
					
					
						commit
						34ec12349c
					
				
					 3 changed files with 25 additions and 26 deletions
				
			
		|  | @ -20,28 +20,6 @@ static inline void taskstats_tgid_init(struct signal_struct *sig) | ||||||
| 	sig->stats = NULL; | 	sig->stats = NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void taskstats_tgid_alloc(struct task_struct *tsk) |  | ||||||
| { |  | ||||||
| 	struct signal_struct *sig = tsk->signal; |  | ||||||
| 	struct taskstats *stats; |  | ||||||
| 
 |  | ||||||
| 	if (sig->stats != NULL) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	/* No problem if kmem_cache_zalloc() fails */ |  | ||||||
| 	stats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); |  | ||||||
| 
 |  | ||||||
| 	spin_lock_irq(&tsk->sighand->siglock); |  | ||||||
| 	if (!sig->stats) { |  | ||||||
| 		sig->stats = stats; |  | ||||||
| 		stats = NULL; |  | ||||||
| 	} |  | ||||||
| 	spin_unlock_irq(&tsk->sighand->siglock); |  | ||||||
| 
 |  | ||||||
| 	if (stats) |  | ||||||
| 		kmem_cache_free(taskstats_cache, stats); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline void taskstats_tgid_free(struct signal_struct *sig) | static inline void taskstats_tgid_free(struct signal_struct *sig) | ||||||
| { | { | ||||||
| 	if (sig->stats) | 	if (sig->stats) | ||||||
|  | @ -55,8 +33,6 @@ static inline void taskstats_exit(struct task_struct *tsk, int group_dead) | ||||||
| {} | {} | ||||||
| static inline void taskstats_tgid_init(struct signal_struct *sig) | static inline void taskstats_tgid_init(struct signal_struct *sig) | ||||||
| {} | {} | ||||||
| static inline void taskstats_tgid_alloc(struct task_struct *tsk) |  | ||||||
| {} |  | ||||||
| static inline void taskstats_tgid_free(struct signal_struct *sig) | static inline void taskstats_tgid_free(struct signal_struct *sig) | ||||||
| {} | {} | ||||||
| static inline void taskstats_init_early(void) | static inline void taskstats_init_early(void) | ||||||
|  |  | ||||||
|  | @ -847,7 +847,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts | ||||||
| 	if (clone_flags & CLONE_THREAD) { | 	if (clone_flags & CLONE_THREAD) { | ||||||
| 		atomic_inc(¤t->signal->count); | 		atomic_inc(¤t->signal->count); | ||||||
| 		atomic_inc(¤t->signal->live); | 		atomic_inc(¤t->signal->live); | ||||||
| 		taskstats_tgid_alloc(current); |  | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); | 	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); | ||||||
|  |  | ||||||
|  | @ -412,6 +412,30 @@ static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | ||||||
| 	return rc; | 	return rc; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) | ||||||
|  | { | ||||||
|  | 	struct signal_struct *sig = tsk->signal; | ||||||
|  | 	struct taskstats *stats; | ||||||
|  | 
 | ||||||
|  | 	if (sig->stats || thread_group_empty(tsk)) | ||||||
|  | 		goto ret; | ||||||
|  | 
 | ||||||
|  | 	/* No problem if kmem_cache_zalloc() fails */ | ||||||
|  | 	stats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); | ||||||
|  | 
 | ||||||
|  | 	spin_lock_irq(&tsk->sighand->siglock); | ||||||
|  | 	if (!sig->stats) { | ||||||
|  | 		sig->stats = stats; | ||||||
|  | 		stats = NULL; | ||||||
|  | 	} | ||||||
|  | 	spin_unlock_irq(&tsk->sighand->siglock); | ||||||
|  | 
 | ||||||
|  | 	if (stats) | ||||||
|  | 		kmem_cache_free(taskstats_cache, stats); | ||||||
|  | ret: | ||||||
|  | 	return sig->stats; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Send pid data out on exit */ | /* Send pid data out on exit */ | ||||||
| void taskstats_exit(struct task_struct *tsk, int group_dead) | void taskstats_exit(struct task_struct *tsk, int group_dead) | ||||||
| { | { | ||||||
|  | @ -433,7 +457,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) | ||||||
| 	size = nla_total_size(sizeof(u32)) + | 	size = nla_total_size(sizeof(u32)) + | ||||||
| 		nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | 		nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | ||||||
| 
 | 
 | ||||||
| 	is_thread_group = (tsk->signal->stats != NULL); | 	is_thread_group = !!taskstats_tgid_alloc(tsk); | ||||||
| 	if (is_thread_group) { | 	if (is_thread_group) { | ||||||
| 		/* PID + STATS + TGID + STATS */ | 		/* PID + STATS + TGID + STATS */ | ||||||
| 		size = 2 * size; | 		size = 2 * size; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Oleg Nesterov
						Oleg Nesterov