summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorad <ad@NetBSD.org>2006-12-25 11:57:40 +0000
committerad <ad@NetBSD.org>2006-12-25 11:57:40 +0000
commit9f07c24ec6d2bfa84ece84d79a50387e488c75ce (patch)
tree963a1e0422dcf1a99d5f08d4e74be860a5285292 /sys
parentae979b216270e8fc54df94853fc74aecb080fc90 (diff)
lockstat: improve reporting slightly, and fix a bug where the command
could spin while resorting lists.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/lockstat.c35
-rw-r--r--sys/dev/lockstat.h20
-rw-r--r--sys/kern/kern_lock.c6
3 files changed, 36 insertions, 25 deletions
diff --git a/sys/dev/lockstat.c b/sys/dev/lockstat.c
index ad9b67a0461..6f591d645df 100644
--- a/sys/dev/lockstat.c
+++ b/sys/dev/lockstat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lockstat.c,v 1.4 2006/11/16 01:32:45 christos Exp $ */
+/* $NetBSD: lockstat.c,v 1.5 2006/12/25 11:57:40 ad Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -39,10 +39,12 @@
/*
* Lock statistics driver, providing kernel support for the lockstat(8)
* command.
+ *
+ * XXX Timings for contention on sleep locks are currently incorrect.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lockstat.c,v 1.4 2006/11/16 01:32:45 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lockstat.c,v 1.5 2006/12/25 11:57:40 ad Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -101,7 +103,8 @@ volatile u_int lockstat_enabled;
uintptr_t lockstat_csstart;
uintptr_t lockstat_csend;
uintptr_t lockstat_csmask;
-uintptr_t lockstat_lockaddr;
+uintptr_t lockstat_lockstart;
+uintptr_t lockstat_lockend;
/* Protected by lockstat_lock(). */
struct simplelock lockstat_slock;
@@ -237,19 +240,23 @@ lockstat_start(lsenable_t *le)
lockstat_csstart = le->le_csstart;
lockstat_csend = le->le_csend;
- lockstat_lockaddr = le->le_lock;
-
- /*
- * Force a write barrier. XXX This may not be sufficient..
- */
+ lockstat_lockstart = le->le_lockstart;
+ lockstat_lockend = le->le_lockend;
+#ifdef notyet
+ mb_memory();
+#else
lockstat_unlock(0);
- tsleep(&lockstat_start, PPAUSE, "lockstat", mstohz(10));
(void)lockstat_lock(0);
+#endif
getnanotime(&lockstat_stime);
lockstat_enabled = le->le_mask;
+#ifdef notyet
+ mb_write();
+#else
lockstat_unlock(0);
(void)lockstat_lock(0);
+#endif
}
/*
@@ -268,7 +275,7 @@ lockstat_stop(lsdisable_t *ld)
/*
* Set enabled false, force a write barrier, and wait for other CPUs
- * to exit lockstat_event(). XXX This may not be sufficient..
+ * to exit lockstat_event().
*/
lockstat_enabled = 0;
lockstat_unlock(0);
@@ -372,7 +379,7 @@ lockstat_event(uintptr_t lock, uintptr_t callsite, u_int flags, u_int count,
if ((flags & lockstat_enabled) != flags || count == 0)
return;
- if (lockstat_lockaddr != 0 && lock != lockstat_lockaddr)
+ if (lock < lockstat_lockstart || lock > lockstat_lockend)
return;
if (callsite < lockstat_csstart || callsite > lockstat_csend)
return;
@@ -516,8 +523,10 @@ lockstat_ioctl(dev_t dev, u_long cmd, caddr_t data,
le->le_csstart = 0;
le->le_csend = le->le_csstart - 1;
}
- if ((le->le_flags & LE_ONE_LOCK) == 0)
- le->le_lock = 0;
+ if ((le->le_flags & LE_ONE_LOCK) == 0) {
+ le->le_lockstart = 0;
+ le->le_lockend = le->le_lockstart - 1;
+ }
if ((le->le_mask & LB_EVENT_MASK) == 0)
return (EINVAL);
if ((le->le_mask & LB_LOCK_MASK) == 0)
diff --git a/sys/dev/lockstat.h b/sys/dev/lockstat.h
index 315c28c6f13..4c0792ae57d 100644
--- a/sys/dev/lockstat.h
+++ b/sys/dev/lockstat.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lockstat.h,v 1.1 2006/09/07 00:20:28 ad Exp $ */
+/* $NetBSD: lockstat.h,v 1.2 2006/12/25 11:57:40 ad Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
#define IOC_LOCKSTAT_GVERSION _IOR('L', 0, int)
-#define LS_VERSION 0
+#define LS_VERSION 3
/*
* Enable request. We can limit tracing by the call site and by
@@ -77,7 +77,8 @@
typedef struct lsenable {
uintptr_t le_csstart; /* callsite start */
uintptr_t le_csend; /* callsite end */
- uintptr_t le_lock; /* lock address */
+ uintptr_t le_lockstart; /* lock address start */
+ uintptr_t le_lockend; /* lock address end */
uintptr_t le_nbufs; /* buffers to allocate, 0 = default */
u_int le_flags; /* request flags */
u_int le_mask; /* event mask (LB_*) */
@@ -105,8 +106,9 @@ typedef struct lsdisable {
* in le_mask.
*/
#define LB_SPIN 0x00000001
-#define LB_SLEEP 0x00000002
-#define LB_NEVENT 0x00000002
+#define LB_SLEEP1 0x00000002
+#define LB_SLEEP2 0x00000003
+#define LB_NEVENT 0x00000003
#define LB_EVENT_MASK 0x000000ff
/*
@@ -114,10 +116,10 @@ typedef struct lsdisable {
* provided with the enable request in le_mask.
*/
#define LB_ADAPTIVE_MUTEX 0x00000100
-#define LB_ADAPTIVE_RWLOCK 0x00000200
-#define LB_SPIN_MUTEX 0x00000300
-#define LB_SPIN_RWLOCK 0x00000400
-#define LB_LOCKMGR 0x00000500
+#define LB_SPIN_MUTEX 0x00000200
+#define LB_RWLOCK 0x00000300
+#define LB_LOCKMGR 0x00000400
+#define LB_KERNEL_LOCK 0x00000500
#define LB_NLOCK 0x00000500
#define LB_LOCK_MASK 0x0000ff00
#define LB_LOCK_SHIFT 8
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 4124ca0c34f..69f4bc58eb5 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_lock.c,v 1.103 2006/12/09 15:59:25 chs Exp $ */
+/* $NetBSD: kern_lock.c,v 1.104 2006/12/25 11:57:40 ad Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.103 2006/12/09 15:59:25 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.104 2006/12/25 11:57:40 ad Exp $");
#include "opt_multiprocessor.h"
#include "opt_lockdebug.h"
@@ -269,7 +269,7 @@ acquire(volatile struct lock **lkpp, int *s, int extflags,
lkp->lk_wmesg, lkp->lk_timo, &lkp->lk_interlock);
LOCKSTAT_STOP_TIMER(slptime);
LOCKSTAT_EVENT_RA((void *)(uintptr_t)lkp,
- LB_LOCKMGR | LB_SLEEP, 1, slptime, ra);
+ LB_LOCKMGR | LB_SLEEP1, 1, slptime, ra);
if (!drain) {
lkp->lk_waitcount--;
if (lkp->lk_waitcount == 0)