summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/sys')
-rw-r--r--usr/src/uts/common/sys/Makefile1
-rw-r--r--usr/src/uts/common/sys/callb.h12
-rw-r--r--usr/src/uts/common/sys/cmt.h62
-rw-r--r--usr/src/uts/common/sys/cpu_pm.h139
-rw-r--r--usr/src/uts/common/sys/cpudrv.h62
-rw-r--r--usr/src/uts/common/sys/cpupm.h43
-rw-r--r--usr/src/uts/common/sys/cpuvar.h2
-rw-r--r--usr/src/uts/common/sys/epm.h29
-rw-r--r--usr/src/uts/common/sys/group.h16
-rw-r--r--usr/src/uts/common/sys/pg.h46
-rw-r--r--usr/src/uts/common/sys/pghw.h39
-rw-r--r--usr/src/uts/common/sys/pm.h11
12 files changed, 383 insertions, 79 deletions
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile
index bc7ebb334d..9cd4ae55b4 100644
--- a/usr/src/uts/common/sys/Makefile
+++ b/usr/src/uts/common/sys/Makefile
@@ -139,6 +139,7 @@ CHKHDRS= \
cpr.h \
cpupart.h \
cpuvar.h \
+ cpu_pm.h \
crc32.h \
cred.h \
cred_impl.h \
diff --git a/usr/src/uts/common/sys/callb.h b/usr/src/uts/common/sys/callb.h
index b548f4ca23..302f314b80 100644
--- a/usr/src/uts/common/sys/callb.h
+++ b/usr/src/uts/common/sys/callb.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_CALLB_H
#define _SYS_CALLB_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/t_lock.h>
#include <sys/thread.h>
@@ -69,7 +66,8 @@ extern "C" {
#define CB_CL_MDBOOT CB_CL_UADMIN
#define CB_CL_ENTER_DEBUGGER 14
#define CB_CL_CPR_POST_KERNEL 15
-#define NCBCLASS 16 /* CHANGE ME if classes are added/removed */
+#define CB_CL_CPU_DEEP_IDLE 16
+#define NCBCLASS 17 /* CHANGE ME if classes are added/removed */
/*
* CB_CL_CPR_DAEMON class specific definitions are given below:
diff --git a/usr/src/uts/common/sys/cmt.h b/usr/src/uts/common/sys/cmt.h
index f1a95dc8c3..3ea49ded99 100644
--- a/usr/src/uts/common/sys/cmt.h
+++ b/usr/src/uts/common/sys/cmt.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,9 +37,20 @@ extern "C" {
#if (defined(_KERNEL) || defined(_KMEMUSER))
#include <sys/group.h>
#include <sys/pghw.h>
+#include <sys/lgrp.h>
#include <sys/types.h>
/*
+ * CMT related dispatcher policies
+ */
+#define CMT_NO_POLICY 0x0
+#define CMT_BALANCE 0x1
+#define CMT_COALESCE 0x2
+#define CMT_AFFINITY 0x4
+
+typedef uint_t pg_cmt_policy_t;
+
+/*
* CMT pg structure
*/
typedef struct pg_cmt {
@@ -47,26 +58,67 @@ typedef struct pg_cmt {
struct group *cmt_siblings; /* CMT PGs to balance with */
struct pg_cmt *cmt_parent; /* Parent CMT PG */
struct group *cmt_children; /* Active children CMT PGs */
+ pg_cmt_policy_t cmt_policy; /* Dispatcher policies to use */
+ uint32_t cmt_utilization; /* Group's utilization */
int cmt_nchildren; /* # of children CMT PGs */
- uint32_t cmt_nrunning; /* # of running threads */
+ int cmt_hint; /* hint for balancing */
struct group cmt_cpus_actv;
struct bitset cmt_cpus_actv_set; /* bitset of active CPUs */
} pg_cmt_t;
/*
+ * CMT lgroup structure
+ */
+typedef struct cmt_lgrp {
+ group_t cl_pgs; /* Top level group of active CMT PGs */
+ int cl_npgs; /* # of top level PGs in the lgroup */
+ lgrp_handle_t cl_hand; /* lgroup's platform handle */
+ struct cmt_lgrp *cl_next; /* next cmt_lgrp */
+} cmt_lgrp_t;
+
+/*
* Change the number of running threads on the pg
*/
-#define PG_NRUN_UPDATE(cp, n) (pg_cmt_load((cp), (n)))
+#define PG_NRUN_UPDATE(cp, n) (pg_cmt_load((cp), (n)))
+
+/*
+ * Indicate that the given logical CPU is (or isn't) currently utilized
+ */
+#define CMT_CPU_UTILIZED(cp) (pg_cmt_load((cp), 1))
+#define CMT_CPU_NOT_UTILIZED(cp) (pg_cmt_load((cp), -1))
+
+/*
+ * CMT PG's capacity
+ *
+ * Currently, this is defined to be the number of active
+ * logical CPUs in the group.
+ *
+ * This will be used in conjunction with the utilization, which is defined
+ * to be the number of threads actively running on CPUs in the group.
+ */
+#define CMT_CAPACITY(pg) (GROUP_SIZE(&((pg_cmt_t *)pg)->cmt_cpus_actv))
void pg_cmt_load(cpu_t *, int);
void pg_cmt_cpu_startup(cpu_t *);
int pg_cmt_can_migrate(cpu_t *, cpu_t *);
-int pg_plat_cmt_load_bal_hw(pghw_type_t);
-int pg_plat_cmt_affinity_hw(pghw_type_t);
+/*
+ * CMT platform interfaces
+ */
+pg_cmt_policy_t pg_plat_cmt_policy(pghw_type_t);
+int pg_plat_cmt_rank(pg_cmt_t *, pg_cmt_t *);
+/*
+ * CMT dispatcher policy
+ */
cpu_t *cmt_balance(kthread_t *, cpu_t *);
+/*
+ * Power Aware Dispatcher Interfaces
+ */
+int cmt_pad_enable(pghw_type_t);
+int cmt_pad_disable(pghw_type_t);
+
#endif /* !_KERNEL && !_KMEMUSER */
#ifdef __cplusplus
diff --git a/usr/src/uts/common/sys/cpu_pm.h b/usr/src/uts/common/sys/cpu_pm.h
new file mode 100644
index 0000000000..3ec3bcd68d
--- /dev/null
+++ b/usr/src/uts/common/sys/cpu_pm.h
@@ -0,0 +1,139 @@
+/*
+ * 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 _CPU_PM_H
+#define _CPU_PM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(_KERNEL) || defined(_KMEMUSER))
+#include <sys/cpuvar.h>
+#include <sys/processor.h>
+#include <sys/types.h>
+#include <sys/kstat.h>
+#include <sys/cmt.h>
+
+/*
+ * CPU Power Manager Policies
+ */
+typedef enum cpupm_policy {
+ CPUPM_POLICY_ELASTIC,
+ CPUPM_POLICY_DISABLED,
+ CPUPM_NUM_POLICIES
+} cpupm_policy_t;
+
+/*
+ * Power Managable CPU Domain Types
+ */
+typedef enum cpupm_dtype {
+ CPUPM_DTYPE_ACTIVE, /* Active Power Domain */
+ CPUPM_DTYPE_IDLE /* Idle Power Domain */
+} cpupm_dtype_t;
+
+/*
+ * CPUPM state names for policy implementation.
+ * The last element is used to size the enumeration.
+ */
+typedef enum cpupm_state_name {
+ CPUPM_STATE_LOW_POWER,
+ CPUPM_STATE_MAX_PERF,
+ CPUPM_STATE_NAMES
+} cpupm_state_name_t;
+
+/*
+ * Utilization events delivered by the dispatcher.
+ */
+typedef enum cpupm_util_event {
+ CPUPM_DOM_BUSY_FROM_IDLE,
+ CPUPM_DOM_IDLE_FROM_BUSY,
+ CPUPM_DOM_REMAIN_BUSY
+} cpupm_util_event_t;
+
+typedef uintptr_t cpupm_handle_t; /* Platform handle */
+
+/*
+ * CPU Power Domain State
+ */
+typedef struct cpupm_state {
+ uint32_t cps_speed;
+ cpupm_handle_t cps_handle;
+} cpupm_state_t;
+
+/*
+ * CPU Power Domain
+ */
+typedef struct cpupm_domain {
+ id_t cpd_id; /* Domain ID */
+ cpupm_dtype_t cpd_type; /* Active or Idle */
+ cpupm_state_t *cpd_states; /* Available Power States */
+ cpupm_state_t *cpd_state; /* Current State */
+ uint_t cpd_nstates; /* Number of States */
+ cpupm_state_t *cpd_named_states[CPUPM_STATE_NAMES];
+ hrtime_t cpd_last_raise; /* Last raise request time */
+ hrtime_t cpd_last_lower; /* last lower request time */
+ int cpd_tw; /* transient work history */
+ int cpd_ti; /* transient idle history */
+ boolean_t cpd_ti_governed; /* transient idle governor */
+ boolean_t cpd_tw_governed; /* transient work governor */
+ struct cpupm_domain *cpd_next;
+} cpupm_domain_t;
+
+#define CPUPM_NO_DOMAIN ((id_t)-1)
+
+/*
+ * CPU power manager domain management interfaces
+ */
+cpupm_domain_t *cpupm_domain_init(struct cpu *, cpupm_dtype_t);
+id_t cpupm_domain_id(struct cpu *, cpupm_dtype_t);
+int cpupm_change_state(struct cpu *, cpupm_domain_t *,
+ cpupm_state_t *);
+extern void cpupm_redefine_max_activepwr_state(struct cpu *, int);
+
+/*
+ * CPU power manager policy engine interfaces
+ */
+int cpupm_set_policy(cpupm_policy_t);
+cpupm_policy_t cpupm_get_policy(void);
+void cpupm_utilization_event(struct cpu *, hrtime_t,
+ cpupm_domain_t *, cpupm_util_event_t);
+
+/*
+ * CPU power platform driver interfaces
+ */
+id_t cpupm_plat_domain_id(struct cpu *, cpupm_dtype_t);
+uint_t cpupm_plat_state_enumerate(struct cpu *, cpupm_dtype_t,
+ cpupm_state_t *);
+int cpupm_plat_change_state(struct cpu *, cpupm_state_t *);
+
+
+#endif /* !_KERNEL && !_KMEMUSER */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CPU_PM_H */
diff --git a/usr/src/uts/common/sys/cpudrv.h b/usr/src/uts/common/sys/cpudrv.h
index 782d8f509c..4cf4e4d1b6 100644
--- a/usr/src/uts/common/sys/cpudrv.h
+++ b/usr/src/uts/common/sys/cpudrv.h
@@ -76,10 +76,10 @@ typedef struct cpudrv_pm {
cpudrv_pm_spd_t *cur_spd; /* ptr to current speed */
uint_t num_spd; /* number of speeds */
hrtime_t lastquan_mstate[NCMSTATES]; /* last quantum's mstate */
- clock_t lastquan_ticks; /* last quantum's clock tick */
+ clock_t lastquan_ticks; /* last quantum's clock tick */
int pm_busycnt; /* pm_busy_component() count */
taskq_t *tq; /* taskq handler for CPU monitor */
- timeout_id_t timeout_id; /* cpudrv_pm_monitor()'s timeout_id */
+ timeout_id_t timeout_id; /* cpudrv_monitor()'s timeout_id */
int timeout_count; /* count dispatched timeouts */
kmutex_t timeout_lock; /* protect timeout_count */
kcondvar_t timeout_cv; /* wait on timeout_count change */
@@ -94,31 +94,31 @@ typedef struct cpudrv_pm {
* Idle & user threads water marks in percentage
*/
#if defined(__x86)
-#define CPUDRV_PM_IDLE_HWM 85 /* idle high water mark */
-#define CPUDRV_PM_IDLE_LWM 70 /* idle low water mark */
-#define CPUDRV_PM_IDLE_BLWM_CNT_MAX 1 /* # of iters idle can be < lwm */
-#define CPUDRV_PM_IDLE_BHWM_CNT_MAX 1 /* # of iters idle can be < hwm */
+#define CPUDRV_IDLE_HWM 85 /* idle high water mark */
+#define CPUDRV_IDLE_LWM 70 /* idle low water mark */
+#define CPUDRV_IDLE_BLWM_CNT_MAX 1 /* # of iters idle can be < lwm */
+#define CPUDRV_IDLE_BHWM_CNT_MAX 1 /* # of iters idle can be < hwm */
#else
-#define CPUDRV_PM_IDLE_HWM 98 /* idle high water mark */
-#define CPUDRV_PM_IDLE_LWM 8 /* idle low water mark */
-#define CPUDRV_PM_IDLE_BLWM_CNT_MAX 2 /* # of iters idle can be < lwm */
-#define CPUDRV_PM_IDLE_BHWM_CNT_MAX 2 /* # of iters idle can be < hwm */
+#define CPUDRV_IDLE_HWM 98 /* idle high water mark */
+#define CPUDRV_IDLE_LWM 8 /* idle low water mark */
+#define CPUDRV_IDLE_BLWM_CNT_MAX 2 /* # of iters idle can be < lwm */
+#define CPUDRV_IDLE_BHWM_CNT_MAX 2 /* # of iters idle can be < hwm */
#endif
-#define CPUDRV_PM_USER_HWM 20 /* user high water mark */
-#define CPUDRV_PM_IDLE_BUF_ZONE 4 /* buffer zone when going down */
+#define CPUDRV_USER_HWM 20 /* user high water mark */
+#define CPUDRV_IDLE_BUF_ZONE 4 /* buffer zone when going down */
/*
* Maximums for creating 'pm-components' property
*/
-#define CPUDRV_PM_COMP_MAX_DIG 4 /* max digits in power level */
+#define CPUDRV_COMP_MAX_DIG 4 /* max digits in power level */
/* or divisor */
-#define CPUDRV_PM_COMP_MAX_VAL 9999 /* max value in above digits */
+#define CPUDRV_COMP_MAX_VAL 9999 /* max value in above digits */
/*
* Component number for calls to PM framework
*/
-#define CPUDRV_PM_COMP_NUM 0 /* first component is 0 */
+#define CPUDRV_COMP_NUM 0 /* first component is 0 */
/*
* Quantum counts for normal and other clock speeds in terms of ticks.
@@ -132,26 +132,26 @@ typedef struct cpudrv_pm {
* that we monitor less frequently.
*
* We reach a tradeoff between these two requirements by monitoring
- * more frequently when we are in low speed mode (CPUDRV_PM_QUANT_CNT_OTHR)
+ * more frequently when we are in low speed mode (CPUDRV_QUANT_CNT_OTHR)
* so we can bring the CPU up without user noticing it. Moreover, at low
* speed we are not using CPU much so extra code execution should be fine.
* Since we are in no hurry to bring CPU down and at normal speed and we
* might really be using the CPU fully, we monitor less frequently
- * (CPUDRV_PM_QUANT_CNT_NORMAL).
+ * (CPUDRV_QUANT_CNT_NORMAL).
*/
#if defined(__x86)
-#define CPUDRV_PM_QUANT_CNT_NORMAL (hz * 1) /* 1 sec */
+#define CPUDRV_QUANT_CNT_NORMAL (hz * 1) /* 1 sec */
#else
-#define CPUDRV_PM_QUANT_CNT_NORMAL (hz * 5) /* 5 sec */
+#define CPUDRV_QUANT_CNT_NORMAL (hz * 5) /* 5 sec */
#endif
-#define CPUDRV_PM_QUANT_CNT_OTHR (hz * 1) /* 1 sec */
+#define CPUDRV_QUANT_CNT_OTHR (hz * 1) /* 1 sec */
/*
* Taskq parameters
*/
-#define CPUDRV_PM_TASKQ_THREADS 1 /* # threads to run CPU monitor */
-#define CPUDRV_PM_TASKQ_MIN 2 /* min # of taskq entries */
-#define CPUDRV_PM_TASKQ_MAX 2 /* max # of taskq entries */
+#define CPUDRV_TASKQ_THREADS 1 /* # threads to run CPU monitor */
+#define CPUDRV_TASKQ_MIN 2 /* min # of taskq entries */
+#define CPUDRV_TASKQ_MAX 2 /* max # of taskq entries */
/*
@@ -159,13 +159,14 @@ typedef struct cpudrv_pm {
*/
typedef struct cpudrv_devstate {
dev_info_t *dip; /* devinfo handle */
+ cpu_t *cp; /* CPU data for this node */
processorid_t cpu_id; /* CPU number for this node */
cpudrv_pm_t cpudrv_pm; /* power management data */
kmutex_t lock; /* protects state struct */
- void *mach_state; /* machine specific state */
} cpudrv_devstate_t;
extern void *cpudrv_state;
+extern boolean_t cpudrv_enabled;
/*
* Debugging definitions
@@ -191,12 +192,13 @@ extern uint_t cpudrv_debug;
#define DPRINTF(flag, args)
#endif /* DEBUG */
-extern int cpudrv_pm_change_speed(cpudrv_devstate_t *, cpudrv_pm_spd_t *);
-extern boolean_t cpudrv_pm_get_cpu_id(dev_info_t *, processorid_t *);
-extern boolean_t cpudrv_pm_power_ready(void);
-extern boolean_t cpudrv_pm_is_governor_thread(cpudrv_pm_t *);
-extern boolean_t cpudrv_mach_pm_init(cpudrv_devstate_t *);
-extern void cpudrv_mach_pm_free(cpudrv_devstate_t *);
+extern int cpudrv_change_speed(cpudrv_devstate_t *, cpudrv_pm_spd_t *);
+extern boolean_t cpudrv_get_cpu_id(dev_info_t *, processorid_t *);
+extern boolean_t cpudrv_is_governor_thread(cpudrv_pm_t *);
+extern boolean_t cpudrv_mach_init(cpudrv_devstate_t *);
+extern boolean_t cpudrv_power_ready(void);
+extern boolean_t cpudrv_is_enabled(cpudrv_devstate_t *);
+extern void cpudrv_set_supp_freqs(cpudrv_devstate_t *);
#endif /* _KERNEL */
diff --git a/usr/src/uts/common/sys/cpupm.h b/usr/src/uts/common/sys/cpupm.h
new file mode 100644
index 0000000000..2f74775450
--- /dev/null
+++ b/usr/src/uts/common/sys/cpupm.h
@@ -0,0 +1,43 @@
+/*
+ * 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 _CPUPM_H
+#define _CPUPM_H
+
+#include <sys/types.h>
+#include <sys/cpuvar.h>
+#include <sys/cpupm_mach.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void cpupm_set_supp_freqs(cpu_t *, int *, uint_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CPUPM_H */
diff --git a/usr/src/uts/common/sys/cpuvar.h b/usr/src/uts/common/sys/cpuvar.h
index 2d056fa6ab..99829bbb03 100644
--- a/usr/src/uts/common/sys/cpuvar.h
+++ b/usr/src/uts/common/sys/cpuvar.h
@@ -366,7 +366,6 @@ extern cpu_core_t cpu_core[];
#define CPU_DISP_DONTSTEAL 0x01 /* CPU undergoing context swtch */
#define CPU_DISP_HALTED 0x02 /* CPU halted waiting for interrupt */
-
#endif /* _KERNEL || _KMEMUSER */
#if (defined(_KERNEL) || defined(_KMEMUSER)) && defined(_MACHDEP)
@@ -673,6 +672,7 @@ int cpu_get_state(cpu_t *); /* get current cpu state */
const char *cpu_get_state_str(cpu_t *); /* get current cpu state as string */
+void cpu_set_curr_clock(uint64_t); /* indicate the current CPU's freq */
void cpu_set_supp_freqs(cpu_t *, const char *); /* set the CPU supported */
/* frequencies */
diff --git a/usr/src/uts/common/sys/epm.h b/usr/src/uts/common/sys/epm.h
index 222fd59675..476b254d1a 100644
--- a/usr/src/uts/common/sys/epm.h
+++ b/usr/src/uts/common/sys/epm.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -227,7 +227,8 @@ typedef enum pm_canblock
typedef enum pm_cpupm
{
PM_CPUPM_NOTSET, /* no specific treatment of CPU devices */
- PM_CPUPM_ENABLE, /* power manage CPU devices */
+ PM_CPUPM_POLLING, /* CPUPM enabled: polling mode */
+ PM_CPUPM_EVENT, /* CPUPM enabled: event driven mode */
PM_CPUPM_DISABLE /* do not power manage CPU devices */
} pm_cpupm_t;
@@ -609,9 +610,19 @@ typedef struct pm_thresh_rec {
#define PM_ISCPU(dip) (DEVI(dip)->devi_pm_flags & PMC_CPU_DEVICE)
/*
- * Returns true if cpupm is enabled.
+ * Returns true if cpupm is enabled in event driven mode.
*/
-#define PM_CPUPM_ENABLED (cpupm == PM_CPUPM_ENABLE)
+#define PM_EVENT_CPUPM (cpupm == PM_CPUPM_EVENT)
+
+/*
+ * Returns true if cpupm is enabled in polling mode.
+ */
+#define PM_POLLING_CPUPM (cpupm == PM_CPUPM_POLLING)
+
+/*
+ * Returns true if cpupm operating using the default mode.
+ */
+#define PM_DEFAULT_CPUPM (cpupm == cpupm_default_mode)
/*
* Returns true if is disabled.
@@ -619,12 +630,14 @@ typedef struct pm_thresh_rec {
#define PM_CPUPM_DISABLED (cpupm == PM_CPUPM_DISABLE)
/*
- * If (autopm is enabled and
- * (CPUs are not disabled, or it isn't a cpu)) OR
- * (CPUs are enabled and it is one)
+ * If ((autopm is enabled and
+ * (CPUPM is not disabled and we're not in event mode, or it isn't a cpu))
+ * OR
+ * (CPUPM are enabled and it is one))
*/
#define PM_SCANABLE(dip) ((autopm_enabled && \
-(!PM_CPUPM_DISABLED || !PM_ISCPU(dip))) || (PM_CPUPM_ENABLED && PM_ISCPU(dip)))
+ ((!PM_CPUPM_DISABLED && !PM_EVENT_CPUPM) || !PM_ISCPU(dip))) || \
+ (PM_POLLING_CPUPM && PM_ISCPU(dip)))
#define PM_NOT_ALL_LOWEST 0x0 /* not all components are at lowest */
#define PM_ALL_LOWEST 0x1 /* all components are at lowest lvl */
diff --git a/usr/src/uts/common/sys/group.h b/usr/src/uts/common/sys/group.h
index 89a5ca1f1a..bb5613bc35 100644
--- a/usr/src/uts/common/sys/group.h
+++ b/usr/src/uts/common/sys/group.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _GROUP_H
#define _GROUP_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Group Abstraction
*/
@@ -79,13 +77,14 @@ void group_expand(group_t *, uint_t);
* Group element iteration
*/
void group_iter_init(group_iter_t *);
-void *group_iterate(group_t *, uint_t *);
+void *group_iterate(group_t *, group_iter_t *);
/*
- * Add / remove an element from the group
+ * Add / remove an element (or elements) from the group
*/
int group_add(group_t *, void *, int);
int group_remove(group_t *, void *, int);
+void group_empty(group_t *);
/*
* Add / remove / access an element at a specified index.
@@ -95,6 +94,13 @@ int group_remove(group_t *, void *, int);
int group_add_at(group_t *, void *, uint_t);
void group_remove_at(group_t *, uint_t);
+/*
+ * Search for an element in a group.
+ * Returns an index that may be used with the *_at()
+ * routines above to add or remove the element.
+ */
+uint_t group_find(group_t *, void *);
+
#endif /* !_KERNEL && !_KMEMUSER */
#ifdef __cplusplus
diff --git a/usr/src/uts/common/sys/pg.h b/usr/src/uts/common/sys/pg.h
index 99c51ca09a..4ab31ffdd2 100644
--- a/usr/src/uts/common/sys/pg.h
+++ b/usr/src/uts/common/sys/pg.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _PG_H
#define _PG_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Processor Groups
*/
@@ -48,6 +46,8 @@ extern "C" {
typedef uint_t pgid_t; /* processor group id */
typedef uint_t pg_cid_t; /* processor group class id */
+struct pg;
+
/*
* Nature of CPU relationships
*/
@@ -57,13 +57,26 @@ typedef enum pg_relation {
} pg_relation_t;
/*
+ * Processor Group callbacks ops vector
+ * These provide a mechanism allowing per PG routines to invoked
+ * in response to events.
+ */
+typedef struct pg_cb_ops {
+ void (*thread_swtch)(struct pg *, struct cpu *, hrtime_t,
+ kthread_t *, kthread_t *);
+ void (*thread_remain)(struct pg *, struct cpu *,
+ kthread_t *);
+} pg_cb_ops_t;
+
+/*
* Processor group structure
*/
typedef struct pg {
- pgid_t pg_id; /* seq id */
- pg_relation_t pg_relation; /* grouping relationship */
- struct pg_class *pg_class; /* pg class */
- struct group pg_cpus; /* group of CPUs */
+ pgid_t pg_id; /* seq id */
+ pg_relation_t pg_relation; /* grouping relationship */
+ struct pg_class *pg_class; /* pg class */
+ struct group pg_cpus; /* group of CPUs */
+ pg_cb_ops_t pg_cb; /* pg events ops vector */
} pg_t;
/*
@@ -81,6 +94,7 @@ struct pg_ops {
void (*cpupart_move)(struct cpu *, struct cpupart *,
struct cpupart *);
int (*cpu_belongs)(struct pg *, struct cpu *);
+ char *(*policy_name)(struct pg *);
};
#define PG_CLASS_NAME_MAX 32
@@ -130,6 +144,12 @@ typedef struct pg_cpu_itr {
GROUP_ACCESS(&((pg_t *)pgrp)->pg_cpus, 0) : NULL)
/*
+ * Return the number of CPUs in a PG
+ */
+#define PG_NUM_CPUS(pgrp) \
+ (GROUP_SIZE(&(pgrp)->pg_cpus))
+
+/*
* Framework routines
*/
void pg_init(void);
@@ -162,7 +182,19 @@ void pg_cpu_add(pg_t *, cpu_t *);
void pg_cpu_delete(pg_t *, cpu_t *);
pg_t *pg_cpu_find_pg(cpu_t *, group_t *);
cpu_t *pg_cpu_next(pg_cpu_itr_t *);
+boolean_t pg_cpu_find(pg_t *, cpu_t *);
+
+/*
+ * PG Event callbacks
+ */
+void pg_callback_set_defaults(pg_t *);
+void pg_ev_thread_swtch(cpu_t *, hrtime_t, kthread_t *, kthread_t *);
+void pg_ev_thread_remain(cpu_t *, kthread_t *);
+/*
+ * PG Observability interfaces
+ */
+char *pg_policy_name(pg_t *);
#endif /* !_KERNEL && !_KMEMUSER */
diff --git a/usr/src/uts/common/sys/pghw.h b/usr/src/uts/common/sys/pghw.h
index f22afc021b..0953bc19c9 100644
--- a/usr/src/uts/common/sys/pghw.h
+++ b/usr/src/uts/common/sys/pghw.h
@@ -19,16 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _PGHW_H
#define _PGHW_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -48,27 +45,47 @@ extern "C" {
*/
typedef enum pghw_type {
PGHW_START,
- PGHW_IPIPE,
- PGHW_CACHE,
- PGHW_FPU,
- PGHW_MPIPE,
- PGHW_CHIP,
+ PGHW_IPIPE, /* Instruction Pipeline */
+ PGHW_CACHE, /* Cache (generally last level) */
+ PGHW_FPU, /* Floating Point Unit / Pipeline */
+ PGHW_MPIPE, /* Pipe to Memory */
+ PGHW_CHIP, /* Socket */
PGHW_MEMORY,
+ PGHW_POW_ACTIVE, /* Active Power Management Domain */
+ PGHW_POW_IDLE, /* Idle Power Management Domain */
PGHW_NUM_COMPONENTS
} pghw_type_t;
/*
+ * Returns true if the hardware is a type of power management domain
+ */
+#define PGHW_IS_PM_DOMAIN(hw) \
+ (hw == PGHW_POW_ACTIVE || hw == PGHW_POW_IDLE)
+
+/*
* Anonymous instance id
*/
#define PGHW_INSTANCE_ANON ((id_t)0xdecafbad)
/*
+ * Max length of PGHW kstat strings
+ */
+#define PGHW_KSTAT_STR_LEN_MAX 32
+
+
+/*
+ * Platform specific handle
+ */
+typedef uintptr_t pghw_handle_t;
+
+/*
* Processor Group (physical sharing relationship)
*/
typedef struct pghw {
pg_t pghw_pg; /* processor group */
pghw_type_t pghw_hw; /* HW sharing relationship */
id_t pghw_instance; /* sharing instance identifier */
+ pghw_handle_t pghw_handle; /* hw specific opaque handle */
kstat_t *pghw_kstat; /* physical kstats exported */
} pghw_t;
@@ -102,16 +119,14 @@ pghw_t *pghw_find_pg(cpu_t *, pghw_type_t);
pghw_t *pghw_find_by_instance(id_t, pghw_type_t);
group_t *pghw_set_lookup(pghw_type_t);
-int pghw_level(pghw_type_t);
-
void pghw_kstat_create(pghw_t *);
int pghw_kstat_update(kstat_t *, int);
/* Hardware sharing relationship platform interfaces */
int pg_plat_hw_shared(cpu_t *, pghw_type_t);
int pg_plat_cpus_share(cpu_t *, cpu_t *, pghw_type_t);
-int pg_plat_hw_level(pghw_type_t);
id_t pg_plat_hw_instance_id(cpu_t *, pghw_type_t);
+pghw_type_t pg_plat_hw_rank(pghw_type_t, pghw_type_t);
/*
* What comprises a "core" may vary across processor implementations,
diff --git a/usr/src/uts/common/sys/pm.h b/usr/src/uts/common/sys/pm.h
index 8be171fef1..f98bb79fcb 100644
--- a/usr/src/uts/common/sys/pm.h
+++ b/usr/src/uts/common/sys/pm.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_PM_H
#define _SYS_PM_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -92,6 +90,8 @@ typedef enum {
PM_GET_DEFAULT_SYSTEM_THRESHOLD,
PM_ADD_DEPENDENT_PROPERTY,
PM_START_CPUPM,
+ PM_START_CPUPM_EV,
+ PM_START_CPUPM_POLL,
PM_STOP_CPUPM,
PM_GET_CPU_THRESHOLD,
PM_SET_CPU_THRESHOLD,
@@ -104,7 +104,10 @@ typedef enum {
PM_SEARCH_LIST, /* search S3 enable/disable list */
PM_GET_AUTOS3_STATE,
PM_GET_S3_SUPPORT_STATE,
- PM_GET_CMD_NAME
+ PM_GET_CMD_NAME,
+ PM_DISABLE_CPU_DEEP_IDLE,
+ PM_ENABLE_CPU_DEEP_IDLE,
+ PM_DEFAULT_CPU_DEEP_IDLE
} pm_cmds;
/*