Skip to content

Commit 8da36b2

Browse files
Matthew Wilcox (Oracle)akpm00
authored andcommitted
mips: implement xor_unlock_is_negative_byte
Inspired by the mips test_and_change_bit(), this will surely be more efficient than the generic one defined in filemap.c Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Matthew Wilcox (Oracle) <[email protected]> Cc: Albert Ou <[email protected]> Cc: Alexander Gordeev <[email protected]> Cc: Andreas Dilger <[email protected]> Cc: Christian Borntraeger <[email protected]> Cc: Christophe Leroy <[email protected]> Cc: Geert Uytterhoeven <[email protected]> Cc: Heiko Carstens <[email protected]> Cc: Ivan Kokshaysky <[email protected]> Cc: Matt Turner <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Nicholas Piggin <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Paul Walmsley <[email protected]> Cc: Richard Henderson <[email protected]> Cc: Sven Schnelle <[email protected]> Cc: "Theodore Ts'o" <[email protected]> Cc: Thomas Bogendoerfer <[email protected]> Cc: Vasily Gorbik <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent ea845e3 commit 8da36b2

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

arch/mips/include/asm/bitops.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ int __mips_test_and_clear_bit(unsigned long nr,
7373
volatile unsigned long *addr);
7474
int __mips_test_and_change_bit(unsigned long nr,
7575
volatile unsigned long *addr);
76-
76+
bool __mips_xor_is_negative_byte(unsigned long mask,
77+
volatile unsigned long *addr);
7778

7879
/*
7980
* set_bit - Atomically set a bit in memory
@@ -279,6 +280,29 @@ static inline int test_and_change_bit(unsigned long nr,
279280
return res;
280281
}
281282

283+
static inline bool xor_unlock_is_negative_byte(unsigned long mask,
284+
volatile unsigned long *p)
285+
{
286+
unsigned long orig;
287+
bool res;
288+
289+
smp_mb__before_atomic();
290+
291+
if (!kernel_uses_llsc) {
292+
res = __mips_xor_is_negative_byte(mask, p);
293+
} else {
294+
orig = __test_bit_op(*p, "%0",
295+
"xor\t%1, %0, %3",
296+
"ir"(mask));
297+
res = (orig & BIT(7)) != 0;
298+
}
299+
300+
smp_llsc_mb();
301+
302+
return res;
303+
}
304+
#define xor_unlock_is_negative_byte xor_unlock_is_negative_byte
305+
282306
#undef __bit_op
283307
#undef __test_bit_op
284308

arch/mips/lib/bitops.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,17 @@ int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
146146
return res;
147147
}
148148
EXPORT_SYMBOL(__mips_test_and_change_bit);
149+
150+
bool __mips_xor_is_negative_byte(unsigned long mask,
151+
volatile unsigned long *addr)
152+
{
153+
unsigned long flags;
154+
unsigned long data;
155+
156+
raw_local_irq_save(flags);
157+
data = *addr;
158+
*addr = data ^ mask;
159+
raw_local_irq_restore(flags);
160+
161+
return (data & BIT(7)) != 0;
162+
}

0 commit comments

Comments
 (0)