/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_CAP_UTIL_H #define _SYS_CAP_UTIL_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #ifdef _KERNEL /* * Capacity and utilization flags for each CPU */ #define CU_CPU_CNTRS_ON 1 /* CPU performance counters are on */ #define CU_CPU_CNTRS_OFF_ON 2 /* Off -> on transition */ /* * Macro that returns whether CPU performance counters turned on for given CPU */ #define CU_CPC_ON(cp) \ ((cp) != NULL && (cp)->cpu_cu_info != NULL && \ ((cp)->cpu_cu_info->cu_flag & CU_CPU_CNTRS_ON)) /* * Per counter statistics */ typedef struct cu_cntr_stats { hrtime_t cs_time_running; /* running total of time counting */ hrtime_t cs_time_stopped; /* ... time not counting */ hrtime_t cs_time_start; /* start time of current sample */ uint64_t cs_value_start; /* starting value for next sample */ uint64_t cs_value_last; /* last value */ uint64_t cs_value_total; /* running total */ uint64_t cs_rate; /* observed rate since last */ uint64_t cs_rate_max; /* maximum rate */ kcpc_request_t *cs_cpc_req; /* corresponding CPC request */ struct cpu *cs_cpu_start; /* CPU where starting value gotten */ } cu_cntr_stats_t; /* * Counter info for a PG hardware sharing relationship */ typedef struct cu_cntr_info { cpu_t *ci_cpu; /* CPU being measured */ pghw_t *ci_pg; /* hardware PG being measured */ kstat_t *ci_kstat; /* kstats being exported */ cu_cntr_stats_t *ci_stats; /* counter statistics */ uint_t ci_nstats; /* number of statistics */ } cu_cntr_info_t; /* * Each CPU can have one or more CPC contexts for measuring capacity and * utilization * * One CPC context is needed per CPU if the counter events needed to measure * capacity and utilization on each CPU can be programmed onto all the counters * on a CPU at the same time and there are fewer or same number of desired * counter events as counters on each CPU. Otherwise, the desired counter * events are assigned across multiple CPC contexts, so the contexts and their * counter events can be multiplexed onto the counters over time to get the * data for all of the counter events. */ typedef struct cu_cpc_ctx { int cur_index; /* index for current context */ int nctx; /* number of CPC contexts */ kcpc_ctx_t **ctx_ptr_array; /* array of context pointers */ size_t ctx_ptr_array_sz; /* size of array */ } cu_cpc_ctx_t; /* * Per CPU capacity and utilization info */ typedef struct cu_cpu_info { struct cpu *cu_cpu; /* CPU for the statistics */ uint_t cu_flag; /* capacity & utilization flag */ hrtime_t cu_sample_time; /* when last sample taken */ cu_cpc_ctx_t cu_cpc_ctx; /* performance counter contexts */ cu_cntr_stats_t *cu_cntr_stats; /* counter statistics array */ uint_t cu_ncntr_stats; /* number of counter statistics */ uint_t cu_disabled; /* count of disable requests */ /* * Per PG hardware sharing relationship counter info */ cu_cntr_info_t *cu_cntr_info[PGHW_NUM_COMPONENTS]; } cu_cpu_info_t; /* * COMMON INTERFACE ROUTINES */ /* * Setup capacity and utilization support */ extern void cu_init(void); /* * Tear down capacity and utilization support */ extern int cu_fini(void); /* * Program CPC for capacity and utilization on given CPU */ extern void cu_cpc_program(struct cpu *, int *); /* * Unprogram CPC for capacity and utilization on given CPU */ extern void cu_cpc_unprogram(struct cpu *, int *); /* * Update counter statistics on a given CPU */ extern int cu_cpu_update(struct cpu *, boolean_t); /* * Update utilization and capacity data for CMT PG */ extern void cu_pg_update(pghw_t *); /* * Disable or enable capacity and utilization on all CPUs */ extern void cu_disable(void); extern void cu_enable(void); /* * PLATFORM SPECIFIC INTERFACE ROUTINES */ extern int cu_plat_cpc_init(cpu_t *, kcpc_request_list_t *, int); #endif /* _KERNEL */ #ifdef __cplusplus } #endif #endif /* _SYS_CAP_UTIL_H */