fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * CDDL HEADER START
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * The contents of this file are subject to the terms of the
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Common Development and Distribution License (the "License").
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * You may not use this file except in compliance with the License.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * or http://www.opensolaris.org/os/licensing.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * See the License for the specific language governing permissions
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * and limitations under the License.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * When distributing Covered Code, include this CDDL HEADER in each
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * If applicable, add the following below this CDDL HEADER, with the
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * fields enclosed by brackets "[]" replaced with your own identifying
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * information: Portions Copyright [yyyy] [name of copyright owner]
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * CDDL HEADER END
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Use is subject to license terms.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/systm.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/types.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/param.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/thread.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/cpuvar.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/cpupart.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/kmem.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/cmn_err.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/kstat.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/processor.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/disp.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/group.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#include <sys/pg.h>
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Processor groups
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * With the introduction of Chip Multi-Threaded (CMT) processor architectures,
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * it is no longer necessarily true that a given physical processor module
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * will present itself as a single schedulable entity (cpu_t). Rather, each
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * chip and/or processor core may present itself as one or more "logical" CPUs.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * The logical CPUs presented may share physical components such as caches,
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * data pipes, execution pipelines, FPUs, etc. It is advantageous to have the
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * kernel be aware of the relationships existing between logical CPUs so that
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * the appropriate optmizations may be employed.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * The processor group abstraction represents a set of logical CPUs that
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * generally share some sort of physical or characteristic relationship.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * In the case of a physical sharing relationship, the CPUs in the group may
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * share a pipeline, cache or floating point unit. In the case of a logical
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * relationship, a PG may represent the set of CPUs in a processor set, or the
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * set of CPUs running at a particular clock speed.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * The generic processor group structure, pg_t, contains the elements generic
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * to a group of CPUs. Depending on the nature of the CPU relationship
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * (LOGICAL or PHYSICAL), a pointer to a pg may be recast to a "view" of that
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * PG where more specific data is represented.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * As an example, a PG representing a PHYSICAL relationship, may be recast to
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * a pghw_t, where data further describing the hardware sharing relationship
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * is maintained. See pghw.c and pghw.h for details on physical PGs.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * At this time a more specialized casting of a PG representing a LOGICAL
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * relationship has not been implemented, but the architecture allows for this
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * in the future.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Processor Group Classes
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Processor group consumers may wish to maintain and associate specific
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * data with the PGs they create. For this reason, a mechanism for creating
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * class specific PGs exists. Classes may overload the default functions for
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * creating, destroying, and associating CPUs with PGs, and may also register
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * class specific callbacks to be invoked when the CPU related system
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * configuration changes. Class specific data is stored/associated with
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * PGs by incorporating the pg_t (or pghw_t, as appropriate), as the first
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * element of a class specific PG object. In memory, such a structure may look
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * like:
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * ----------------------- - - -
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * | common | | | | <--(pg_t *)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * ----------------------- | | -
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * | HW specific | | | <-----(pghw_t *)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * ----------------------- | -
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * | class specific | | <-------(pg_cmt_t *)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * ----------------------- -
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Access to the PG class specific data can be had by casting a pointer to
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * it's class specific view.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic pg_t *pg_alloc_default(pg_class_t);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic void pg_free_default(pg_t *);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxestatic void pg_null_op();
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Bootstrap CPU specific PG data
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * See pg_cpu_bootstrap()
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic cpu_pg_t bootstrap_pg_data;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Bitset of allocated PG ids (they are sequential)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * and the next free id in the set.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic bitset_t pg_id_set;
b885580b43755ee4ea1e280b85428893d2ba9291Alexander Kolbasov
b885580b43755ee4ea1e280b85428893d2ba9291Alexander Kolbasov/*
b885580b43755ee4ea1e280b85428893d2ba9291Alexander Kolbasov * ID space starts from 1 to assume that root has ID 0;
b885580b43755ee4ea1e280b85428893d2ba9291Alexander Kolbasov */
b885580b43755ee4ea1e280b85428893d2ba9291Alexander Kolbasovstatic pgid_t pg_id_next = 1;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Default and externed PG ops vectors
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic struct pg_ops pg_ops_default = {
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_alloc_default, /* alloc */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_free_default, /* free */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe NULL, /* cpu_init */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe NULL, /* cpu_fini */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe NULL, /* cpu_active */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe NULL, /* cpu_inactive */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe NULL, /* cpupart_in */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe NULL, /* cpupart_out */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe NULL, /* cpupart_move */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe NULL, /* cpu_belongs */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe NULL, /* policy_name */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe};
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxestatic struct pg_cb_ops pg_cb_ops_default = {
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg_null_op, /* thread_swtch */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg_null_op, /* thread_remain */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe};
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Class specific PG allocation callbacks
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#define PG_ALLOC(class) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe (pg_classes[class].pgc_ops->alloc ? \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes[class].pgc_ops->alloc() : \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes[pg_default_cid].pgc_ops->alloc())
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#define PG_FREE(pg) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ((pg)->pg_class->pgc_ops->free ? \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe (pg)->pg_class->pgc_ops->free(pg) : \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes[pg_default_cid].pgc_ops->free(pg)) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe/*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Class specific PG policy name
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe#define PG_POLICY_NAME(pg) \
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe ((pg)->pg_class->pgc_ops->policy_name ? \
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe (pg)->pg_class->pgc_ops->policy_name(pg) : NULL) \
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Class specific membership test callback
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#define PG_CPU_BELONGS(pg, cp) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ((pg)->pg_class->pgc_ops->cpu_belongs ? \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe (pg)->pg_class->pgc_ops->cpu_belongs(pg, cp) : 0) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * CPU configuration callbacks
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe#define PG_CPU_INIT(class, cp, cpu_pg) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{ \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_classes[class].pgc_ops->cpu_init) \
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe pg_classes[class].pgc_ops->cpu_init(cp, cpu_pg); \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe#define PG_CPU_FINI(class, cp, cpu_pg) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{ \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_classes[class].pgc_ops->cpu_fini) \
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe pg_classes[class].pgc_ops->cpu_fini(cp, cpu_pg); \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#define PG_CPU_ACTIVE(class, cp) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{ \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_classes[class].pgc_ops->cpu_active) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes[class].pgc_ops->cpu_active(cp); \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#define PG_CPU_INACTIVE(class, cp) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{ \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_classes[class].pgc_ops->cpu_inactive) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes[class].pgc_ops->cpu_inactive(cp); \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * CPU / cpupart configuration callbacks
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#define PG_CPUPART_IN(class, cp, pp) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{ \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_classes[class].pgc_ops->cpupart_in) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes[class].pgc_ops->cpupart_in(cp, pp); \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#define PG_CPUPART_OUT(class, cp, pp) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{ \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_classes[class].pgc_ops->cpupart_out) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes[class].pgc_ops->cpupart_out(cp, pp); \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe#define PG_CPUPART_MOVE(class, cp, old, new) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{ \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_classes[class].pgc_ops->cpupart_move) \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes[class].pgc_ops->cpupart_move(cp, old, new); \
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic pg_class_t *pg_classes;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic int pg_nclasses;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic pg_cid_t pg_default_cid;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Initialze common PG subsystem.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_init(void)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe extern void pg_cmt_class_init();
ad7a79fd98967dd3c7f9e9c09391089afc20f2a2Eric Saxe extern void pg_cmt_cpu_startup();
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_default_cid =
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_class_register("default", &pg_ops_default, PGR_LOGICAL);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe /*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Initialize classes to allow them to register with the framework
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg_cmt_class_init();
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg_cpu0_init();
ad7a79fd98967dd3c7f9e9c09391089afc20f2a2Eric Saxe pg_cmt_cpu_startup(CPU);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Perform CPU 0 initialization
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpu0_init(void)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe extern void pghw_physid_create();
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Create the physical ID cache for the boot CPU
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pghw_physid_create(CPU);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * pg_cpu_* require that cpu_lock be held
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe mutex_enter(&cpu_lock);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian (void) pg_cpu_init(CPU, B_FALSE);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_cpupart_in(CPU, &cp_default);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_cpu_active(CPU);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe mutex_exit(&cpu_lock);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe/*
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe * Invoked when topology for CPU0 changes
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe * post pg_cpu0_init().
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe *
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe * Currently happens as a result of null_proc_lpa
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe * on Starcat.
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe */
a66044504f7011cf96863fe62f0c6c692d5e357fesaxevoid
a66044504f7011cf96863fe62f0c6c692d5e357fesaxepg_cpu0_reinit(void)
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe{
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe mutex_enter(&cpu_lock);
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe pg_cpu_inactive(CPU);
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe pg_cpupart_out(CPU, &cp_default);
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian pg_cpu_fini(CPU, NULL);
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian (void) pg_cpu_init(CPU, B_FALSE);
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe pg_cpupart_in(CPU, &cp_default);
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe pg_cpu_active(CPU);
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe mutex_exit(&cpu_lock);
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe}
a66044504f7011cf96863fe62f0c6c692d5e357fesaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Register a new PG class
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cid_t
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_class_register(char *name, struct pg_ops *ops, pg_relation_t relation)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_class_t *newclass;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_class_t *classes_old;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe id_t cid;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe mutex_enter(&cpu_lock);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Allocate a new pg_class_t in the pg_classes array
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_nclasses == 0) {
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes = kmem_zalloc(sizeof (pg_class_t), KM_SLEEP);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe } else {
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe classes_old = pg_classes;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_classes =
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe kmem_zalloc(sizeof (pg_class_t) * (pg_nclasses + 1),
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe KM_SLEEP);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe (void) kcopy(classes_old, pg_classes,
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe sizeof (pg_class_t) * pg_nclasses);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe kmem_free(classes_old, sizeof (pg_class_t) * pg_nclasses);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe }
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe cid = pg_nclasses++;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe newclass = &pg_classes[cid];
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe (void) strncpy(newclass->pgc_name, name, PG_CLASS_NAME_MAX);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe newclass->pgc_id = cid;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe newclass->pgc_ops = ops;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe newclass->pgc_relation = relation;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe mutex_exit(&cpu_lock);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe return (cid);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Try to find an existing pg in set in which to place cp.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Returns the pg if found, and NULL otherwise.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * In the event that the CPU could belong to multiple
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * PGs in the set, the first matching PG will be returned.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_t *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpu_find_pg(cpu_t *cp, group_t *set)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_t *pg;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe group_iter_t i;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe group_iter_init(&i);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe while ((pg = group_iterate(set, &i)) != NULL) {
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Ask the class if the CPU belongs here
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (PG_CPU_BELONGS(pg, cp))
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe return (pg);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe }
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe return (NULL);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Iterate over the CPUs in a PG after initializing
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * the iterator with PG_CPU_ITR_INIT()
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxecpu_t *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpu_next(pg_cpu_itr_t *itr)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe cpu_t *cpu;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_t *pg = itr->pg;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe cpu = group_iterate(&pg->pg_cpus, &itr->position);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe return (cpu);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe/*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Test if a given PG contains a given CPU
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxeboolean_t
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxepg_cpu_find(pg_t *pg, cpu_t *cp)
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe{
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe if (group_find(&pg->pg_cpus, cp) == (uint_t)-1)
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe return (B_FALSE);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe return (B_TRUE);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe}
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe/*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Set the PGs callbacks to the default
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxevoid
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxepg_callback_set_defaults(pg_t *pg)
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe{
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe bcopy(&pg_cb_ops_default, &pg->pg_cb, sizeof (struct pg_cb_ops));
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe}
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Create a PG of a given class.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may block.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_t *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_create(pg_cid_t cid)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_t *pg;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pgid_t id;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Call the class specific PG allocation routine
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg = PG_ALLOC(cid);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg->pg_class = &pg_classes[cid];
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg->pg_relation = pg->pg_class->pgc_relation;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Find the next free sequential pg id
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe do {
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_id_next >= bitset_capacity(&pg_id_set))
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe bitset_resize(&pg_id_set, pg_id_next + 1);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe id = pg_id_next++;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe } while (bitset_in_set(&pg_id_set, id));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg->pg_id = id;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe bitset_add(&pg_id_set, pg->pg_id);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Create the PG's CPU group
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe group_create(&pg->pg_cpus);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe /*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Initialize the events ops vector
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg_callback_set_defaults(pg);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe return (pg);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Destroy a PG.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may block.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_destroy(pg_t *pg)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe group_destroy(&pg->pg_cpus);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Unassign the pg_id
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe if (pg_id_next > pg->pg_id)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_id_next = pg->pg_id;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe bitset_del(&pg_id_set, pg->pg_id);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Invoke the class specific de-allocation routine
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe PG_FREE(pg);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Add the CPU "cp" to processor group "pg"
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may block.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxepg_cpu_add(pg_t *pg, cpu_t *cp, cpu_pg_t *cpu_pg)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe int err;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /* This adds the CPU to the PG's CPU group */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe err = group_add(&pg->pg_cpus, cp, GRP_RESIZE);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(err == 0);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe /*
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * The CPU should be referencing the bootstrap PG data still
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * at this point, since this routine may block causing us to
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * enter the dispatcher.
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe */
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe ASSERT(pg_cpu_is_bootstrapped(cp));
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /* This adds the PG to the CPUs PG group */
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe err = group_add(&cpu_pg->pgs, pg, GRP_RESIZE);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(err == 0);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Remove "cp" from "pg".
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may block.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxepg_cpu_delete(pg_t *pg, cpu_t *cp, cpu_pg_t *cpu_pg)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe int err;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /* Remove the CPU from the PG */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe err = group_remove(&pg->pg_cpus, cp, GRP_RESIZE);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(err == 0);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe /*
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * The CPU should be referencing the bootstrap PG data still
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * at this point, since this routine may block causing us to
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * enter the dispatcher.
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe */
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe ASSERT(pg_cpu_is_bootstrapped(cp));
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /* Remove the PG from the CPU's PG group */
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe err = group_remove(&cpu_pg->pgs, pg, GRP_RESIZE);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(err == 0);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Allocate a CPU's PG data. This hangs off struct cpu at cpu_pg
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic cpu_pg_t *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpu_data_alloc(void)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe cpu_pg_t *pgd;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pgd = kmem_zalloc(sizeof (cpu_pg_t), KM_SLEEP);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe group_create(&pgd->pgs);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe group_create(&pgd->cmt_pgs);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe return (pgd);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Free the CPU's PG data.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic void
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpu_data_free(cpu_pg_t *pgd)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe group_destroy(&pgd->pgs);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe group_destroy(&pgd->cmt_pgs);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe kmem_free(pgd, sizeof (cpu_pg_t));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * Called when either a new CPU is coming into the system (either
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * via booting or DR) or when the CPU's PG data is being recalculated.
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * Allocate its PG data, and notify all registered classes about
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * the new CPU.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * If "deferred_init" is B_TRUE, the CPU's PG data will be allocated
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * and returned, but the "bootstrap" structure will be left in place.
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * The deferred_init option is used when all CPUs in the system are
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * using the bootstrap structure as part of the process of recalculating
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * all PG data. The caller must replace the bootstrap structure with the
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * allocated PG data before pg_cpu_active is called.
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may block.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandiliancpu_pg_t *
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilianpg_cpu_init(cpu_t *cp, boolean_t deferred_init)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_cid_t i;
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe cpu_pg_t *cpu_pg;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Allocate and size the per CPU pg data
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe *
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * The CPU's PG data will be populated by the various
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * PG classes during the invocation of the PG_CPU_INIT()
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * callback below.
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe *
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * Since the we could block and enter the dispatcher during
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * this process, the CPU will continue to reference the bootstrap
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * PG data until all the initialization completes.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe ASSERT(pg_cpu_is_bootstrapped(cp));
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe cpu_pg = pg_cpu_data_alloc();
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Notify all registered classes about the new CPU
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe for (i = 0; i < pg_nclasses; i++)
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe PG_CPU_INIT(i, cp, cpu_pg);
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe /*
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe * The CPU's PG data is now ready to use.
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe */
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian if (deferred_init == B_FALSE)
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian cp->cpu_pg = cpu_pg;
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian return (cpu_pg);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * Either this CPU is being deleted from the system or its PG data is
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * being recalculated. Notify the classes and free up the CPU's PG data.
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian *
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * If "cpu_pg_deferred" is non-NULL, it points to the CPU's PG data and
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * serves to indicate that this CPU is already using the bootstrap
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * stucture. Used as part of the process to recalculate the PG data for
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * all CPUs in the system.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilianpg_cpu_fini(cpu_t *cp, cpu_pg_t *cpu_pg_deferred)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_cid_t i;
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe cpu_pg_t *cpu_pg;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian if (cpu_pg_deferred == NULL) {
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian cpu_pg = cp->cpu_pg;
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian /*
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * This can happen if the CPU coming into the system
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * failed to power on.
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian */
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian if (cpu_pg == NULL || pg_cpu_is_bootstrapped(cp))
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian return;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian /*
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * Have the CPU reference the bootstrap PG data to survive
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian * the dispatcher should it block from here on out.
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian */
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian pg_cpu_bootstrap(cp);
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian } else {
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian ASSERT(pg_cpu_is_bootstrapped(cp));
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian cpu_pg = cpu_pg_deferred;
023e71de9e5670cebc23dd51162833661d3d2d3bHaik Aftandilian }
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe for (i = 0; i < pg_nclasses; i++)
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe PG_CPU_FINI(i, cp, cpu_pg);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
47ab0c7c6702159d8bb84e3b1533d9f9843dd568Eric Saxe pg_cpu_data_free(cpu_pg);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This CPU is becoming active (online)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may not block as it is called from paused CPUs
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * context.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpu_active(cpu_t *cp)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_cid_t i;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Notify all registered classes about the new CPU
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe for (i = 0; i < pg_nclasses; i++)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe PG_CPU_ACTIVE(i, cp);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This CPU is going inactive (offline)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may not block, as it is called from paused
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * CPUs context.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpu_inactive(cpu_t *cp)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe pg_cid_t i;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Notify all registered classes about the new CPU
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe for (i = 0; i < pg_nclasses; i++)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe PG_CPU_INACTIVE(i, cp);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Invoked when the CPU is about to move into the partition
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may block.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpupart_in(cpu_t *cp, cpupart_t *pp)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe int i;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Notify all registered classes that the
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * CPU is about to enter the CPU partition
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe for (i = 0; i < pg_nclasses; i++)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe PG_CPUPART_IN(i, cp, pp);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Invoked when the CPU is about to move out of the partition
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may block.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*ARGSUSED*/
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpupart_out(cpu_t *cp, cpupart_t *pp)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe int i;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Notify all registered classes that the
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * CPU is about to leave the CPU partition
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe for (i = 0; i < pg_nclasses; i++)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe PG_CPUPART_OUT(i, cp, pp);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Invoked when the CPU is *moving* partitions.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This routine may not block, as it is called from paused CPUs
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * context.
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpupart_move(cpu_t *cp, cpupart_t *oldpp, cpupart_t *newpp)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe int i;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe ASSERT(MUTEX_HELD(&cpu_lock));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe /*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Notify all registered classes that the
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * CPU is about to leave the CPU partition
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe for (i = 0; i < pg_nclasses; i++)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe PG_CPUPART_MOVE(i, cp, oldpp, newpp);
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe/*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Return a class specific string describing a policy implemented
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * across this PG
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxechar *
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxepg_policy_name(pg_t *pg)
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe{
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe char *str;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe if ((str = PG_POLICY_NAME(pg)) != NULL)
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe return (str);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe return ("N/A");
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe}
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * Provide the specified CPU a bootstrap pg
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * This is needed to allow sane behaviour if any PG consuming
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe * code needs to deal with a partially initialized CPU
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe */
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxevoid
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_cpu_bootstrap(cpu_t *cp)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe cp->cpu_pg = &bootstrap_pg_data;
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe/*
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe * Return non-zero if the specified CPU is bootstrapped,
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe * which means it's CPU specific PG data has not yet been
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe * fully constructed.
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe */
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxeint
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxepg_cpu_is_bootstrapped(cpu_t *cp)
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe{
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe return (cp->cpu_pg == &bootstrap_pg_data);
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe}
1a77c24bc3a54fb48592de0041508561c5781501Eric Saxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*ARGSUSED*/
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic pg_t *
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_alloc_default(pg_class_t class)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe return (kmem_zalloc(sizeof (pg_t), KM_SLEEP));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe/*ARGSUSED*/
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxestatic void
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxepg_free_default(struct pg *pg)
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe{
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe kmem_free(pg, sizeof (pg_t));
fb2f18f820d90b001aea4fb27dd654bc1263c440esaxe}
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxestatic void
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxepg_null_op()
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe{
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe}
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe/*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Invoke the "thread switch" callback for each of the CPU's PGs
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * This is invoked from the dispatcher swtch() routine, which is called
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * when a thread running an a CPU should switch to another thread.
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * "cp" is the CPU on which the thread switch is happening
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * "now" is an unscaled hrtime_t timestamp taken in swtch()
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * "old" and "new" are the outgoing and incoming threads, respectively.
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxevoid
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxepg_ev_thread_swtch(struct cpu *cp, hrtime_t now, kthread_t *old, kthread_t *new)
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe{
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe int i, sz;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe group_t *grp;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg_t *pg;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe grp = &cp->cpu_pg->pgs;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe sz = GROUP_SIZE(grp);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe for (i = 0; i < sz; i++) {
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg = GROUP_ACCESS(grp, i);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg->pg_cb.thread_swtch(pg, cp, now, old, new);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe }
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe}
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe/*
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * Invoke the "thread remain" callback for each of the CPU's PGs.
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * This is called from the dispatcher's swtch() routine when a thread
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * running on the CPU "cp" is switching to itself, which can happen as an
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe * artifact of the thread's timeslice expiring.
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe */
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxevoid
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxepg_ev_thread_remain(struct cpu *cp, kthread_t *t)
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe{
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe int i, sz;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe group_t *grp;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg_t *pg;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe grp = &cp->cpu_pg->pgs;
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe sz = GROUP_SIZE(grp);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe for (i = 0; i < sz; i++) {
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg = GROUP_ACCESS(grp, i);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe pg->pg_cb.thread_remain(pg, cp, t);
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe }
0e7515250c8395f368aa45fb9acae7c4f8f8b786Eric Saxe}