FreeBSD does not support SMP on ARMv5. Since processor is always

self-consistent, there is no need in anything but compiler barrier in
the implementation of atomic_thread_fence_*() on ARMv5.  Split
implementation of fences for ARMv4/5 and ARMv6; the former use
compiler barriers, the later also perform hardware barriers.

An issue which is fixed by the change is the faults from the CP15
coprocessor accesses in the user mode.  This was uncovered by the
pthread_once() changes in r287556.

Reported by:	Mattia Rossi <mattia.rossi.mailinglists@gmail.com>
Discussed with:	alc, cognet, jhb
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
kib 2015-10-02 13:21:08 +00:00
parent a587458e05
commit a7abd83f35
3 changed files with 61 additions and 28 deletions

View File

@ -439,4 +439,37 @@ atomic_subtract_long(volatile u_long *p, u_long v)
atomic_subtract_32((volatile uint32_t *)p, v);
}
/*
* ARMv5 does not support SMP. For both kernel and user modes, only a
* compiler barrier is needed for fences, since CPU is always
* self-consistent.
*/
static __inline void
atomic_thread_fence_acq(void)
{
__compiler_membar();
}
static __inline void
atomic_thread_fence_rel(void)
{
__compiler_membar();
}
static __inline void
atomic_thread_fence_acq_rel(void)
{
__compiler_membar();
}
static __inline void
atomic_thread_fence_seq_cst(void)
{
__compiler_membar();
}
#endif /* _MACHINE_ATOMIC_H_ */

View File

@ -596,4 +596,32 @@ atomic_store_rel_long(volatile u_long *p, u_long v)
#undef ATOMIC_ACQ_REL
#undef ATOMIC_ACQ_REL_LONG
static __inline void
atomic_thread_fence_acq(void)
{
dmb();
}
static __inline void
atomic_thread_fence_rel(void)
{
dmb();
}
static __inline void
atomic_thread_fence_acq_rel(void)
{
dmb();
}
static __inline void
atomic_thread_fence_seq_cst(void)
{
dmb();
}
#endif /* _MACHINE_ATOMIC_V6_H_ */

View File

@ -82,34 +82,6 @@ atomic_store_long(volatile u_long *dst, u_long src)
*dst = src;
}
static __inline void
atomic_thread_fence_acq(void)
{
dmb();
}
static __inline void
atomic_thread_fence_rel(void)
{
dmb();
}
static __inline void
atomic_thread_fence_acq_rel(void)
{
dmb();
}
static __inline void
atomic_thread_fence_seq_cst(void)
{
dmb();
}
#define atomic_clear_ptr atomic_clear_32
#define atomic_set_ptr atomic_set_32
#define atomic_cmpset_ptr atomic_cmpset_32