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.
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.
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]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
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>
46 typedef int pgid_t
; /* processor group id */
47 typedef uint_t pg_cid_t
; /* processor group class id */
52 * Nature of CPU relationships
54 typedef enum pg_relation
{
60 * Processor Group callbacks ops vector
61 * These provide a mechanism allowing per PG routines to invoked
62 * in response to events.
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
*,
72 * Processor group structure
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 */
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
*,
96 int (*cpu_belongs
)(struct pg
*, struct cpu
*);
97 char *(*policy_name
)(struct pg
*);
100 #define PG_CLASS_NAME_MAX 32
105 typedef struct pg_class
{
107 char pgc_name
[PG_CLASS_NAME_MAX
];
108 struct pg_ops
*pgc_ops
;
109 pg_relation_t pgc_relation
;
113 * Per CPU processor group data
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 */
123 * PG cpu iterator cookie
125 typedef struct pg_cpu_itr
{
127 group_iter_t position
;
131 * Initialize a PG CPU iterator cookie
133 #define PG_CPU_ITR_INIT(pgrp, itr) \
135 group_iter_init(&(itr).position); \
136 (itr).pg = ((pg_t *)pgrp); \
140 * Return the first CPU in a PG
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)
147 * Return the number of CPUs in a PG
149 #define PG_NUM_CPUS(pgrp) \
150 (GROUP_SIZE(&(pgrp)->pg_cpus))
156 pg_cid_t
pg_class_register(char *, struct pg_ops
*, pg_relation_t
);
159 * PG CPU reconfiguration hooks
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
*);
171 * PG cpupart service hooks
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
*);
178 * PG CPU utility routines
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
*);
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
*);
196 * PG Observability interfaces
198 char *pg_policy_name(pg_t
*);
200 #endif /* !_KERNEL && !_KMEMUSER */