svn commit: r185296 - in user/netchild/linuxulator-dtrace/src/sys:
amd64/linux32 compat/linux i386/linux
Alexander Leidinger
netchild at FreeBSD.org
Tue Nov 25 05:52:02 PST 2008
Author: netchild
Date: Tue Nov 25 13:52:02 2008
New Revision: 185296
URL: http://svn.freebsd.org/changeset/base/185296
Log:
Commit what I started yesterday (first few static dtrace probes in the
linuxulator).
Beware, this is WIP, this is not even compile tested.
Modified:
user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux.h
user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.c
user/netchild/linuxulator-dtrace/src/sys/i386/linux/linux.h
Modified: user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux.h
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux.h Tue Nov 25 13:35:06 2008 (r185295)
+++ user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux.h Tue Nov 25 13:52:02 2008 (r185296)
@@ -42,6 +42,7 @@ extern u_char linux_debug_map[];
#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name)
#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid
#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid
+#define LINUX_DTRACE linuxulator32
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_LINUX);
Modified: user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.c
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.c Tue Nov 25 13:35:06 2008 (r185295)
+++ user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.c Tue Nov 25 13:52:02 2008 (r185296)
@@ -30,6 +30,8 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
+#include "opt_kdtrace.h"
+#include "opt_ktrace.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -38,11 +40,15 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/sdt.h>
#include <sys/sx.h>
#include <sys/proc.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/unistd.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
@@ -55,6 +61,55 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_futex.h>
+/*
+ * In this file we define the provider for the entire linuxulator. All
+ * modules (= files of the linuxulator) use it.
+ *
+ * We define a different name depending on the emulated bitsize, see
+ * ../../<ARCH>/linux*/linux.h, e.g.:
+ * native bitsize = linuxulator
+ * amd64, 32bit emulation = linuxulator32
+ */
+SDT_PROVIDER_DEFINE(LINUX_DTRACE);
+
+/* DTrace probes in this module. */
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, em_find, entry);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, em_find, entry, 0, "struct proc *");
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, em_find, entry, 1, "int");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, em_find, emul_locked);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, em_find, emul_locked, 0, "struct mtx *");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, em_find, emul_unlock);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, em_find, emul_unlock, 0, "struct mtx *");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, em_find, return);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, em_find, return, 0,
+ "struct linux_emuldata *");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_init, entry);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_init, entry, 0, "struct thread *");
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_init, entry, 1, "pid_t");
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_init, entry, 2, "int");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_init, emul_unlock);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_init, emul_unlock, 0,
+ "struct mtx *");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_init, return);
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_exit, entry);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_exit, entry, 0, "struct proc *");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_exit, emul_unlock);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_exit, emul_unlock, 0,
+ "struct mtx *");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_exit, reparent);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_exit, reparent, 0, "pid_t");
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_exit, reparent, 1, "pid_t");
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_exit, reparent, 2, "struct proc *");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_exit, child_clear_tid_error);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_exit, child_clear_tid_error, 0,
+ "int");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_exit, return);
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_exec, entry);
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_exec, entry, 0, "struct proc *");
+SDT_PROBE_ARGTYPE(LINUX_DTRACE, emul, proc_exec, entry, 0,
+ "struct image_params *");
+SDT_PROBE_DEFINE(LINUX_DTRACE, emul, proc_exec, return);
+
struct sx emul_shared_lock;
struct mtx emul_lock;
@@ -64,14 +119,23 @@ em_find(struct proc *p, int locked)
{
struct linux_emuldata *em;
- if (locked == EMUL_DOLOCK)
+ SDT_PROBE(LINUX_DTRACE, emul, em_find, entry, p, locked, 0, 0, 0);
+
+ if (locked == EMUL_DOLOCK) {
EMUL_LOCK(&emul_lock);
+ SDT_PROBE(LINUX_DTRACE, emul, em_find, emul_lock, &emul_lock,
+ 0, 0, 0, 0);
+ }
em = p->p_emuldata;
- if (em == NULL && locked == EMUL_DOLOCK)
+ if (em == NULL && locked == EMUL_DOLOCK) {
+ SDT_PROBE(LINUX_DTRACE, emul, em_find, emul_unlock, &emul_lock,
+ 0, 0, 0, 0);
EMUL_UNLOCK(&emul_lock);
+ }
+ SDT_PROBE(LINUX_DTRACE, emul, em_find, return, em, 0, 0, 0, 0);
return (em);
}
@@ -81,17 +145,25 @@ linux_proc_init(struct thread *td, pid_t
struct linux_emuldata *em, *p_em;
struct proc *p;
+ SDT_PROBE(LINUX_DTRACE, emul, proc_init, entry, td, child, flags, 0, 0);
+
if (child != 0) {
- /* non-exec call */
+ /* fork or create a thread */
+
em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO);
em->pid = child;
em->pdeath_signal = 0;
em->robust_futexes = NULL;
if (flags & LINUX_CLONE_THREAD) {
/* handled later in the code */
+ SDT_PROBE(LINUX_DTRACE, emul, proc_init, create_thread,
+ 0, 0, 0, 0, 0);
} else {
struct linux_emuldata_shared *s;
+ SDT_PROBE(LINUX_DTRACE, emul, proc_init, fork, 0, 0, 0,
+ 0, 0);
+
s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO);
s->refs = 1;
s->group_pid = child;
@@ -100,6 +172,10 @@ linux_proc_init(struct thread *td, pid_t
em->shared = s;
}
} else {
+ /* exec */
+
+ SDT_PROBE(LINUX_DTRACE, emul, proc_init, exec, 0, 0, 0, 0, 0);
+
/* lookup the old one */
em = em_find(td->td_proc, EMUL_DOLOCK);
KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n"));
@@ -134,8 +210,7 @@ linux_proc_init(struct thread *td, pid_t
* rwlock held
*/
}
- }
- if (child != 0) {
+
EMUL_SHARED_WLOCK(&emul_shared_lock);
LIST_INSERT_HEAD(&em->shared->threads, em, threads);
EMUL_SHARED_WUNLOCK(&emul_shared_lock);
@@ -144,9 +219,13 @@ linux_proc_init(struct thread *td, pid_t
KASSERT(p != NULL, ("process not found in proc_init\n"));
p->p_emuldata = em;
PROC_UNLOCK(p);
- } else
+ } else {
+ SDT_PROBE(LINUX_DTRACE, emul, proc_init, emul_unlock,
+ &emul_lock, 0, 0, 0, 0);
EMUL_UNLOCK(&emul_lock);
+ }
+ SDT_PROBE(LINUX_DTRACE, emul, proc_init, return, 0, 0, 0, 0, 0);
return (0);
}
@@ -162,17 +241,25 @@ linux_proc_exit(void *arg __unused, stru
if (__predict_true(p->p_sysent != &elf_linux_sysvec))
return;
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit, entry, p, 0, 0, 0, 0);
+
release_futexes(p);
/* find the emuldata */
em = em_find(p, EMUL_DOLOCK);
-
KASSERT(em != NULL, ("proc_exit: emuldata not found.\n"));
/* reparent all procs that are not a thread leader to initproc */
if (em->shared->group_pid != p->p_pid) {
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit, reparent,
+ em->shared->group_pid, p->p_pid, p, 0, 0);
+
child_clear_tid = em->child_clear_tid;
+
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit, emul_unlock,
+ &emul_lock, 0, 0, 0, 0);
EMUL_UNLOCK(&emul_lock);
+
sx_xlock(&proctree_lock);
wakeup(initproc);
PROC_LOCK(p);
@@ -182,6 +269,9 @@ linux_proc_exit(void *arg __unused, stru
sx_xunlock(&proctree_lock);
} else {
child_clear_tid = em->child_clear_tid;
+
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit, emul_unlock,
+ &emul_lock, 0, 0, 0, 0);
EMUL_UNLOCK(&emul_lock);
}
@@ -201,7 +291,13 @@ linux_proc_exit(void *arg __unused, stru
error = copyout(&null, child_clear_tid, sizeof(null));
if (error) {
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit,
+ child_clear_tid_error, error, 0, 0, 0, 0);
+
free(em, M_LINUX);
+
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit, return, 0, 0,
+ 0, 0, 0);
return;
}
@@ -217,8 +313,11 @@ linux_proc_exit(void *arg __unused, stru
* this cannot happen at the moment and if this happens it
* probably means there is a user space bug
*/
- if (error)
+ if (error) {
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit, futex_failed,
+ 0, 0, 0, 0, 0);
printf(LMSG("futex stuff in proc_exit failed.\n"));
+ }
}
/* clean the stuff up */
@@ -240,9 +339,13 @@ linux_proc_exit(void *arg __unused, stru
psignal(q, em->pdeath_signal);
}
PROC_UNLOCK(q);
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit, emul_unlock,
+ &emul_lock, 0, 0, 0, 0);
EMUL_UNLOCK(&emul_lock);
}
sx_xunlock(&proctree_lock);
+
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exit, return, 0, 0, 0, 0, 0);
}
/*
@@ -253,38 +356,44 @@ linux_proc_exit(void *arg __unused, stru
void
linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
{
- if (__predict_false(imgp->sysent == &elf_linux_sysvec
- && p->p_sysent != &elf_linux_sysvec))
- linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0);
- if (__predict_false(imgp->sysent != &elf_linux_sysvec
- && p->p_sysent == &elf_linux_sysvec)) {
- struct linux_emuldata *em;
-
- /*
- * XXX:There's a race because here we assign p->p_emuldata NULL
- * but the process is still counted as linux one for a short
- * time so some other process might reference it and try to
- * access its p->p_emuldata and panicing on a NULL reference.
- */
- em = em_find(p, EMUL_DONTLOCK);
+ if (__predict_false(imgp->sysent == &elf_linux_sysvec) {
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exec, entry, p, imgp, 0, 0,
+ 0);
+
+ if (p->p_sysent != &elf_linux_sysvec))
+ linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0);
+ else {
+ struct linux_emuldata *em;
- KASSERT(em != NULL, ("proc_exec: emuldata not found.\n"));
+ /*
+ * XXX:There's a race because here we assign
+ * p->p_emuldata NULL but the process is still counted
+ * as linux one for a short time so some other process
+ * might reference it and try to access its
+ * p->p_emuldata and panicing on a NULL reference.
+ */
+ em = em_find(p, EMUL_DONTLOCK);
+ KASSERT(em != NULL,
+ ("proc_exec: emuldata not found.\n"));
- EMUL_SHARED_WLOCK(&emul_shared_lock);
- LIST_REMOVE(em, threads);
+ EMUL_SHARED_WLOCK(&emul_shared_lock);
+ LIST_REMOVE(em, threads);
- PROC_LOCK(p);
- p->p_emuldata = NULL;
- PROC_UNLOCK(p);
+ PROC_LOCK(p);
+ p->p_emuldata = NULL;
+ PROC_UNLOCK(p);
+
+ em->shared->refs--;
+ if (em->shared->refs == 0) {
+ EMUL_SHARED_WUNLOCK(&emul_shared_lock);
+ free(em->shared, M_LINUX);
+ } else
+ EMUL_SHARED_WUNLOCK(&emul_shared_lock);
- em->shared->refs--;
- if (em->shared->refs == 0) {
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
- free(em->shared, M_LINUX);
- } else
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
+ free(em, M_LINUX);
+ }
- free(em, M_LINUX);
+ SDT_PROBE(LINUX_DTRACE, emul, proc_exec, return, 0, 0, 0, 0, 0);
}
}
Modified: user/netchild/linuxulator-dtrace/src/sys/i386/linux/linux.h
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/i386/linux/linux.h Tue Nov 25 13:35:06 2008 (r185295)
+++ user/netchild/linuxulator-dtrace/src/sys/i386/linux/linux.h Tue Nov 25 13:52:02 2008 (r185296)
@@ -42,6 +42,7 @@ extern u_char linux_debug_map[];
#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name)
#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid
#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid
+#define LINUX_DTRACE linuxulator
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_LINUX);
More information about the svn-src-user
mailing list