13434Sesaxe /* 23434Sesaxe * CDDL HEADER START 33434Sesaxe * 43434Sesaxe * The contents of this file are subject to the terms of the 53434Sesaxe * Common Development and Distribution License (the "License"). 63434Sesaxe * You may not use this file except in compliance with the License. 73434Sesaxe * 83434Sesaxe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93434Sesaxe * or http://www.opensolaris.org/os/licensing. 103434Sesaxe * See the License for the specific language governing permissions 113434Sesaxe * and limitations under the License. 123434Sesaxe * 133434Sesaxe * When distributing Covered Code, include this CDDL HEADER in each 143434Sesaxe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153434Sesaxe * If applicable, add the following below this CDDL HEADER, with the 163434Sesaxe * fields enclosed by brackets "[]" replaced with your own identifying 173434Sesaxe * information: Portions Copyright [yyyy] [name of copyright owner] 183434Sesaxe * 193434Sesaxe * CDDL HEADER END 203434Sesaxe */ 21*13124SAlexander.Kolbasov@Sun.COM 223434Sesaxe /* 23*13124SAlexander.Kolbasov@Sun.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 243434Sesaxe */ 253434Sesaxe 263434Sesaxe #ifndef _PG_H 273434Sesaxe #define _PG_H 283434Sesaxe 293434Sesaxe /* 303434Sesaxe * Processor Groups 313434Sesaxe */ 323434Sesaxe 333434Sesaxe #ifdef __cplusplus 343434Sesaxe extern "C" { 353434Sesaxe #endif 363434Sesaxe 373434Sesaxe #if (defined(_KERNEL) || defined(_KMEMUSER)) 383434Sesaxe #include <sys/cpuvar.h> 393434Sesaxe #include <sys/group.h> 403434Sesaxe #include <sys/processor.h> 413434Sesaxe #include <sys/bitset.h> 423434Sesaxe #include <sys/atomic.h> 433434Sesaxe #include <sys/types.h> 443434Sesaxe #include <sys/kstat.h> 453434Sesaxe 46*13124SAlexander.Kolbasov@Sun.COM typedef int pgid_t; /* processor group id */ 473434Sesaxe typedef uint_t pg_cid_t; /* processor group class id */ 483434Sesaxe 498906SEric.Saxe@Sun.COM struct pg; 508906SEric.Saxe@Sun.COM 513434Sesaxe /* 523434Sesaxe * Nature of CPU relationships 533434Sesaxe */ 543434Sesaxe typedef enum pg_relation { 553434Sesaxe PGR_LOGICAL, 563434Sesaxe PGR_PHYSICAL 573434Sesaxe } pg_relation_t; 583434Sesaxe 593434Sesaxe /* 608906SEric.Saxe@Sun.COM * Processor Group callbacks ops vector 618906SEric.Saxe@Sun.COM * These provide a mechanism allowing per PG routines to invoked 628906SEric.Saxe@Sun.COM * in response to events. 638906SEric.Saxe@Sun.COM */ 648906SEric.Saxe@Sun.COM typedef struct pg_cb_ops { 658906SEric.Saxe@Sun.COM void (*thread_swtch)(struct pg *, struct cpu *, hrtime_t, 668906SEric.Saxe@Sun.COM kthread_t *, kthread_t *); 678906SEric.Saxe@Sun.COM void (*thread_remain)(struct pg *, struct cpu *, 688906SEric.Saxe@Sun.COM kthread_t *); 698906SEric.Saxe@Sun.COM } pg_cb_ops_t; 708906SEric.Saxe@Sun.COM 718906SEric.Saxe@Sun.COM /* 723434Sesaxe * Processor group structure 733434Sesaxe */ 743434Sesaxe typedef struct pg { 758906SEric.Saxe@Sun.COM pgid_t pg_id; /* seq id */ 768906SEric.Saxe@Sun.COM pg_relation_t pg_relation; /* grouping relationship */ 778906SEric.Saxe@Sun.COM struct pg_class *pg_class; /* pg class */ 788906SEric.Saxe@Sun.COM struct group pg_cpus; /* group of CPUs */ 798906SEric.Saxe@Sun.COM pg_cb_ops_t pg_cb; /* pg events ops vector */ 803434Sesaxe } pg_t; 813434Sesaxe 823434Sesaxe /* 833434Sesaxe * PG class callbacks 843434Sesaxe */ 853434Sesaxe struct pg_ops { 863434Sesaxe struct pg *(*alloc)(); 873434Sesaxe void (*free)(struct pg *); 889352SEric.Saxe@Sun.COM void (*cpu_init)(struct cpu *, struct cpu_pg *); 899352SEric.Saxe@Sun.COM void (*cpu_fini)(struct cpu *, struct cpu_pg *); 903434Sesaxe void (*cpu_active)(struct cpu *); 913434Sesaxe void (*cpu_inactive)(struct cpu *); 923434Sesaxe void (*cpupart_in)(struct cpu *, struct cpupart *); 933434Sesaxe void (*cpupart_out)(struct cpu *, struct cpupart *); 943434Sesaxe void (*cpupart_move)(struct cpu *, struct cpupart *, 953434Sesaxe struct cpupart *); 963434Sesaxe int (*cpu_belongs)(struct pg *, struct cpu *); 978906SEric.Saxe@Sun.COM char *(*policy_name)(struct pg *); 983434Sesaxe }; 993434Sesaxe 1003434Sesaxe #define PG_CLASS_NAME_MAX 32 1013434Sesaxe 1023434Sesaxe /* 1033434Sesaxe * PG class structure 1043434Sesaxe */ 1053434Sesaxe typedef struct pg_class { 1063434Sesaxe pg_cid_t pgc_id; 1073434Sesaxe char pgc_name[PG_CLASS_NAME_MAX]; 1083434Sesaxe struct pg_ops *pgc_ops; 1093434Sesaxe pg_relation_t pgc_relation; 1103434Sesaxe } pg_class_t; 1113434Sesaxe 1123434Sesaxe /* 1133434Sesaxe * Per CPU processor group data 1143434Sesaxe */ 1153434Sesaxe typedef struct cpu_pg { 1163434Sesaxe struct group pgs; /* All the CPU's PGs */ 1173434Sesaxe struct group cmt_pgs; /* CMT load balancing lineage */ 1183434Sesaxe /* (Group hierarchy ordered) */ 1193434Sesaxe struct pg *cmt_lineage; /* Ascending lineage chain */ 1203434Sesaxe } cpu_pg_t; 1213434Sesaxe 1223434Sesaxe /* 1233434Sesaxe * PG cpu iterator cookie 1243434Sesaxe */ 1253434Sesaxe typedef struct pg_cpu_itr { 1263434Sesaxe pg_t *pg; 1273434Sesaxe group_iter_t position; 1283434Sesaxe } pg_cpu_itr_t; 1293434Sesaxe 1303434Sesaxe /* 1313434Sesaxe * Initialize a PG CPU iterator cookie 1323434Sesaxe */ 1333434Sesaxe #define PG_CPU_ITR_INIT(pgrp, itr) \ 1343434Sesaxe { \ 1353434Sesaxe group_iter_init(&(itr).position); \ 1363434Sesaxe (itr).pg = ((pg_t *)pgrp); \ 1373434Sesaxe } 1383434Sesaxe 1393434Sesaxe /* 1403434Sesaxe * Return the first CPU in a PG 1413434Sesaxe */ 1423434Sesaxe #define PG_CPU_GET_FIRST(pgrp) \ 1433434Sesaxe (GROUP_SIZE(&((pg_t *)pgrp)->pg_cpus) > 0 ? \ 1443434Sesaxe GROUP_ACCESS(&((pg_t *)pgrp)->pg_cpus, 0) : NULL) 1453434Sesaxe 1463434Sesaxe /* 1478906SEric.Saxe@Sun.COM * Return the number of CPUs in a PG 1488906SEric.Saxe@Sun.COM */ 1498906SEric.Saxe@Sun.COM #define PG_NUM_CPUS(pgrp) \ 1508906SEric.Saxe@Sun.COM (GROUP_SIZE(&(pgrp)->pg_cpus)) 1518906SEric.Saxe@Sun.COM 1528906SEric.Saxe@Sun.COM /* 1533434Sesaxe * Framework routines 1543434Sesaxe */ 1553434Sesaxe void pg_init(void); 1563434Sesaxe pg_cid_t pg_class_register(char *, struct pg_ops *, pg_relation_t); 1573434Sesaxe 1583434Sesaxe /* 1593434Sesaxe * PG CPU reconfiguration hooks 1603434Sesaxe */ 1613434Sesaxe void pg_cpu0_init(void); 16211172SHaik.Aftandilian@Sun.COM cpu_pg_t *pg_cpu_init(cpu_t *, boolean_t deferred_init); 16311172SHaik.Aftandilian@Sun.COM void pg_cpu_fini(cpu_t *, cpu_pg_t *cpu_pg_deferred); 1643434Sesaxe void pg_cpu_active(cpu_t *); 1653434Sesaxe void pg_cpu_inactive(cpu_t *); 1663434Sesaxe void pg_cpu_startup(cpu_t *); 1673434Sesaxe void pg_cpu_bootstrap(cpu_t *); 1689438SEric.Saxe@Sun.COM int pg_cpu_is_bootstrapped(cpu_t *); 1693434Sesaxe 1703434Sesaxe /* 1713434Sesaxe * PG cpupart service hooks 1723434Sesaxe */ 1733434Sesaxe void pg_cpupart_in(cpu_t *, struct cpupart *); 1743434Sesaxe void pg_cpupart_out(cpu_t *, struct cpupart *); 1753434Sesaxe void pg_cpupart_move(cpu_t *, struct cpupart *, struct cpupart *); 1763434Sesaxe 1773434Sesaxe /* 1783434Sesaxe * PG CPU utility routines 1793434Sesaxe */ 1803434Sesaxe pg_t *pg_create(pg_cid_t); 1813434Sesaxe void pg_destroy(pg_t *); 1829352SEric.Saxe@Sun.COM void pg_cpu_add(pg_t *, cpu_t *, cpu_pg_t *); 1839352SEric.Saxe@Sun.COM void pg_cpu_delete(pg_t *, cpu_t *, cpu_pg_t *); 1843434Sesaxe pg_t *pg_cpu_find_pg(cpu_t *, group_t *); 1853434Sesaxe cpu_t *pg_cpu_next(pg_cpu_itr_t *); 1868906SEric.Saxe@Sun.COM boolean_t pg_cpu_find(pg_t *, cpu_t *); 1873434Sesaxe 1888906SEric.Saxe@Sun.COM /* 1898906SEric.Saxe@Sun.COM * PG Event callbacks 1908906SEric.Saxe@Sun.COM */ 1918906SEric.Saxe@Sun.COM void pg_callback_set_defaults(pg_t *); 1928906SEric.Saxe@Sun.COM void pg_ev_thread_swtch(cpu_t *, hrtime_t, kthread_t *, kthread_t *); 1938906SEric.Saxe@Sun.COM void pg_ev_thread_remain(cpu_t *, kthread_t *); 1948906SEric.Saxe@Sun.COM 1958906SEric.Saxe@Sun.COM /* 1968906SEric.Saxe@Sun.COM * PG Observability interfaces 1978906SEric.Saxe@Sun.COM */ 1988906SEric.Saxe@Sun.COM char *pg_policy_name(pg_t *); 1993434Sesaxe 2003434Sesaxe #endif /* !_KERNEL && !_KMEMUSER */ 2013434Sesaxe 2023434Sesaxe #ifdef __cplusplus 2033434Sesaxe } 2043434Sesaxe #endif 2053434Sesaxe 2063434Sesaxe #endif /* _PG_H */ 207