From 595c9149eced25d3bc2048ad3c4956968009f582 Mon Sep 17 00:00:00 2001 From: Jinyu Tang Date: Wed, 17 Dec 2025 10:36:02 +0800 Subject: [PATCH] anolis: sw64: fix xor_unlock_is_negative_byte() ANBZ: #26707 We tested on the H8000 and found that running multithreaded programs with this kernel causes the app hang. For example, executing make -j256 to compile kernel. We find that the issue come from xor_unlock_is_negative_byte() lacking proper locking mechanisms. We implemented separate fixes for both the 3B and 4B, which resolved the problem. Signed-off-by: Jinyu Tang Signed-off-by: Yizhou Chen --- arch/sw_64/include/asm/bitops.h | 68 +++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/arch/sw_64/include/asm/bitops.h b/arch/sw_64/include/asm/bitops.h index ec19d38efb61..04eaa086b514 100644 --- a/arch/sw_64/include/asm/bitops.h +++ b/arch/sw_64/include/asm/bitops.h @@ -22,6 +22,31 @@ * bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1). */ +static inline bool xor_unlock_is_negative_byte(unsigned long mask, + volatile unsigned long *p) +{ + unsigned long temp1, temp2, old, base; + + __asm__ __volatile__( + + " ldi %4, %6\n" + "1: lldw %0, 0(%4)\n" + " ldi %1, 1\n" + " wr_f %1\n" + " mov %0, %3\n" + " xor %0, %5,%0\n" + " lstw %0, 0(%4)\n" + " rd_f %0\n" + " beq %0, 2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (temp1), "=&r" (temp2), "=m" (*p), "=&r" (old), "=&r" (base) + : "Ir" (mask), "m" (*p)); + + return (old & BIT(7)) != 0; +} + static inline void set_bit(unsigned long nr, volatile void *addr) { @@ -200,6 +225,29 @@ test_and_change_bit(unsigned long nr, volatile void *addr) } #else /* !CONFIG_SUBARCH_C3B */ + +static inline bool xor_unlock_is_negative_byte(unsigned long mask, + volatile unsigned long *p) +{ + unsigned long temp1, temp2, old, base; + + __asm__ __volatile__( + + " ldi %4, %6\n" + "1: lldw %0, 0(%4)\n" + " mov %0, %3\n" + " xor %0, %5,%0\n" + " lstw %0, 0(%4)\n" + " beq %0, 2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (temp1), "=&r" (temp2), "=m" (*p), "=&r" (old), "=&r" (base) + : "Ir" (mask), "m" (*p)); + + return (old & BIT(7)) != 0; +} + static inline void set_bit(unsigned long nr, volatile void *addr) { @@ -438,26 +486,6 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr) #define arch_test_bit generic_test_bit #define arch_test_bit_acquire generic_test_bit_acquire -static inline bool xor_unlock_is_negative_byte(unsigned long mask, - volatile unsigned long *p) -{ - unsigned long temp, old; - - __asm__ __volatile__( - "1: ldl %0,%4\n" - " mov %0,%2\n" - " xor %0,%3,%0\n" - " stl %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (*p), "=&r" (old) - :"Ir" (mask), "m" (*p)); - - return (old & BIT(7)) != 0; -} - /* * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. -- Gitee