chip.c revision 25cf1a301a396c38e8adf52c15f537b80d2483f7
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Common Development and Distribution License (the "License").
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CMT aware scheduler/dispatcher support
fa9e4066f08beec538e775443c5be79dd423fcabahrens * With the introduction of Chip Multi-Threaded (CMT) processor architectures,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * it is no longer necessarily true that a given physical processor
fa9e4066f08beec538e775443c5be79dd423fcabahrens * module (chip) will present itself as a single schedulable entity (cpu_t).
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Rather, each chip may present itself as one or more "logical" CPUs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The logical CPUs presented may share physical components on the chip
fa9e4066f08beec538e775443c5be79dd423fcabahrens * such as caches, data pipes, FPUs, etc. It is advantageous to have the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * kernel know which logical CPUs are presented by a given chip,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and what facilities on the chip are shared, since the kernel can then use
fa9e4066f08beec538e775443c5be79dd423fcabahrens * this information to employ scheduling policies that help improve the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * availability of per chip resources, and increase utilization of a thread's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * cache investment.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The "chip_t" structure represents a physical processor.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * It is used to keep track of which logical CPUs are presented by a given
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chip, and to provide a parameterized representation of a chip's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * properties. A count of the number of running threads is also
fa9e4066f08beec538e775443c5be79dd423fcabahrens * maintained, and is used by the dispatcher to balance load across the
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley * system's chips to improve performance through increased chip resource
fa9e4066f08beec538e775443c5be79dd423fcabahrens * availability.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Safely traversing the per lgroup lists requires the same protections
fa9e4066f08beec538e775443c5be79dd423fcabahrens * as traversing the cpu lists. One must either:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - hold cpu_lock
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - have disabled kernel preemption
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - be at high SPL
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - have cpu's paused
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Safely traversing the global "chip_list" requires holding cpu_lock.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * A chip's nrunning count should only be modified using the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CHIP_NRUNNING() macro, through which updates of the count are done
fa9e4066f08beec538e775443c5be79dd423fcabahrens * atomically.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chip_bootstrap is used on platforms where it is possible to enter the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * dispatcher before a new CPU's chip initialization has happened.
fa9e4066f08beec538e775443c5be79dd423fcabahrens ((cp)->cpu_chip == NULL || (cp)->cpu_chip == &chip_bootstrap)
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic chip_set_t chip_set; /* bitmap of chips in existence */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* indexed by chip_seqid */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic chipid_t chip_seqid_next = 0; /* next sequential chip id */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Declare static kstat names (defined in chip.h)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Find the chip_t with the given chip_id.
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(chip_list == NULL || chip_list->chip_next == chip_list ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Setup the kstats for this chip, if needed
fa9e4066f08beec538e775443c5be79dd423fcabahrens return; /* already initialized */
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_kstat = kstat_create("chip", chp->chip_id, NULL, "misc",
fa9e4066f08beec538e775443c5be79dd423fcabahrens mutex_init(chip_kstat->ks_lock, NULL, MUTEX_DEFAULT, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Note: On sun4v systems, chip kstats don't currently
fa9e4066f08beec538e775443c5be79dd423fcabahrens * exist, since "chip" structures and policies are being
fa9e4066f08beec538e775443c5be79dd423fcabahrens * leveraged to implement core level balancing, and exporting
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chip kstats in light of this would be both misleading
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and confusing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* !sun4v */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The chip kstats are read only
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If necessary, instantiate a chip_t for this CPU.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Called when a CPU is being added to the system either in startup,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or because of DR. The cpu will be assigned to the chip's active
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CPU list later in chip_cpu_assign()
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT((chip_list == NULL) || (MUTEX_HELD(&cpu_lock)));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Call into the platform to fetch this cpu's chipid
fa9e4066f08beec538e775443c5be79dd423fcabahrens * On sun4v platforms, the chip infrastructure is currently being
fa9e4066f08beec538e775443c5be79dd423fcabahrens * leveraged to implement core level load balancing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* DO_CORELEVEL_LOADBAL */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Create a new chip
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we're booting, take this moment to perform
fa9e4066f08beec538e775443c5be79dd423fcabahrens * some additional initialization
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Find the next free sequential chip id.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * A chip's sequential id exists in the range
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 0 .. CHIP_MAX_CHIPS, and is suitable for use with
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chip sets.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Query the platform specific parameters
fa9e4066f08beec538e775443c5be79dd423fcabahrens * for this chip
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Insert this chip in chip_list
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The boot cpu will create the first chip's kstats
fa9e4066f08beec538e775443c5be79dd423fcabahrens * later in cpu_kstat_init()
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initialize the effective rechoose interval cached
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in this cpu structure.
fa9e4066f08beec538e775443c5be79dd423fcabahrens rechoose = rechoose_interval + chp->chip_rechoose_adj;
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This cpu is being deleted. It has already been removed from
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the chip's active cpu list back in chip_cpu_unassign(). Here
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we remove the cpu's reference to the chip, and cleanup/destroy
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the chip if needed.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This can happen if the CPU failed to power on
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley * make sure the chip is really empty
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley * remove the chip from the system's chip list
3349c8dc868dbab8bd2e9355b835f83837de8900talley * clean up any chip kstats
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If the chip_t structure was dynamically
fa9e4066f08beec538e775443c5be79dd423fcabahrens * allocated, free it.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This cpu is becoming active (online).
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Perform all the necessary bookkeeping in it's chip_t
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(chip_list == NULL || chip_list->chip_next == chip_list ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add this cpu to the chip's cpu list
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Notate this chip's seqid in the cpu partition's chipset
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This cpu is being offlined, so do the reverse
fa9e4066f08beec538e775443c5be79dd423fcabahrens * of cpu_chip_assign()
fa9e4066f08beec538e775443c5be79dd423fcabahrens * remove this cpu from the chip's cpu list
fa9e4066f08beec538e775443c5be79dd423fcabahrens * A cpu on the chip is moving into and/or out of a cpu partition.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Maintain the cpuparts' chip membership set.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * oldpp is NULL when a cpu is being offlined.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * newpp is NULL when a cpu is being onlined.
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_cpu_move_part(cpu_t *cp, cpupart_t *oldpp, cpupart_t *newpp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(chip_list->chip_next == chip_list || MUTEX_HELD(&cpu_lock));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add the chip's seqid to the cpupart's chip set
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Another cpu on the chip is in the old
fa9e4066f08beec538e775443c5be79dd423fcabahrens * cpu partition, so we're done
fa9e4066f08beec538e775443c5be79dd423fcabahrens * No other cpu on the chip is in the old partition
fa9e4066f08beec538e775443c5be79dd423fcabahrens * so remove the chip's seqid from it's set
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Called to indicate a slave CPU has started up.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Indicate that the chip has a new running thread
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (slave startup)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Provide the specified CPU a bootstrap chip
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a chip set, return 1 if it is empty.
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < CHIP_SET_WORDS; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);