Index: cddl/compat/opensolaris/sys/mutex.h =================================================================== --- cddl/compat/opensolaris/sys/mutex.h (revision 192392) +++ cddl/compat/opensolaris/sys/mutex.h (working copy) @@ -47,9 +47,9 @@ typedef struct sx kmutex_t; #ifndef DEBUG -#define MUTEX_FLAGS (SX_DUPOK | SX_NOWITNESS | SX_ADAPTIVESPIN) +#define MUTEX_FLAGS (SX_DUPOK | SX_NOWITNESS) #else -#define MUTEX_FLAGS (SX_DUPOK | SX_ADAPTIVESPIN) +#define MUTEX_FLAGS (SX_DUPOK) #endif #define mutex_init(lock, desc, type, arg) do { \ Index: cddl/compat/opensolaris/sys/rwlock.h =================================================================== --- cddl/compat/opensolaris/sys/rwlock.h (revision 192392) +++ cddl/compat/opensolaris/sys/rwlock.h (working copy) @@ -49,9 +49,9 @@ typedef struct sx krwlock_t; #ifndef DEBUG -#define RW_FLAGS (SX_DUPOK | SX_NOWITNESS | SX_ADAPTIVESPIN) +#define RW_FLAGS (SX_DUPOK | SX_NOWITNESS) #else -#define RW_FLAGS (SX_DUPOK | SX_ADAPTIVESPIN) +#define RW_FLAGS (SX_DUPOK) #endif #define RW_READ_HELD(x) (rw_read_held((x))) Index: WORKING/share/man/man9/sx.9 =================================================================== --- WORKING/share/man/man9/sx.9 (revision 192114) +++ WORKING/share/man/man9/sx.9 (working copy) @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 25, 2007 +.Dd May 19, 2009 .Dt SX 9 .Os .Sh NAME @@ -122,10 +122,10 @@ specifies a set of optional flags to alter the behavior of .Fa sx . It contains one or more of the following flags: -.Bl -tag -width SX_ADAPTIVESPIN -.It Dv SX_ADAPTIVESPIN -If the kernel is compiled with -.Cd "options ADAPTIVE_SX" , +.Bl -tag -width SX_NOADAPTIVE +.It Dv SX_NOADAPTIVE +If the kernel is not compiled with +.Cd "options NO_ADAPTIVE_SX" , then lock operations for .Fa sx will spin instead of sleeping while an exclusive lock holder is executing on Index: WORKING/UPDATING =================================================================== --- WORKING/UPDATING (revision 192114) +++ WORKING/UPDATING (working copy) @@ -22,6 +22,14 @@ to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20090519: + The compiling option ADAPTIVE_SX has been retired while it has been + introduced the option NO_ADAPTIVE_SX which handles the reversed logic. + The KPI for sx_init_flags() changes as accepting flags: + SX_ADAPTIVESPIN flag has been retired while the SX_NOADAPTIVE flag + has been introduced in order to handle the reversed logic. + Bump __FreeBSD_version to XXXXXX. + 20090430: The layout of the following structs has changed: sysctl_oid, socket, ifnet, inpcbinfo, tcpcb, syncache_head, vnet_inet, Index: WORKING/sys/conf/NOTES =================================================================== --- WORKING/sys/conf/NOTES (revision 192114) +++ WORKING/sys/conf/NOTES (working copy) @@ -215,11 +215,11 @@ # to disable it. options NO_ADAPTIVE_RWLOCKS -# ADAPTIVE_SX changes the behavior of sx locks to spin if the thread -# that currently owns the lock is executing on another CPU. Note that -# in addition to enabling this option, individual sx locks must be -# initialized with the SX_ADAPTIVESPIN flag. -options ADAPTIVE_SX +# ADAPTIVE_SX changes the behavior of sx locks to spin if the thread that +# currently owns the sx lock is executing on another CPU. +# This behaviour is enabled by default, so this option can be used to +# disable it. +options NO_ADAPTIVE_SX # MUTEX_NOINLINE forces mutex operations to call functions to perform each # operation rather than inlining the simple cases. This can be used to Index: WORKING/sys/conf/options =================================================================== --- WORKING/sys/conf/options (revision 192114) +++ WORKING/sys/conf/options (working copy) @@ -60,7 +60,6 @@ SYSCTL_DEBUG opt_sysctl.h # Miscellaneous options. -ADAPTIVE_SX ALQ AUDIT opt_global.h CODA_COMPAT_5 opt_coda.h @@ -134,6 +133,7 @@ MPROF_HASH_SIZE opt_mprof.h NO_ADAPTIVE_MUTEXES opt_adaptive_mutexes.h NO_ADAPTIVE_RWLOCKS +NO_ADAPTIVE_SX NO_SYSCTL_DESCR opt_global.h NSWBUF_MIN opt_swap.h MBUF_PACKET_ZONE_DISABLE opt_global.h Index: WORKING/sys/kern/kern_sx.c =================================================================== --- WORKING/sys/kern/kern_sx.c (revision 192114) +++ WORKING/sys/kern/kern_sx.c (working copy) @@ -36,7 +36,7 @@ * so should not be relied upon in combination with sx locks. */ -#include "opt_adaptive_sx.h" +#include "opt_no_adaptive_sx.h" #include "opt_ddb.h" #include @@ -51,7 +51,7 @@ #include #include -#ifdef ADAPTIVE_SX +#if defined(SMP) && !defined(NO_ADAPTIVE_SX) #include #endif @@ -59,12 +59,12 @@ #include #endif -#if !defined(SMP) && defined(ADAPTIVE_SX) -#error "You must have SMP to enable the ADAPTIVE_SX option" +#if defined(SMP) && !defined(NO_ADAPTIVE_SX) +#define ADAPTIVE_SX #endif -CTASSERT(((SX_ADAPTIVESPIN | SX_RECURSE) & LO_CLASSFLAGS) == - (SX_ADAPTIVESPIN | SX_RECURSE)); +CTASSERT(((SX_NOADAPTIVE | SX_RECURSE) & LO_CLASSFLAGS) == + (SX_NOADAPTIVE | SX_RECURSE)); /* Handy macros for sleep queues. */ #define SQ_EXCLUSIVE_QUEUE 0 @@ -126,6 +126,11 @@ #define _sx_assert(sx, what, file, line) #endif +#ifdef ADAPTIVE_SX +static u_int asx_retries = 10; +static u_int asx_loops = 10000; +#endif + void assert_sx(struct lock_object *lock, int what) { @@ -175,7 +180,7 @@ int flags; MPASS((opts & ~(SX_QUIET | SX_RECURSE | SX_NOWITNESS | SX_DUPOK | - SX_NOPROFILE | SX_ADAPTIVESPIN)) == 0); + SX_NOPROFILE | SX_NOADAPTIVE)) == 0); flags = LO_RECURSABLE | LO_SLEEPABLE | LO_UPGRADABLE; if (opts & SX_DUPOK) @@ -187,7 +192,7 @@ if (opts & SX_QUIET) flags |= LO_QUIET; - flags |= opts & (SX_ADAPTIVESPIN | SX_RECURSE); + flags |= opts & (SX_NOADAPTIVE | SX_RECURSE); sx->sx_lock = SX_LOCK_UNLOCKED; sx->sx_recurse = 0; lock_init(&sx->lock_object, &lock_class_sx, description, NULL, flags); @@ -430,6 +435,7 @@ GIANT_DECLARE; #ifdef ADAPTIVE_SX volatile struct thread *owner; + u_int i, spintries = 0; #endif uintptr_t x; #ifdef LOCK_PROFILING @@ -464,20 +470,37 @@ * running or the state of the lock changes. */ x = sx->sx_lock; - if (!(x & SX_LOCK_SHARED) && - (sx->lock_object.lo_flags & SX_ADAPTIVESPIN)) { - x = SX_OWNER(x); - owner = (struct thread *)x; - if (TD_IS_RUNNING(owner)) { - if (LOCK_LOG_TEST(&sx->lock_object, 0)) - CTR3(KTR_LOCK, + if ((sx->lock_object.lo_flags & SX_NOADAPTIVE) != 0) { + if ((x & SX_LOCK_SHARED) == 0) { + x = SX_OWNER(x); + owner = (struct thread *)x; + if (TD_IS_RUNNING(owner)) { + if (LOCK_LOG_TEST(&sx->lock_object, 0)) + CTR3(KTR_LOCK, "%s: spinning on %p held by %p", - __func__, sx, owner); - GIANT_SAVE(); - while (SX_OWNER(sx->sx_lock) == x && - TD_IS_RUNNING(owner)) + __func__, sx, owner); + GIANT_SAVE(); + while (SX_OWNER(sx->sx_lock) == x && + TD_IS_RUNNING(owner)) + cpu_spinwait(); + continue; + } + } else if (SX_SHARERS(x) && spintries < asx_retries) { + spintries++; + for (i = 0; i < asx_loops; i++) { + if (LOCK_LOG_TEST(&sx->lock_object, 0)) + CTR4(KTR_LOCK, + "%s: shared spinning on %p with %u and %u", + __func__, sx, spintries, i); + GIANT_SAVE(); + x = sx->sx_lock; + if ((x & SX_LOCK_SHARED) == 0 || + SX_SHARERS(x) == 0) + break; cpu_spinwait(); - continue; + } + if (i != asx_loops) + continue; } } #endif @@ -503,7 +526,7 @@ * again. */ if (!(x & SX_LOCK_SHARED) && - (sx->lock_object.lo_flags & SX_ADAPTIVESPIN)) { + (sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) { owner = (struct thread *)SX_OWNER(x); if (TD_IS_RUNNING(owner)) { sleepq_release(&sx->lock_object); @@ -697,7 +720,7 @@ * the owner stops running or the state of the lock * changes. */ - if (sx->lock_object.lo_flags & SX_ADAPTIVESPIN) { + if ((sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) { x = SX_OWNER(x); owner = (struct thread *)x; if (TD_IS_RUNNING(owner)) { @@ -737,7 +760,7 @@ * changes. */ if (!(x & SX_LOCK_SHARED) && - (sx->lock_object.lo_flags & SX_ADAPTIVESPIN)) { + (sx->lock_object.lo_flags & SX_NOADAPTIVE) == 0) { owner = (struct thread *)SX_OWNER(x); if (TD_IS_RUNNING(owner)) { sleepq_release(&sx->lock_object); Index: WORKING/sys/sys/sx.h =================================================================== --- WORKING/sys/sys/sx.h (revision 192114) +++ WORKING/sys/sys/sx.h (working copy) @@ -264,7 +264,7 @@ #define SX_NOPROFILE 0x02 #define SX_NOWITNESS 0x04 #define SX_QUIET 0x08 -#define SX_ADAPTIVESPIN 0x10 +#define SX_NOADAPTIVE 0x10 #define SX_RECURSE 0x20 /*