aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/kstat.h
blob: 456481057c207a1276895c2cab30bc9fcde3066c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* $OpenBSD: kstat.h,v 1.1 2020/07/06 03:56:51 dlg Exp $ */

/*
 * Copyright (c) 2020 David Gwynne <dlg@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef _SYS_KSTAT_H_
#define _SYS_KSTAT_H_

#include <sys/ioccom.h>

#define KSTAT_STRLEN		32

#define KSTAT_T_RAW		0
#define KSTAT_T_KV		1
#define KSTAT_T_COUNTERS	2

struct kstat_req {
	unsigned int		 ks_rflags;
#define KSTATIOC_F_IGNVER		(1 << 0)
	/* the current version of the kstat subsystem */
	unsigned int		 ks_version;

	uint64_t		 ks_id;

	char			 ks_provider[KSTAT_STRLEN];
	unsigned int		 ks_instance;
	char			 ks_name[KSTAT_STRLEN];
	unsigned int		 ks_unit;

	struct timespec		 ks_created;
	struct timespec		 ks_updated;
	struct timespec		 ks_interval;
	unsigned int		 ks_type;
	unsigned int		 ks_state;

	void			*ks_data;
	size_t			 ks_datalen;
	unsigned int		 ks_dataver;
};

/* ioctls */

#define KSTATIOC_VERSION	_IOR('k', 1, unsigned int)
#define KSTATIOC_FIND_ID	_IOWR('k', 2, struct kstat_req)
#define KSTATIOC_NFIND_ID	_IOWR('k', 3, struct kstat_req)
#define KSTATIOC_FIND_PROVIDER	_IOWR('k', 4, struct kstat_req)
#define KSTATIOC_NFIND_PROVIDER	_IOWR('k', 5, struct kstat_req)
#define KSTATIOC_FIND_NAME	_IOWR('k', 6, struct kstat_req)
#define KSTATIOC_NFIND_NAME	_IOWR('k', 7, struct kstat_req)

/* named data */

#define KSTAT_KV_NAMELEN	16
#define KSTAT_KV_ALIGN		sizeof(uint64_t)

enum kstat_kv_type {
	KSTAT_KV_T_NULL,
	KSTAT_KV_T_BOOL,
	KSTAT_KV_T_COUNTER64,
	KSTAT_KV_T_COUNTER32,
	KSTAT_KV_T_UINT64,
	KSTAT_KV_T_INT64,
	KSTAT_KV_T_UINT32,
	KSTAT_KV_T_INT32,
	KSTAT_KV_T_ISTR,	/* inline string */
	KSTAT_KV_T_STR,		/* trailing string */
	KSTAT_KV_T_BYTES,	/* trailing bytes */
	KSTAT_KV_T_TEMP,	/* temperature (uK) */
};

/* units only apply to integer types */
enum kstat_kv_unit {
	KSTAT_KV_U_NONE = 0,
	KSTAT_KV_U_PACKETS,	/* packets */
	KSTAT_KV_U_BYTES,	/* bytes */
	KSTAT_KV_U_CYCLES,	/* cycles */
};

struct kstat_kv {
	char			 kv_key[KSTAT_KV_NAMELEN];
	union {
		char			v_istr[16];
		unsigned int		v_bool;	
		uint64_t		v_u64;
		int64_t			v_s64;
		uint32_t		v_u32;
		int32_t			v_s32;
		size_t			v_len;
	}			 kv_v;
	enum kstat_kv_type	 kv_type;
	enum kstat_kv_unit	 kv_unit;
} __aligned(KSTAT_KV_ALIGN);

#define kstat_kv_istr(_kv)	(_kv)->kv_v.v_istr
#define kstat_kv_bool(_kv)	(_kv)->kv_v.v_bool
#define kstat_kv_u64(_kv)	(_kv)->kv_v.v_u64
#define kstat_kv_s64(_kv)	(_kv)->kv_v.v_s64
#define kstat_kv_u32(_kv)	(_kv)->kv_v.v_u32
#define kstat_kv_s32(_kv)	(_kv)->kv_v.v_s32
#define kstat_kv_len(_kv)	(_kv)->kv_v.v_len
#define kstat_kv_temp(_kv)	(_kv)->kv_v.v_u64

#ifdef _KERNEL

#include <sys/tree.h>

struct kstat_lock_ops;

struct kstat {
	uint64_t		  ks_id;

	const char		 *ks_provider;
	unsigned int		  ks_instance;
	const char		 *ks_name;
	unsigned int		  ks_unit;

	unsigned int		  ks_type;
	unsigned int		  ks_flags;
#define KSTAT_F_REALLOC			(1 << 0)
	unsigned int		  ks_state;
#define KSTAT_S_CREATED			0
#define KSTAT_S_INSTALLED		1

	struct timespec		  ks_created;
	RBT_ENTRY(kstat)	  ks_id_entry;
	RBT_ENTRY(kstat)	  ks_pv_entry;
	RBT_ENTRY(kstat)	  ks_nm_entry;

	/* the driver can update these between kstat creation and install */
	unsigned int		  ks_dataver;
	void			 *ks_softc;
	void			 *ks_ptr;
	int			(*ks_read)(struct kstat *);
	int			(*ks_copy)(struct kstat *, void *);

	const struct kstat_lock_ops *
				  ks_lock_ops;
	void			 *ks_lock;

	/* the data that is updated by ks_read */
	void			 *ks_data;
	size_t			  ks_datalen;
	struct timespec		  ks_updated;
	struct timespec		  ks_interval;
};

struct kstat	*kstat_create(const char *, unsigned int,
		     const char *, unsigned int,
		     unsigned int, unsigned int);

void		 kstat_set_rlock(struct kstat *, struct rwlock *);
void		 kstat_set_wlock(struct kstat *, struct rwlock *);
void		 kstat_set_mutex(struct kstat *, struct mutex *);
void		 kstat_set_cpu(struct kstat *, struct cpu_info *);

int		 kstat_read_nop(struct kstat *);

void		 kstat_install(struct kstat *);
void		 kstat_destroy(struct kstat *);

/*
 * kstat_kv api
 */

#define KSTAT_KV_UNIT_INITIALIZER(_key, _type, _unit) {	\
	.kv_key = (_key),				\
	.kv_type = (_type),				\
	.kv_unit = (_unit),				\
}

#define KSTAT_KV_INITIALIZER(_key, _type)		\
    KSTAT_KV_UNIT_INITIALIZER((_key), (_type), KSTAT_KV_U_NONE)

void	kstat_kv_init(struct kstat_kv *, const char *, enum kstat_kv_type);
void	kstat_kv_unit_init(struct kstat_kv *, const char *,
	    enum kstat_kv_type, enum kstat_kv_unit);

#endif /* _KERNEL */

#endif /* _SYS_KSTAT_H_ */