xref: /illumos-gate/usr/src/uts/common/sys/kcpc.h (revision 5a469116)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
58d4e547dSae  * Common Development and Distribution License (the "License").
68d4e547dSae  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22b9e93c10SJonathan Haslam  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef _SYS_KCPC_H
277c478bd9Sstevel@tonic-gate #define	_SYS_KCPC_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/cpc_impl.h>
304568bee7Strevtom #include <sys/ksynch.h>
31b885580bSAlexander Kolbasov #include <sys/types.h>
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
347c478bd9Sstevel@tonic-gate extern "C" {
357c478bd9Sstevel@tonic-gate #endif
367c478bd9Sstevel@tonic-gate 
37b885580bSAlexander Kolbasov 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate  * Kernel clients need this file in order to know what a request is and how to
407c478bd9Sstevel@tonic-gate  * program one.
417c478bd9Sstevel@tonic-gate  */
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate typedef struct _kcpc_set kcpc_set_t;
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #ifdef _KERNEL
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate  * Forward declarations.
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate struct _kthread;
517c478bd9Sstevel@tonic-gate struct cpu;
527c478bd9Sstevel@tonic-gate typedef struct _kcpc_request kcpc_request_t;
537c478bd9Sstevel@tonic-gate struct __pcbe_ops;
547c478bd9Sstevel@tonic-gate 
554568bee7Strevtom #define	KCPC_SET_BOUND		0x0001		/* Used in ks_state */
564568bee7Strevtom 
577c478bd9Sstevel@tonic-gate struct _kcpc_set {
587c478bd9Sstevel@tonic-gate 	int			ks_flags;
597c478bd9Sstevel@tonic-gate 	int			ks_nreqs;	/* Number of reqs */
607c478bd9Sstevel@tonic-gate 	kcpc_request_t		*ks_req;	/* Pointer to reqs */
617c478bd9Sstevel@tonic-gate 	uint64_t		*ks_data;	/* Data store for this set */
627c478bd9Sstevel@tonic-gate 	kcpc_ctx_t		*ks_ctx;	/* ctx this set belongs to */
634568bee7Strevtom 	ushort_t		ks_state;	/* Set is bound or unbound */
644568bee7Strevtom 	kmutex_t		ks_lock;	/* Protects ks_state */
654568bee7Strevtom 	kcondvar_t		ks_condv;	/* Wait for bind to complete */
667c478bd9Sstevel@tonic-gate };
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate struct _kcpc_request {
697c478bd9Sstevel@tonic-gate 	void			*kr_config;
707c478bd9Sstevel@tonic-gate 	int			kr_index;	/* indx of data for this req */
717c478bd9Sstevel@tonic-gate 	int			kr_picnum;	/* Number of phys pic */
727c478bd9Sstevel@tonic-gate 	kcpc_pic_t		*kr_picp;	/* Ptr to PIC in context */
737c478bd9Sstevel@tonic-gate 	uint64_t		*kr_data;	/* Ptr to virtual 64-bit pic */
747c478bd9Sstevel@tonic-gate 	char			kr_event[CPC_MAX_EVENT_LEN];
757c478bd9Sstevel@tonic-gate 	uint64_t		kr_preset;
767c478bd9Sstevel@tonic-gate 	uint_t			kr_flags;
777c478bd9Sstevel@tonic-gate 	uint_t			kr_nattrs;
787c478bd9Sstevel@tonic-gate 	kcpc_attr_t		*kr_attr;
79b885580bSAlexander Kolbasov 	void			*kr_ptr;	/* Ptr assigned by requester */
807c478bd9Sstevel@tonic-gate };
817c478bd9Sstevel@tonic-gate 
82b885580bSAlexander Kolbasov typedef struct _kcpc_request_list {
83b885580bSAlexander Kolbasov 	kcpc_request_t		*krl_list;	/* counter event requests */
84b885580bSAlexander Kolbasov 	int			krl_cnt;	/* how many requests */
85b885580bSAlexander Kolbasov 	int			krl_max;	/* max request entries */
86b885580bSAlexander Kolbasov } kcpc_request_list_t;
87b885580bSAlexander Kolbasov 
88b885580bSAlexander Kolbasov /*
89b885580bSAlexander Kolbasov  * Type of update function to be called when reading counters on current CPU in
90b885580bSAlexander Kolbasov  * kcpc_read()
91b885580bSAlexander Kolbasov  */
92b885580bSAlexander Kolbasov typedef int (*kcpc_update_func_t)(void *, uint64_t);
93b885580bSAlexander Kolbasov 
94b885580bSAlexander Kolbasov /*
95b885580bSAlexander Kolbasov  * Type of read function to be called when reading counters on current CPU
96b885580bSAlexander Kolbasov  * (ie. should be same type signature as kcpc_read())
97b885580bSAlexander Kolbasov  */
98b885580bSAlexander Kolbasov typedef int (*kcpc_read_func_t)(kcpc_update_func_t);
99b885580bSAlexander Kolbasov 
100b885580bSAlexander Kolbasov 
101b885580bSAlexander Kolbasov /*
102b885580bSAlexander Kolbasov  * Initialize the kcpc framework
103b885580bSAlexander Kolbasov  */
104b885580bSAlexander Kolbasov extern int kcpc_init(void);
105b885580bSAlexander Kolbasov 
1067c478bd9Sstevel@tonic-gate /*
1077c478bd9Sstevel@tonic-gate  * Bind the set to the indicated thread.
1087c478bd9Sstevel@tonic-gate  * Returns 0 on success, or an errno in case of error. If EINVAL is returned,
1097c478bd9Sstevel@tonic-gate  * a specific error code will be returned in the subcode parameter.
1107c478bd9Sstevel@tonic-gate  */
1117c478bd9Sstevel@tonic-gate extern int kcpc_bind_thread(kcpc_set_t *set, struct _kthread *t, int *subcode);
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate /*
1147c478bd9Sstevel@tonic-gate  * Bind the set to the indicated CPU.
1157c478bd9Sstevel@tonic-gate  * Same return convention as kcpc_bind_thread().
1167c478bd9Sstevel@tonic-gate  */
1177c478bd9Sstevel@tonic-gate extern int kcpc_bind_cpu(kcpc_set_t *set, int cpuid, int *subcode);
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate /*
1207c478bd9Sstevel@tonic-gate  * Request the system to sample the current state of the set into users buf.
1217c478bd9Sstevel@tonic-gate  */
1227c478bd9Sstevel@tonic-gate extern int kcpc_sample(kcpc_set_t *set, uint64_t *buf, hrtime_t *hrtime,
1237c478bd9Sstevel@tonic-gate     uint64_t *tick);
1247c478bd9Sstevel@tonic-gate 
125b885580bSAlexander Kolbasov /*
126b885580bSAlexander Kolbasov  * Create CPC context containing specified list of requested counter events
127b885580bSAlexander Kolbasov  */
128b885580bSAlexander Kolbasov extern int kcpc_cpu_ctx_create(struct cpu *cp, kcpc_request_list_t *req_list,
129b885580bSAlexander Kolbasov     int kmem_flags, kcpc_ctx_t ***ctx_ptr_array, size_t *ctx_ptr_array_sz);
130b885580bSAlexander Kolbasov 
131b885580bSAlexander Kolbasov /*
132b885580bSAlexander Kolbasov  * Returns whether specified counter event is supported
133b885580bSAlexander Kolbasov  */
134b885580bSAlexander Kolbasov extern boolean_t kcpc_event_supported(char *event);
135b885580bSAlexander Kolbasov 
136b885580bSAlexander Kolbasov /*
137b885580bSAlexander Kolbasov  * Initialize list of CPC event requests
138b885580bSAlexander Kolbasov  */
139b885580bSAlexander Kolbasov extern kcpc_request_list_t *kcpc_reqs_init(int nreqs, int kmem_flags);
140b885580bSAlexander Kolbasov 
141b885580bSAlexander Kolbasov /*
142b885580bSAlexander Kolbasov  * Add counter event request to given list of counter event requests
143b885580bSAlexander Kolbasov  */
144b885580bSAlexander Kolbasov extern int kcpc_reqs_add(kcpc_request_list_t *req_list, char *event,
145b885580bSAlexander Kolbasov     uint64_t preset, uint_t flags, uint_t nattrs, kcpc_attr_t *attr, void *ptr,
146b885580bSAlexander Kolbasov     int kmem_flags);
147b885580bSAlexander Kolbasov 
148b885580bSAlexander Kolbasov /*
149b885580bSAlexander Kolbasov  * Reset list of CPC event requests so its space can be used for another set
150b885580bSAlexander Kolbasov  * of requests
151b885580bSAlexander Kolbasov  */
152b885580bSAlexander Kolbasov extern int kcpc_reqs_reset(kcpc_request_list_t *req_list);
153b885580bSAlexander Kolbasov 
154b885580bSAlexander Kolbasov /*
155b885580bSAlexander Kolbasov  * Free given list of counter event requests
156b885580bSAlexander Kolbasov  */
157b885580bSAlexander Kolbasov extern int kcpc_reqs_fini(kcpc_request_list_t *req_list);
158b885580bSAlexander Kolbasov 
159b885580bSAlexander Kolbasov /*
160b885580bSAlexander Kolbasov  * Read CPC data for given event on current CPU
161b885580bSAlexander Kolbasov  */
162b885580bSAlexander Kolbasov extern int kcpc_read(kcpc_update_func_t);
163b885580bSAlexander Kolbasov 
164b885580bSAlexander Kolbasov /*
165b885580bSAlexander Kolbasov  * Program current CPU with given CPC context
166b885580bSAlexander Kolbasov  */
167b885580bSAlexander Kolbasov extern void kcpc_program(kcpc_ctx_t *ctx, boolean_t for_thread,
168b885580bSAlexander Kolbasov     boolean_t cu_interpose);
169b885580bSAlexander Kolbasov 
170b885580bSAlexander Kolbasov /*
171b885580bSAlexander Kolbasov  * Unprogram CPC counters on current CPU
172b885580bSAlexander Kolbasov  */
173b885580bSAlexander Kolbasov extern void kcpc_unprogram(kcpc_ctx_t *ctx, boolean_t cu_interpose);
174b885580bSAlexander Kolbasov 
1757c478bd9Sstevel@tonic-gate /*
1767c478bd9Sstevel@tonic-gate  * Unbind a request and release the associated resources.
1777c478bd9Sstevel@tonic-gate  */
1787c478bd9Sstevel@tonic-gate extern int kcpc_unbind(kcpc_set_t *set);
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /*
1817c478bd9Sstevel@tonic-gate  * Preset the indicated request's counter and underlying PCBE config to the
1827c478bd9Sstevel@tonic-gate  * given value.
1837c478bd9Sstevel@tonic-gate  */
1847c478bd9Sstevel@tonic-gate extern int kcpc_preset(kcpc_set_t *set, int index, uint64_t preset);
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate /*
1877c478bd9Sstevel@tonic-gate  * Unfreeze the set and get it counting again.
1887c478bd9Sstevel@tonic-gate  */
1897c478bd9Sstevel@tonic-gate extern int kcpc_restart(kcpc_set_t *set);
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate extern int kcpc_enable(struct _kthread *t, int cmd, int enable);
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate /*
1947c478bd9Sstevel@tonic-gate  * Mark a thread's CPC context, if it exists, INVALID.
1957c478bd9Sstevel@tonic-gate  */
1967c478bd9Sstevel@tonic-gate extern void kcpc_invalidate(struct _kthread *t);
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate extern int kcpc_overflow_ast(void);
1997c478bd9Sstevel@tonic-gate extern uint_t kcpc_hw_overflow_intr(caddr_t, caddr_t);
2007c478bd9Sstevel@tonic-gate extern int kcpc_hw_cpu_hook(int cpuid, ulong_t *kcpc_cpumap);
2017c478bd9Sstevel@tonic-gate extern int kcpc_hw_lwp_hook(void);
202*5a469116SPatrick Mooney extern void kcpc_idle_ctxop_install(struct _kthread *, struct cpu *);
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate extern krwlock_t	kcpc_cpuctx_lock;  /* lock for 'kcpc_cpuctx' below */
2057c478bd9Sstevel@tonic-gate extern int		kcpc_cpuctx;	   /* number of cpu-specific contexts */
2067c478bd9Sstevel@tonic-gate 
207*5a469116SPatrick Mooney extern void kcpc_free_cpu(kcpc_ctx_t *);
208b885580bSAlexander Kolbasov 
209b9e93c10SJonathan Haslam /*
210b9e93c10SJonathan Haslam  * 'dtrace_cpc_in_use' contains the number of currently active cpc provider
211b9e93c10SJonathan Haslam  * based enablings. See the block comment in uts/common/os/dtrace_subr.c for
212b9e93c10SJonathan Haslam  * details of its actual usage.
213b9e93c10SJonathan Haslam  */
214b9e93c10SJonathan Haslam extern uint32_t		dtrace_cpc_in_use;
215b9e93c10SJonathan Haslam extern void (*dtrace_cpc_fire)(uint64_t);
216b9e93c10SJonathan Haslam 
2177c478bd9Sstevel@tonic-gate extern void kcpc_free_set(kcpc_set_t *set);
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate extern void *kcpc_next_config(void *token, void *current,
2207c478bd9Sstevel@tonic-gate     uint64_t **data);
2218d4e547dSae extern void kcpc_invalidate_config(void *token);
222b9e93c10SJonathan Haslam extern char *kcpc_list_attrs(void);
223b9e93c10SJonathan Haslam extern char *kcpc_list_events(uint_t pic);
224b9e93c10SJonathan Haslam extern void kcpc_free_configs(kcpc_set_t *set);
225b9e93c10SJonathan Haslam extern uint_t kcpc_pcbe_capabilities(void);
226b9e93c10SJonathan Haslam extern int kcpc_pcbe_loaded(void);
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate /*
2297c478bd9Sstevel@tonic-gate  * Called by a PCBE to determine if nonprivileged access to counters should be
2307c478bd9Sstevel@tonic-gate  * allowed. Returns non-zero if non-privileged access is allowed, 0 if not.
2317c478bd9Sstevel@tonic-gate  */
2327c478bd9Sstevel@tonic-gate extern int kcpc_allow_nonpriv(void *token);
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate extern void kcpc_register_pcbe(struct __pcbe_ops *);
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate #endif
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate #endif /* _SYS_KCPC_H */
243