summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorchristos <christos@NetBSD.org>2015-03-09 01:41:41 +0000
committerchristos <christos@NetBSD.org>2015-03-09 01:41:41 +0000
commitaf55bcce70ead248bc33e3800eba32df4a05fcd6 (patch)
tree1a08a106612714c752aedafaed48d990a74a416f /sys/dev
parentece957cdede698b49e517ccf470d50bdf5bb6274 (diff)
Introduce a new flag LB_DTRACE for dtrace lockstat events.
Split lockstat_enabled into two parts, one controlled by dtrace called "lockstat_dtrace_enabled" and one by the lockstat device called "lockstat_dev_enabled". Create a macro that needs to be called when either of them changes LOCKSTAT_ENABLED_UPDATE().
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/lockstat.c34
-rw-r--r--sys/dev/lockstat.h14
2 files changed, 31 insertions, 17 deletions
diff --git a/sys/dev/lockstat.c b/sys/dev/lockstat.c
index fb1a8da7ea0..05d5769eb54 100644
--- a/sys/dev/lockstat.c
+++ b/sys/dev/lockstat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lockstat.c,v 1.20 2015/03/08 22:45:16 christos Exp $ */
+/* $NetBSD: lockstat.c,v 1.21 2015/03/09 01:41:41 christos Exp $ */
/*-
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lockstat.c,v 1.20 2015/03/08 22:45:16 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lockstat.c,v 1.21 2015/03/09 01:41:41 christos Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -97,6 +97,7 @@ dev_type_read(lockstat_read);
dev_type_ioctl(lockstat_ioctl);
volatile u_int lockstat_enabled;
+volatile u_int lockstat_dev_enabled;
uintptr_t lockstat_csstart;
uintptr_t lockstat_csend;
uintptr_t lockstat_csmask;
@@ -111,6 +112,7 @@ int lockstat_busy;
struct timespec lockstat_stime;
#ifdef KDTRACE_HOOKS
+volatile u_int lockstat_dtrace_enabled;
CTASSERT(LB_NEVENT <= 3);
CTASSERT(LB_NLOCK <= (7 << LB_LOCK_SHIFT));
void
@@ -164,7 +166,7 @@ lockstat_init_tables(lsenable_t *le)
lscpu_t *lc;
lsbuf_t *lb;
- KASSERT(!lockstat_enabled);
+ KASSERT(!lockstat_dev_enabled);
for (CPU_INFO_FOREACH(cii, ci)) {
if (ci->ci_lockstat != NULL) {
@@ -209,7 +211,7 @@ void
lockstat_start(lsenable_t *le)
{
- KASSERT(!lockstat_enabled);
+ KASSERT(!lockstat_dev_enabled);
lockstat_init_tables(le);
@@ -230,8 +232,8 @@ lockstat_start(lsenable_t *le)
lockstat_lockend = le->le_lockend;
membar_sync();
getnanotime(&lockstat_stime);
- lockstat_enabled = le->le_mask;
- membar_producer();
+ lockstat_dev_enabled = le->le_mask;
+ LOCKSTAT_ENABLED_UPDATE();
}
/*
@@ -247,14 +249,14 @@ lockstat_stop(lsdisable_t *ld)
int error;
lwp_t *l;
- KASSERT(lockstat_enabled);
+ KASSERT(lockstat_dev_enabled);
/*
* Set enabled false, force a write barrier, and wait for other CPUs
* to exit lockstat_event().
*/
- lockstat_enabled = 0;
- membar_producer();
+ lockstat_dev_enabled = 0;
+ LOCKSTAT_ENABLED_UPDATE();
getnanotime(&ts);
tsleep(&lockstat_stop, PPAUSE, "lockstat", mstohz(10));
@@ -313,7 +315,7 @@ lockstat_alloc(lsenable_t *le)
lsbuf_t *lb;
size_t sz;
- KASSERT(!lockstat_enabled);
+ KASSERT(!lockstat_dev_enabled);
lockstat_free();
sz = sizeof(*lb) * le->le_nbufs;
@@ -322,7 +324,7 @@ lockstat_alloc(lsenable_t *le)
if (lb == NULL)
return (ENOMEM);
- KASSERT(!lockstat_enabled);
+ KASSERT(!lockstat_dev_enabled);
KASSERT(lockstat_baseb == NULL);
lockstat_sizeb = sz;
lockstat_baseb = lb;
@@ -337,7 +339,7 @@ void
lockstat_free(void)
{
- KASSERT(!lockstat_enabled);
+ KASSERT(!lockstat_dev_enabled);
if (lockstat_baseb != NULL) {
kmem_free(lockstat_baseb, lockstat_sizeb);
@@ -366,7 +368,7 @@ lockstat_event(uintptr_t lock, uintptr_t callsite, u_int flags, u_int count,
cycles);
#endif
- if ((flags & lockstat_enabled) != flags || count == 0)
+ if ((flags & lockstat_dev_enabled) != flags || count == 0)
return;
if (lock < lockstat_lockstart || lock > lockstat_lockend)
return;
@@ -474,7 +476,7 @@ lockstat_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
error = ENODEV;
break;
}
- if (lockstat_enabled) {
+ if (lockstat_dev_enabled) {
error = EBUSY;
break;
}
@@ -510,7 +512,7 @@ lockstat_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
break;
case IOC_LOCKSTAT_DISABLE:
- if (!lockstat_enabled)
+ if (!lockstat_dev_enabled)
error = EINVAL;
else
error = lockstat_stop((lsdisable_t *)data);
@@ -531,7 +533,7 @@ int
lockstat_read(dev_t dev, struct uio *uio, int flag)
{
- if (curlwp != lockstat_lwp || lockstat_enabled)
+ if (curlwp != lockstat_lwp || lockstat_dev_enabled)
return EBUSY;
return uiomove(lockstat_baseb, lockstat_sizeb, uio);
}
diff --git a/sys/dev/lockstat.h b/sys/dev/lockstat.h
index 87d2885ae67..f6029e8f9bc 100644
--- a/sys/dev/lockstat.h
+++ b/sys/dev/lockstat.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lockstat.h,v 1.12 2015/03/09 00:40:35 christos Exp $ */
+/* $NetBSD: lockstat.h,v 1.13 2015/03/09 01:41:41 christos Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -119,6 +119,8 @@ typedef struct lsdisable {
#define LB_LOCK_MASK 0x0000ff00
#define LB_LOCK_SHIFT 8
+#define LB_DTRACE 0x00010000
+
typedef struct lsbuf {
union {
LIST_ENTRY(lsbuf) list;
@@ -180,6 +182,7 @@ do { \
void lockstat_event(uintptr_t, uintptr_t, u_int, u_int, uint64_t);
extern volatile u_int lockstat_enabled;
+extern volatile u_int lockstat_dev_enabled;
#else
@@ -197,6 +200,8 @@ extern volatile u_int lockstat_enabled;
#endif
#ifdef KDTRACE_HOOKS
+extern volatile u_int lockstat_dtrace_enabled;
+#define KDTRACE_LOCKSTAT_ENABLED lockstat_dtrace_enabled
#define LS_COMPRESS(f) \
((((f) & 0x3) | (((f) & 0x700) >> 6)) & (LS_NPROBES - 1))
#define LS_NPROBES 0x20 /* 5 bits */
@@ -207,6 +212,13 @@ extern void (*lockstat_probe_func)(uint32_t, uintptr_t, uintptr_t,
void lockstat_probe_stub(uint32_t, uintptr_t, uintptr_t,
uintptr_t, uintptr_t, uintptr_t);
+#else
+#define KDTRACE_LOCKSTAT_ENABLED 0
#endif
+#define LOCKSTAT_ENABLED_UPDATE() do { \
+ lockstat_enabled = lockstat_dev_enabled | KDTRACE_LOCKSTAT_ENABLED; \
+ membar_producer(); \
+ } while (/*CONSTCOND*/0)
+
#endif /* _SYS_LOCKSTAT_H_ */