Skip to content

Commit

Permalink
[PATCH] taskstats_tgid_free: fix usage
Browse files Browse the repository at this point in the history
taskstats_tgid_free() is called on copy_process's error path. This is wrong.

	IF (clone_flags & CLONE_THREAD)
		We should not clear ->signal->taskstats, current uses it,
		it probably has a valid accumulated info.
	ELSE
		taskstats_tgid_init() set ->signal->taskstats = NULL,
		there is nothing to free.

Move the callsite to __exit_signal(). We don't need any locking, entire
thread group is exiting, nobody should have a reference to soon to be
released ->signal.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Shailabh Nagar <nagar@watson.ibm.com>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Jay Lan <jlan@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed Oct 28, 2006
1 parent 05d5bcd commit 093a8e8
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 12 deletions.
13 changes: 2 additions & 11 deletions include/linux/taskstats_kern.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,8 @@ static inline void taskstats_tgid_alloc(struct signal_struct *sig)

static inline void taskstats_tgid_free(struct signal_struct *sig)
{
struct taskstats *stats = NULL;
unsigned long flags;

spin_lock_irqsave(&sig->stats_lock, flags);
if (sig->stats) {
stats = sig->stats;
sig->stats = NULL;
}
spin_unlock_irqrestore(&sig->stats_lock, flags);
if (stats)
kmem_cache_free(taskstats_cache, stats);
if (sig->stats)
kmem_cache_free(taskstats_cache, sig->stats);
}

extern void taskstats_exit_alloc(struct taskstats **, unsigned int *);
Expand Down
1 change: 1 addition & 0 deletions kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ static void __exit_signal(struct task_struct *tsk)
flush_sigqueue(&tsk->pending);
if (sig) {
flush_sigqueue(&sig->shared_pending);
taskstats_tgid_free(sig);
__cleanup_signal(sig);
}
}
Expand Down
1 change: 0 additions & 1 deletion kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
void __cleanup_signal(struct signal_struct *sig)
{
exit_thread_group_keys(sig);
taskstats_tgid_free(sig);
kmem_cache_free(signal_cachep, sig);
}

Expand Down

0 comments on commit 093a8e8

Please sign in to comment.