diff options
| author | ad <ad@NetBSD.org> | 2006-12-25 11:57:40 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2006-12-25 11:57:40 +0000 |
| commit | 9f07c24ec6d2bfa84ece84d79a50387e488c75ce (patch) | |
| tree | 963a1e0422dcf1a99d5f08d4e74be860a5285292 /sys | |
| parent | ae979b216270e8fc54df94853fc74aecb080fc90 (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.c | 35 | ||||
| -rw-r--r-- | sys/dev/lockstat.h | 20 | ||||
| -rw-r--r-- | sys/kern/kern_lock.c | 6 |
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) |
