From 9b34eb708314dd0786b8a904f5c223be55123ff2 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Wed, 25 Sep 2002 18:04:38 -0700
Subject: [PATCH] [PATCH] exit-fix-2.5.38-F0

From Andrew Morton.

There are a couple of places where we would enable interrupts while
write-holding the tasklist_lock ...  nasty.
---
 kernel/sched.c  | 6 ++++--
 kernel/signal.c | 5 +++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 9965e5f7549e..c4ba26fd875a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -477,13 +477,15 @@ void wake_up_forked_process(task_t * p)
  */
 void sched_exit(task_t * p)
 {
-	local_irq_disable();
+	unsigned long flags;
+
+	local_irq_save(flags);
 	if (p->first_time_slice) {
 		p->parent->time_slice += p->time_slice;
 		if (unlikely(p->parent->time_slice > MAX_TIMESLICE))
 			p->parent->time_slice = MAX_TIMESLICE;
 	}
-	local_irq_enable();
+	local_irq_restore(flags);
 	/*
 	 * If the child was a (relative-) CPU hog then decrease
 	 * the sleep_avg of the parent as well.
diff --git a/kernel/signal.c b/kernel/signal.c
index 013c7a899152..86c999cdecfd 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1086,6 +1086,7 @@ kill_proc(pid_t pid, int sig, int priv)
  */
 static inline void wake_up_parent(struct task_struct *p)
 {
+	unsigned long flags;
 	struct task_struct *parent = p->parent, *tsk = parent;
 
 	/*
@@ -1095,14 +1096,14 @@ static inline void wake_up_parent(struct task_struct *p)
 		wake_up_interruptible(&tsk->wait_chldexit);
 		return;
 	}
-	spin_lock_irq(&parent->sig->siglock);
+	spin_lock_irqsave(&parent->sig->siglock, flags);
 	do {
 		wake_up_interruptible(&tsk->wait_chldexit);
 		tsk = next_thread(tsk);
 		if (tsk->sig != parent->sig)
 			BUG();
 	} while (tsk != parent);
-	spin_unlock_irq(&parent->sig->siglock);
+	spin_unlock_irqrestore(&parent->sig->siglock, flags);
 }
 
 /*
-- 
2.30.9