summaryrefslogtreecommitdiff
path: root/usr/src/cmd/intrd/intrd.h
blob: 1b7f812494f148d7789aaf5740aece5bf330575c (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
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2018, Joyent, Inc.
 */

#ifndef _INTRD_H
#define	_INTRD_H

#include <kstat.h>
#include <sys/kstat.h>
#include <sys/lgrp_user.h>
#include <sys/list.h>
#include <sys/types.h>

#ifdef __cplusplus
extern "C" {
#endif

struct custr;

typedef struct config {
	uint_t	cfg_interval;
	uint_t	cfg_idle_interval;
	uint_t	cfg_retry_interval;
	// idle_load
	uint_t	cfg_avginterval;
	uint_t	cfg_statslen;
	double	cfg_tooslow;
	double	cfg_unsafe_load;
	double	cfg_mindelta;
} config_t;

typedef struct ivec {
	list_node_t	ivec_node;
	hrtime_t	ivec_snaptime;
	int		ivec_instance;
	int		ivec_cpuid;
	int		ivec_oldcpuid;
	uint64_t	ivec_cookie;
	uint64_t	ivec_pil;
	uint64_t	ivec_ino;
	uint64_t	ivec_time;
	size_t		ivec_num_ino;
	size_t		ivec_nshared;
	char		*ivec_buspath;
	struct custr	*ivec_name;
	char		ivec_type[16];	/* sizeof kstat_named_t.value.c */
} ivec_t;

typedef struct cpustat {
	hrtime_t	cs_snaptime;
	int		cs_cpuid;
	lgrp_id_t	cs_lgrp;
	uint64_t	cs_cpu_nsec_idle;
	uint64_t	cs_cpu_nsec_user;
	uint64_t	cs_cpu_nsec_kernel;
	uint64_t	cs_cpu_nsec_dtrace;
	uint64_t	cs_cpu_nsec_intr;
	list_t		cs_ivecs;
	size_t		cs_nivecs;
} cpustat_t;

typedef struct cpugrp {
	lgrp_id_t	cg_id;
	lgrp_id_t	cg_parent;
	lgrp_id_t	*cg_children;
	size_t		cg_nchildren;
} cpugrp_t;

/*
 * A snapshot of the interrupt statistics on the system.  This is assembled
 * from multiple individual kstats, so the kstat times will not be identical.
 * sts_{min,max}time represent the smallest and largest values of
 * kstat_t.ks_crtime of all the individual kstats used to create this snapshot.
 *
 * cpustat_t's are indexed by CPU id.  That is, the cpustat_t for CPU 5 is
 * sts_cpu[5] -- i.e. there may be gaps in this.  It is sized to hold
 * max_cpu (i.e. _SC_N_PROCESSORS_MAX) cpustat_t *'s.
 */
typedef struct stats {
	kid_t		sts_kid;

	hrtime_t	sts_mintime;
	hrtime_t	sts_maxtime;

	cpustat_t	**sts_cpu;
	size_t		sts_ncpu;

	cpugrp_t	*sts_lgrp;
	size_t		sts_nlgrp;
} stats_t;
#define STATS_CPU(_st, _id) (_st)->sts_cpu[(_id)]

typedef struct load {
	uint64_t	ld_total;
	uint64_t	ld_intrtotal;
	ivec_t		*ld_bigint;
} load_t;
#define LOAD_LGRP(_load, _id) ((_load) + max_cpu + (_id))
#define LOAD_CPU(_load, _id) ((_load) + (_id))
#define LOAD_BIGINT_LOAD(_load) \
    (((_load)->ld_bigint != NULL) ? (_load)->ld_bigint->ivec_time : 0)
#define LOAD_MAXINT(_l1, _l2) \
    ((LOAD_BIGINT_LOAD(_l1) > LOAD_BIGINT_LOAD(_l2)) ? \
     (_l1)->ld_bigint : (_l2)->ld_bigint)

extern uint_t max_cpu;

typedef enum intrd_walk_ret {
    INTRD_WALK_ERROR = -1,
    INTRD_WALK_NEXT = 0,
    INTRD_WALK_DONE = 1
} intrd_walk_ret_t;

typedef intrd_walk_ret_t (*cpu_itercb_t)(stats_t *, cpustat_t *, void *);
intrd_walk_ret_t cpu_iter(stats_t *, cpu_itercb_t, void *);

stats_t *stats_get(const config_t *restrict, kstat_ctl_t *restrict, uint_t);
stats_t *stats_delta(const stats_t *, const stats_t *);
stats_t *stats_sum(stats_t * const*, size_t, size_t *);
stats_t *stats_dup(const stats_t *);
void stats_free(stats_t *);
void stats_dump(const stats_t *);

cpustat_t *cpustat_new(void);
cpustat_t *cpustat_dup(const cpustat_t *);
void cpustat_free(cpustat_t *);

ivec_t *ivec_new(void);
ivec_t *ivec_dup(const ivec_t *);
void ivec_free(ivec_t *);

char *xstrdup(const char *);
void *xcalloc(size_t, size_t);
void *xreallocarray(void *, size_t, size_t);

void nanonicenum(uint64_t, char *, size_t);

int intrmove(const char *, int, int, int, int);

void intrd_kstat_init(void);

#ifdef __cplusplus
}
#endif

#endif /* _INTRD_H */