Module Name: src
Committed By: yamt
Date: Sat Feb 5 14:04:40 UTC 2011
Modified Files:
src/sys/arch/x86/x86: tprof_amdpmi.c tprof_pmi.c
src/sys/dev/tprof: tprof.c tprof.h tprof_ioctl.h
Added Files:
src/sys/dev/tprof: tprof_types.h
Log Message:
tprof: record pid and userland events.
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/x86/x86/tprof_amdpmi.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/x86/x86/tprof_pmi.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/tprof/tprof.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/tprof/tprof.h
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/tprof/tprof_ioctl.h
cvs rdiff -u -r0 -r1.1 src/sys/dev/tprof/tprof_types.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/x86/x86/tprof_amdpmi.c
diff -u src/sys/arch/x86/x86/tprof_amdpmi.c:1.2 src/sys/arch/x86/x86/tprof_amdpmi.c:1.3
--- src/sys/arch/x86/x86/tprof_amdpmi.c:1.2 Fri Mar 13 11:10:20 2009
+++ src/sys/arch/x86/x86/tprof_amdpmi.c Sat Feb 5 14:04:40 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: tprof_amdpmi.c,v 1.2 2009/03/13 11:10:20 yamt Exp $ */
+/* $NetBSD: tprof_amdpmi.c,v 1.3 2011/02/05 14:04:40 yamt Exp $ */
/*-
* Copyright (c)2008,2009 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tprof_amdpmi.c,v 1.2 2009/03/13 11:10:20 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tprof_amdpmi.c,v 1.3 2011/02/05 14:04:40 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -39,6 +39,8 @@
#include <dev/tprof/tprof.h>
+#include <uvm/uvm.h> /* VM_MIN_KERNEL_ADDRESS */
+
#include <x86/tprof.h>
#include <x86/nmi.h>
@@ -100,7 +102,7 @@
event_hi = event >> 8;
event_lo = event & 0xff;
- pesr = PESR_OS | PESR_INT |
+ pesr = PESR_USR | PESR_OS | PESR_INT |
__SHIFTIN(event_lo, PESR_EVENT_MASK_LO) |
__SHIFTIN(event_hi, PESR_EVENT_MASK_HI) |
__SHIFTIN(0, PESR_COUNTER_MASK) |
@@ -146,6 +148,7 @@
#else /* defined(__x86_64__) */
tfi.tfi_pc = tf->tf_eip;
#endif /* defined(__x86_64__) */
+ tfi.tfi_inkernel = tfi.tfi_pc >= VM_MIN_KERNEL_ADDRESS;
tprof_sample(tprof_cookie, &tfi);
/* reset counter */
Index: src/sys/arch/x86/x86/tprof_pmi.c
diff -u src/sys/arch/x86/x86/tprof_pmi.c:1.11 src/sys/arch/x86/x86/tprof_pmi.c:1.12
--- src/sys/arch/x86/x86/tprof_pmi.c:1.11 Sun May 9 20:32:41 2010
+++ src/sys/arch/x86/x86/tprof_pmi.c Sat Feb 5 14:04:40 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: tprof_pmi.c,v 1.11 2010/05/09 20:32:41 rmind Exp $ */
+/* $NetBSD: tprof_pmi.c,v 1.12 2011/02/05 14:04:40 yamt Exp $ */
/*-
* Copyright (c)2008,2009 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tprof_pmi.c,v 1.11 2010/05/09 20:32:41 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tprof_pmi.c,v 1.12 2011/02/05 14:04:40 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -40,6 +40,8 @@
#include <dev/tprof/tprof.h>
+#include <uvm/uvm.h> /* VM_MIN_KERNEL_ADDRESS */
+
#include <x86/tprof.h>
#include <x86/nmi.h>
@@ -126,10 +128,10 @@
cccr = CCCR_ENABLE | __SHIFTIN(cccr_escr_select, CCCR_ESCR_SELECT) |
CCCR_MUST_BE_SET;
if (ci->ci_smt_id == 0) {
- escr |= ESCR_T0_OS;
+ escr |= ESCR_T0_OS | ESCR_T0_USR;
cccr |= CCCR_OVF_PMI_T0;
} else {
- escr |= ESCR_T1_OS;
+ escr |= ESCR_T1_OS | ESCR_T0_USR;
cccr |= CCCR_OVF_PMI_T1;
}
@@ -189,6 +191,7 @@
#else /* defined(__x86_64__) */
tfi.tfi_pc = tf->tf_eip;
#endif /* defined(__x86_64__) */
+ tfi.tfi_inkernel = tfi.tfi_pc >= VM_MIN_KERNEL_ADDRESS;
tprof_sample(tprof_cookie, &tfi);
/* reset counter */
Index: src/sys/dev/tprof/tprof.c
diff -u src/sys/dev/tprof/tprof.c:1.7 src/sys/dev/tprof/tprof.c:1.8
--- src/sys/dev/tprof/tprof.c:1.7 Wed Aug 11 11:36:02 2010
+++ src/sys/dev/tprof/tprof.c Sat Feb 5 14:04:40 2011
@@ -1,7 +1,7 @@
-/* $NetBSD: tprof.c,v 1.7 2010/08/11 11:36:02 pgoyette Exp $ */
+/* $NetBSD: tprof.c,v 1.8 2011/02/05 14:04:40 yamt Exp $ */
/*-
- * Copyright (c)2008,2009 YAMAMOTO Takashi,
+ * Copyright (c)2008,2009,2010 YAMAMOTO Takashi,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tprof.c,v 1.7 2010/08/11 11:36:02 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tprof.c,v 1.8 2011/02/05 14:04:40 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -38,6 +38,7 @@
#include <sys/callout.h>
#include <sys/kmem.h>
#include <sys/module.h>
+#include <sys/proc.h>
#include <sys/workqueue.h>
#include <sys/queue.h>
@@ -55,12 +56,10 @@
* L: tprof_lock
* R: tprof_reader_lock
* S: tprof_startstop_lock
+ * s: writer should hold tprof_startstop_lock and tprof_lock
+ * reader should hold tprof_startstop_lock or tprof_lock
*/
-typedef struct {
- uintptr_t s_pc; /* program counter */
-} tprof_sample_t;
-
typedef struct tprof_buf {
u_int b_used;
u_int b_size;
@@ -89,7 +88,7 @@
} tprof_backend_t;
static kmutex_t tprof_lock;
-static bool tprof_running;
+static bool tprof_running; /* s: */
static u_int tprof_nworker; /* L: # of running worker LWPs */
static lwp_t *tprof_owner;
static STAILQ_HEAD(, tprof_buf) tprof_list; /* L: global buffer list */
@@ -318,8 +317,6 @@
static void
tprof_stop(void)
{
- CPU_INFO_ITERATOR cii;
- struct cpu_info *ci;
tprof_backend_t *tb;
KASSERT(mutex_owned(&tprof_startstop_lock));
@@ -335,15 +332,10 @@
mutex_enter(&tprof_lock);
tprof_running = false;
cv_broadcast(&tprof_reader_cv);
- mutex_exit(&tprof_lock);
-
- for (CPU_INFO_FOREACH(cii, ci)) {
- mutex_enter(&tprof_lock);
- while (tprof_nworker > 0) {
- cv_wait(&tprof_cv, &tprof_lock);
- }
- mutex_exit(&tprof_lock);
+ while (tprof_nworker > 0) {
+ cv_wait(&tprof_cv, &tprof_lock);
}
+ mutex_exit(&tprof_lock);
tprof_stop1();
done:
@@ -400,7 +392,7 @@
* tprof_sample: record a sample on the per-cpu buffer.
*
* be careful; can be called in NMI context.
- * we are assuming that curcpu() is safe.
+ * we are bluntly assuming that curcpu() and curlwp->l_proc->p_pid are safe.
*/
void
@@ -408,6 +400,7 @@
{
tprof_cpu_t * const c = tprof_curcpu();
tprof_buf_t * const buf = c->c_buf;
+ tprof_sample_t *sp;
const uintptr_t pc = tfi->tfi_pc;
u_int idx;
@@ -416,7 +409,10 @@
buf->b_overflow++;
return;
}
- buf->b_data[idx].s_pc = pc;
+ sp = &buf->b_data[idx];
+ sp->s_pid = curlwp->l_proc->p_pid;
+ sp->s_flags = (tfi->tfi_inkernel) ? TPROF_SAMPLE_INKERNEL : 0;
+ sp->s_pc = pc;
buf->b_used = idx + 1;
}
Index: src/sys/dev/tprof/tprof.h
diff -u src/sys/dev/tprof/tprof.h:1.4 src/sys/dev/tprof/tprof.h:1.5
--- src/sys/dev/tprof/tprof.h:1.4 Wed Nov 18 12:24:05 2009
+++ src/sys/dev/tprof/tprof.h Sat Feb 5 14:04:40 2011
@@ -1,7 +1,7 @@
-/* $NetBSD: tprof.h,v 1.4 2009/11/18 12:24:05 yamt Exp $ */
+/* $NetBSD: tprof.h,v 1.5 2011/02/05 14:04:40 yamt Exp $ */
/*-
- * Copyright (c)2008,2009 YAMAMOTO Takashi,
+ * Copyright (c)2008,2009,2010 YAMAMOTO Takashi,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,14 @@
#ifndef _DEV_TPROF_TPROF_H_
#define _DEV_TPROF_TPROF_H_
+/*
+ * definitions used by backend drivers
+ */
+
+#include <sys/types.h>
+
+#include <dev/tprof/tprof_types.h>
+
typedef struct tprof_backend_cookie tprof_backend_cookie_t;
typedef struct tprof_backend_ops {
@@ -37,12 +45,13 @@
void (*tbo_stop)(tprof_backend_cookie_t *);
} tprof_backend_ops_t;
-#define TPROF_BACKEND_VERSION 2
+#define TPROF_BACKEND_VERSION 3
int tprof_backend_register(const char *, const tprof_backend_ops_t *, int);
int tprof_backend_unregister(const char *);
typedef struct {
- uintptr_t tfi_pc;
+ uintptr_t tfi_pc; /* program counter */
+ bool tfi_inkernel; /* if tfi_pc is in the kernel address space */
} tprof_frame_info_t;
void tprof_sample(tprof_backend_cookie_t *, const tprof_frame_info_t *);
Index: src/sys/dev/tprof/tprof_ioctl.h
diff -u src/sys/dev/tprof/tprof_ioctl.h:1.1 src/sys/dev/tprof/tprof_ioctl.h:1.2
--- src/sys/dev/tprof/tprof_ioctl.h:1.1 Tue Jan 1 21:28:38 2008
+++ src/sys/dev/tprof/tprof_ioctl.h Sat Feb 5 14:04:40 2011
@@ -1,7 +1,7 @@
-/* $NetBSD: tprof_ioctl.h,v 1.1 2008/01/01 21:28:38 yamt Exp $ */
+/* $NetBSD: tprof_ioctl.h,v 1.2 2011/02/05 14:04:40 yamt Exp $ */
/*-
- * Copyright (c)2008 YAMAMOTO Takashi,
+ * Copyright (c)2008,2010 YAMAMOTO Takashi,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,9 +29,15 @@
#ifndef _DEV_TPROF_TPROF_IOCTL_H_
#define _DEV_TPROF_TPROF_IOCTL_H_
+/*
+ * definitions for userland consumer
+ */
+
#include <sys/ioccom.h>
-#define TPROF_VERSION 1
+#include <dev/tprof/tprof_types.h>
+
+#define TPROF_VERSION 2
#define TPROF_IOC_GETVERSION _IOR('T', 1, int)
Added files:
Index: src/sys/dev/tprof/tprof_types.h
diff -u /dev/null src/sys/dev/tprof/tprof_types.h:1.1
--- /dev/null Sat Feb 5 14:04:40 2011
+++ src/sys/dev/tprof/tprof_types.h Sat Feb 5 14:04:40 2011
@@ -0,0 +1,54 @@
+/* $NetBSD: tprof_types.h,v 1.1 2011/02/05 14:04:40 yamt Exp $ */
+
+/*-
+ * Copyright (c)2010 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _DEV_TPROF_TPROF_TYPES_H_
+#define _DEV_TPROF_TPROF_TYPES_H_
+
+/*
+ * definitions used by both of kernel and userland
+ */
+
+#if defined(_KERNEL)
+#include <sys/types.h>
+#else /* defined(_KERNEL) */
+#include <stdint.h>
+#endif /* defined(_KERNEL) */
+
+typedef struct {
+ uint32_t s_pid; /* process id */
+ uint32_t s_flags; /* flags */
+ uintptr_t s_pc; /* program counter */
+} tprof_sample_t;
+
+/*
+ * s_flags
+ */
+
+#define TPROF_SAMPLE_INKERNEL 1 /* s_pc is in kernel address space */
+
+#endif /* _DEV_TPROF_TPROF_TYPES_H_ */