The branch stable/15 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=1bb1d38e4160836c048b79b922a1a3f980e9128b
commit 1bb1d38e4160836c048b79b922a1a3f980e9128b Author: Mark Johnston <[email protected]> AuthorDate: 2026-08-24 17:05:28 +0000 Commit: Mark Johnston <[email protected]> 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 */ } /*
