xref: /openbsd/sys/sys/kstat.h (revision 6ba0eb46)
1*6ba0eb46Sdlg /* $OpenBSD: kstat.h,v 1.5 2024/03/26 00:53:51 dlg Exp $ */
2402315e8Sdlg 
3402315e8Sdlg /*
4402315e8Sdlg  * Copyright (c) 2020 David Gwynne <dlg@openbsd.org>
5402315e8Sdlg  *
6402315e8Sdlg  * Permission to use, copy, modify, and distribute this software for any
7402315e8Sdlg  * purpose with or without fee is hereby granted, provided that the above
8402315e8Sdlg  * copyright notice and this permission notice appear in all copies.
9402315e8Sdlg  *
10402315e8Sdlg  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11402315e8Sdlg  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12402315e8Sdlg  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13402315e8Sdlg  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14402315e8Sdlg  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15402315e8Sdlg  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16402315e8Sdlg  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17402315e8Sdlg  */
18402315e8Sdlg 
19402315e8Sdlg #ifndef _SYS_KSTAT_H_
20402315e8Sdlg #define _SYS_KSTAT_H_
21402315e8Sdlg 
22402315e8Sdlg #include <sys/ioccom.h>
23402315e8Sdlg 
24402315e8Sdlg #define KSTAT_STRLEN		32
25402315e8Sdlg 
26402315e8Sdlg #define KSTAT_T_RAW		0
27402315e8Sdlg #define KSTAT_T_KV		1
28402315e8Sdlg #define KSTAT_T_COUNTERS	2
29402315e8Sdlg 
30402315e8Sdlg struct kstat_req {
31402315e8Sdlg 	unsigned int		 ks_rflags;
32402315e8Sdlg #define KSTATIOC_F_IGNVER		(1 << 0)
33402315e8Sdlg 	/* the current version of the kstat subsystem */
34402315e8Sdlg 	unsigned int		 ks_version;
35402315e8Sdlg 
36402315e8Sdlg 	uint64_t		 ks_id;
37402315e8Sdlg 
38402315e8Sdlg 	char			 ks_provider[KSTAT_STRLEN];
39402315e8Sdlg 	unsigned int		 ks_instance;
40402315e8Sdlg 	char			 ks_name[KSTAT_STRLEN];
41402315e8Sdlg 	unsigned int		 ks_unit;
42402315e8Sdlg 
43402315e8Sdlg 	struct timespec		 ks_created;
44402315e8Sdlg 	struct timespec		 ks_updated;
45402315e8Sdlg 	struct timespec		 ks_interval;
46402315e8Sdlg 	unsigned int		 ks_type;
47402315e8Sdlg 	unsigned int		 ks_state;
48402315e8Sdlg 
49402315e8Sdlg 	void			*ks_data;
50402315e8Sdlg 	size_t			 ks_datalen;
51402315e8Sdlg 	unsigned int		 ks_dataver;
52402315e8Sdlg };
53402315e8Sdlg 
54402315e8Sdlg /* ioctls */
55402315e8Sdlg 
56402315e8Sdlg #define KSTATIOC_VERSION	_IOR('k', 1, unsigned int)
57402315e8Sdlg #define KSTATIOC_FIND_ID	_IOWR('k', 2, struct kstat_req)
58402315e8Sdlg #define KSTATIOC_NFIND_ID	_IOWR('k', 3, struct kstat_req)
59402315e8Sdlg #define KSTATIOC_FIND_PROVIDER	_IOWR('k', 4, struct kstat_req)
60402315e8Sdlg #define KSTATIOC_NFIND_PROVIDER	_IOWR('k', 5, struct kstat_req)
61402315e8Sdlg #define KSTATIOC_FIND_NAME	_IOWR('k', 6, struct kstat_req)
62402315e8Sdlg #define KSTATIOC_NFIND_NAME	_IOWR('k', 7, struct kstat_req)
63402315e8Sdlg 
64402315e8Sdlg /* named data */
65402315e8Sdlg 
66402315e8Sdlg #define KSTAT_KV_NAMELEN	16
67402315e8Sdlg #define KSTAT_KV_ALIGN		sizeof(uint64_t)
68402315e8Sdlg 
69402315e8Sdlg enum kstat_kv_type {
70402315e8Sdlg 	KSTAT_KV_T_NULL,
71402315e8Sdlg 	KSTAT_KV_T_BOOL,
72402315e8Sdlg 	KSTAT_KV_T_COUNTER64,
73402315e8Sdlg 	KSTAT_KV_T_COUNTER32,
74402315e8Sdlg 	KSTAT_KV_T_UINT64,
75402315e8Sdlg 	KSTAT_KV_T_INT64,
76402315e8Sdlg 	KSTAT_KV_T_UINT32,
77402315e8Sdlg 	KSTAT_KV_T_INT32,
78402315e8Sdlg 	KSTAT_KV_T_ISTR,	/* inline string */
79402315e8Sdlg 	KSTAT_KV_T_STR,		/* trailing string */
80402315e8Sdlg 	KSTAT_KV_T_BYTES,	/* trailing bytes */
81402315e8Sdlg 	KSTAT_KV_T_TEMP,	/* temperature (uK) */
82cdfe77a4Sdlg 	KSTAT_KV_T_COUNTER16,
83cdfe77a4Sdlg 	KSTAT_KV_T_UINT16,
84cdfe77a4Sdlg 	KSTAT_KV_T_INT16,
8594e482dfSdlg 	KSTAT_KV_T_FREQ,	/* frequency (Hz) */
8694e482dfSdlg 	KSTAT_KV_T_VOLTS_DC,	/* voltage (uV DC) */
8794e482dfSdlg 	KSTAT_KV_T_VOLTS_AC,	/* voltage (uV AC) */
88*6ba0eb46Sdlg 	KSTAT_KV_T_AMPS,	/* current (uA) */
89*6ba0eb46Sdlg 	KSTAT_KV_T_WATTS,	/* power (uW) */
90402315e8Sdlg };
91402315e8Sdlg 
92402315e8Sdlg /* units only apply to integer types */
93402315e8Sdlg enum kstat_kv_unit {
94402315e8Sdlg 	KSTAT_KV_U_NONE = 0,
95402315e8Sdlg 	KSTAT_KV_U_PACKETS,	/* packets */
96402315e8Sdlg 	KSTAT_KV_U_BYTES,	/* bytes */
97402315e8Sdlg 	KSTAT_KV_U_CYCLES,	/* cycles */
98402315e8Sdlg };
99402315e8Sdlg 
100402315e8Sdlg struct kstat_kv {
101402315e8Sdlg 	char			 kv_key[KSTAT_KV_NAMELEN];
102402315e8Sdlg 	union {
103402315e8Sdlg 		char			v_istr[16];
104402315e8Sdlg 		unsigned int		v_bool;
105402315e8Sdlg 		uint64_t		v_u64;
106402315e8Sdlg 		int64_t			v_s64;
107402315e8Sdlg 		uint32_t		v_u32;
108402315e8Sdlg 		int32_t			v_s32;
109cdfe77a4Sdlg 		uint16_t		v_u16;
110cdfe77a4Sdlg 		int16_t			v_s16;
111402315e8Sdlg 		size_t			v_len;
112402315e8Sdlg 	}			 kv_v;
113402315e8Sdlg 	enum kstat_kv_type	 kv_type;
114402315e8Sdlg 	enum kstat_kv_unit	 kv_unit;
115402315e8Sdlg } __aligned(KSTAT_KV_ALIGN);
116402315e8Sdlg 
117402315e8Sdlg #define kstat_kv_istr(_kv)	(_kv)->kv_v.v_istr
118402315e8Sdlg #define kstat_kv_bool(_kv)	(_kv)->kv_v.v_bool
119402315e8Sdlg #define kstat_kv_u64(_kv)	(_kv)->kv_v.v_u64
120402315e8Sdlg #define kstat_kv_s64(_kv)	(_kv)->kv_v.v_s64
121402315e8Sdlg #define kstat_kv_u32(_kv)	(_kv)->kv_v.v_u32
122402315e8Sdlg #define kstat_kv_s32(_kv)	(_kv)->kv_v.v_s32
123cdfe77a4Sdlg #define kstat_kv_u16(_kv)	(_kv)->kv_v.v_u16
124cdfe77a4Sdlg #define kstat_kv_s16(_kv)	(_kv)->kv_v.v_s16
125402315e8Sdlg #define kstat_kv_len(_kv)	(_kv)->kv_v.v_len
126402315e8Sdlg #define kstat_kv_temp(_kv)	(_kv)->kv_v.v_u64
12794e482dfSdlg #define kstat_kv_freq(_kv)	(_kv)->kv_v.v_u64
12894e482dfSdlg #define kstat_kv_volts(_kv)	(_kv)->kv_v.v_u64
129*6ba0eb46Sdlg #define kstat_kv_amps(_kv)	(_kv)->kv_v.v_u64
130*6ba0eb46Sdlg #define kstat_kv_watts(_kv)	(_kv)->kv_v.v_u64
131402315e8Sdlg 
132402315e8Sdlg #ifdef _KERNEL
133402315e8Sdlg 
134402315e8Sdlg #include <sys/tree.h>
135402315e8Sdlg 
136402315e8Sdlg struct kstat_lock_ops;
137402315e8Sdlg 
138402315e8Sdlg struct kstat {
139402315e8Sdlg 	uint64_t		  ks_id;
140402315e8Sdlg 
141402315e8Sdlg 	const char		 *ks_provider;
142402315e8Sdlg 	unsigned int		  ks_instance;
143402315e8Sdlg 	const char		 *ks_name;
144402315e8Sdlg 	unsigned int		  ks_unit;
145402315e8Sdlg 
146402315e8Sdlg 	unsigned int		  ks_type;
147402315e8Sdlg 	unsigned int		  ks_flags;
148402315e8Sdlg #define KSTAT_F_REALLOC			(1 << 0)
149402315e8Sdlg 	unsigned int		  ks_state;
150402315e8Sdlg #define KSTAT_S_CREATED			0
151402315e8Sdlg #define KSTAT_S_INSTALLED		1
152402315e8Sdlg 
153402315e8Sdlg 	struct timespec		  ks_created;
154402315e8Sdlg 	RBT_ENTRY(kstat)	  ks_id_entry;
155402315e8Sdlg 	RBT_ENTRY(kstat)	  ks_pv_entry;
156402315e8Sdlg 	RBT_ENTRY(kstat)	  ks_nm_entry;
157402315e8Sdlg 
158402315e8Sdlg 	/* the driver can update these between kstat creation and install */
159402315e8Sdlg 	unsigned int		  ks_dataver;
160402315e8Sdlg 	void			 *ks_softc;
161402315e8Sdlg 	void			 *ks_ptr;
162402315e8Sdlg 	int			(*ks_read)(struct kstat *);
163402315e8Sdlg 	int			(*ks_copy)(struct kstat *, void *);
164402315e8Sdlg 
165402315e8Sdlg 	const struct kstat_lock_ops *
166402315e8Sdlg 				  ks_lock_ops;
167402315e8Sdlg 	void			 *ks_lock;
168402315e8Sdlg 
169402315e8Sdlg 	/* the data that is updated by ks_read */
170402315e8Sdlg 	void			 *ks_data;
171402315e8Sdlg 	size_t			  ks_datalen;
172402315e8Sdlg 	struct timespec		  ks_updated;
173402315e8Sdlg 	struct timespec		  ks_interval;
174402315e8Sdlg };
175402315e8Sdlg 
176402315e8Sdlg struct kstat	*kstat_create(const char *, unsigned int,
177402315e8Sdlg 		     const char *, unsigned int,
178402315e8Sdlg 		     unsigned int, unsigned int);
179402315e8Sdlg 
180402315e8Sdlg void		 kstat_set_rlock(struct kstat *, struct rwlock *);
181402315e8Sdlg void		 kstat_set_wlock(struct kstat *, struct rwlock *);
182402315e8Sdlg void		 kstat_set_mutex(struct kstat *, struct mutex *);
183402315e8Sdlg void		 kstat_set_cpu(struct kstat *, struct cpu_info *);
184402315e8Sdlg 
185402315e8Sdlg int		 kstat_read_nop(struct kstat *);
186402315e8Sdlg 
187402315e8Sdlg void		 kstat_install(struct kstat *);
188a94953c6Sdlg void		 kstat_remove(struct kstat *);
189402315e8Sdlg void		 kstat_destroy(struct kstat *);
190402315e8Sdlg 
191402315e8Sdlg /*
192402315e8Sdlg  * kstat_kv api
193402315e8Sdlg  */
194402315e8Sdlg 
195402315e8Sdlg #define KSTAT_KV_UNIT_INITIALIZER(_key, _type, _unit) {	\
196402315e8Sdlg 	.kv_key = (_key),				\
197402315e8Sdlg 	.kv_type = (_type),				\
198402315e8Sdlg 	.kv_unit = (_unit),				\
199402315e8Sdlg }
200402315e8Sdlg 
201402315e8Sdlg #define KSTAT_KV_INITIALIZER(_key, _type)		\
202402315e8Sdlg     KSTAT_KV_UNIT_INITIALIZER((_key), (_type), KSTAT_KV_U_NONE)
203402315e8Sdlg 
204402315e8Sdlg void	kstat_kv_init(struct kstat_kv *, const char *, enum kstat_kv_type);
205402315e8Sdlg void	kstat_kv_unit_init(struct kstat_kv *, const char *,
206402315e8Sdlg 	    enum kstat_kv_type, enum kstat_kv_unit);
207402315e8Sdlg 
208402315e8Sdlg #endif /* _KERNEL */
209402315e8Sdlg 
210402315e8Sdlg #endif /* _SYS_KSTAT_H_ */
211