summaryrefslogtreecommitdiffstats
path: root/sys-utils/lscpu.h
blob: 8cb0d630ce88cfcaf4c41c56a78652b4cf80605c (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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#ifndef LSCPU_H
#define LSCPU_H

#include "c.h"
#include "nls.h"
#include "cpuset.h"
#include "xalloc.h"
#include "strutils.h"
#include "bitops.h"
#include "path.h"
#include "pathnames.h"
#include "all-io.h"
#include "debug.h"

#define LSCPU_DEBUG_INIT	(1 << 1)
#define LSCPU_DEBUG_MISC	(1 << 2)
#define LSCPU_DEBUG_GATHER	(1 << 3)
#define LSCPU_DEBUG_TYPE	(1 << 4)
#define LSCPU_DEBUG_CPU		(1 << 5)
#define LSCPU_DEBUG_VIRT	(1 << 6)
#define LSBLK_DEBUG_ALL		0xFFFF

UL_DEBUG_DECLARE_MASK(lscpu);
#define DBG(m, x)       __UL_DBG(lscpu, LSCPU_DEBUG_, m, x)
#define ON_DBG(m, x)    __UL_DBG_CALL(lscpu, LSCPU_DEBUG_, m, x)

#define UL_DEBUG_CURRENT_MASK	UL_DEBUG_MASK(lscpu)
#include "debugobj.h"

#define _PATH_SYS_SYSTEM	"/sys/devices/system"
#define _PATH_SYS_HYP_FEATURES	"/sys/hypervisor/properties/features"
#define _PATH_SYS_CPU		_PATH_SYS_SYSTEM "/cpu"
#define _PATH_SYS_NODE		_PATH_SYS_SYSTEM "/node"
#define _PATH_SYS_DMI		"/sys/firmware/dmi/tables/DMI"
#define _PATH_ACPI_PPTT		"/sys/firmware/acpi/tables/PPTT"

struct lscpu_cache {
	int		id;		/* unique identifier */
	int		nth;		/* cache<number> from cpuinfo */
	char		*name;
	char		*type;
	char		*allocation_policy;
	char		*write_policy;

	int		level;
	uint64_t	size;

	unsigned int	ways_of_associativity;
	unsigned int	physical_line_partition;
	unsigned int	number_of_sets;
	unsigned int	coherency_line_size;

	cpu_set_t	*sharedmap;
};

struct lscpu_cputype {
	int	refcount;

	char	*vendor;
	int	vendor_id;	/* created by lscpu_decode_arm() */
	char	*bios_vendor;	/* aarch64 */
	char	*machinetype;	/* s390 */
	char	*family;
	char	*model;
	char	*modelname;
	char	*bios_modelname; /* aarch64 */
	char	*bios_family; /* aarch64 */
	char	*revision;	/* alternative for model (ppc) */
	char	*stepping;
	char    *bogomips;
	char	*flags;
	char	*mtid;		/* maximum thread id (s390) */
	char	*addrsz;	/* address sizes */
	int	dispatching;	/* -1 if not evailable, DIST_* */
	int	freqboost;	/* -1 if not evailable */

	size_t	physsockets;	/* Physical sockets (modules) */
	size_t	physchips;	/* Physical chips */
	size_t	physcoresperchip;	/* Physical cores per chip */

	size_t	nthreads_per_core;
	size_t	ncores_per_socket;
	size_t	nsockets_per_book;
	size_t	nbooks_per_drawer;
	size_t	ndrawers_per_system;

	char	*dynamic_mhz;	/* s390; copy from the first CPU */
	char	*static_mhz;	/* s390; copy from the first CPU */

	/* siblings maps */
	size_t		ncores;
	cpu_set_t	**coremaps;
	size_t		nsockets;
	cpu_set_t       **socketmaps;
	size_t		nbooks;
	cpu_set_t	**bookmaps;
	size_t		ndrawers;
	cpu_set_t	**drawermaps;

	unsigned int	has_freq : 1,
			has_configured : 1,
			has_polarization : 1,
			has_addresses : 1;

	size_t nr_socket_on_cluster; /* the number of sockets if the is_cluster is 1 */
};

/* dispatching modes */
enum {
	DISP_HORIZONTAL = 0,
	DISP_VERTICAL	= 1
};

/* cpu polarization */
enum {
	POLAR_UNKNOWN	= 0,
	POLAR_VLOW,
	POLAR_VMEDIUM,
	POLAR_VHIGH,
	POLAR_HORIZONTAL
};

struct lscpu_cpu {
	int refcount;
	struct lscpu_cputype *type;

	int logical_id;

	char	*bogomips;	/* per-CPU bogomips */
	char	*mhz;		/* freq from cpuinfo */
	char	*dynamic_mhz;   /* from cpuinf for s390 */
	char	*static_mhz;	/* from cpuinf for s390 */
	float	mhz_max_freq;	/* realtime freq from /sys/.../cpuinfo_max_freq */
	float	mhz_min_freq;	/* realtime freq from /sys/.../cpuinfo_min_freq */
	float   mhz_cur_freq;

	int	coreid;
	int	socketid;
	int	bookid;
	int	drawerid;

	int	polarization;	/* POLAR_* */
	int	address;	/* physical cpu address */
	int	configured;	/* cpu configured */
};

struct lscpu_arch {
	char	*name;		/* uname() .machine */

	unsigned int	bit32:1,
			bit64:1;
};

struct lscpu_vulnerability {
	char	*name;
	char	*text;
};

/* virtualization types */
enum {
	VIRT_TYPE_NONE	= 0,
	VIRT_TYPE_PARA,
	VIRT_TYPE_FULL,
	VIRT_TYPE_CONTAINER
};

/* hypervisor vendors */
enum {
	VIRT_VENDOR_NONE	= 0,
	VIRT_VENDOR_XEN,
	VIRT_VENDOR_KVM,
	VIRT_VENDOR_MSHV,
	VIRT_VENDOR_VMWARE,
	VIRT_VENDOR_IBM,		/* sys-z powervm */
	VIRT_VENDOR_VSERVER,
	VIRT_VENDOR_UML,
	VIRT_VENDOR_INNOTEK,		/* VBOX */
	VIRT_VENDOR_HITACHI,
	VIRT_VENDOR_PARALLELS,	/* OpenVZ/VIrtuozzo */
	VIRT_VENDOR_VBOX,
	VIRT_VENDOR_OS400,
	VIRT_VENDOR_PHYP,
	VIRT_VENDOR_SPAR,
	VIRT_VENDOR_WSL,
};

struct lscpu_virt {
	char	*cpuflag;	/* virtualization flag (vmx, svm) */
	char	*hypervisor;	/* hypervisor software */
	int	vendor;		/* VIRT_VENDOR_* */
	int	type;		/* VIRT_TYPE_* ? */

};

enum {
	LSCPU_OUTPUT_SUMMARY = 0,	/* default */
	LSCPU_OUTPUT_CACHES,
	LSCPU_OUTPUT_PARSABLE,
	LSCPU_OUTPUT_READABLE
};

struct lscpu_cxt {
	int maxcpus;		/* size in bits of kernel cpu mask */
	size_t setsize;
	const char *prefix;	/* path to /sys and /proc snapshot or NULL */

	struct path_cxt	*syscpu; /* _PATH_SYS_CPU path handler */
	struct path_cxt *procfs; /* /proc path handler */

	size_t ncputypes;
	struct lscpu_cputype **cputypes;

	size_t npossibles;	/* number of possible CPUs */
	struct lscpu_cpu **cpus; /* possible CPUs, contains gaps (cups[n]=NULL) */

	size_t npresents;
	cpu_set_t *present;	/* mask with present CPUs */

	size_t nonlines;	/* aka number of trhreads */
	cpu_set_t *online;	/* mask with online CPUs */

	struct lscpu_arch *arch;
	struct lscpu_virt *virt;

	struct lscpu_vulnerability *vuls;	/* array of CPU vulnerabilities */
	size_t  nvuls;				/* number of CPU vulnerabilities */

	struct lscpu_cache *caches;		/* all instances of the all caches from /sys */
	size_t ncaches;

	struct lscpu_cache *ecaches;
	size_t necaches;		/* extra caches (s390) from /proc/cpuinfo */

	size_t nnodes;		/* number of NUMA modes */
	int *idx2nodenum;	/* Support for discontinuous nodes */
	cpu_set_t **nodemaps;	/* array with NUMA nodes */

	int mode;	/* LSCPU_OUTPUT_* */

	unsigned int noalive : 1,
		     show_online : 1,
		     show_offline : 1,
		     show_physical : 1,
		     show_compatible : 1,
		     hex : 1,
		     json : 1,
		     bytes : 1;

	int is_cluster; /* For aarch64 if the machine doesn't have ACPI PPTT */
};

#define is_cpu_online(_cxt, _cpu) \
		((_cxt) && (_cpu) && (_cxt)->online && \
		 CPU_ISSET_S((_cpu)->logical_id, (_cxt)->setsize, (_cxt)->online))

#define is_cpu_present(_cxt, _cpu) \
		((_cxt) && (_cpu) && (_cxt)->present && \
		 CPU_ISSET_S((_cpu)->logical_id, (_cxt)->setsize, (_cxt)->present))

struct lscpu_cputype *lscpu_new_cputype(void);
void lscpu_ref_cputype(struct lscpu_cputype *ct);
void lscpu_unref_cputype(struct lscpu_cputype *ct);
struct lscpu_cputype *lscpu_add_cputype(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
struct lscpu_cputype *lscpu_cputype_get_default(struct lscpu_cxt *cxt);

int lscpu_read_cpuinfo(struct lscpu_cxt *cxt);
int lscpu_read_cpulists(struct lscpu_cxt *cxt);
int lscpu_read_archext(struct lscpu_cxt *cxt);
int lscpu_read_vulnerabilities(struct lscpu_cxt *cxt);
int lscpu_read_numas(struct lscpu_cxt *cxt);

void lscpu_free_caches(struct lscpu_cache *caches, size_t n);
void lscpu_sort_caches(struct lscpu_cache *caches, size_t n);

size_t lscpu_get_cache_full_size(struct lscpu_cxt *cxt, const char *name, int *instances);
struct lscpu_cache *lscpu_cpu_get_cache(struct lscpu_cxt *cxt,
                                struct lscpu_cpu *cpu, const char *name);

int lscpu_read_topology(struct lscpu_cxt *cxt);
void lscpu_cputype_free_topology(struct lscpu_cputype *ct);

float lsblk_cputype_get_maxmhz(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
float lsblk_cputype_get_minmhz(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
float lsblk_cputype_get_scalmhz(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);

struct lscpu_arch *lscpu_read_architecture(struct lscpu_cxt *cxt);
void lscpu_free_architecture(struct lscpu_arch *ar);

struct lscpu_virt *lscpu_read_virtualization(struct lscpu_cxt *cxt);
void lscpu_free_virtualization(struct lscpu_virt *virt);

struct lscpu_cpu *lscpu_new_cpu(int id);
void lscpu_ref_cpu(struct lscpu_cpu *cpu);
void lscpu_unref_cpu(struct lscpu_cpu *cpu);
struct lscpu_cpu *lscpu_get_cpu(struct lscpu_cxt *cxt, int logical_id);
int lscpu_cpu_set_type(struct lscpu_cpu *cpu, struct lscpu_cputype *type);
int lscpu_create_cpus(struct lscpu_cxt *cxt, cpu_set_t *cpuset, size_t setsize);
struct lscpu_cpu *lscpu_cpus_loopup_by_type(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);

void lscpu_decode_arm(struct lscpu_cxt *cxt);

int lookup(char *line, char *pattern, char **value);

void *get_mem_chunk(size_t base, size_t len, const char *devmem);

struct lscpu_dmi_header
{
	uint8_t type;
	uint8_t length;
	uint16_t handle;
	uint8_t *data;
};

struct dmi_info {
	char *vendor;
	char *product;
	char *manufacturer;
	int sockets;

	/* Processor Information */
	uint16_t processor_family;
	char *processor_manufacturer;
	char *processor_version;
	uint16_t current_speed;
	char *part_num;
};


void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data);
char *dmi_string(const struct lscpu_dmi_header *dm, uint8_t s);
int parse_dmi_table(uint16_t len, uint16_t num, uint8_t *data, struct dmi_info *di);
size_t get_number_of_physical_sockets_from_dmi(void);
int dmi_decode_cputype(struct lscpu_cputype *);
#endif /* LSCPU_H */