Re: [PATCH] fix futex_atomic_op_inuser

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 11 Jun 2006 23:25:43 +0900 (JST), Atsushi Nemoto <anemo@xxxxxxxxxxxxx> wrote:
> I found that NPTL's pthread_cond_signal() does not work properly on
> kernels compiled by gcc 4.1.x.  I suppose inline asm for
> __futex_atomic_op() was wrong.  I suppose:
> 
> 1. "=&r" constraint should be used for oldval.
> 2. Instead of "r" (uaddr), "=R" (*uaddr) for output and "R" (*uaddr)
>    for input should be used.
> 3. "memory" should be added to the clobber list.
> 
> This patch solved the problem.

And here is a patch for 2.6.16-stable tree.

Signed-off-by: Atsushi Nemoto <anemo@xxxxxxxxxxxxx>

diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
index 2454c44..e1f960d 100644
--- a/include/asm-mips/futex.h
+++ b/include/asm-mips/futex.h
@@ -20,26 +20,27 @@
 	"	.set	push					\n"	\
 	"	.set	noat					\n"	\
 	"	.set	mips3					\n"	\
-	"1:	ll	%1, (%3)	# __futex_atomic_op1	\n"	\
+	"1:	ll	%1, %4	# __futex_atomic_op1		\n"	\
 	"	.set	mips0					\n"	\
 	"	" insn	"					\n"	\
 	"	.set	mips3					\n"	\
-	"2:	sc	$1, (%3)				\n"	\
+	"2:	sc	$1, %2					\n"	\
 	"	beqzl	$1, 1b					\n"	\
 	__FUTEX_SMP_SYNC						\
 	"3:							\n"	\
 	"	.set	pop					\n"	\
 	"	.set	mips0					\n"	\
 	"	.section .fixup,\"ax\"				\n"	\
-	"4:	li	%0, %5					\n"	\
+	"4:	li	%0, %6					\n"	\
 	"	j	2b					\n"	\
 	"	.previous					\n"	\
 	"	.section __ex_table,\"a\"			\n"	\
 	"	"__UA_ADDR "\t1b, 4b				\n"	\
 	"	"__UA_ADDR "\t2b, 4b				\n"	\
 	"	.previous					\n"	\
-	: "=r" (ret), "=r" (oldval)					\
-	: "0" (0), "r" (uaddr), "Jr" (oparg), "i" (-EFAULT));		\
+	: "=r" (ret), "=&r" (oldval), "=R" (*uaddr)			\
+	: "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT)		\
+	: "memory");							\
 }
 
 static inline int
@@ -60,23 +61,23 @@ futex_atomic_op_inuser (int encoded_op, 
 
 	switch (op) {
 	case FUTEX_OP_SET:
-		__futex_atomic_op("move	$1, %z4", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("move	$1, %z5", ret, oldval, uaddr, oparg);
 		break;
 
 	case FUTEX_OP_ADD:
-		__futex_atomic_op("addu	$1, %1, %z4",
+		__futex_atomic_op("addu	$1, %1, %z5",
 		                  ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_OR:
-		__futex_atomic_op("or	$1, %1, %z4",
+		__futex_atomic_op("or	$1, %1, %z5",
 		                  ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_ANDN:
-		__futex_atomic_op("and	$1, %1, %z4",
+		__futex_atomic_op("and	$1, %1, %z5",
 		                  ret, oldval, uaddr, ~oparg);
 		break;
 	case FUTEX_OP_XOR:
-		__futex_atomic_op("xor	$1, %1, %z4",
+		__futex_atomic_op("xor	$1, %1, %z5",
 		                  ret, oldval, uaddr, oparg);
 		break;
 	default:


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux