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