aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--UPDATING8
-rw-r--r--share/man/man9/sx.910
-rw-r--r--sys/cddl/compat/opensolaris/sys/mutex.h4
-rw-r--r--sys/cddl/compat/opensolaris/sys/rwlock.h4
-rw-r--r--sys/conf/NOTES10
-rw-r--r--sys/conf/options2
-rw-r--r--sys/kern/kern_sx.c71
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/sx.h2
9 files changed, 75 insertions, 38 deletions
diff --git a/UPDATING b/UPDATING
index f60c8046072a..a0363808853d 100644
--- a/UPDATING
+++ b/UPDATING
@@ -22,6 +22,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
+20090528:
+ 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 800092.
+
20090527:
Add support for hierarchical jails. Remove global securelevel.
Bump __FreeBSD_version to 800091.
diff --git a/share/man/man9/sx.9 b/share/man/man9/sx.9
index 41a7faad75c3..c75c6a70331f 100644
--- a/share/man/man9/sx.9
+++ b/share/man/man9/sx.9
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 25, 2007
+.Dd May 28, 2009
.Dt SX 9
.Os
.Sh NAME
@@ -122,10 +122,10 @@ argument to
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
diff --git a/sys/cddl/compat/opensolaris/sys/mutex.h b/sys/cddl/compat/opensolaris/sys/mutex.h
index 56c41a4f5e9d..8756cd0534f4 100644
--- a/sys/cddl/compat/opensolaris/sys/mutex.h
+++ b/sys/cddl/compat/opensolaris/sys/mutex.h
@@ -47,9 +47,9 @@ typedef enum {
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 { \
diff --git a/sys/cddl/compat/opensolaris/sys/rwlock.h b/sys/cddl/compat/opensolaris/sys/rwlock.h
index 0d4ac2e1e2a9..a3e55153bbcf 100644
--- a/sys/cddl/compat/opensolaris/sys/rwlock.h
+++ b/sys/cddl/compat/opensolaris/sys/rwlock.h
@@ -49,9 +49,9 @@ typedef enum {
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)))
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index f25c98ca7e5e..477006445cad 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -215,11 +215,11 @@ options NO_ADAPTIVE_MUTEXES
# 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
diff --git a/sys/conf/options b/sys/conf/options
index 298c170fb04b..a668ea50a139 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -60,7 +60,6 @@ KDB_UNATTENDED opt_kdb.h
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_BUFFERS opt_mprof.h
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
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index 8c099ac12d47..9e2a1fb3db53 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -60,12 +60,12 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
#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
@@ -133,6 +133,14 @@ struct lock_class lock_class_sx = {
#define _sx_assert(sx, what, file, line)
#endif
+#ifdef ADAPTIVE_SX
+static u_int asx_retries = 10;
+static u_int asx_loops = 10000;
+SYSCTL_NODE(_debug, OID_AUTO, sx, CTLFLAG_RD, NULL, "sxlock debugging");
+SYSCTL_INT(_debug_sx, OID_AUTO, retries, CTLFLAG_RW, &asx_retries, 0, "");
+SYSCTL_INT(_debug_sx, OID_AUTO, loops, CTLFLAG_RW, &asx_loops, 0, "");
+#endif
+
void
assert_sx(struct lock_object *lock, int what)
{
@@ -195,7 +203,7 @@ sx_init_flags(struct sx *sx, const char *description, int opts)
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)
@@ -207,7 +215,7 @@ sx_init_flags(struct sx *sx, const char *description, int opts)
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);
@@ -453,6 +461,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
GIANT_DECLARE;
#ifdef ADAPTIVE_SX
volatile struct thread *owner;
+ u_int i, spintries = 0;
#endif
uintptr_t x;
#ifdef LOCK_PROFILING
@@ -495,24 +504,44 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
* 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();
+#ifdef KDTRACE_HOOKS
+ spin_cnt++;
+#endif
+ }
+ 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();
#ifdef KDTRACE_HOOKS
spin_cnt++;
#endif
}
- continue;
+ if (i != asx_loops)
+ continue;
}
}
#endif
@@ -538,7 +567,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
* 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);
@@ -752,7 +781,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
* 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)) {
@@ -796,7 +825,7 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
* 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);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 834dde3da4ef..34d3c139fbf2 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 800091 /* Master, propagated to newvers */
+#define __FreeBSD_version 800092 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>
diff --git a/sys/sys/sx.h b/sys/sys/sx.h
index e050bab1525c..11e61f69611a 100644
--- a/sys/sys/sx.h
+++ b/sys/sys/sx.h
@@ -265,7 +265,7 @@ __sx_sunlock(struct sx *sx, const char *file, int line)
#define SX_NOPROFILE 0x02
#define SX_NOWITNESS 0x04
#define SX_QUIET 0x08
-#define SX_ADAPTIVESPIN 0x10
+#define SX_NOADAPTIVE 0x10
#define SX_RECURSE 0x20
/*