1/* $OpenBSD: kstat.h,v 1.6 2025/05/13 21:20:10 kettenis 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
30struct 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
69enum 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 */
93enum 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
100struct 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
136struct kstat_lock_ops;
137struct rwlock;
138
139struct kstat {
140 uint64_t ks_id;
141
142 const char *ks_provider;
143 unsigned int ks_instance;
144 const char *ks_name;
145 unsigned int ks_unit;
146
147 unsigned int ks_type;
148 unsigned int ks_flags;
149#define KSTAT_F_REALLOC (1 << 0)
150 unsigned int ks_state;
151#define KSTAT_S_CREATED 0
152#define KSTAT_S_INSTALLED 1
153
154 struct timespec ks_created;
155 RBT_ENTRY(kstat) ks_id_entry;
156 RBT_ENTRY(kstat) ks_pv_entry;
157 RBT_ENTRY(kstat) ks_nm_entry;
158
159 /* the driver can update these between kstat creation and install */
160 unsigned int ks_dataver;
161 void *ks_softc;
162 void *ks_ptr;
163 int (*ks_read)(struct kstat *);
164 int (*ks_copy)(struct kstat *, void *);
165
166 const struct kstat_lock_ops *
167 ks_lock_ops;
168 void *ks_lock;
169
170 /* the data that is updated by ks_read */
171 void *ks_data;
172 size_t ks_datalen;
173 struct timespec ks_updated;
174 struct timespec ks_interval;
175};
176
177struct kstat *kstat_create(const char *, unsigned int,
178 const char *, unsigned int,
179 unsigned int, unsigned int);
180
181void kstat_set_rlock(struct kstat *, struct rwlock *);
182void kstat_set_wlock(struct kstat *, struct rwlock *);
183void kstat_set_mutex(struct kstat *, struct mutex *);
184void kstat_set_cpu(struct kstat *, struct cpu_info *);
185
186int kstat_read_nop(struct kstat *);
187
188void kstat_install(struct kstat *);
189void kstat_remove(struct kstat *);
190void kstat_destroy(struct kstat *);
191
192/*
193 * kstat_kv api
194 */
195
196#define KSTAT_KV_UNIT_INITIALIZER(_key, _type, _unit) { \
197 .kv_key = (_key), \
198 .kv_type = (_type), \
199 .kv_unit = (_unit), \
200}
201
202#define KSTAT_KV_INITIALIZER(_key, _type) \
203 KSTAT_KV_UNIT_INITIALIZER((_key), (_type), KSTAT_KV_U_NONE)
204
205void kstat_kv_init(struct kstat_kv *, const char *, enum kstat_kv_type);
206void kstat_kv_unit_init(struct kstat_kv *, const char *,
207 enum kstat_kv_type, enum kstat_kv_unit);
208
209#endif /* _KERNEL */
210
211#endif /* _SYS_KSTAT_H_ */