summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/cpupart.h
blob: a91c989bbff158b3ce386019882f655455d9d23e (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
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright 2017 RackTop Systems.
 */

#ifndef	_SYS_CPUPART_H
#define	_SYS_CPUPART_H

#include <sys/types.h>
#include <sys/processor.h>
#include <sys/cpuvar.h>
#include <sys/disp.h>
#include <sys/pset.h>
#include <sys/lgrp.h>
#include <sys/lgrp_user.h>
#include <sys/pg.h>
#include <sys/bitset.h>
#include <sys/time.h>

#ifdef	__cplusplus
extern "C" {
#endif

#if defined(_KERNEL) || defined(_FAKE_KERNEL)

typedef int	cpupartid_t;

/*
 * Special partition id.
 */
#define	CP_DEFAULT	0

/*
 * Flags for cpupart_list()
 */
#define	CP_ALL		0		/* return all cpu partitions */
#define	CP_NONEMPTY	1		/* return only non-empty ones */

typedef struct cpupart {
	disp_t		cp_kp_queue;	/* partition-wide kpreempt queue */
	cpupartid_t	cp_id;		/* partition ID */
	int		cp_ncpus;	/* number of online processors */
	struct cpupart	*cp_next;	/* next partition in list */
	struct cpupart	*cp_prev;	/* previous partition in list */
	struct cpu	*cp_cpulist;	/* processor list */
	struct kstat	*cp_kstat;	/* per-partition statistics */

	/*
	 * cp_nrunnable and cp_nrunning are used to calculate load average.
	 */
	uint_t		cp_nrunnable;	/* current # of runnable threads */
	uint_t		cp_nrunning;	/* current # of running threads */

	/*
	 * cp_updates, cp_nrunnable_cum, cp_nwaiting_cum, and cp_hp_avenrun
	 * are used to generate kstat information on an as-needed basis.
	 */
	uint64_t	cp_updates;	/* number of statistics updates */
	uint64_t	cp_nrunnable_cum; /* cum. # of runnable threads */
	uint64_t	cp_nwaiting_cum;  /* cum. # of waiting threads */

	struct loadavg_s cp_loadavg;	/* cpupart loadavg */

	klgrpset_t	cp_lgrpset;	/* set of lgroups on which this */
					/*    partition has cpus */
	lpl_t		*cp_lgrploads;	/* table of load averages for this  */
					/*    partition, indexed by lgrp ID */
	int		cp_nlgrploads;	/* size of cp_lgrploads table */
	uint64_t	cp_hp_avenrun[3]; /* high-precision load average */
	uint_t		cp_attr;	/* bitmask of attributes */
	lgrp_gen_t	cp_gen;		/* generation number */
	lgrp_id_t	cp_lgrp_hint;	/* last home lgroup chosen */
	bitset_t	cp_cmt_pgs;	/* CMT PGs represented */
	bitset_t	cp_haltset;	/* halted CPUs */
} cpupart_t;

typedef struct cpupart_kstat {
	kstat_named_t	cpk_updates;		/* number of updates */
	kstat_named_t	cpk_runnable;		/* cum # of runnable threads */
	kstat_named_t	cpk_waiting;		/* cum # waiting for I/O */
	kstat_named_t	cpk_ncpus;		/* current # of CPUs */
	kstat_named_t	cpk_avenrun_1min;	/* 1-minute load average */
	kstat_named_t	cpk_avenrun_5min;	/* 5-minute load average */
	kstat_named_t	cpk_avenrun_15min;	/* 15-minute load average */
} cpupart_kstat_t;

/*
 * Macro to obtain the maximum run priority for the global queue associated
 * with given cpu partition.
 */
#define	CP_MAXRUNPRI(cp)	((cp)->cp_kp_queue.disp_maxrunpri)

/*
 * This macro is used to determine if the given thread must surrender
 * CPU to higher priority runnable threads on one of its dispatch queues.
 * This should really be defined in <sys/disp.h> but it is not because
 * including <sys/cpupart.h> there would cause recursive includes.
 */
#define	DISP_MUST_SURRENDER(t)				\
	((DISP_MAXRUNPRI(t) > DISP_PRIO(t)) ||		\
	(CP_MAXRUNPRI(t->t_cpupart) > DISP_PRIO(t)))

extern cpupart_t	cp_default;
extern cpupart_t	*cp_list_head;
extern uint_t		cp_numparts;
extern uint_t		cp_numparts_nonempty;

/*
 * Each partition contains a bitset that indicates which CPUs are halted and
 * which ones are running. Given the growing number of CPUs in current and
 * future platforms, it's important to fanout each CPU within its partition's
 * haltset to prevent contention due to false sharing. The fanout factor
 * is platform specific, and declared accordingly.
 */
extern uint_t cp_haltset_fanout;

extern void	cpupart_initialize_default();
extern cpupart_t *cpupart_find(psetid_t);
extern int	cpupart_create(psetid_t *);
extern int	cpupart_destroy(psetid_t);
extern psetid_t	cpupart_query_cpu(cpu_t *);
extern int	cpupart_attach_cpu(psetid_t, cpu_t *, int);
extern int	cpupart_get_cpus(psetid_t *, processorid_t *, uint_t *);
extern int	cpupart_bind_thread(kthread_id_t, psetid_t, int, void *,
    void *);
extern void	cpupart_kpqalloc(pri_t);
extern int	cpupart_get_loadavg(psetid_t, int *, int);
extern uint_t	cpupart_list(psetid_t *, uint_t, int);
extern int	cpupart_setattr(psetid_t, uint_t);
extern int	cpupart_getattr(psetid_t, uint_t *);

#endif	/* _KERNEL || _FAKE_KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_CPUPART_H */