Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add the DTrace hooks to the kernel (KDTRACE_HOOKS config...



details:   https://anonhg.NetBSD.org/src/rev/34d030231488
branches:  trunk
changeset: 752248:34d030231488
user:      darran <darran%NetBSD.org@localhost>
date:      Sun Feb 21 02:11:39 2010 +0000

description:
Add the DTrace hooks to the kernel (KDTRACE_HOOKS config option).
DTrace adds a pointer to the lwp and proc structures which it uses to
manage its state.  These are opaque from the kernel perspective to keep
the kernel free of CDDL code. The state arenas are kmem_alloced and freed
as proccesses and threads are created and destoyed.

Also add a check for trap06 (privileged/illegal instruction) so that
DTrace can check for D scripts that may have triggered the trap so it
can clean up after them and resume normal operation.

Ok with core@.

diffstat:

 sys/arch/i386/i386/trap.c   |   39 +++++++++-
 sys/arch/i386/i386/vector.S |   60 +++++++++++++++-
 sys/kern/kern_lwp.c         |   14 +++-
 sys/kern/kern_proc.c        |   19 ++++-
 sys/kern/kern_synch.c       |   32 +++++++-
 sys/sys/dtrace_bsd.h        |  170 ++++++++++++++++++++++++++++++++++++++++++++
 sys/sys/lwp.h               |    4 +-
 sys/sys/proc.h              |    3 +-
 8 files changed, 329 insertions(+), 12 deletions(-)

diffs (truncated from 543 to 300 lines):

diff -r 1fcb25202413 -r 34d030231488 sys/arch/i386/i386/trap.c
--- a/sys/arch/i386/i386/trap.c Sun Feb 21 01:48:03 2010 +0000
+++ b/sys/arch/i386/i386/trap.c Sun Feb 21 02:11:39 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.253 2010/01/17 22:21:18 dsl Exp $   */
+/*     $NetBSD: trap.c,v 1.254 2010/02/21 02:11:40 darran Exp $        */
 
 /*-
  * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.253 2010/01/17 22:21:18 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.254 2010/02/21 02:11:40 darran Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -120,6 +120,20 @@
 
 #include "npx.h"
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+/*
+ * This is a hook which is initialised by the dtrace module
+ * to handle traps which might occur during DTrace probe
+ * execution.
+ */
+dtrace_trap_func_t     dtrace_trap_func = NULL;
+
+dtrace_doubletrap_func_t       dtrace_doubletrap_func = NULL;
+#endif
+
+
 static inline int xmm_si_code(struct lwp *);
 void trap(struct trapframe *);
 void trap_tss(struct i386tss *, int, int);
@@ -338,6 +352,27 @@
                LWP_CACHE_CREDS(l, p);
        }
 
+#ifdef KDTRACE_HOOKS
+       /*
+        * A trap can occur while DTrace executes a probe. Before
+        * executing the probe, DTrace blocks re-scheduling and sets
+        * a flag in it's per-cpu flags to indicate that it doesn't
+        * want to fault. On returning from the the probe, the no-fault
+        * flag is cleared and finally re-scheduling is enabled.
+        *
+        * If the DTrace kernel module has registered a trap handler,
+        * call it and if it returns non-zero, assume that it has
+        * handled the trap and modified the trap frame so that this
+        * function can return normally.
+        */
+       if ((type == T_PROTFLT || type == T_PAGEFLT) &&
+           dtrace_trap_func != NULL) {
+               if ((*dtrace_trap_func)(frame, type)) {
+                       return;
+               }
+       }
+#endif
+
        switch (type) {
 
        case T_ASTFLT:
diff -r 1fcb25202413 -r 34d030231488 sys/arch/i386/i386/vector.S
--- a/sys/arch/i386/i386/vector.S       Sun Feb 21 01:48:03 2010 +0000
+++ b/sys/arch/i386/i386/vector.S       Sun Feb 21 02:11:39 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vector.S,v 1.51 2010/01/17 22:21:18 dsl Exp $  */
+/*     $NetBSD: vector.S,v 1.52 2010/02/21 02:11:40 darran Exp $       */
 
 /*
  * Copyright 2002 (c) Wasabi Systems, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: vector.S,v 1.51 2010/01/17 22:21:18 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vector.S,v 1.52 2010/02/21 02:11:40 darran Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -129,6 +129,23 @@
        shl     $24,%eax                                ;\
        orl     %edx,%eax
 
+#ifdef KDTRACE_HOOKS
+       .bss
+       .globl  dtrace_invop_jump_addr
+       .align  4
+       .type   dtrace_invop_jump_addr, @object
+        .size  dtrace_invop_jump_addr, 4
+dtrace_invop_jump_addr:
+       .zero   4
+       .globl  dtrace_invop_calltrap_addr
+       .align  4
+       .type   dtrace_invop_calltrap_addr, @object
+        .size  dtrace_invop_calltrap_addr, 4
+dtrace_invop_calltrap_addr:
+       .zero   8
+       .text
+#endif
+
 #ifndef XEN
 #if NLAPIC > 0
 #ifdef MULTIPROCESSOR
@@ -885,8 +902,47 @@
        ZTRAP(T_OFLOW)
 IDTVEC(trap05)
        ZTRAP(T_BOUND)
+/*
+ * Privileged instruction fault.
+ */
+#ifdef KDTRACE_HOOKS
+       SUPERALIGN_TEXT
+IDTVEC(trap06)
+       /* Check if there is no DTrace hook registered. */
+       cmpl    $0,dtrace_invop_jump_addr
+       je      norm_ill
+
+       /* Check if this is a user fault. */
+       /* XXX this was 0x0020 in FreeBSD */
+       cmpl    $GSEL(GCODE_SEL, SEL_KPL), 4(%esp)   /* Check code segment. */
+
+       /* If so, just handle it as a normal trap. */
+       jne     norm_ill
+              
+       /*
+        * This is a kernel instruction fault that might have been caused
+        * by a DTrace provider.
+        */
+       pushal                          /* Push all registers onto the stack. */
+
+       /*
+        * Set our jump address for the jump back in the event that
+        * the exception wasn't caused by DTrace at all.
+        */
+       movl    $norm_ill, dtrace_invop_calltrap_addr
+
+       /* Jump to the code hooked in by DTrace. */
+       jmpl    *dtrace_invop_jump_addr
+
+       /*
+        * Process the instruction fault in the normal way.
+        */
+norm_ill:
+       ZTRAP(T_PRIVINFLT)
+#else
 IDTVEC(trap06)
        ZTRAP(T_PRIVINFLT)
+#endif
 IDTVEC(trap07)
 #if NNPX > 0
        pushl   $0                      # dummy error code
diff -r 1fcb25202413 -r 34d030231488 sys/kern/kern_lwp.c
--- a/sys/kern/kern_lwp.c       Sun Feb 21 01:48:03 2010 +0000
+++ b/sys/kern/kern_lwp.c       Sun Feb 21 02:11:39 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_lwp.c,v 1.137 2009/12/17 01:25:10 rmind Exp $     */
+/*     $NetBSD: kern_lwp.c,v 1.138 2010/02/21 02:11:40 darran Exp $    */
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -209,7 +209,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.137 2009/12/17 01:25:10 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.138 2010/02/21 02:11:40 darran Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -236,6 +236,10 @@
 #include <sys/atomic.h>
 #include <sys/filedesc.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+#endif
+
 #include <uvm/uvm_extern.h>
 #include <uvm/uvm_object.h>
 
@@ -620,6 +624,9 @@
        l2->l_cpu = l1->l_cpu;
        kpreempt_enable();
 
+#ifdef KDTRACE_HOOKS
+       kdtrace_thread_ctor(NULL, l2);
+#endif
        lwp_initspecific(l2);
        sched_lwp_fork(l1, l2);
        lwp_update_creds(l2);
@@ -956,6 +963,9 @@
 
        KASSERT(SLIST_EMPTY(&l->l_pi_lenders));
        KASSERT(l->l_inheritedprio == -1);
+#ifdef KDTRACE_HOOKS
+       kdtrace_thread_dtor(NULL, l);
+#endif
        if (!recycle)
                pool_cache_put(lwp_cache, l);
 }
diff -r 1fcb25202413 -r 34d030231488 sys/kern/kern_proc.c
--- a/sys/kern/kern_proc.c      Sun Feb 21 01:48:03 2010 +0000
+++ b/sys/kern/kern_proc.c      Sun Feb 21 02:11:39 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_proc.c,v 1.159 2009/12/17 01:25:10 rmind Exp $    */
+/*     $NetBSD: kern_proc.c,v 1.160 2010/02/21 02:11:40 darran Exp $   */
 
 /*-
  * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.159 2009/12/17 01:25:10 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.160 2010/02/21 02:11:40 darran Exp $");
 
 #include "opt_kstack.h"
 #include "opt_maxuprc.h"
@@ -94,6 +94,10 @@
 #include <sys/atomic.h>
 #include <sys/kmem.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+#endif
+
 #include <uvm/uvm.h>
 #include <uvm/uvm_extern.h>
 
@@ -442,6 +446,10 @@
        mutex_init(&p->p_sigacts->sa_mutex, MUTEX_DEFAULT, IPL_SCHED);
        siginit(p);
 
+#ifdef KDTRACE_HOOKS
+       kdtrace_proc_ctor(NULL, p);
+#endif
+
        proc_initspecific(p);
        lwp_initspecific(l);
 
@@ -710,6 +718,10 @@
        pt->pt_proc = p;
        pid_alloc_cnt++;
 
+#ifdef KDTRACE_HOOKS
+       kdtrace_proc_ctor(NULL, p);
+#endif
+
        mutex_exit(proc_lock);
 
        return p;
@@ -753,6 +765,9 @@
 proc_free_mem(struct proc *p)
 {
 
+#ifdef KDTRACE_HOOKS
+       kdtrace_proc_dtor(NULL, p);
+#endif
        pool_cache_put(proc_cache, p);
 }
 
diff -r 1fcb25202413 -r 34d030231488 sys/kern/kern_synch.c
--- a/sys/kern/kern_synch.c     Sun Feb 21 01:48:03 2010 +0000
+++ b/sys/kern/kern_synch.c     Sun Feb 21 02:11:39 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_synch.c,v 1.275 2010/02/18 20:58:23 skrll Exp $   */
+/*     $NetBSD: kern_synch.c,v 1.276 2010/02/21 02:11:40 darran Exp $  */
 
 /*-
  * Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2009
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.275 2010/02/18 20:58:23 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.276 2010/02/21 02:11:40 darran Exp $");
 
 #include "opt_kstack.h"
 #include "opt_perfctrs.h"
@@ -102,6 +102,12 @@
 
 #include <dev/lockstat.h>
 
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+int                             dtrace_vtime_active;
+dtrace_vtime_switch_func_t      dtrace_vtime_switch_func;
+#endif
+
 static void    sched_unsleep(struct lwp *, bool);
 static void    sched_changepri(struct lwp *, pri_t);
 static void    sched_lendpri(struct lwp *, pri_t);
@@ -762,6 +768,17 @@
                                SPINLOCK_BACKOFF(count);



Home | Main Index | Thread Index | Old Index