1*b885580bSAlexander Kolbasov /* 2*b885580bSAlexander Kolbasov * CDDL HEADER START 3*b885580bSAlexander Kolbasov * 4*b885580bSAlexander Kolbasov * The contents of this file are subject to the terms of the 5*b885580bSAlexander Kolbasov * Common Development and Distribution License (the "License"). 6*b885580bSAlexander Kolbasov * You may not use this file except in compliance with the License. 7*b885580bSAlexander Kolbasov * 8*b885580bSAlexander Kolbasov * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*b885580bSAlexander Kolbasov * or http://www.opensolaris.org/os/licensing. 10*b885580bSAlexander Kolbasov * See the License for the specific language governing permissions 11*b885580bSAlexander Kolbasov * and limitations under the License. 12*b885580bSAlexander Kolbasov * 13*b885580bSAlexander Kolbasov * When distributing Covered Code, include this CDDL HEADER in each 14*b885580bSAlexander Kolbasov * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*b885580bSAlexander Kolbasov * If applicable, add the following below this CDDL HEADER, with the 16*b885580bSAlexander Kolbasov * fields enclosed by brackets "[]" replaced with your own identifying 17*b885580bSAlexander Kolbasov * information: Portions Copyright [yyyy] [name of copyright owner] 18*b885580bSAlexander Kolbasov * 19*b885580bSAlexander Kolbasov * CDDL HEADER END 20*b885580bSAlexander Kolbasov */ 21*b885580bSAlexander Kolbasov 22*b885580bSAlexander Kolbasov /* 23*b885580bSAlexander Kolbasov * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*b885580bSAlexander Kolbasov * Use is subject to license terms. 25*b885580bSAlexander Kolbasov */ 26*b885580bSAlexander Kolbasov 27*b885580bSAlexander Kolbasov #ifndef _SYS_CAP_UTIL_H 28*b885580bSAlexander Kolbasov #define _SYS_CAP_UTIL_H 29*b885580bSAlexander Kolbasov 30*b885580bSAlexander Kolbasov 31*b885580bSAlexander Kolbasov #ifdef __cplusplus 32*b885580bSAlexander Kolbasov extern "C" { 33*b885580bSAlexander Kolbasov #endif 34*b885580bSAlexander Kolbasov 35*b885580bSAlexander Kolbasov #include <sys/types.h> 36*b885580bSAlexander Kolbasov #include <sys/kcpc.h> 37*b885580bSAlexander Kolbasov #include <sys/cpc_impl.h> 38*b885580bSAlexander Kolbasov #include <sys/pghw.h> 39*b885580bSAlexander Kolbasov #include <sys/cmt.h> 40*b885580bSAlexander Kolbasov 41*b885580bSAlexander Kolbasov #ifdef _KERNEL 42*b885580bSAlexander Kolbasov 43*b885580bSAlexander Kolbasov /* 44*b885580bSAlexander Kolbasov * Capacity and utilization flags for each CPU 45*b885580bSAlexander Kolbasov */ 46*b885580bSAlexander Kolbasov #define CU_CPU_CNTRS_ON 1 /* CPU performance counters are on */ 47*b885580bSAlexander Kolbasov #define CU_CPU_CNTRS_OFF_ON 2 /* Off -> on transition */ 48*b885580bSAlexander Kolbasov 49*b885580bSAlexander Kolbasov /* 50*b885580bSAlexander Kolbasov * Macro that returns whether CPU performance counters turned on for given CPU 51*b885580bSAlexander Kolbasov */ 52*b885580bSAlexander Kolbasov #define CU_CPC_ON(cp) \ 53*b885580bSAlexander Kolbasov ((cp) != NULL && (cp)->cpu_cu_info != NULL && \ 54*b885580bSAlexander Kolbasov ((cp)->cpu_cu_info->cu_flag & CU_CPU_CNTRS_ON)) 55*b885580bSAlexander Kolbasov 56*b885580bSAlexander Kolbasov 57*b885580bSAlexander Kolbasov /* 58*b885580bSAlexander Kolbasov * Per counter statistics 59*b885580bSAlexander Kolbasov */ 60*b885580bSAlexander Kolbasov typedef struct cu_cntr_stats { 61*b885580bSAlexander Kolbasov hrtime_t cs_time_running; /* running total of time counting */ 62*b885580bSAlexander Kolbasov hrtime_t cs_time_stopped; /* ... time not counting */ 63*b885580bSAlexander Kolbasov hrtime_t cs_time_start; /* start time of current sample */ 64*b885580bSAlexander Kolbasov uint64_t cs_value_start; /* starting value for next sample */ 65*b885580bSAlexander Kolbasov uint64_t cs_value_last; /* last value */ 66*b885580bSAlexander Kolbasov uint64_t cs_value_total; /* running total */ 67*b885580bSAlexander Kolbasov uint64_t cs_rate; /* observed rate since last */ 68*b885580bSAlexander Kolbasov uint64_t cs_rate_max; /* maximum rate */ 69*b885580bSAlexander Kolbasov kcpc_request_t *cs_cpc_req; /* corresponding CPC request */ 70*b885580bSAlexander Kolbasov struct cpu *cs_cpu_start; /* CPU where starting value gotten */ 71*b885580bSAlexander Kolbasov } cu_cntr_stats_t; 72*b885580bSAlexander Kolbasov 73*b885580bSAlexander Kolbasov 74*b885580bSAlexander Kolbasov /* 75*b885580bSAlexander Kolbasov * Counter info for a PG hardware sharing relationship 76*b885580bSAlexander Kolbasov */ 77*b885580bSAlexander Kolbasov typedef struct cu_cntr_info { 78*b885580bSAlexander Kolbasov cpu_t *ci_cpu; /* CPU being measured */ 79*b885580bSAlexander Kolbasov pghw_t *ci_pg; /* hardware PG being measured */ 80*b885580bSAlexander Kolbasov kstat_t *ci_kstat; /* kstats being exported */ 81*b885580bSAlexander Kolbasov cu_cntr_stats_t *ci_stats; /* counter statistics */ 82*b885580bSAlexander Kolbasov uint_t ci_nstats; /* number of statistics */ 83*b885580bSAlexander Kolbasov } cu_cntr_info_t; 84*b885580bSAlexander Kolbasov 85*b885580bSAlexander Kolbasov 86*b885580bSAlexander Kolbasov /* 87*b885580bSAlexander Kolbasov * Each CPU can have one or more CPC contexts for measuring capacity and 88*b885580bSAlexander Kolbasov * utilization 89*b885580bSAlexander Kolbasov * 90*b885580bSAlexander Kolbasov * One CPC context is needed per CPU if the counter events needed to measure 91*b885580bSAlexander Kolbasov * capacity and utilization on each CPU can be programmed onto all the counters 92*b885580bSAlexander Kolbasov * on a CPU at the same time and there are fewer or same number of desired 93*b885580bSAlexander Kolbasov * counter events as counters on each CPU. Otherwise, the desired counter 94*b885580bSAlexander Kolbasov * events are assigned across multiple CPC contexts, so the contexts and their 95*b885580bSAlexander Kolbasov * counter events can be multiplexed onto the counters over time to get the 96*b885580bSAlexander Kolbasov * data for all of the counter events. 97*b885580bSAlexander Kolbasov */ 98*b885580bSAlexander Kolbasov typedef struct cu_cpc_ctx { 99*b885580bSAlexander Kolbasov int cur_index; /* index for current context */ 100*b885580bSAlexander Kolbasov int nctx; /* number of CPC contexts */ 101*b885580bSAlexander Kolbasov kcpc_ctx_t **ctx_ptr_array; /* array of context pointers */ 102*b885580bSAlexander Kolbasov size_t ctx_ptr_array_sz; /* size of array */ 103*b885580bSAlexander Kolbasov } cu_cpc_ctx_t; 104*b885580bSAlexander Kolbasov 105*b885580bSAlexander Kolbasov /* 106*b885580bSAlexander Kolbasov * Per CPU capacity and utilization info 107*b885580bSAlexander Kolbasov */ 108*b885580bSAlexander Kolbasov typedef struct cu_cpu_info { 109*b885580bSAlexander Kolbasov struct cpu *cu_cpu; /* CPU for the statistics */ 110*b885580bSAlexander Kolbasov uint_t cu_flag; /* capacity & utilization flag */ 111*b885580bSAlexander Kolbasov hrtime_t cu_sample_time; /* when last sample taken */ 112*b885580bSAlexander Kolbasov cu_cpc_ctx_t cu_cpc_ctx; /* performance counter contexts */ 113*b885580bSAlexander Kolbasov cu_cntr_stats_t *cu_cntr_stats; /* counter statistics array */ 114*b885580bSAlexander Kolbasov uint_t cu_ncntr_stats; /* number of counter statistics */ 115*b885580bSAlexander Kolbasov uint_t cu_disabled; /* count of disable requests */ 116*b885580bSAlexander Kolbasov /* 117*b885580bSAlexander Kolbasov * Per PG hardware sharing relationship counter info 118*b885580bSAlexander Kolbasov */ 119*b885580bSAlexander Kolbasov cu_cntr_info_t *cu_cntr_info[PGHW_NUM_COMPONENTS]; 120*b885580bSAlexander Kolbasov } cu_cpu_info_t; 121*b885580bSAlexander Kolbasov 122*b885580bSAlexander Kolbasov /* 123*b885580bSAlexander Kolbasov * COMMON INTERFACE ROUTINES 124*b885580bSAlexander Kolbasov */ 125*b885580bSAlexander Kolbasov 126*b885580bSAlexander Kolbasov /* 127*b885580bSAlexander Kolbasov * Setup capacity and utilization support 128*b885580bSAlexander Kolbasov */ 129*b885580bSAlexander Kolbasov extern void cu_init(void); 130*b885580bSAlexander Kolbasov 131*b885580bSAlexander Kolbasov /* 132*b885580bSAlexander Kolbasov * Tear down capacity and utilization support 133*b885580bSAlexander Kolbasov */ 134*b885580bSAlexander Kolbasov extern int cu_fini(void); 135*b885580bSAlexander Kolbasov 136*b885580bSAlexander Kolbasov /* 137*b885580bSAlexander Kolbasov * Program CPC for capacity and utilization on given CPU 138*b885580bSAlexander Kolbasov */ 139*b885580bSAlexander Kolbasov extern void cu_cpc_program(struct cpu *, int *); 140*b885580bSAlexander Kolbasov 141*b885580bSAlexander Kolbasov /* 142*b885580bSAlexander Kolbasov * Unprogram CPC for capacity and utilization on given CPU 143*b885580bSAlexander Kolbasov */ 144*b885580bSAlexander Kolbasov extern void cu_cpc_unprogram(struct cpu *, int *); 145*b885580bSAlexander Kolbasov 146*b885580bSAlexander Kolbasov /* 147*b885580bSAlexander Kolbasov * Update counter statistics on a given CPU 148*b885580bSAlexander Kolbasov */ 149*b885580bSAlexander Kolbasov extern int cu_cpu_update(struct cpu *, boolean_t); 150*b885580bSAlexander Kolbasov 151*b885580bSAlexander Kolbasov /* 152*b885580bSAlexander Kolbasov * Update utilization and capacity data for CMT PG 153*b885580bSAlexander Kolbasov */ 154*b885580bSAlexander Kolbasov extern void cu_pg_update(pghw_t *); 155*b885580bSAlexander Kolbasov 156*b885580bSAlexander Kolbasov /* 157*b885580bSAlexander Kolbasov * Disable or enable capacity and utilization on all CPUs 158*b885580bSAlexander Kolbasov */ 159*b885580bSAlexander Kolbasov extern void cu_disable(void); 160*b885580bSAlexander Kolbasov extern void cu_enable(void); 161*b885580bSAlexander Kolbasov 162*b885580bSAlexander Kolbasov /* 163*b885580bSAlexander Kolbasov * PLATFORM SPECIFIC INTERFACE ROUTINES 164*b885580bSAlexander Kolbasov */ 165*b885580bSAlexander Kolbasov extern int cu_plat_cpc_init(cpu_t *, kcpc_request_list_t *, int); 166*b885580bSAlexander Kolbasov 167*b885580bSAlexander Kolbasov #endif /* _KERNEL */ 168*b885580bSAlexander Kolbasov 169*b885580bSAlexander Kolbasov #ifdef __cplusplus 170*b885580bSAlexander Kolbasov } 171*b885580bSAlexander Kolbasov #endif 172*b885580bSAlexander Kolbasov 173*b885580bSAlexander Kolbasov #endif /* _SYS_CAP_UTIL_H */ 174