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 59fb2f18f8Sesaxe /* 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 710e751525SEric Saxe /* 72fb2f18f8Sesaxe * Processor group structure 73fb2f18f8Sesaxe */ 74fb2f18f8Sesaxe typedef struct pg { 75fb2f18f8Sesaxe pgid_t pg_id; /* seq id */ 76fb2f18f8Sesaxe pg_relation_t pg_relation; /* grouping relationship */ 77fb2f18f8Sesaxe struct pg_class *pg_class; /* pg class */ 78fb2f18f8Sesaxe 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 146fb2f18f8Sesaxe /* 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 1520e751525SEric Saxe /* 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 *); 187fb2f18f8Sesaxe 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 *); 1940e751525SEric Saxe 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