xref: /illumos-gate/usr/src/uts/common/sys/pg.h (revision 6a634c9d)
1fb2f18f8Sesaxe /*
2fb2f18f8Sesaxe  * CDDL HEADER START
3fb2f18f8Sesaxe  *
4fb2f18f8Sesaxe  * The contents of this file are subject to the terms of the
5fb2f18f8Sesaxe  * Common Development and Distribution License (the "License").
6fb2f18f8Sesaxe  * You may not use this file except in compliance with the License.
7fb2f18f8Sesaxe  *
8fb2f18f8Sesaxe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fb2f18f8Sesaxe  * or http://www.opensolaris.org/os/licensing.
10fb2f18f8Sesaxe  * See the License for the specific language governing permissions
11fb2f18f8Sesaxe  * and limitations under the License.
12fb2f18f8Sesaxe  *
13fb2f18f8Sesaxe  * When distributing Covered Code, include this CDDL HEADER in each
14fb2f18f8Sesaxe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fb2f18f8Sesaxe  * If applicable, add the following below this CDDL HEADER, with the
16fb2f18f8Sesaxe  * fields enclosed by brackets "[]" replaced with your own identifying
17fb2f18f8Sesaxe  * information: Portions Copyright [yyyy] [name of copyright owner]
18fb2f18f8Sesaxe  *
19fb2f18f8Sesaxe  * CDDL HEADER END
20fb2f18f8Sesaxe  */
21*d3c97224SAlexander Kolbasov 
22fb2f18f8Sesaxe /*
23*d3c97224SAlexander Kolbasov  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24fb2f18f8Sesaxe  */
25fb2f18f8Sesaxe 
26fb2f18f8Sesaxe #ifndef	_PG_H
27fb2f18f8Sesaxe #define	_PG_H
28fb2f18f8Sesaxe 
29fb2f18f8Sesaxe /*
30fb2f18f8Sesaxe  * Processor Groups
31fb2f18f8Sesaxe  */
32fb2f18f8Sesaxe 
33fb2f18f8Sesaxe #ifdef	__cplusplus
34fb2f18f8Sesaxe extern "C" {
35fb2f18f8Sesaxe #endif
36fb2f18f8Sesaxe 
37fb2f18f8Sesaxe #if (defined(_KERNEL) || defined(_KMEMUSER))
38fb2f18f8Sesaxe #include <sys/cpuvar.h>
39fb2f18f8Sesaxe #include <sys/group.h>
40fb2f18f8Sesaxe #include <sys/processor.h>
41fb2f18f8Sesaxe #include <sys/bitset.h>
42fb2f18f8Sesaxe #include <sys/atomic.h>
43fb2f18f8Sesaxe #include <sys/types.h>
44fb2f18f8Sesaxe #include <sys/kstat.h>
45fb2f18f8Sesaxe 
46*d3c97224SAlexander Kolbasov typedef int		pgid_t;		/* processor group id */
47fb2f18f8Sesaxe typedef uint_t		pg_cid_t;	/* processor group class id */
48fb2f18f8Sesaxe 
490e751525SEric Saxe struct pg;
500e751525SEric Saxe 
51fb2f18f8Sesaxe /*
52fb2f18f8Sesaxe  * Nature of CPU relationships
53fb2f18f8Sesaxe  */
54fb2f18f8Sesaxe typedef enum pg_relation {
55fb2f18f8Sesaxe 	PGR_LOGICAL,
56fb2f18f8Sesaxe 	PGR_PHYSICAL
57fb2f18f8Sesaxe } pg_relation_t;
58fb2f18f8Sesaxe 
590e751525SEric Saxe /*
600e751525SEric Saxe  * Processor Group callbacks ops vector
610e751525SEric Saxe  * These provide a mechanism allowing per PG routines to invoked
620e751525SEric Saxe  * in response to events.
630e751525SEric Saxe  */
640e751525SEric Saxe typedef struct pg_cb_ops {
650e751525SEric Saxe 	void		(*thread_swtch)(struct pg *, struct cpu *, hrtime_t,
660e751525SEric Saxe 			    kthread_t *, kthread_t *);
670e751525SEric Saxe 	void		(*thread_remain)(struct pg *, struct cpu *,
680e751525SEric Saxe 			    kthread_t *);
690e751525SEric Saxe } pg_cb_ops_t;
700e751525SEric Saxe 
71fb2f18f8Sesaxe /*
72fb2f18f8Sesaxe  * Processor group structure
73fb2f18f8Sesaxe  */
74fb2f18f8Sesaxe typedef struct pg {
750e751525SEric Saxe 	pgid_t			pg_id;		/* seq id */
760e751525SEric Saxe 	pg_relation_t		pg_relation;	/* grouping relationship */
770e751525SEric Saxe 	struct pg_class		*pg_class;	/* pg class */
780e751525SEric Saxe 	struct group		pg_cpus;	/* group of CPUs */
790e751525SEric Saxe 	pg_cb_ops_t		pg_cb;		/* pg events ops vector */
80fb2f18f8Sesaxe } pg_t;
81fb2f18f8Sesaxe 
82fb2f18f8Sesaxe /*
83fb2f18f8Sesaxe  * PG class callbacks
84fb2f18f8Sesaxe  */
85fb2f18f8Sesaxe struct pg_ops {
86fb2f18f8Sesaxe 	struct pg	*(*alloc)();
87fb2f18f8Sesaxe 	void		(*free)(struct pg *);
8847ab0c7cSEric Saxe 	void		(*cpu_init)(struct cpu *, struct cpu_pg *);
8947ab0c7cSEric Saxe 	void		(*cpu_fini)(struct cpu *, struct cpu_pg *);
90fb2f18f8Sesaxe 	void		(*cpu_active)(struct cpu *);
91fb2f18f8Sesaxe 	void		(*cpu_inactive)(struct cpu *);
92fb2f18f8Sesaxe 	void		(*cpupart_in)(struct cpu *, struct cpupart *);
93fb2f18f8Sesaxe 	void		(*cpupart_out)(struct cpu *, struct cpupart *);
94fb2f18f8Sesaxe 	void		(*cpupart_move)(struct cpu *, struct cpupart *,
95fb2f18f8Sesaxe 			    struct cpupart *);
96fb2f18f8Sesaxe 	int		(*cpu_belongs)(struct pg *, struct cpu *);
970e751525SEric Saxe 	char		*(*policy_name)(struct pg *);
98fb2f18f8Sesaxe };
99fb2f18f8Sesaxe 
100fb2f18f8Sesaxe #define	PG_CLASS_NAME_MAX 32
101fb2f18f8Sesaxe 
102fb2f18f8Sesaxe /*
103fb2f18f8Sesaxe  * PG class structure
104fb2f18f8Sesaxe  */
105fb2f18f8Sesaxe typedef struct pg_class {
106fb2f18f8Sesaxe 	pg_cid_t	pgc_id;
107fb2f18f8Sesaxe 	char		pgc_name[PG_CLASS_NAME_MAX];
108fb2f18f8Sesaxe 	struct pg_ops	*pgc_ops;
109fb2f18f8Sesaxe 	pg_relation_t	pgc_relation;
110fb2f18f8Sesaxe } pg_class_t;
111fb2f18f8Sesaxe 
112fb2f18f8Sesaxe /*
113fb2f18f8Sesaxe  * Per CPU processor group data
114fb2f18f8Sesaxe  */
115fb2f18f8Sesaxe typedef struct cpu_pg {
116fb2f18f8Sesaxe 	struct group	pgs;		/* All the CPU's PGs */
117fb2f18f8Sesaxe 	struct group	cmt_pgs;	/* CMT load balancing lineage */
118fb2f18f8Sesaxe 					/* (Group hierarchy ordered) */
119fb2f18f8Sesaxe 	struct pg	*cmt_lineage;	/* Ascending lineage chain */
120fb2f18f8Sesaxe } cpu_pg_t;
121fb2f18f8Sesaxe 
122fb2f18f8Sesaxe /*
123fb2f18f8Sesaxe  * PG cpu iterator cookie
124fb2f18f8Sesaxe  */
125fb2f18f8Sesaxe typedef struct	pg_cpu_itr {
126fb2f18f8Sesaxe 	pg_t		*pg;
127fb2f18f8Sesaxe 	group_iter_t	position;
128fb2f18f8Sesaxe } pg_cpu_itr_t;
129fb2f18f8Sesaxe 
130fb2f18f8Sesaxe /*
131fb2f18f8Sesaxe  * Initialize a PG CPU iterator cookie
132fb2f18f8Sesaxe  */
133fb2f18f8Sesaxe #define	PG_CPU_ITR_INIT(pgrp, itr)		\
134fb2f18f8Sesaxe {						\
135fb2f18f8Sesaxe 	group_iter_init(&(itr).position);	\
136fb2f18f8Sesaxe 	(itr).pg = ((pg_t *)pgrp);		\
137fb2f18f8Sesaxe }
138fb2f18f8Sesaxe 
139fb2f18f8Sesaxe /*
140fb2f18f8Sesaxe  * Return the first CPU in a PG
141fb2f18f8Sesaxe  */
142fb2f18f8Sesaxe #define	PG_CPU_GET_FIRST(pgrp)			\
143fb2f18f8Sesaxe 	(GROUP_SIZE(&((pg_t *)pgrp)->pg_cpus) > 0 ?	\
144fb2f18f8Sesaxe 	    GROUP_ACCESS(&((pg_t *)pgrp)->pg_cpus, 0) : NULL)
145fb2f18f8Sesaxe 
1460e751525SEric Saxe /*
1470e751525SEric Saxe  * Return the number of CPUs in a PG
1480e751525SEric Saxe  */
1490e751525SEric Saxe #define	PG_NUM_CPUS(pgrp)			\
1500e751525SEric Saxe 	(GROUP_SIZE(&(pgrp)->pg_cpus))
1510e751525SEric Saxe 
152fb2f18f8Sesaxe /*
153fb2f18f8Sesaxe  * Framework routines
154fb2f18f8Sesaxe  */
155fb2f18f8Sesaxe void		pg_init(void);
156fb2f18f8Sesaxe pg_cid_t	pg_class_register(char *, struct pg_ops *, pg_relation_t);
157fb2f18f8Sesaxe 
158fb2f18f8Sesaxe /*
159fb2f18f8Sesaxe  * PG CPU reconfiguration hooks
160fb2f18f8Sesaxe  */
161fb2f18f8Sesaxe void		pg_cpu0_init(void);
162023e71deSHaik Aftandilian cpu_pg_t	*pg_cpu_init(cpu_t *, boolean_t deferred_init);
163023e71deSHaik Aftandilian void		pg_cpu_fini(cpu_t *, cpu_pg_t *cpu_pg_deferred);
164fb2f18f8Sesaxe void		pg_cpu_active(cpu_t *);
165fb2f18f8Sesaxe void		pg_cpu_inactive(cpu_t *);
166fb2f18f8Sesaxe void		pg_cpu_startup(cpu_t *);
167fb2f18f8Sesaxe void		pg_cpu_bootstrap(cpu_t *);
1681a77c24bSEric Saxe int		pg_cpu_is_bootstrapped(cpu_t *);
169fb2f18f8Sesaxe 
170fb2f18f8Sesaxe /*
171fb2f18f8Sesaxe  * PG cpupart service hooks
172fb2f18f8Sesaxe  */
173fb2f18f8Sesaxe void		pg_cpupart_in(cpu_t *, struct cpupart *);
174fb2f18f8Sesaxe void		pg_cpupart_out(cpu_t *, struct cpupart *);
175fb2f18f8Sesaxe void		pg_cpupart_move(cpu_t *, struct cpupart *, struct cpupart *);
176fb2f18f8Sesaxe 
177fb2f18f8Sesaxe /*
178fb2f18f8Sesaxe  * PG CPU utility routines
179fb2f18f8Sesaxe  */
180fb2f18f8Sesaxe pg_t		*pg_create(pg_cid_t);
181fb2f18f8Sesaxe void		pg_destroy(pg_t *);
18247ab0c7cSEric Saxe void		pg_cpu_add(pg_t *, cpu_t *, cpu_pg_t *);
18347ab0c7cSEric Saxe void		pg_cpu_delete(pg_t *, cpu_t *, cpu_pg_t *);
184fb2f18f8Sesaxe pg_t		*pg_cpu_find_pg(cpu_t *, group_t *);
185fb2f18f8Sesaxe cpu_t		*pg_cpu_next(pg_cpu_itr_t *);
1860e751525SEric Saxe boolean_t	pg_cpu_find(pg_t *, cpu_t *);
1870e751525SEric Saxe 
1880e751525SEric Saxe /*
1890e751525SEric Saxe  * PG Event callbacks
1900e751525SEric Saxe  */
1910e751525SEric Saxe void		pg_callback_set_defaults(pg_t *);
1920e751525SEric Saxe void		pg_ev_thread_swtch(cpu_t *, hrtime_t, kthread_t *, kthread_t *);
1930e751525SEric Saxe void		pg_ev_thread_remain(cpu_t *, kthread_t *);
194fb2f18f8Sesaxe 
1950e751525SEric Saxe /*
1960e751525SEric Saxe  * PG Observability interfaces
1970e751525SEric Saxe  */
1980e751525SEric Saxe char		*pg_policy_name(pg_t *);
199fb2f18f8Sesaxe 
200fb2f18f8Sesaxe #endif	/* !_KERNEL && !_KMEMUSER */
201fb2f18f8Sesaxe 
202fb2f18f8Sesaxe #ifdef	__cplusplus
203fb2f18f8Sesaxe }
204fb2f18f8Sesaxe #endif
205fb2f18f8Sesaxe 
206fb2f18f8Sesaxe #endif /* _PG_H */
207