1*c97ad5cdSakolb /* 2*c97ad5cdSakolb * CDDL HEADER START 3*c97ad5cdSakolb * 4*c97ad5cdSakolb * The contents of this file are subject to the terms of the 5*c97ad5cdSakolb * Common Development and Distribution License (the "License"). 6*c97ad5cdSakolb * You may not use this file except in compliance with the License. 7*c97ad5cdSakolb * 8*c97ad5cdSakolb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*c97ad5cdSakolb * or http://www.opensolaris.org/os/licensing. 10*c97ad5cdSakolb * See the License for the specific language governing permissions 11*c97ad5cdSakolb * and limitations under the License. 12*c97ad5cdSakolb * 13*c97ad5cdSakolb * When distributing Covered Code, include this CDDL HEADER in each 14*c97ad5cdSakolb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*c97ad5cdSakolb * If applicable, add the following below this CDDL HEADER, with the 16*c97ad5cdSakolb * fields enclosed by brackets "[]" replaced with your own identifying 17*c97ad5cdSakolb * information: Portions Copyright [yyyy] [name of copyright owner] 18*c97ad5cdSakolb * 19*c97ad5cdSakolb * CDDL HEADER END 20*c97ad5cdSakolb */ 21*c97ad5cdSakolb 22*c97ad5cdSakolb /* 23*c97ad5cdSakolb * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*c97ad5cdSakolb * Use is subject to license terms. 25*c97ad5cdSakolb */ 26*c97ad5cdSakolb 27*c97ad5cdSakolb #ifndef _SYS_CPUCAPS_H 28*c97ad5cdSakolb #define _SYS_CPUCAPS_H 29*c97ad5cdSakolb 30*c97ad5cdSakolb #pragma ident "%Z%%M% %I% %E% SMI" 31*c97ad5cdSakolb 32*c97ad5cdSakolb #ifdef __cplusplus 33*c97ad5cdSakolb extern "C" { 34*c97ad5cdSakolb #endif 35*c97ad5cdSakolb 36*c97ad5cdSakolb #include <sys/types.h> 37*c97ad5cdSakolb #include <sys/zone.h> 38*c97ad5cdSakolb #include <sys/project.h> 39*c97ad5cdSakolb #include <sys/time.h> 40*c97ad5cdSakolb #include <sys/rctl.h> 41*c97ad5cdSakolb 42*c97ad5cdSakolb /* 43*c97ad5cdSakolb * CPU caps provide an absolute hard CPU usage limit which is enforced even if 44*c97ad5cdSakolb * some CPUs are idle. It can be enforced at project or zone level. 45*c97ad5cdSakolb */ 46*c97ad5cdSakolb 47*c97ad5cdSakolb #ifdef _KERNEL 48*c97ad5cdSakolb 49*c97ad5cdSakolb /* 50*c97ad5cdSakolb * Valid caps values go from 1 to MAXCAP - 1. Specifying the MAXCAP as the cap 51*c97ad5cdSakolb * value is equivalent to disabling the cap. 52*c97ad5cdSakolb */ 53*c97ad5cdSakolb #define MAXCAP UINT_MAX 54*c97ad5cdSakolb 55*c97ad5cdSakolb /* 56*c97ad5cdSakolb * cpucaps_enabled is used to quickly check whether any CPU caps specific code 57*c97ad5cdSakolb * should be invoked. Users outside CPU Caps framework should use CPUCAPS_ON() 58*c97ad5cdSakolb * and CPUCAPS_OFF() macros. 59*c97ad5cdSakolb */ 60*c97ad5cdSakolb extern boolean_t cpucaps_enabled; 61*c97ad5cdSakolb 62*c97ad5cdSakolb #define CPUCAPS_ON() cpucaps_enabled 63*c97ad5cdSakolb #define CPUCAPS_OFF() (!cpucaps_enabled) 64*c97ad5cdSakolb 65*c97ad5cdSakolb /* 66*c97ad5cdSakolb * Initialize the CPU caps framework. 67*c97ad5cdSakolb */ 68*c97ad5cdSakolb extern void cpucaps_init(void); 69*c97ad5cdSakolb 70*c97ad5cdSakolb /* 71*c97ad5cdSakolb * Notify caps framework of a new project coming in or existing project 72*c97ad5cdSakolb * going away 73*c97ad5cdSakolb */ 74*c97ad5cdSakolb extern void cpucaps_project_add(kproject_t *); 75*c97ad5cdSakolb extern void cpucaps_project_remove(kproject_t *); 76*c97ad5cdSakolb 77*c97ad5cdSakolb /* 78*c97ad5cdSakolb * Notify caps framework when a zone is going away. 79*c97ad5cdSakolb */ 80*c97ad5cdSakolb extern void cpucaps_zone_remove(zone_t *); 81*c97ad5cdSakolb 82*c97ad5cdSakolb /* 83*c97ad5cdSakolb * Set project/zone cap to specified value. Value of MAXCAP should disable caps. 84*c97ad5cdSakolb */ 85*c97ad5cdSakolb extern int cpucaps_project_set(kproject_t *, rctl_qty_t); 86*c97ad5cdSakolb extern int cpucaps_zone_set(zone_t *, rctl_qty_t); 87*c97ad5cdSakolb 88*c97ad5cdSakolb /* 89*c97ad5cdSakolb * Get current CPU usage for a project/zone. 90*c97ad5cdSakolb */ 91*c97ad5cdSakolb extern rctl_qty_t cpucaps_project_get(kproject_t *); 92*c97ad5cdSakolb extern rctl_qty_t cpucaps_zone_get(zone_t *); 93*c97ad5cdSakolb 94*c97ad5cdSakolb /* 95*c97ad5cdSakolb * Scheduling class hooks into CPU caps framework. 96*c97ad5cdSakolb */ 97*c97ad5cdSakolb 98*c97ad5cdSakolb /* 99*c97ad5cdSakolb * CPU caps specific data for each scheduling class. 100*c97ad5cdSakolb * 101*c97ad5cdSakolb * There is a small amount of accounting data that should be kept by each 102*c97ad5cdSakolb * scheduling class for each thread which is only used by CPU caps code. This 103*c97ad5cdSakolb * data is kept in the caps_sc structure which is transparent for all scheduling 104*c97ad5cdSakolb * classes. The fields in the structure are: 105*c97ad5cdSakolb * 106*c97ad5cdSakolb * csc_cputime - Total time spent on CPU during thread lifetime, obtained 107*c97ad5cdSakolb * as the sum of user, system and trap time, reported by 108*c97ad5cdSakolb * microstate accounting. 109*c97ad5cdSakolb */ 110*c97ad5cdSakolb typedef struct caps_sc { 111*c97ad5cdSakolb hrtime_t csc_cputime; 112*c97ad5cdSakolb } caps_sc_t; 113*c97ad5cdSakolb 114*c97ad5cdSakolb /* 115*c97ad5cdSakolb * Initialize per-thread cpu-caps specific data. 116*c97ad5cdSakolb */ 117*c97ad5cdSakolb extern void cpucaps_sc_init(caps_sc_t *); 118*c97ad5cdSakolb 119*c97ad5cdSakolb /* 120*c97ad5cdSakolb * Modus operandi for cpucaps_charge() function. 121*c97ad5cdSakolb * 122*c97ad5cdSakolb * CPUCAPS_CHARGE_ENFORCE - charge a thread for its CPU time and 123*c97ad5cdSakolb * flag it to be placed on wait queue. 124*c97ad5cdSakolb * 125*c97ad5cdSakolb * CPUCAPS_CHARGE_ONLY - charge a thread for its CPU time. 126*c97ad5cdSakolb */ 127*c97ad5cdSakolb typedef enum { 128*c97ad5cdSakolb CPUCAPS_CHARGE_ENFORCE, 129*c97ad5cdSakolb CPUCAPS_CHARGE_ONLY 130*c97ad5cdSakolb } cpucaps_charge_t; 131*c97ad5cdSakolb 132*c97ad5cdSakolb /* 133*c97ad5cdSakolb * Add accumulated CPU usage of a thread to its cap. 134*c97ad5cdSakolb * Return True if thread should be placed on waitq. 135*c97ad5cdSakolb */ 136*c97ad5cdSakolb extern boolean_t cpucaps_charge(kthread_t *, caps_sc_t *, cpucaps_charge_t); 137*c97ad5cdSakolb #define CPUCAPS_CHARGE(t, scp, flag) \ 138*c97ad5cdSakolb (CPUCAPS_ON() && cpucaps_charge(t, scp, flag)) 139*c97ad5cdSakolb 140*c97ad5cdSakolb /* 141*c97ad5cdSakolb * Request a thread to be placed on a wait queue because the cap is exceeded 142*c97ad5cdSakolb */ 143*c97ad5cdSakolb extern boolean_t cpucaps_enforce(kthread_t *); 144*c97ad5cdSakolb #define CPUCAPS_ENFORCE(t) (CPUCAPS_ON() && cpucaps_enforce(t)) 145*c97ad5cdSakolb 146*c97ad5cdSakolb /* 147*c97ad5cdSakolb * CPU Caps hook into clock(). 148*c97ad5cdSakolb */ 149*c97ad5cdSakolb extern void (*cpucaps_clock_callout)(void); 150*c97ad5cdSakolb 151*c97ad5cdSakolb #endif /* _KERNEL */ 152*c97ad5cdSakolb 153*c97ad5cdSakolb #ifdef __cplusplus 154*c97ad5cdSakolb } 155*c97ad5cdSakolb #endif 156*c97ad5cdSakolb 157*c97ad5cdSakolb #endif /* _SYS_CPUCAPS_H */ 158