Index: external/cddl/osnet/dev/lockstat/lockstat.c =================================================================== RCS file: /cvsroot/src/external/cddl/osnet/dev/lockstat/lockstat.c,v retrieving revision 1.3 diff -p -u -r1.3 lockstat.c --- external/cddl/osnet/dev/lockstat/lockstat.c 21 Jun 2013 19:16:00 -0000 1.3 +++ external/cddl/osnet/dev/lockstat/lockstat.c 7 Mar 2015 16:44:21 -0000 @@ -31,8 +31,6 @@ * Use is subject to license terms. */ -#include "opt_kdtrace.h" - #include #include #include @@ -43,9 +41,20 @@ #include #include #include +#ifdef __NetBSD__ +#include +#endif #include +#ifdef __NetBSD__ +#include +#else #include +#endif + +#ifdef __NetBSD__ +#define ASSERT KASSERT +#endif #if defined(__i386__) || defined(__amd64__) || defined(__arm__) #define LOCKSTAT_AFRAMES 1 @@ -53,18 +62,22 @@ #error "architecture not supported" #endif +#if defined(__FreeBSD__) static d_open_t lockstat_open; -static void lockstat_provide(void *, dtrace_probedesc_t *); -static void lockstat_destroy(void *, dtrace_id_t, void *); -static void lockstat_enable(void *, dtrace_id_t, void *); -static void lockstat_disable(void *, dtrace_id_t, void *); -static void lockstat_load(void *); -static int lockstat_unload(void); +#elif defined(__NetBSD__) +static dev_type_open(lockstat_open); +#endif +static void lockstat_provide(void *, const dtrace_probedesc_t *); +static void lockstat_destroy(void *, dtrace_id_t, void *); +static int lockstat_enable(void *, dtrace_id_t, void *); +static void lockstat_disable(void *, dtrace_id_t, void *); +static void lockstat_load(void *); +static int lockstat_unload(void); typedef struct lockstat_probe { - char *lsp_func; - char *lsp_name; + const char *lsp_func; + const char *lsp_name; int lsp_probe; dtrace_id_t lsp_id; #ifdef __FreeBSD__ @@ -72,7 +85,7 @@ typedef struct lockstat_probe { #endif } lockstat_probe_t; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) lockstat_probe_t lockstat_probes[] = { /* Spin Locks */ @@ -140,11 +153,23 @@ lockstat_probe_t lockstat_probes[] = DTRACE_IDNONE, LOCKSTAT_AFRAMES }, { NULL } }; +#elif defined(__NetBSD__) +lockstat_probe_t lockstat_probes[] = { + { "mutex_spin", "spin", LB_SPIN_MUTEX | LB_SPIN, 0 }, + { "mutex_adaptive", "sleep", LB_SPIN_MUTEX | LB_SLEEP1, 0 }, + { "mutex_adaptive", "spin", LB_SPIN_MUTEX | LB_SPIN, 0 }, + { "rwlock", "sleep_writer", LB_RWLOCK | LB_SLEEP1, 0 }, + { "rwlock", "sleep_reader", LB_RWLOCK | LB_SLEEP2, 0 }, + { "rwlock", "spin", LB_RWLOCK | LB_SPIN, 0 }, + { "kernel", "spin", LB_KERNEL_LOCK | LB_SPIN, 0 }, + { "lwp", "spin", LB_NOPREEMPT | LB_SPIN, 0 }, +}; #else #error "OS not supported" #endif +#if defined(__FreeBSD__) static struct cdevsw lockstat_cdevsw = { .d_version = D_VERSION, .d_open = lockstat_open, @@ -152,28 +177,41 @@ static struct cdevsw lockstat_cdevsw = { }; static struct cdev *lockstat_cdev; +#elif defined(__NetBSD__) +static struct cdevsw lockstat_cdevsw = { + .d_open = lockstat_open, + .d_close = noclose, + .d_read = noread, + .d_write = nowrite, + .d_ioctl = noioctl, + .d_stop = nostop, + .d_tty = notty, + .d_poll = nopoll, + .d_mmap = nommap, + .d_kqfilter = nokqfilter, + .d_discard = nodiscard, + .d_flag = D_OTHER, +}; +#endif + static dtrace_provider_id_t lockstat_id; /*ARGSUSED*/ -static void +static int lockstat_enable(void *arg, dtrace_id_t id, void *parg) { lockstat_probe_t *probe = parg; ASSERT(!lockstat_probemap[probe->lsp_probe]); - + if (lockstat_probe_func == lockstat_probe_stub) { + lockstat_probe_func = dtrace_probe; + membar_producer(); + } else { + ASSERT(lockstat_probe_func == dtrace_probe); + } lockstat_probemap[probe->lsp_probe] = id; -#ifdef DOODAD - membar_producer(); -#endif - lockstat_probe_func = dtrace_probe; -#ifdef DOODAD - membar_producer(); - - lockstat_hot_patch(); - membar_producer(); -#endif + return 0; } /*ARGSUSED*/ @@ -183,13 +221,10 @@ lockstat_disable(void *arg, dtrace_id_t lockstat_probe_t *probe = parg; int i; + ASSERT(lockstat_probe_func == dtrace_probe); ASSERT(lockstat_probemap[probe->lsp_probe]); - lockstat_probemap[probe->lsp_probe] = 0; -#ifdef DOODAD - lockstat_hot_patch(); membar_producer(); -#endif /* * See if we have any probes left enabled. @@ -205,8 +240,16 @@ lockstat_disable(void *arg, dtrace_id_t } } + lockstat_probe_func = lockstat_probe_stub; + + /* + * Trigger some activity on all CPUs to make sure they're not + * in lockstat any more. + */ + xc_wait(xc_broadcast(0, (void *)nullop, NULL, NULL)); } +#if defined(__FreeBSD__) /*ARGSUSED*/ static int lockstat_open(struct cdev *dev __unused, int oflags __unused, @@ -214,18 +257,28 @@ lockstat_open(struct cdev *dev __unused, { return (0); } +#elif defined(__NetBSD__) +static int +lockstat_open(dev_t dev __unused, int flags __unused, int mode __unused, + struct lwp *l __unused) +{ + + return 0; +} +#endif /*ARGSUSED*/ static void -lockstat_provide(void *arg, dtrace_probedesc_t *desc) +lockstat_provide(void *arg, const dtrace_probedesc_t *desc) { int i = 0; for (i = 0; lockstat_probes[i].lsp_func != NULL; i++) { lockstat_probe_t *probe = &lockstat_probes[i]; - if (dtrace_probe_lookup(lockstat_id, "kernel", - probe->lsp_func, probe->lsp_name) != 0) + if (dtrace_probe_lookup(lockstat_id, __UNCONST("kernel"), + __UNCONST(probe->lsp_func), __UNCONST(probe->lsp_name)) + != 0) continue; ASSERT(!probe->lsp_id); @@ -235,8 +288,8 @@ lockstat_provide(void *arg, dtrace_probe probe->lsp_frame, probe); #else probe->lsp_id = dtrace_probe_create(lockstat_id, - "kernel", probe->lsp_func, probe->lsp_name, - LOCKSTAT_AFRAMES, probe); + __UNCONST("kernel"), __UNCONST(probe->lsp_func), + __UNCONST(probe->lsp_name), LOCKSTAT_AFRAMES, probe); #endif } } @@ -275,9 +328,11 @@ static dtrace_pops_t lockstat_pops = { static void lockstat_load(void *dummy) { +#ifdef __FreeBSD__ /* Create the /dev/dtrace/lockstat entry. */ lockstat_cdev = make_dev(&lockstat_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "dtrace/lockstat"); +#endif if (dtrace_register("lockstat", &lockstat_attr, DTRACE_PRIV_USER, NULL, &lockstat_pops, NULL, &lockstat_id) != 0) @@ -285,18 +340,22 @@ lockstat_load(void *dummy) } static int -lockstat_unload() +lockstat_unload(void) { int error = 0; if ((error = dtrace_unregister(lockstat_id)) != 0) return (error); +#ifdef __FreeBSD__ destroy_dev(lockstat_cdev); +#endif return (error); } +#if defined(__FreeBSD__) + /* ARGSUSED */ static int lockstat_modevent(module_t mod __unused, int type, void *data __unused) @@ -327,3 +386,32 @@ DEV_MODULE(lockstat, lockstat_modevent, MODULE_VERSION(lockstat, 1); MODULE_DEPEND(lockstat, dtrace, 1, 1, 1); MODULE_DEPEND(lockstat, opensolaris, 1, 1, 1); + +#elif defined(__NetBSD__) + +static int +dtrace_lockstat_modcmd(modcmd_t cmd, void *data) +{ + int bmajor = -1, cmajor = -1; + int error; + + switch (cmd) { + case MODULE_CMD_INIT: + lockstat_load(NULL); + return devsw_attach("lockstat", NULL, &bmajor, + &lockstat_cdevsw, &cmajor); + case MODULE_CMD_FINI: + error = lockstat_unload(); + if (error) + return error; + return devsw_detach(NULL, &lockstat_cdevsw); + case MODULE_CMD_AUTOUNLOAD: + return EBUSY; + default: + return ENOTTY; + } +} + +MODULE(MODULE_CLASS_MISC, dtrace_lockstat, "dtrace"); + +#endif Index: sys/dev/lockstat.c =================================================================== RCS file: /cvsroot/src/sys/dev/lockstat.c,v retrieving revision 1.19 diff -p -u -r1.19 lockstat.c --- sys/dev/lockstat.c 25 Jul 2014 08:10:35 -0000 1.19 +++ sys/dev/lockstat.c 7 Mar 2015 16:44:24 -0000 @@ -110,6 +110,18 @@ size_t lockstat_sizeb; int lockstat_busy; struct timespec lockstat_stime; +#ifdef KDTRACE_HOOKS +void +lockstat_probe_stub(uint32_t id, uintptr_t lock, uintptr_t callsite, + uintptr_t flags, uintptr_t count, uintptr_t cycles) +{ +} + +uint32_t lockstat_probemap[LS_NPROBES]; +void (*lockstat_probe_func)(uint32_t, uintptr_t, uintptr_t, + uintptr_t, uintptr_t, uintptr_t) = &lockstat_probe_stub; +#endif + const struct cdevsw lockstat_cdevsw = { .d_open = lockstat_open, .d_close = lockstat_close, @@ -344,6 +356,16 @@ lockstat_event(uintptr_t lock, uintptr_t u_int event; int s; +#ifdef KDTRACE_HOOKS + { + uint32_t id; + CTASSERT(LS_NPROBES & (LS_NPROBES - 1) == 0); + if ((id = lockstat_probemap[flags & (LS_NPROBES - 1)]) != 0) + (*lockstat_probe_func)(id, lock, callsite, flags, count, + cycles); + } +#endif + if ((flags & lockstat_enabled) != flags || count == 0) return; if (lock < lockstat_lockstart || lock > lockstat_lockend) Index: sys/dev/lockstat.h =================================================================== RCS file: /cvsroot/src/sys/dev/lockstat.h,v retrieving revision 1.10 diff -p -u -r1.10 lockstat.h --- sys/dev/lockstat.h 20 Jan 2009 14:49:00 -0000 1.10 +++ sys/dev/lockstat.h 7 Mar 2015 16:44:24 -0000 @@ -34,6 +34,7 @@ #ifdef _KERNEL_OPT #include +#include "opt_dtrace.h" #endif #include @@ -195,4 +196,14 @@ extern volatile u_int lockstat_enabled; #endif +#ifdef KDTRACE_HOOKS +#define LS_NPROBES 0x800 /* XXX Too many, please compress me! */ +extern uint32_t lockstat_probemap[]; +extern void (*lockstat_probe_func)(uint32_t, uintptr_t, uintptr_t, + uintptr_t, uintptr_t, uintptr_t); + +void lockstat_probe_stub(uint32_t, uintptr_t, uintptr_t, + uintptr_t, uintptr_t, uintptr_t); +#endif + #endif /* _SYS_LOCKSTAT_H_ */ Index: sys/modules/dtrace/Makefile =================================================================== RCS file: /cvsroot/src/sys/modules/dtrace/Makefile,v retrieving revision 1.4 diff -p -u -r1.4 Makefile --- sys/modules/dtrace/Makefile 2 Dec 2012 01:05:17 -0000 1.4 +++ sys/modules/dtrace/Makefile 7 Mar 2015 16:44:24 -0000 @@ -3,6 +3,10 @@ .include -SUBDIR= dtrace sdt fbt profile +SUBDIR+= dtrace +SUBDIR+= fbt +SUBDIR+= lockstat +SUBDIR+= profile +SUBDIR+= sdt .include Index: sys/modules/dtrace/lockstat/Makefile =================================================================== RCS file: sys/modules/dtrace/lockstat/Makefile diff -N sys/modules/dtrace/lockstat/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/modules/dtrace/lockstat/Makefile 7 Mar 2015 16:44:24 -0000 @@ -0,0 +1,14 @@ +# $NetBSD$ + +.include "../../Makefile.inc" + +.PATH: ${NETBSDSRCDIR}/external/cddl/osnet/dev/lockstat + +KMOD= dtrace_lockstat +SRCS= lockstat.c + +CPPFLAGS+= -I${NETBSDSRCDIR}/external/cddl/osnet/sys +CPPFLAGS+= -I${NETBSDSRCDIR}/external/cddl/osnet/dist/uts/common +CPPFLAGS+= -DKDTRACE_HOOKS + +.include