The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Mark Gross <mgross@linux.co.intel.com>
To: mgross@linux.co.intel.com
Cc: Linus Torvalds <torvalds@osdl.org>, Ingo Molnar <mingo@elte.hu>,
	Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] SMP signal latency fix up.
Date: 06 Nov 2003 17:42:43 -0800	[thread overview]
Message-ID: <1068169363.1831.15.camel@localhost.localdomain> (raw)
In-Reply-To: <1068169185.1831.9.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 5841 bytes --]

On Thu, 2003-11-06 at 17:39, Mark Gross wrote:
> On Thu, 2003-11-06 at 15:20, Linus Torvalds wrote:
> > On 6 Nov 2003, Mark Gross wrote:
> > >
> > > Running on SMP and the 2.6.0-test9 kernel, it takes about 10000 * 1/HZ seconds.  Running this 
> > > command with maxcpus=1 the command finishes in fraction of a second.  Under SMP the 
> > > signal delivery isn't kicking the task if its in the run state on the other CPU.
> > 
> > It looks like the "wake_up_process_kick()" interface is just broken. As it 
> > stands now, it's literally _designed_ to kick the process only when it 
> > wakes it up, which is silly and wrong. It makes no sense to kick a process 
> > that we just woke up, because it _will_ react immediately anyway.
> > 
> > We literally want to kick only processes that didn't need waking up, and 
> > the current interface is totally unsuitable for that.
> > 
> > > The following patch has been tested and seems to fix the problem.  
> > > I'm confident about the change to sched.c actualy fixes a cut and paste bug.
> > 
> > Naah, it's a thinko, the code shouldn't be like that at all.
> > 
> > There's only one user of the "wake_up_process_kick()" thing, and that one 
> > user really wants to kick the process totally independently of waking it 
> > up. Which just implies that we should just have a _regular_ 
> > "wake_up_process()" there, and a _separate_ "kick_process()" thing.
> > 
> > So I've got a feeling that 
> >  - we should remove the "kick" argument from "try_to_wake_up()"
> >  - the signal wakeup case should instead do a _regular_ wakeup.
> >  - we should kick the process if the wakeup _fails_.
> > 
> > Ie signal wakeup should most likely look something like
> > 
> > 
> > 	inline void signal_wake_up(struct task_struct *t, int resume)
> > 	{
> > 		int woken;
> > 		unsigned int mask;
> > 
> > 		set_tsk_thread_flag(t,TIF_SIGPENDING);
> > 		mask = TASK_INTERRUPTIBLE;
> > 		if (resume)
> > 			mask |= TASK_STOPPED;
> > 		woken = 0;
> > 		if (t->state & mask)
> > 			woken = wake_up_state(p, mask);
> > 		if (!woken)
> > 			kick_process(p);
> > 	}
> > 
> > where the "kick_process()" thing does the "is the task running on some 
> > other CPU and if so send it a reschedule event to make it react" thing.
> > 
> > Ingo?
> > 
> > 		Linus
> 
> 
> Are you thinking about something like this?
> 
> It seems to work. I dropped the "task_running" test from
> smp_process_kick intentionaly.  As well as the movement of the success
> flag.  I hope its not too wrong.
> 
> It seems to work on a HT P4 desktop and a dual PIII box.
> 
> --mgross
Evolution messed up my patch.  Retry:

diff -urN -X dontdiff linux-2.6.0-test9/include/linux/sched.h /opt/linux-2.6.0-test9/include/linux/sched.h
--- linux-2.6.0-test9/include/linux/sched.h	2003-10-25 11:42:56.000000000 -0700
+++ /opt/linux-2.6.0-test9/include/linux/sched.h	2003-11-06 14:44:22.000000000 -0800
@@ -573,7 +573,7 @@
 
 extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state));
 extern int FASTCALL(wake_up_process(struct task_struct * tsk));
-extern int FASTCALL(wake_up_process_kick(struct task_struct * tsk));
+extern void FASTCALL(smp_process_kick(struct task_struct * tsk));
 extern void FASTCALL(wake_up_forked_process(struct task_struct * tsk));
 extern void FASTCALL(sched_exit(task_t * p));
 
diff -urN -X dontdiff linux-2.6.0-test9/kernel/sched.c /opt/linux-2.6.0-test9/kernel/sched.c
--- linux-2.6.0-test9/kernel/sched.c	2003-10-25 11:44:29.000000000 -0700
+++ /opt/linux-2.6.0-test9/kernel/sched.c	2003-11-06 14:58:29.000000000 -0800
@@ -585,7 +585,7 @@
  *
  * returns failure only if the task is already active.
  */
-static int try_to_wake_up(task_t * p, unsigned int state, int sync, int kick)
+static int try_to_wake_up(task_t * p, unsigned int state, int sync)
 {
 	unsigned long flags;
 	int success = 0;
@@ -624,13 +624,8 @@
 				if (TASK_PREEMPTS_CURR(p, rq))
 					resched_task(rq->curr);
 			}
-			success = 1;
 		}
-#ifdef CONFIG_SMP
-	       	else
-			if (unlikely(kick) && task_running(rq, p) && (task_cpu(p) != smp_processor_id()))
-				smp_send_reschedule(task_cpu(p));
-#endif
+		success = 1;
 		p->state = TASK_RUNNING;
 	}
 	task_rq_unlock(rq, &flags);
@@ -640,19 +635,22 @@
 
 int wake_up_process(task_t * p)
 {
-	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0, 0);
+	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
 }
 
 EXPORT_SYMBOL(wake_up_process);
 
-int wake_up_process_kick(task_t * p)
+void smp_process_kick(task_t * p)
 {
-	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0, 1);
+#ifdef CONFIG_SMP
+	if (task_cpu(p) != smp_processor_id())
+			smp_send_reschedule(task_cpu(p));
+#endif
 }
 
 int wake_up_state(task_t *p, unsigned int state)
 {
-	return try_to_wake_up(p, state, 0, 0);
+	return try_to_wake_up(p, state, 0);
 }
 
 /*
@@ -1624,7 +1622,7 @@
 int default_wake_function(wait_queue_t *curr, unsigned mode, int sync)
 {
 	task_t *p = curr->task;
-	return try_to_wake_up(p, mode, sync, 0);
+	return try_to_wake_up(p, mode, sync);
 }
 
 EXPORT_SYMBOL(default_wake_function);
diff -urN -X dontdiff linux-2.6.0-test9/kernel/signal.c /opt/linux-2.6.0-test9/kernel/signal.c
--- linux-2.6.0-test9/kernel/signal.c	2003-10-25 11:43:27.000000000 -0700
+++ /opt/linux-2.6.0-test9/kernel/signal.c	2003-11-06 15:05:41.945237624 -0800
@@ -538,6 +538,7 @@
 inline void signal_wake_up(struct task_struct *t, int resume)
 {
 	unsigned int mask;
+	int woken;
 
 	set_tsk_thread_flag(t,TIF_SIGPENDING);
 
@@ -551,10 +552,14 @@
 	mask = TASK_INTERRUPTIBLE;
 	if (resume)
 		mask |= TASK_STOPPED;
+	woken = 0;
 	if (t->state & mask) {
-		wake_up_process_kick(t);
-		return;
+		woken = wake_up_process(t);
 	}
+#ifdef CONFIG_SMP
+	if (!woken) 
+		smp_process_kick(t);
+#endif	
 }
 
 /*



[-- Attachment #2: signal_smp_fix.patch --]
[-- Type: text/x-patch, Size: 3225 bytes --]

diff -urN -X dontdiff linux-2.6.0-test9/include/linux/sched.h /opt/linux-2.6.0-test9/include/linux/sched.h
--- linux-2.6.0-test9/include/linux/sched.h	2003-10-25 11:42:56.000000000 -0700
+++ /opt/linux-2.6.0-test9/include/linux/sched.h	2003-11-06 14:44:22.000000000 -0800
@@ -573,7 +573,7 @@
 
 extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state));
 extern int FASTCALL(wake_up_process(struct task_struct * tsk));
-extern int FASTCALL(wake_up_process_kick(struct task_struct * tsk));
+extern void FASTCALL(smp_process_kick(struct task_struct * tsk));
 extern void FASTCALL(wake_up_forked_process(struct task_struct * tsk));
 extern void FASTCALL(sched_exit(task_t * p));
 
diff -urN -X dontdiff linux-2.6.0-test9/kernel/sched.c /opt/linux-2.6.0-test9/kernel/sched.c
--- linux-2.6.0-test9/kernel/sched.c	2003-10-25 11:44:29.000000000 -0700
+++ /opt/linux-2.6.0-test9/kernel/sched.c	2003-11-06 14:58:29.000000000 -0800
@@ -585,7 +585,7 @@
  *
  * returns failure only if the task is already active.
  */
-static int try_to_wake_up(task_t * p, unsigned int state, int sync, int kick)
+static int try_to_wake_up(task_t * p, unsigned int state, int sync)
 {
 	unsigned long flags;
 	int success = 0;
@@ -624,13 +624,8 @@
 				if (TASK_PREEMPTS_CURR(p, rq))
 					resched_task(rq->curr);
 			}
-			success = 1;
 		}
-#ifdef CONFIG_SMP
-	       	else
-			if (unlikely(kick) && task_running(rq, p) && (task_cpu(p) != smp_processor_id()))
-				smp_send_reschedule(task_cpu(p));
-#endif
+		success = 1;
 		p->state = TASK_RUNNING;
 	}
 	task_rq_unlock(rq, &flags);
@@ -640,19 +635,22 @@
 
 int wake_up_process(task_t * p)
 {
-	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0, 0);
+	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
 }
 
 EXPORT_SYMBOL(wake_up_process);
 
-int wake_up_process_kick(task_t * p)
+void smp_process_kick(task_t * p)
 {
-	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0, 1);
+#ifdef CONFIG_SMP
+	if (task_cpu(p) != smp_processor_id())
+			smp_send_reschedule(task_cpu(p));
+#endif
 }
 
 int wake_up_state(task_t *p, unsigned int state)
 {
-	return try_to_wake_up(p, state, 0, 0);
+	return try_to_wake_up(p, state, 0);
 }
 
 /*
@@ -1624,7 +1622,7 @@
 int default_wake_function(wait_queue_t *curr, unsigned mode, int sync)
 {
 	task_t *p = curr->task;
-	return try_to_wake_up(p, mode, sync, 0);
+	return try_to_wake_up(p, mode, sync);
 }
 
 EXPORT_SYMBOL(default_wake_function);
diff -urN -X dontdiff linux-2.6.0-test9/kernel/signal.c /opt/linux-2.6.0-test9/kernel/signal.c
--- linux-2.6.0-test9/kernel/signal.c	2003-10-25 11:43:27.000000000 -0700
+++ /opt/linux-2.6.0-test9/kernel/signal.c	2003-11-06 15:05:41.945237624 -0800
@@ -538,6 +538,7 @@
 inline void signal_wake_up(struct task_struct *t, int resume)
 {
 	unsigned int mask;
+	int woken;
 
 	set_tsk_thread_flag(t,TIF_SIGPENDING);
 
@@ -551,10 +552,14 @@
 	mask = TASK_INTERRUPTIBLE;
 	if (resume)
 		mask |= TASK_STOPPED;
+	woken = 0;
 	if (t->state & mask) {
-		wake_up_process_kick(t);
-		return;
+		woken = wake_up_process(t);
 	}
+#ifdef CONFIG_SMP
+	if (!woken) 
+		smp_process_kick(t);
+#endif	
 }
 
 /*

  reply	other threads:[~2003-11-07  1:44 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-11-06 22:49 [PATCH] SMP signal latency fix up Mark Gross
2003-11-06 23:20 ` Linus Torvalds
2003-11-07  1:39   ` Mark Gross
2003-11-07  1:42     ` Mark Gross [this message]
2003-11-07  9:45       ` Ingo Molnar
2003-11-07 15:43         ` Mark Gross
2003-11-07  9:39   ` Ingo Molnar
2003-11-07 15:09     ` Linus Torvalds
2003-11-07 15:17       ` Ingo Molnar
2003-11-07 15:31         ` Ingo Molnar
2003-11-07 15:29       ` Ingo Molnar
2003-11-07 17:03     ` Mark Gross
2003-11-08  6:48       ` Ingo Molnar
2003-11-06 23:26 ` Chris Friesen
2003-11-06 23:35   ` Mark Gross
2003-11-07  0:55     ` Nuno Silva
2003-11-07 10:24 ` Ingo Molnar
  -- strict thread matches above, loose matches on Subject: below --
2003-11-06 23:00 Mark Gross

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1068169363.1831.15.camel@localhost.localdomain \
    --to=mgross@linux.co.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox