/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_CPUCAPS_H
#define _SYS_CPUCAPS_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <sys/zone.h>
#include <sys/project.h>
#include <sys/time.h>
#include <sys/rctl.h>
/*
* CPU caps provide an absolute hard CPU usage limit which is enforced even if
* some CPUs are idle. It can be enforced at project or zone level.
*/
#ifdef _KERNEL
/*
* Valid caps values go from 1 to MAXCAP - 1. Specifying the MAXCAP as the cap
* value is equivalent to disabling the cap.
*/
#define MAXCAP UINT_MAX
/*
* cpucaps_enabled is used to quickly check whether any CPU caps specific code
* should be invoked. Users outside CPU Caps framework should use CPUCAPS_ON()
* and CPUCAPS_OFF() macros.
*/
extern boolean_t cpucaps_enabled;
#define CPUCAPS_ON() cpucaps_enabled
#define CPUCAPS_OFF() (!cpucaps_enabled)
/*
* Initialize the CPU caps framework.
*/
extern void cpucaps_init(void);
/*
* Notify caps framework of a new project coming in or existing project
* going away
*/
extern void cpucaps_project_add(kproject_t *);
extern void cpucaps_project_remove(kproject_t *);
/*
* Notify caps framework when a zone is going away.
*/
extern void cpucaps_zone_remove(zone_t *);
/*
* Set project/zone cap to specified value. Value of MAXCAP should disable caps.
*/
extern int cpucaps_project_set(kproject_t *, rctl_qty_t);
extern int cpucaps_zone_set(zone_t *, rctl_qty_t);
/*
* Get current CPU usage for a project/zone.
*/
extern rctl_qty_t cpucaps_project_get(kproject_t *);
extern rctl_qty_t cpucaps_zone_get(zone_t *);
/*
* Scheduling class hooks into CPU caps framework.
*/
/*
* CPU caps specific data for each scheduling class.
*
* There is a small amount of accounting data that should be kept by each
* scheduling class for each thread which is only used by CPU caps code. This
* data is kept in the caps_sc structure which is transparent for all scheduling
* classes. The fields in the structure are:
*
* csc_cputime - Total time spent on CPU during thread lifetime, obtained
* as the sum of user, system and trap time, reported by
* microstate accounting.
*/
typedef struct caps_sc {
hrtime_t csc_cputime;
} caps_sc_t;
/*
* Initialize per-thread cpu-caps specific data.
*/
extern void cpucaps_sc_init(caps_sc_t *);
/*
* Modus operandi for cpucaps_charge() function.
*
* CPUCAPS_CHARGE_ENFORCE - charge a thread for its CPU time and
* flag it to be placed on wait queue.
*
* CPUCAPS_CHARGE_ONLY - charge a thread for its CPU time.
*/
typedef enum {
CPUCAPS_CHARGE_ENFORCE,
CPUCAPS_CHARGE_ONLY
} cpucaps_charge_t;
/*
* Add accumulated CPU usage of a thread to its cap.
* Return True if thread should be placed on waitq.
*/
extern boolean_t cpucaps_charge(kthread_t *, caps_sc_t *, cpucaps_charge_t);
#define CPUCAPS_CHARGE(t, scp, flag) \
(CPUCAPS_ON() && cpucaps_charge(t, scp, flag))
/*
* Request a thread to be placed on a wait queue because the cap is exceeded
*/
extern boolean_t cpucaps_enforce(kthread_t *);
#define CPUCAPS_ENFORCE(t) (CPUCAPS_ON() && cpucaps_enforce(t))
/*
* CPU Caps hook into clock().
*/
extern void (*cpucaps_clock_callout)(void);
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_CPUCAPS_H */