src/sys/sys/kstat.h

211 lines
5.6 KiB
C

/* $OpenBSD: kstat.h,v 1.5 2024/03/26 00:53: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) */
KSTAT_KV_T_COUNTER16,
KSTAT_KV_T_UINT16,
KSTAT_KV_T_INT16,
KSTAT_KV_T_FREQ, /* frequency (Hz) */
KSTAT_KV_T_VOLTS_DC, /* voltage (uV DC) */
KSTAT_KV_T_VOLTS_AC, /* voltage (uV AC) */
KSTAT_KV_T_AMPS, /* current (uA) */
KSTAT_KV_T_WATTS, /* power (uW) */
};
/* 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;
uint16_t v_u16;
int16_t v_s16;
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_u16(_kv) (_kv)->kv_v.v_u16
#define kstat_kv_s16(_kv) (_kv)->kv_v.v_s16
#define kstat_kv_len(_kv) (_kv)->kv_v.v_len
#define kstat_kv_temp(_kv) (_kv)->kv_v.v_u64
#define kstat_kv_freq(_kv) (_kv)->kv_v.v_u64
#define kstat_kv_volts(_kv) (_kv)->kv_v.v_u64
#define kstat_kv_amps(_kv) (_kv)->kv_v.v_u64
#define kstat_kv_watts(_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_remove(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_ */