xref: /openbsd/sys/sys/kstat.h (revision 6ba0eb46)
1 /* $OpenBSD: kstat.h,v 1.5 2024/03/26 00:53:51 dlg Exp $ */
2 
3 /*
4  * Copyright (c) 2020 David Gwynne <dlg@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _SYS_KSTAT_H_
20 #define _SYS_KSTAT_H_
21 
22 #include <sys/ioccom.h>
23 
24 #define KSTAT_STRLEN		32
25 
26 #define KSTAT_T_RAW		0
27 #define KSTAT_T_KV		1
28 #define KSTAT_T_COUNTERS	2
29 
30 struct kstat_req {
31 	unsigned int		 ks_rflags;
32 #define KSTATIOC_F_IGNVER		(1 << 0)
33 	/* the current version of the kstat subsystem */
34 	unsigned int		 ks_version;
35 
36 	uint64_t		 ks_id;
37 
38 	char			 ks_provider[KSTAT_STRLEN];
39 	unsigned int		 ks_instance;
40 	char			 ks_name[KSTAT_STRLEN];
41 	unsigned int		 ks_unit;
42 
43 	struct timespec		 ks_created;
44 	struct timespec		 ks_updated;
45 	struct timespec		 ks_interval;
46 	unsigned int		 ks_type;
47 	unsigned int		 ks_state;
48 
49 	void			*ks_data;
50 	size_t			 ks_datalen;
51 	unsigned int		 ks_dataver;
52 };
53 
54 /* ioctls */
55 
56 #define KSTATIOC_VERSION	_IOR('k', 1, unsigned int)
57 #define KSTATIOC_FIND_ID	_IOWR('k', 2, struct kstat_req)
58 #define KSTATIOC_NFIND_ID	_IOWR('k', 3, struct kstat_req)
59 #define KSTATIOC_FIND_PROVIDER	_IOWR('k', 4, struct kstat_req)
60 #define KSTATIOC_NFIND_PROVIDER	_IOWR('k', 5, struct kstat_req)
61 #define KSTATIOC_FIND_NAME	_IOWR('k', 6, struct kstat_req)
62 #define KSTATIOC_NFIND_NAME	_IOWR('k', 7, struct kstat_req)
63 
64 /* named data */
65 
66 #define KSTAT_KV_NAMELEN	16
67 #define KSTAT_KV_ALIGN		sizeof(uint64_t)
68 
69 enum kstat_kv_type {
70 	KSTAT_KV_T_NULL,
71 	KSTAT_KV_T_BOOL,
72 	KSTAT_KV_T_COUNTER64,
73 	KSTAT_KV_T_COUNTER32,
74 	KSTAT_KV_T_UINT64,
75 	KSTAT_KV_T_INT64,
76 	KSTAT_KV_T_UINT32,
77 	KSTAT_KV_T_INT32,
78 	KSTAT_KV_T_ISTR,	/* inline string */
79 	KSTAT_KV_T_STR,		/* trailing string */
80 	KSTAT_KV_T_BYTES,	/* trailing bytes */
81 	KSTAT_KV_T_TEMP,	/* temperature (uK) */
82 	KSTAT_KV_T_COUNTER16,
83 	KSTAT_KV_T_UINT16,
84 	KSTAT_KV_T_INT16,
85 	KSTAT_KV_T_FREQ,	/* frequency (Hz) */
86 	KSTAT_KV_T_VOLTS_DC,	/* voltage (uV DC) */
87 	KSTAT_KV_T_VOLTS_AC,	/* voltage (uV AC) */
88 	KSTAT_KV_T_AMPS,	/* current (uA) */
89 	KSTAT_KV_T_WATTS,	/* power (uW) */
90 };
91 
92 /* units only apply to integer types */
93 enum kstat_kv_unit {
94 	KSTAT_KV_U_NONE = 0,
95 	KSTAT_KV_U_PACKETS,	/* packets */
96 	KSTAT_KV_U_BYTES,	/* bytes */
97 	KSTAT_KV_U_CYCLES,	/* cycles */
98 };
99 
100 struct kstat_kv {
101 	char			 kv_key[KSTAT_KV_NAMELEN];
102 	union {
103 		char			v_istr[16];
104 		unsigned int		v_bool;
105 		uint64_t		v_u64;
106 		int64_t			v_s64;
107 		uint32_t		v_u32;
108 		int32_t			v_s32;
109 		uint16_t		v_u16;
110 		int16_t			v_s16;
111 		size_t			v_len;
112 	}			 kv_v;
113 	enum kstat_kv_type	 kv_type;
114 	enum kstat_kv_unit	 kv_unit;
115 } __aligned(KSTAT_KV_ALIGN);
116 
117 #define kstat_kv_istr(_kv)	(_kv)->kv_v.v_istr
118 #define kstat_kv_bool(_kv)	(_kv)->kv_v.v_bool
119 #define kstat_kv_u64(_kv)	(_kv)->kv_v.v_u64
120 #define kstat_kv_s64(_kv)	(_kv)->kv_v.v_s64
121 #define kstat_kv_u32(_kv)	(_kv)->kv_v.v_u32
122 #define kstat_kv_s32(_kv)	(_kv)->kv_v.v_s32
123 #define kstat_kv_u16(_kv)	(_kv)->kv_v.v_u16
124 #define kstat_kv_s16(_kv)	(_kv)->kv_v.v_s16
125 #define kstat_kv_len(_kv)	(_kv)->kv_v.v_len
126 #define kstat_kv_temp(_kv)	(_kv)->kv_v.v_u64
127 #define kstat_kv_freq(_kv)	(_kv)->kv_v.v_u64
128 #define kstat_kv_volts(_kv)	(_kv)->kv_v.v_u64
129 #define kstat_kv_amps(_kv)	(_kv)->kv_v.v_u64
130 #define kstat_kv_watts(_kv)	(_kv)->kv_v.v_u64
131 
132 #ifdef _KERNEL
133 
134 #include <sys/tree.h>
135 
136 struct kstat_lock_ops;
137 
138 struct kstat {
139 	uint64_t		  ks_id;
140 
141 	const char		 *ks_provider;
142 	unsigned int		  ks_instance;
143 	const char		 *ks_name;
144 	unsigned int		  ks_unit;
145 
146 	unsigned int		  ks_type;
147 	unsigned int		  ks_flags;
148 #define KSTAT_F_REALLOC			(1 << 0)
149 	unsigned int		  ks_state;
150 #define KSTAT_S_CREATED			0
151 #define KSTAT_S_INSTALLED		1
152 
153 	struct timespec		  ks_created;
154 	RBT_ENTRY(kstat)	  ks_id_entry;
155 	RBT_ENTRY(kstat)	  ks_pv_entry;
156 	RBT_ENTRY(kstat)	  ks_nm_entry;
157 
158 	/* the driver can update these between kstat creation and install */
159 	unsigned int		  ks_dataver;
160 	void			 *ks_softc;
161 	void			 *ks_ptr;
162 	int			(*ks_read)(struct kstat *);
163 	int			(*ks_copy)(struct kstat *, void *);
164 
165 	const struct kstat_lock_ops *
166 				  ks_lock_ops;
167 	void			 *ks_lock;
168 
169 	/* the data that is updated by ks_read */
170 	void			 *ks_data;
171 	size_t			  ks_datalen;
172 	struct timespec		  ks_updated;
173 	struct timespec		  ks_interval;
174 };
175 
176 struct kstat	*kstat_create(const char *, unsigned int,
177 		     const char *, unsigned int,
178 		     unsigned int, unsigned int);
179 
180 void		 kstat_set_rlock(struct kstat *, struct rwlock *);
181 void		 kstat_set_wlock(struct kstat *, struct rwlock *);
182 void		 kstat_set_mutex(struct kstat *, struct mutex *);
183 void		 kstat_set_cpu(struct kstat *, struct cpu_info *);
184 
185 int		 kstat_read_nop(struct kstat *);
186 
187 void		 kstat_install(struct kstat *);
188 void		 kstat_remove(struct kstat *);
189 void		 kstat_destroy(struct kstat *);
190 
191 /*
192  * kstat_kv api
193  */
194 
195 #define KSTAT_KV_UNIT_INITIALIZER(_key, _type, _unit) {	\
196 	.kv_key = (_key),				\
197 	.kv_type = (_type),				\
198 	.kv_unit = (_unit),				\
199 }
200 
201 #define KSTAT_KV_INITIALIZER(_key, _type)		\
202     KSTAT_KV_UNIT_INITIALIZER((_key), (_type), KSTAT_KV_U_NONE)
203 
204 void	kstat_kv_init(struct kstat_kv *, const char *, enum kstat_kv_type);
205 void	kstat_kv_unit_init(struct kstat_kv *, const char *,
206 	    enum kstat_kv_type, enum kstat_kv_unit);
207 
208 #endif /* _KERNEL */
209 
210 #endif /* _SYS_KSTAT_H_ */
211