pmclog.h revision 157217
1/*-
2 * Copyright (c) 2005-2006, Joseph Koshy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/sys/pmclog.h 157217 2006-03-28 16:20:29Z jkoshy $
27 */
28
29#ifndef	_SYS_PMCLOG_H_
30#define	_SYS_PMCLOG_H_
31
32#include <sys/pmc.h>
33
34enum pmclog_type {
35	/* V1 ABI */
36	PMCLOG_TYPE_CLOSELOG,
37	PMCLOG_TYPE_DROPNOTIFY,
38	PMCLOG_TYPE_INITIALIZE,
39	PMCLOG_TYPE_MAPPINGCHANGE, /* unused in v1 */
40	PMCLOG_TYPE_PCSAMPLE,
41	PMCLOG_TYPE_PMCALLOCATE,
42	PMCLOG_TYPE_PMCATTACH,
43	PMCLOG_TYPE_PMCDETACH,
44	PMCLOG_TYPE_PROCCSW,
45	PMCLOG_TYPE_PROCEXEC,
46	PMCLOG_TYPE_PROCEXIT,
47	PMCLOG_TYPE_PROCFORK,
48	PMCLOG_TYPE_SYSEXIT,
49	PMCLOG_TYPE_USERDATA,
50	/*
51	 * V2 ABI
52	 *
53	 * The MAP_{IN,OUT} event types obsolete the MAPPING_CHANGE
54	 * event type of the older (V1) ABI.
55	 */
56	PMCLOG_TYPE_MAP_IN,
57	PMCLOG_TYPE_MAP_OUT
58};
59
60/*
61 * A log entry descriptor comprises of a 32 bit header and a 64 bit
62 * time stamp followed by as many 32 bit words are required to record
63 * the event.
64 *
65 * Header field format:
66 *
67 *  31           24           16                                   0
68 *   +------------+------------+-----------------------------------+
69 *   |    MAGIC   |    TYPE    |               LENGTH              |
70 *   +------------+------------+-----------------------------------+
71 *
72 * MAGIC 	is the constant PMCLOG_HEADER_MAGIC.
73 * TYPE  	contains a value of type enum pmclog_type.
74 * LENGTH	contains the length of the event record, in bytes.
75 */
76
77#define	PMCLOG_ENTRY_HEADER				\
78	uint32_t		pl_header;		\
79	uint32_t		pl_ts_sec;		\
80	uint32_t		pl_ts_nsec;
81
82
83/*
84 * The following structures are used to describe the size of each kind
85 * of log entry to sizeof().  To keep the compiler from adding
86 * padding, the fields of each structure are aligned to their natural
87 * boundaries, and the structures are marked as 'packed'.
88 *
89 * The actual reading and writing of the log file is always in terms
90 * of 4 byte quantities.
91 */
92
93struct pmclog_closelog {
94	PMCLOG_ENTRY_HEADER
95};
96
97struct pmclog_dropnotify {
98	PMCLOG_ENTRY_HEADER
99};
100
101struct pmclog_initialize {
102	PMCLOG_ENTRY_HEADER
103	uint32_t		pl_version;	/* driver version */
104	uint32_t		pl_cpu;		/* enum pmc_cputype */
105} __packed;
106
107struct pmclog_map_in {
108	PMCLOG_ENTRY_HEADER
109	uint32_t		pl_pid;
110	uintfptr_t		pl_start;	/* 8 byte aligned */
111	char			pl_pathname[PATH_MAX];
112} __packed;
113
114struct pmclog_map_out {
115	PMCLOG_ENTRY_HEADER
116	uint32_t		pl_pid;
117	uintfptr_t		pl_start;	/* 8 byte aligned */
118	uintfptr_t		pl_end;
119} __packed;
120
121struct pmclog_pcsample {
122	PMCLOG_ENTRY_HEADER
123	uint32_t		pl_pid;
124	uintfptr_t		pl_pc;		/* 8 byte aligned */
125	uint32_t		pl_pmcid;
126	uint32_t		pl_usermode;
127} __packed;
128
129struct pmclog_pmcallocate {
130	PMCLOG_ENTRY_HEADER
131	uint32_t		pl_pmcid;
132	uint32_t		pl_event;
133	uint32_t		pl_flags;
134} __packed;
135
136struct pmclog_pmcattach {
137	PMCLOG_ENTRY_HEADER
138	uint32_t		pl_pmcid;
139	uint32_t		pl_pid;
140	char			pl_pathname[PATH_MAX];
141} __packed;
142
143struct pmclog_pmcdetach {
144	PMCLOG_ENTRY_HEADER
145	uint32_t		pl_pmcid;
146	uint32_t		pl_pid;
147} __packed;
148
149struct pmclog_proccsw {
150	PMCLOG_ENTRY_HEADER
151	uint32_t		pl_pmcid;
152	uint64_t		pl_value;	/* keep 8 byte aligned */
153	uint32_t		pl_pid;
154} __packed;
155
156struct pmclog_procexec {
157	PMCLOG_ENTRY_HEADER
158	uint32_t		pl_pid;
159	uintfptr_t		pl_start;	/* keep 8 byte aligned */
160	uint32_t		pl_pmcid;
161	char			pl_pathname[PATH_MAX];
162} __packed;
163
164struct pmclog_procexit {
165	PMCLOG_ENTRY_HEADER
166	uint32_t		pl_pmcid;
167	uint64_t		pl_value;	/* keep 8 byte aligned */
168	uint32_t		pl_pid;
169} __packed;
170
171struct pmclog_procfork {
172	PMCLOG_ENTRY_HEADER
173	uint32_t		pl_oldpid;
174	uint32_t		pl_newpid;
175} __packed;
176
177struct pmclog_sysexit {
178	PMCLOG_ENTRY_HEADER
179	uint32_t		pl_pid;
180} __packed;
181
182struct pmclog_userdata {
183	PMCLOG_ENTRY_HEADER
184	uint32_t		pl_userdata;
185} __packed;
186
187union pmclog_entry {		/* only used to size scratch areas */
188	struct pmclog_closelog		pl_cl;
189	struct pmclog_dropnotify	pl_dn;
190	struct pmclog_initialize	pl_i;
191	struct pmclog_map_in		pl_mi;
192	struct pmclog_map_out		pl_mo;
193	struct pmclog_pcsample		pl_s;
194	struct pmclog_pmcallocate	pl_a;
195	struct pmclog_pmcattach		pl_t;
196	struct pmclog_pmcdetach		pl_d;
197	struct pmclog_proccsw		pl_c;
198	struct pmclog_procexec		pl_x;
199	struct pmclog_procexit		pl_e;
200	struct pmclog_procfork		pl_f;
201	struct pmclog_sysexit		pl_se;
202	struct pmclog_userdata		pl_u;
203};
204
205#define	PMCLOG_HEADER_MAGIC					0xEEU
206
207#define	PMCLOG_HEADER_TO_LENGTH(H)				\
208	((H) & 0x0000FFFF)
209#define	PMCLOG_HEADER_TO_TYPE(H)				\
210	(((H) & 0x00FF0000) >> 16)
211#define	PMCLOG_HEADER_TO_MAGIC(H)				\
212	(((H) & 0xFF000000) >> 24)
213#define	PMCLOG_HEADER_CHECK_MAGIC(H)				\
214	(PMCLOG_HEADER_TO_MAGIC(H) == PMCLOG_HEADER_MAGIC)
215
216#ifdef	_KERNEL
217
218/*
219 * Prototypes
220 */
221int	pmclog_configure_log(struct pmc_owner *_po, int _logfd);
222int	pmclog_deconfigure_log(struct pmc_owner *_po);
223int	pmclog_flush(struct pmc_owner *_po);
224void	pmclog_initialize(void);
225void	pmclog_process_closelog(struct pmc_owner *po);
226void	pmclog_process_dropnotify(struct pmc_owner *po);
227void	pmclog_process_map_in(struct pmc_owner *po, pid_t pid,
228    uintfptr_t start, const char *path);
229void	pmclog_process_map_out(struct pmc_owner *po, pid_t pid,
230    uintfptr_t start, uintfptr_t end);
231void	pmclog_process_pcsample(struct pmc *_pm, struct pmc_sample *_ps);
232void	pmclog_process_pmcallocate(struct pmc *_pm);
233void	pmclog_process_pmcattach(struct pmc *_pm, pid_t _pid, char *_path);
234void	pmclog_process_pmcdetach(struct pmc *_pm, pid_t _pid);
235void	pmclog_process_proccsw(struct pmc *_pm, struct pmc_process *_pp,
236    pmc_value_t _v);
237void	pmclog_process_procexec(struct pmc_owner *_po, pmc_id_t _pmid, pid_t _pid,
238    uintfptr_t _startaddr, char *_path);
239void	pmclog_process_procexit(struct pmc *_pm, struct pmc_process *_pp);
240void	pmclog_process_procfork(struct pmc_owner *_po, pid_t _oldpid, pid_t _newpid);
241void	pmclog_process_sysexit(struct pmc_owner *_po, pid_t _pid);
242int	pmclog_process_userlog(struct pmc_owner *_po,
243    struct pmc_op_writelog *_wl);
244void	pmclog_shutdown(void);
245#endif	/* _KERNEL */
246
247#endif	/* _SYS_PMCLOG_H_ */
248