All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Love <rml@tech9.net>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: Andrew Morton <akpm@zip.com.au>,
	George Anzinger <george@mvista.com>,
	lkml <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] preemptive kernel behavior change: don't be rude
Date: 04 Apr 2002 22:09:04 -0500	[thread overview]
Message-ID: <1017976155.22299.746.camel@phantasy> (raw)
In-Reply-To: <Pine.LNX.4.33.0204041740220.7731-100000@penguin.transmeta.com>

Linus and company,

Attached find a final version of the new behavior patch.  It meets
everyone's concerns and it compiles, boots, and survived a basic stress
test here.

The next step would be to push the preempt_count check back into
preempt_schedule and duplicate preempt_schedule in entry.S and then have
it call schedule directly.  This would be both a space and time
optimization.  I will do this, but I'd like to give this as it is some
testing first.

Linus, if this is how you want it, please apply.  Patch is against
2.5.8-pre1.

	Robert Love

diff -urN linux-2.5.8-pre1/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux-2.5.8-pre1/arch/i386/kernel/entry.S	Wed Apr  3 20:57:24 2002
+++ linux/arch/i386/kernel/entry.S	Thu Apr  4 20:44:40 2002
@@ -240,9 +240,7 @@
 	jnz restore_all
 	incl TI_PRE_COUNT(%ebx)
 	sti
-	movl TI_TASK(%ebx), %ecx		# ti->task
-	movl $0,(%ecx)			# current->state = TASK_RUNNING
-	call SYMBOL_NAME(schedule)
+	call SYMBOL_NAME(preempt_schedule)
 	jmp ret_from_intr
 #endif
 
diff -urN linux-2.5.8-pre1/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- linux-2.5.8-pre1/arch/i386/kernel/ptrace.c	Wed Apr  3 20:57:24 2002
+++ linux/arch/i386/kernel/ptrace.c	Thu Apr  4 20:44:40 2002
@@ -455,11 +455,9 @@
 	   between a syscall stop and SIGTRAP delivery */
 	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 					? 0x80 : 0);
-	preempt_disable();
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
-	preempt_enable();
 	/*
 	 * this isn't the same as continuing with a signal, but it will do
 	 * for normal use.  strace only continues with a signal if the
diff -urN linux-2.5.8-pre1/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- linux-2.5.8-pre1/arch/i386/kernel/signal.c	Wed Apr  3 20:57:24 2002
+++ linux/arch/i386/kernel/signal.c	Thu Apr  4 20:44:40 2002
@@ -610,11 +610,9 @@
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
 			/* Let the debugger run.  */
 			current->exit_code = signr;
-			preempt_disable();
 			current->state = TASK_STOPPED;
 			notify_parent(current, SIGCHLD);
 			schedule();
-			preempt_enable();
 
 			/* We're back.  Did the debugger cancel the sig?  */
 			if (!(signr = current->exit_code))
@@ -669,14 +667,12 @@
 
 			case SIGSTOP: {
 				struct signal_struct *sig;
+				current->state = TASK_STOPPED;
 				current->exit_code = signr;
 				sig = current->parent->sig;
-				preempt_disable();
-				current->state = TASK_STOPPED;
 				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
-				preempt_enable();
 				continue;
 			}
 
diff -urN linux-2.5.8-pre1/include/linux/sched.h linux/include/linux/sched.h
--- linux-2.5.8-pre1/include/linux/sched.h	Wed Apr  3 20:57:27 2002
+++ linux/include/linux/sched.h	Thu Apr  4 21:56:11 2002
@@ -91,6 +91,7 @@
 #define TASK_UNINTERRUPTIBLE	2
 #define TASK_ZOMBIE		4
 #define TASK_STOPPED		8
+#define PREEMPT_ACTIVE		0x4000000
 
 #define __set_task_state(tsk, state_value)		\
 	do { (tsk)->state = (state_value); } while (0)
diff -urN linux-2.5.8-pre1/include/linux/spinlock.h linux/include/linux/spinlock.h
--- linux-2.5.8-pre1/include/linux/spinlock.h	Wed Apr  3 20:57:34 2002
+++ linux/include/linux/spinlock.h	Thu Apr  4 21:56:11 2002
@@ -177,8 +177,9 @@
 do { \
 	--current_thread_info()->preempt_count; \
 	barrier(); \
-	if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
-		preempt_schedule(); \
+	if (unlikely(!(current_thread_info()->preempt_count) && \
+		test_thread_flag(TIF_NEED_RESCHED))) \
+			preempt_schedule(); \
 } while (0)
 
 #define spin_lock(lock)	\
diff -urN linux-2.5.8-pre1/kernel/exit.c linux/kernel/exit.c
--- linux-2.5.8-pre1/kernel/exit.c	Wed Apr  3 20:57:37 2002
+++ linux/kernel/exit.c	Thu Apr  4 21:55:29 2002
@@ -499,6 +495,7 @@
 	acct_process(code);
 	__exit_mm(tsk);
 
+	preempt_disable();
 	sem_exit();
 	__exit_files(tsk);
 	__exit_fs(tsk);
diff -urN linux-2.5.8-pre1/kernel/sched.c linux/kernel/sched.c
--- linux-2.5.8-pre1/kernel/sched.c	Wed Apr  3 20:57:37 2002
+++ linux/kernel/sched.c	Thu Apr  4 20:54:17 2002
@@ -764,6 +764,13 @@
 	prev->sleep_timestamp = jiffies;
 	spin_lock_irq(&rq->lock);
 
+	/*
+	 * if entering from preempt_schedule, off a kernel preemption,
+	 * go straight to picking the next task.
+	 */
+	if (unlikely(preempt_get_count() & PREEMPT_ACTIVE))
+		goto pick_next_task;
+
 	switch (prev->state) {
 	case TASK_INTERRUPTIBLE:
 		if (unlikely(signal_pending(prev))) {
@@ -775,9 +782,7 @@
 	case TASK_RUNNING:
 		;
 	}
-#if CONFIG_SMP
 pick_next_task:
-#endif
 	if (unlikely(!rq->nr_running)) {
 #if CONFIG_SMP
 		load_balance(rq, 1);
@@ -841,10 +846,12 @@
  */
 asmlinkage void preempt_schedule(void)
 {
-	if (unlikely(preempt_get_count()))
-		return;
-	current->state = TASK_RUNNING;
-	schedule();
+	do {
+		current_thread_info()->preempt_count += PREEMPT_ACTIVE;
+		schedule();
+		current_thread_info()->preempt_count -= PREEMPT_ACTIVE;
+		barrier();
+	} while(test_thread_flag(TIF_NEED_RESCHED));
 }
 #endif /* CONFIG_PREEMPT */
 


       reply	other threads:[~2002-04-05  3:09 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Pine.LNX.4.33.0204041740220.7731-100000@penguin.transmeta.com>
2002-04-05  3:09 ` Robert Love [this message]
2002-04-05 20:03   ` [PATCH] preemptive kernel behavior change: don't be rude Roger Larsson
2002-04-04 23:55 Patch: linux-2.5.8-pre1/kernel/exit.c change caused BUG() at boot time Linus Torvalds
2002-04-05  0:03 ` [PATCH] preemptive kernel behavior change: don't be rude Robert Love
2002-04-05  1:51   ` george anzinger
2002-04-05  2:06     ` Robert Love

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=1017976155.22299.746.camel@phantasy \
    --to=rml@tech9.net \
    --cc=akpm@zip.com.au \
    --cc=george@mvista.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.