important ppc64 bug fixes

Anton Blanchard anton at samba.org
Wed Nov 12 04:17:31 EST 2003


> - fix signal wakeup race due to unordered access of SIGPENDING and
>   TASK_INTERRUPTIBLE				(Anton)

The arch independent bit (havent compile tested this yet). I originally
added smp_mb()'s around set/clear_thread_flag but ended up putting it in
the functions themselves.

Thoughts?

===== include/linux/thread_info.h 1.5 vs edited =====
--- 1.5/include/linux/thread_info.h	Tue Mar 18 16:32:12 2003
+++ edited/include/linux/thread_info.h	Mon Nov 10 04:55:14 2003
@@ -25,16 +25,18 @@
 /*
  * flag set/clear/test wrappers
  * - pass TIF_xxxx constants to these functions
+ * - we use the test_and_* bitop versions because they guarantee memory
+ *   ordering
  */

 static inline void set_thread_flag(int flag)
 {
-	set_bit(flag,&current_thread_info()->flags);
+	(void)test_and_set_bit(flag,&current_thread_info()->flags);
 }

 static inline void clear_thread_flag(int flag)
 {
-	clear_bit(flag,&current_thread_info()->flags);
+	(void)test_and_clear_bit(flag,&current_thread_info()->flags);
 }

 static inline int test_and_set_thread_flag(int flag)
@@ -54,12 +56,12 @@

 static inline void set_ti_thread_flag(struct thread_info *ti, int flag)
 {
-	set_bit(flag,&ti->flags);
+	(void)test_and_set_bit(flag,&ti->flags);
 }

 static inline void clear_ti_thread_flag(struct thread_info *ti, int flag)
 {
-	clear_bit(flag,&ti->flags);
+	(void)test_and_clear_bit(flag,&ti->flags);
 }

 static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag)
===== kernel/signal.c 1.98 vs edited =====
--- 1.98/kernel/signal.c	Fri Oct 10 08:13:54 2003
+++ edited/kernel/signal.c	Wed Oct 22 16:37:37 2003
@@ -2112,7 +2114,7 @@
 			recalc_sigpending();
 			spin_unlock_irq(&current->sighand->siglock);

-			current->state = TASK_INTERRUPTIBLE;
+			set_current_state(TASK_INTERRUPTIBLE);
 			timeout = schedule_timeout(timeout);

 			spin_lock_irq(&current->sighand->siglock);
@@ -2534,7 +2536,7 @@
 asmlinkage long
 sys_pause(void)
 {
-	current->state = TASK_INTERRUPTIBLE;
+	set_current_state(TASK_INTERRUPTIBLE);
 	schedule();
 	return -ERESTARTNOHAND;
 }

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list