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