public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] de_thread: Use tsk not current.
@ 2006-07-11  4:42 Eric W. Biederman
  2006-07-11 10:16 ` Andrew Morton
  0 siblings, 1 reply; 4+ messages in thread
From: Eric W. Biederman @ 2006-07-11  4:42 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Oleg Nesterov, Ingo Oeser


Ingo Oeser pointed out that because current expands to an inline function it
is more space efficient and somewhat faster to simply keep a cached copy of
current in another variable.  This patch implements that for the de_thread
function.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 fs/exec.c |   46 +++++++++++++++++++++++-----------------------
 1 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 1dd7d49..4dc39b7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -597,7 +597,7 @@ static int de_thread(struct task_struct 
 	if (!newsighand)
 		return -ENOMEM;
 
-	if (thread_group_empty(current))
+	if (thread_group_empty(tsk))
 		goto no_thread_group;
 
 	/*
@@ -622,17 +622,17 @@ static int de_thread(struct task_struct 
 	 * Reparenting needs write_lock on tasklist_lock,
 	 * so it is safe to do it under read_lock.
 	 */
-	if (unlikely(current->group_leader == child_reaper))
-		child_reaper = current;
+	if (unlikely(tsk->group_leader == child_reaper))
+		child_reaper = tsk;
 
-	zap_other_threads(current);
+	zap_other_threads(tsk);
 	read_unlock(&tasklist_lock);
 
 	/*
 	 * Account for the thread group leader hanging around:
 	 */
 	count = 1;
-	if (!thread_group_leader(current)) {
+	if (!thread_group_leader(tsk)) {
 		count = 2;
 		/*
 		 * The SIGALRM timer survives the exec, but needs to point
@@ -641,14 +641,14 @@ static int de_thread(struct task_struct 
 		 * synchronize with any firing (by calling del_timer_sync)
 		 * before we can safely let the old group leader die.
 		 */
-		sig->tsk = current;
+		sig->tsk = tsk;
 		spin_unlock_irq(lock);
 		if (hrtimer_cancel(&sig->real_timer))
 			hrtimer_restart(&sig->real_timer);
 		spin_lock_irq(lock);
 	}
 	while (atomic_read(&sig->count) > count) {
-		sig->group_exit_task = current;
+		sig->group_exit_task = tsk;
 		sig->notify_count = count;
 		__set_current_state(TASK_UNINTERRUPTIBLE);
 		spin_unlock_irq(lock);
@@ -664,13 +664,13 @@ static int de_thread(struct task_struct 
 	 * do is to wait for the thread group leader to become inactive,
 	 * and to assume its PID:
 	 */
-	if (!thread_group_leader(current)) {
+	if (!thread_group_leader(tsk)) {
 		/*
 		 * Wait for the thread group leader to be a zombie.
 		 * It should already be zombie at this point, most
 		 * of the time.
 		 */
-		leader = current->group_leader;
+		leader = tsk->group_leader;
 		while (leader->exit_state != EXIT_ZOMBIE)
 			yield();
 
@@ -684,12 +684,12 @@ static int de_thread(struct task_struct 
 		 * When we take on its identity by switching to its PID, we
 		 * also take its birthdate (always earlier than our own).
 		 */
-		current->start_time = leader->start_time;
+		tsk->start_time = leader->start_time;
 
 		write_lock_irq(&tasklist_lock);
 
-		BUG_ON(leader->tgid != current->tgid);
-		BUG_ON(current->pid == current->tgid);
+		BUG_ON(leader->tgid != tsk->tgid);
+		BUG_ON(tsk->pid == tsk->tgid);
 		/*
 		 * An exec() starts a new thread group with the
 		 * TGID of the previous thread group. Rehash the
@@ -702,17 +702,17 @@ static int de_thread(struct task_struct 
 		 * Note: The old leader also uses this pid until release_task
 		 *       is called.  Odd but simple and correct.
 		 */
-		detach_pid(current, PIDTYPE_PID);
-		current->pid = leader->pid;
-		attach_pid(current, PIDTYPE_PID,  current->pid);
-		transfer_pid(leader, current, PIDTYPE_PGID);
-		transfer_pid(leader, current, PIDTYPE_SID);
-		list_replace_rcu(&leader->tasks, &current->tasks);
+		detach_pid(tsk, PIDTYPE_PID);
+		tsk->pid = leader->pid;
+		attach_pid(tsk, PIDTYPE_PID,  tsk->pid);
+		transfer_pid(leader, tsk, PIDTYPE_PGID);
+		transfer_pid(leader, tsk, PIDTYPE_SID);
+		list_replace_rcu(&leader->tasks, &tsk->tasks);
 
-		current->group_leader = current;
-		leader->group_leader = current;
+		tsk->group_leader = tsk;
+		leader->group_leader = tsk;
 
-		current->exit_signal = SIGCHLD;
+		tsk->exit_signal = SIGCHLD;
 
 		BUG_ON(leader->exit_state != EXIT_ZOMBIE);
 		leader->exit_state = EXIT_DEAD;
@@ -752,7 +752,7 @@ no_thread_group:
 		spin_lock(&oldsighand->siglock);
 		spin_lock(&newsighand->siglock);
 
-		rcu_assign_pointer(current->sighand, newsighand);
+		rcu_assign_pointer(tsk->sighand, newsighand);
 		recalc_sigpending();
 
 		spin_unlock(&newsighand->siglock);
@@ -763,7 +763,7 @@ no_thread_group:
 			kmem_cache_free(sighand_cachep, oldsighand);
 	}
 
-	BUG_ON(!thread_group_leader(current));
+	BUG_ON(!thread_group_leader(tsk));
 	return 0;
 }
 	
-- 
1.4.1.gac83a


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] de_thread: Use tsk not current.
  2006-07-11  4:42 [PATCH] de_thread: Use tsk not current Eric W. Biederman
@ 2006-07-11 10:16 ` Andrew Morton
  2006-07-11 13:08   ` Nick Piggin
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Morton @ 2006-07-11 10:16 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: linux-kernel, oleg, ioe-lkml

On Mon, 10 Jul 2006 22:42:25 -0600
ebiederm@xmission.com (Eric W. Biederman) wrote:

> 
> Ingo Oeser pointed out that because current expands to an inline function it
> is more space efficient and somewhat faster to simply keep a cached copy of
> current in another variable.  This patch implements that for the de_thread
> function.
> 
> -	if (thread_group_empty(current))
> +	if (thread_group_empty(tsk))
> -	if (unlikely(current->group_leader == child_reaper))
> -		child_reaper = current;
> +	if (unlikely(tsk->group_leader == child_reaper))
> +		child_reaper = tsk;
> -	zap_other_threads(current);
> +	zap_other_threads(tsk);
>  	read_unlock(&tasklist_lock);
> ...

This saves nearly 100 bytes of text on gcc-4.1.0/i686.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] de_thread: Use tsk not current.
  2006-07-11 10:16 ` Andrew Morton
@ 2006-07-11 13:08   ` Nick Piggin
  2006-07-12  8:52     ` Andreas Mohr
  0 siblings, 1 reply; 4+ messages in thread
From: Nick Piggin @ 2006-07-11 13:08 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Eric W. Biederman, linux-kernel, oleg, ioe-lkml

Andrew Morton wrote:
> On Mon, 10 Jul 2006 22:42:25 -0600
> ebiederm@xmission.com (Eric W. Biederman) wrote:
> 
> 
>>Ingo Oeser pointed out that because current expands to an inline function it
>>is more space efficient and somewhat faster to simply keep a cached copy of
>>current in another variable.  This patch implements that for the de_thread
>>function.
>>
>>-	if (thread_group_empty(current))
>>+	if (thread_group_empty(tsk))
>>-	if (unlikely(current->group_leader == child_reaper))
>>-		child_reaper = current;
>>+	if (unlikely(tsk->group_leader == child_reaper))
>>+		child_reaper = tsk;
>>-	zap_other_threads(current);
>>+	zap_other_threads(tsk);
>> 	read_unlock(&tasklist_lock);
>>...
> 
> 
> This saves nearly 100 bytes of text on gcc-4.1.0/i686.

Why can't current be a pure function, I wonder?

-- 
SUSE Labs, Novell Inc.
Send instant messages to your online friends http://au.messenger.yahoo.com 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] de_thread: Use tsk not current.
  2006-07-11 13:08   ` Nick Piggin
@ 2006-07-12  8:52     ` Andreas Mohr
  0 siblings, 0 replies; 4+ messages in thread
From: Andreas Mohr @ 2006-07-12  8:52 UTC (permalink / raw)
  To: Nick Piggin
  Cc: Andrew Morton, Eric W. Biederman, linux-kernel, oleg, ioe-lkml

Hi,

On Tue, Jul 11, 2006 at 11:08:33PM +1000, Nick Piggin wrote:
> Andrew Morton wrote:
> >On Mon, 10 Jul 2006 22:42:25 -0600
> >ebiederm@xmission.com (Eric W. Biederman) wrote:
> >
> >
> >>Ingo Oeser pointed out that because current expands to an inline 
> >>function it
> >>is more space efficient and somewhat faster to simply keep a cached copy 
> >>of
> >>current in another variable.  This patch implements that for the 
> >>de_thread
> >>function.
> >>
> >>-	if (thread_group_empty(current))
> >>+	if (thread_group_empty(tsk))
> >>-	if (unlikely(current->group_leader == child_reaper))
> >>-		child_reaper = current;
> >>+	if (unlikely(tsk->group_leader == child_reaper))
> >>+		child_reaper = tsk;
> >>-	zap_other_threads(current);
> >>+	zap_other_threads(tsk);
> >>	read_unlock(&tasklist_lock);
> >>...
> >
> >
> >This saves nearly 100 bytes of text on gcc-4.1.0/i686.
> 
> Why can't current be a pure function, I wonder?

Most likely due to compiler issues:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17972
(which turns out to deal with current_thread_info() specifically!)
http://www.cs.helsinki.fi/linux/linux-kernel/2003-22/0265.html

However as I've been interested in this issue since I noticed
AGI stalls (pipeline stalls) in oprofile output on x86 recently
due to very non-parallel "mov    %esp,%eax; and    $0xffffe000,%eax"
sequence (but couldn't think of a way to get rid of this),
I'm going to verify what adding pure does with my >= 4.0.0 gcc on my x86 box.

I'm expecting quite some *general* performance improvement in the
low percentage range here...
(since this would be much more than simply merging multiple "current"
into a local stack variable, since *every* current_thread_info() call
would benefit from this and current_tread_info() is used all over the
place in high-profile call sites)

If this works for >= 4.0.0, then I'll try to add conditional support
for pure etc. in our compiler version dependent infrastructure headers.

Plus, we also access current_thread_info() related things within loops
in some cases; would be much better then to store it in a stack variable
outside, methinks. Or could this conflict with aggressive preemption???

Andreas Mohr

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-07-12  8:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-11  4:42 [PATCH] de_thread: Use tsk not current Eric W. Biederman
2006-07-11 10:16 ` Andrew Morton
2006-07-11 13:08   ` Nick Piggin
2006-07-12  8:52     ` Andreas Mohr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox