2 * Copyright 2009, Intel Corporation
3 * Copyright 2009, Sun Microsystems, Inc
5 * This file is part of PowerTOP
7 * This program file is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * You should have received a copy of the GNU General Public License
17 * along with this program in a file named COPYING; if not, write to the
18 * Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
23 * Arjan van de Ven <arjan@linux.intel.com>
24 * Eric C Saxe <eric.saxe@sun.com>
25 * Aubrey Li <aubrey.li@intel.com>
31 * For the avoidance of doubt, except that if any license choice other
32 * than GPL or LGPL is available it will apply instead, Sun elects to
33 * use only the General Public License version 2 (GPLv2) at this time
34 * for any software where a choice of GPL license versions is made
35 * available with the language indicating that GPLv2 or any later
36 * version may be used, or where a choice of which version of the GPL
37 * is applied is otherwise unspecified.
48 * Global turbo related variables definitions
50 boolean_t g_turbo_supported
;
54 * The variables to store kstat snapshot
56 static turbo_info_t
*cpu_turbo_info
= NULL
;
57 static turbo_info_t
*t_new
= NULL
;
60 * Perform setup necessary to enumerate and track CPU turbo information
70 * check if the CPU turbo is supported
72 if ((kc
= kstat_open()) == NULL
) {
73 g_turbo_supported
= B_FALSE
;
77 ksp
= kstat_lookup(kc
, "turbo", 0, NULL
);
79 g_turbo_supported
= B_FALSE
;
80 (void) kstat_close(kc
);
84 (void) kstat_read(kc
, ksp
, NULL
);
86 knp
= kstat_data_lookup(ksp
, "turbo_supported");
88 pt_error("couldn't find 'turbo_supported' kstat\n");
89 g_turbo_supported
= B_FALSE
;
90 (void) kstat_close(kc
);
95 * Initialize turbo information structure if turbo mode is supported
97 if (knp
->value
.ui32
) {
98 g_turbo_supported
= B_TRUE
;
99 cpu_turbo_info
= calloc((size_t)g_ncpus
, sizeof (turbo_info_t
));
100 t_new
= calloc((size_t)g_ncpus
, sizeof (turbo_info_t
));
103 (void) kstat_close(kc
);
108 * Take a snapshot of each CPU's turbo information
109 * by looking through the turbo kstats.
112 pt_turbo_snapshot(turbo_info_t
*turbo_snapshot
)
118 turbo_info_t
*turbo_info
;
120 if ((kc
= kstat_open()) == NULL
)
123 for (cpu
= 0; cpu
< g_ncpus
; cpu
++) {
124 turbo_info
= &turbo_snapshot
[cpu
];
125 ksp
= kstat_lookup(kc
, "turbo", g_cpu_table
[cpu
], NULL
);
127 pt_error("couldn't find 'turbo' kstat for CPU %d\n",
129 (void) kstat_close(kc
);
133 if (kstat_read(kc
, ksp
, NULL
) == -1) {
134 pt_error("couldn't read 'turbo' kstat for CPU %d\n",
136 (void) kstat_close(kc
);
140 knp
= kstat_data_lookup(ksp
, "turbo_mcnt");
142 pt_error("couldn't find 'turbo_mcnt' kstat for CPU "
144 (void) kstat_close(kc
);
149 * snapshot IA32_MPERF_MSR
151 turbo_info
->t_mcnt
= knp
->value
.ui64
;
153 knp
= kstat_data_lookup(ksp
, "turbo_acnt");
155 pt_error("couldn't find 'turbo_acnt' kstat for CPU "
157 (void) kstat_close(kc
);
162 * snapshot IA32_APERF_MSR
164 turbo_info
->t_acnt
= knp
->value
.ui64
;
167 if (kstat_close(kc
) != 0)
168 pt_error("couldn't close 'turbo' kstat\n");
174 * Turbo support checking and information initialization
177 pt_turbo_stat_prepare(void)
181 if ((ret
= pt_turbo_init()) != 0)
184 if ((ret
= pt_turbo_snapshot(cpu_turbo_info
)) != 0)
185 pt_error("failed to snapshot 'turbo' kstat\n");
191 * When doing the statistics collection, we compare two kstat snapshot
192 * and get a delta. the final ratio of performance boost will be worked
193 * out according to the kstat delta
196 pt_turbo_stat_collect(void)
199 uint64_t delta_mcnt
, delta_acnt
;
204 * Take a snapshot of turbo information to setup turbo_info_t
207 if ((ret
= pt_turbo_snapshot(t_new
)) != 0) {
208 pt_error("failed to snapshot 'turbo' kstat\n");
213 * Calculate the kstat delta and work out the performance boost ratio
215 for (cpu
= 0; cpu
< g_ncpus
; cpu
++) {
216 delta_mcnt
= t_new
[cpu
].t_mcnt
- cpu_turbo_info
[cpu
].t_mcnt
;
217 delta_acnt
= t_new
[cpu
].t_acnt
- cpu_turbo_info
[cpu
].t_acnt
;
219 if ((delta_mcnt
> delta_acnt
) || (delta_mcnt
== 0))
222 ratio
= (double)delta_acnt
/ (double)delta_mcnt
;
223 g_turbo_ratio
+= ratio
;
226 g_turbo_ratio
= g_turbo_ratio
/ (double)g_ncpus
;
229 * Update the structure of the kstat for the next time calculation
231 (void) memcpy(cpu_turbo_info
, t_new
, g_ncpus
* (sizeof (turbo_info_t
)));