git: 1bb1d38e4160 - stable/15 - Revert "atomic: Implement atomic_{set,clear}_8 in _atomic_subword.h"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 24 Aug 2026 17:07:08 UTC
The branch stable/15 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=1bb1d38e4160836c048b79b922a1a3f980e9128b
commit 1bb1d38e4160836c048b79b922a1a3f980e9128b
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-08-24 17:05:28 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-08-24 17:06:24 +0000
Revert "atomic: Implement atomic_{set,clear}_8 in _atomic_subword.h"
This commit fails to compile for powerpc64le. Just revert it as it's
only a cleanup motivated by adding support for KASAN to riscv.
This is a direct commit to stable/15.
This reverts commit 318915568443f1fdb65faab0f559c872f09628c6.
Reported by: jenkins
---
sys/sys/_atomic_subword.h | 54 ++++++++++-----------------------
sys/vm/vm_page.c | 76 +++++++++++++++++++++++++++++++++++++++++------
2 files changed, 82 insertions(+), 48 deletions(-)
diff --git a/sys/sys/_atomic_subword.h b/sys/sys/_atomic_subword.h
index 907fef0bb193..284e2bfa340f 100644
--- a/sys/sys/_atomic_subword.h
+++ b/sys/sys/_atomic_subword.h
@@ -201,42 +201,21 @@ atomic_load_acq_16(const volatile uint16_t *p)
}
#endif
-#ifndef atomic_set_8
-static __inline void
-atomic_set_8(volatile uint8_t *p, uint8_t bit)
-{
- uint32_t *addr;
- int shift;
-
- addr = _ATOMIC_WORD_ALIGNED(p);
- shift = _ATOMIC_BYTE_SHIFT(p);
- atomic_set_32(addr, (uint32_t)bit << shift);
-}
-#endif
+#undef _ATOMIC_WORD_ALIGNED
+#undef _ATOMIC_BYTE_SHIFT
+#undef _ATOMIC_HWORD_SHIFT
#ifndef atomic_set_16
static __inline void
atomic_set_16(volatile uint16_t *p, uint16_t bit)
{
- uint32_t *addr;
- int shift;
-
- addr = _ATOMIC_WORD_ALIGNED(p);
- shift = _ATOMIC_HWORD_SHIFT(p);
- atomic_set_32(addr, (uint32_t)bit << shift);
-}
-#endif
-
-#ifndef atomic_clear_8
-static __inline void
-atomic_clear_8(volatile uint8_t *p, uint8_t bit)
-{
- uint32_t *addr;
- int shift;
+ uint16_t v;
- addr = _ATOMIC_WORD_ALIGNED(p);
- shift = _ATOMIC_BYTE_SHIFT(p);
- atomic_clear_32(addr, (uint32_t)bit << shift);
+ v = atomic_load_16(p);
+ for (;;) {
+ if (atomic_fcmpset_16(p, &v, v | bit))
+ break;
+ }
}
#endif
@@ -244,17 +223,14 @@ atomic_clear_8(volatile uint8_t *p, uint8_t bit)
static __inline void
atomic_clear_16(volatile uint16_t *p, uint16_t bit)
{
- uint32_t *addr;
- int shift;
+ uint16_t v;
- addr = _ATOMIC_WORD_ALIGNED(p);
- shift = _ATOMIC_HWORD_SHIFT(p);
- atomic_clear_32(addr, (uint32_t)bit << shift);
+ v = atomic_load_16(p);
+ for (;;) {
+ if (atomic_fcmpset_16(p, &v, v & ~bit))
+ break;
+ }
}
#endif
-#undef _ATOMIC_WORD_ALIGNED
-#undef _ATOMIC_BYTE_SHIFT
-#undef _ATOMIC_HWORD_SHIFT
-
#endif /* _SYS__ATOMIC_SUBWORD_H_ */
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index fdf63b2160f6..ce5748bd5f33 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -5363,33 +5363,67 @@ vm_page_bits(int base, int size)
void
vm_page_bits_set(vm_page_t m, vm_page_bits_t *bits, vm_page_bits_t set)
{
+
#if PAGE_SIZE == 32768
atomic_set_64((uint64_t *)bits, set);
#elif PAGE_SIZE == 16384
atomic_set_32((uint32_t *)bits, set);
-#elif PAGE_SIZE == 8192
+#elif (PAGE_SIZE == 8192) && defined(atomic_set_16)
atomic_set_16((uint16_t *)bits, set);
-#elif PAGE_SIZE == 4096
+#elif (PAGE_SIZE == 4096) && defined(atomic_set_8)
atomic_set_8((uint8_t *)bits, set);
+#else /* PAGE_SIZE <= 8192 */
+ uintptr_t addr;
+ int shift;
+
+ addr = (uintptr_t)bits;
+ /*
+ * Use a trick to perform a 32-bit atomic on the
+ * containing aligned word, to not depend on the existence
+ * of atomic_{set, clear}_{8, 16}.
+ */
+ shift = addr & (sizeof(uint32_t) - 1);
+#if BYTE_ORDER == BIG_ENDIAN
+ shift = (sizeof(uint32_t) - sizeof(vm_page_bits_t) - shift) * NBBY;
#else
-#error unhandled page size
+ shift *= NBBY;
#endif
+ addr &= ~(sizeof(uint32_t) - 1);
+ atomic_set_32((uint32_t *)addr, set << shift);
+#endif /* PAGE_SIZE */
}
static inline void
vm_page_bits_clear(vm_page_t m, vm_page_bits_t *bits, vm_page_bits_t clear)
{
+
#if PAGE_SIZE == 32768
atomic_clear_64((uint64_t *)bits, clear);
#elif PAGE_SIZE == 16384
atomic_clear_32((uint32_t *)bits, clear);
-#elif PAGE_SIZE == 8192
+#elif (PAGE_SIZE == 8192) && defined(atomic_clear_16)
atomic_clear_16((uint16_t *)bits, clear);
-#elif PAGE_SIZE == 4096
+#elif (PAGE_SIZE == 4096) && defined(atomic_clear_8)
atomic_clear_8((uint8_t *)bits, clear);
+#else /* PAGE_SIZE <= 8192 */
+ uintptr_t addr;
+ int shift;
+
+ addr = (uintptr_t)bits;
+ /*
+ * Use a trick to perform a 32-bit atomic on the
+ * containing aligned word, to not depend on the existence
+ * of atomic_{set, clear}_{8, 16}.
+ */
+ shift = addr & (sizeof(uint32_t) - 1);
+#if BYTE_ORDER == BIG_ENDIAN
+ shift = (sizeof(uint32_t) - sizeof(vm_page_bits_t) - shift) * NBBY;
#else
-#error unhandled page size
+ shift *= NBBY;
#endif
+ addr &= ~(sizeof(uint32_t) - 1);
+ atomic_clear_32((uint32_t *)addr, clear << shift);
+#endif /* PAGE_SIZE */
}
static inline vm_page_bits_t
@@ -5407,21 +5441,45 @@ vm_page_bits_swap(vm_page_t m, vm_page_bits_t *bits, vm_page_bits_t newbits)
old = *bits;
while (atomic_fcmpset_32(bits, &old, newbits) == 0);
return (old);
-#elif PAGE_SIZE == 8192
+#elif (PAGE_SIZE == 8192) && defined(atomic_fcmpset_16)
uint16_t old;
old = *bits;
while (atomic_fcmpset_16(bits, &old, newbits) == 0);
return (old);
-#elif PAGE_SIZE == 4096
+#elif (PAGE_SIZE == 4096) && defined(atomic_fcmpset_8)
uint8_t old;
old = *bits;
while (atomic_fcmpset_8(bits, &old, newbits) == 0);
return (old);
+#else /* PAGE_SIZE <= 4096*/
+ uintptr_t addr;
+ uint32_t old, new, mask;
+ int shift;
+
+ addr = (uintptr_t)bits;
+ /*
+ * Use a trick to perform a 32-bit atomic on the
+ * containing aligned word, to not depend on the existence
+ * of atomic_{set, swap, clear}_{8, 16}.
+ */
+ shift = addr & (sizeof(uint32_t) - 1);
+#if BYTE_ORDER == BIG_ENDIAN
+ shift = (sizeof(uint32_t) - sizeof(vm_page_bits_t) - shift) * NBBY;
#else
-#error unhandled page size
+ shift *= NBBY;
#endif
+ addr &= ~(sizeof(uint32_t) - 1);
+ mask = VM_PAGE_BITS_ALL << shift;
+
+ old = *bits;
+ do {
+ new = old & ~mask;
+ new |= newbits << shift;
+ } while (atomic_fcmpset_32((uint32_t *)addr, &old, new) == 0);
+ return (old >> shift);
+#endif /* PAGE_SIZE */
}
/*