diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-08-29 09:30:41 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-08-29 09:31:47 +0200 | 
| commit | eebc57f73d42095b778e899f6aa90ad050c72655 (patch) | |
| tree | 2ba80c75e9284093e6d7606dbb1b6a4bb752a2a5 /kernel/fork.c | |
| parent | d3a247bfb2c26f5b67367d58af7ad8c2efbbc6c1 (diff) | |
| parent | 2a4ab640d3c28c2952967e5f63ea495555bf2a5f (diff) | |
Merge branch 'for-ingo' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-sfi-2.6 into x86/apic
Merge reason: the SFI (Simple Firmware Interface) feature in the ACPI
              tree needs this cleanup, pull it into the APIC branch as
	      well so that there's no interactions.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 49 | 
1 files changed, 17 insertions, 32 deletions
| diff --git a/kernel/fork.c b/kernel/fork.c index bd2959228871..e6c04d462ab2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -567,18 +567,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)  	 * the value intact in a core dump, and to save the unnecessary  	 * trouble otherwise.  Userland only wants this done for a sys_exit.  	 */ -	if (tsk->clear_child_tid -	    && !(tsk->flags & PF_SIGNALED) -	    && atomic_read(&mm->mm_users) > 1) { -		u32 __user * tidptr = tsk->clear_child_tid; +	if (tsk->clear_child_tid) { +		if (!(tsk->flags & PF_SIGNALED) && +		    atomic_read(&mm->mm_users) > 1) { +			/* +			 * We don't check the error code - if userspace has +			 * not set up a proper pointer then tough luck. +			 */ +			put_user(0, tsk->clear_child_tid); +			sys_futex(tsk->clear_child_tid, FUTEX_WAKE, +					1, NULL, NULL, 0); +		}  		tsk->clear_child_tid = NULL; - -		/* -		 * We don't check the error code - if userspace has -		 * not set up a proper pointer then tough luck. -		 */ -		put_user(0, tidptr); -		sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);  	}  } @@ -815,11 +815,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)  {  	struct signal_struct *sig; -	if (clone_flags & CLONE_THREAD) { -		atomic_inc(¤t->signal->count); -		atomic_inc(¤t->signal->live); +	if (clone_flags & CLONE_THREAD)  		return 0; -	}  	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);  	tsk->signal = sig; @@ -877,16 +874,6 @@ void __cleanup_signal(struct signal_struct *sig)  	kmem_cache_free(signal_cachep, sig);  } -static void cleanup_signal(struct task_struct *tsk) -{ -	struct signal_struct *sig = tsk->signal; - -	atomic_dec(&sig->live); - -	if (atomic_dec_and_test(&sig->count)) -		__cleanup_signal(sig); -} -  static void copy_flags(unsigned long clone_flags, struct task_struct *p)  {  	unsigned long new_flags = p->flags; @@ -1239,6 +1226,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,  	}  	if (clone_flags & CLONE_THREAD) { +		atomic_inc(¤t->signal->count); +		atomic_inc(¤t->signal->live);  		p->group_leader = current->group_leader;  		list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);  	} @@ -1268,6 +1257,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,  	write_unlock_irq(&tasklist_lock);  	proc_fork_connector(p);  	cgroup_post_fork(p); +	perf_counter_fork(p);  	return p;  bad_fork_free_pid: @@ -1281,7 +1271,8 @@ bad_fork_cleanup_mm:  	if (p->mm)  		mmput(p->mm);  bad_fork_cleanup_signal: -	cleanup_signal(p); +	if (!(clone_flags & CLONE_THREAD)) +		__cleanup_signal(p->signal);  bad_fork_cleanup_sighand:  	__cleanup_sighand(p->sighand);  bad_fork_cleanup_fs: @@ -1407,12 +1398,6 @@ long do_fork(unsigned long clone_flags,  		if (clone_flags & CLONE_VFORK) {  			p->vfork_done = &vfork;  			init_completion(&vfork); -		} else if (!(clone_flags & CLONE_VM)) { -			/* -			 * vfork will do an exec which will call -			 * set_task_comm() -			 */ -			perf_counter_fork(p);  		}  		audit_finish_fork(p); | 
