| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: subr_cpufreq.c,v 1.5 2011/10/20 06:48:24 jruoho Exp $ */ | | 1 | /* $NetBSD: subr_cpufreq.c,v 1.6 2011/10/25 11:35:49 jruoho Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2011 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2011 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jukka Ruohonen. | | 8 | * by Jukka Ruohonen. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * | | 13 | * |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -20,27 +20,27 @@ | | | @@ -20,27 +20,27 @@ |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | * POSSIBILITY OF SUCH DAMAGE. | | 30 | * POSSIBILITY OF SUCH DAMAGE. |
31 | */ | | 31 | */ |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: subr_cpufreq.c,v 1.5 2011/10/20 06:48:24 jruoho Exp $"); | | 33 | __KERNEL_RCSID(0, "$NetBSD: subr_cpufreq.c,v 1.6 2011/10/25 11:35:49 jruoho Exp $"); |
34 | | | 34 | |
35 | #include <sys/param.h> | | 35 | #include <sys/param.h> |
36 | #include <sys/cpu.h> | | 36 | #include <sys/cpu.h> |
37 | #include <sys/cpufreq.h> | | 37 | #include <sys/cpufreq.h> |
38 | #include <sys/kmem.h> | | 38 | #include <sys/kmem.h> |
39 | #include <sys/mutex.h> | | 39 | #include <sys/mutex.h> |
40 | #include <sys/time.h> | | 40 | #include <sys/time.h> |
41 | #include <sys/xcall.h> | | 41 | #include <sys/xcall.h> |
42 | | | 42 | |
43 | static int cpufreq_latency(void); | | 43 | static int cpufreq_latency(void); |
44 | static uint32_t cpufreq_get_max(void); | | 44 | static uint32_t cpufreq_get_max(void); |
45 | static uint32_t cpufreq_get_min(void); | | 45 | static uint32_t cpufreq_get_min(void); |
46 | static uint32_t cpufreq_get_raw(struct cpu_info *); | | 46 | static uint32_t cpufreq_get_raw(struct cpu_info *); |
| @@ -146,68 +146,68 @@ cpufreq_register(struct cpufreq *cf) | | | @@ -146,68 +146,68 @@ cpufreq_register(struct cpufreq *cf) |
146 | void | | 146 | void |
147 | cpufreq_deregister(void) | | 147 | cpufreq_deregister(void) |
148 | { | | 148 | { |
149 | | | 149 | |
150 | mutex_enter(&cpufreq_lock); | | 150 | mutex_enter(&cpufreq_lock); |
151 | memset(cf_backend, 0, sizeof(*cf_backend)); | | 151 | memset(cf_backend, 0, sizeof(*cf_backend)); |
152 | mutex_exit(&cpufreq_lock); | | 152 | mutex_exit(&cpufreq_lock); |
153 | } | | 153 | } |
154 | | | 154 | |
155 | static int | | 155 | static int |
156 | cpufreq_latency(void) | | 156 | cpufreq_latency(void) |
157 | { | | 157 | { |
158 | struct cpufreq *cf = cf_backend; | | 158 | struct cpufreq *cf = cf_backend; |
159 | struct timespec nta, ntb; | | 159 | struct timeval nta, ntb; |
160 | const uint32_t n = 10; | | 160 | const uint32_t n = 10; |
161 | uint32_t i, j, l, m; | | 161 | uint32_t i, j, l, m; |
162 | uint64_t s; | | 162 | uint64_t s; |
163 | | | 163 | |
164 | l = cpufreq_get_min(); | | 164 | l = cpufreq_get_min(); |
165 | m = cpufreq_get_max(); | | 165 | m = cpufreq_get_max(); |
166 | | | 166 | |
167 | /* | | 167 | /* |
168 | * For each state, sample the average transition | | 168 | * For each state, sample the average transition |
169 | * latency required to set the state for all CPUs. | | 169 | * latency required to set the state for all CPUs. |
170 | */ | | 170 | */ |
171 | for (i = 0; i < cf->cf_state_count; i++) { | | 171 | for (i = 0; i < cf->cf_state_count; i++) { |
172 | | | 172 | |
173 | for (s = 0, j = 0; j < n; j++) { | | 173 | for (s = 0, j = 0; j < n; j++) { |
174 | | | 174 | |
175 | /* | | 175 | /* |
176 | * Attempt to exclude possible | | 176 | * Attempt to exclude possible |
177 | * caching done by the backend. | | 177 | * caching done by the backend. |
178 | */ | | 178 | */ |
179 | if (i == 0) | | 179 | if (i == 0) |
180 | cpufreq_set_all_raw(l); | | 180 | cpufreq_set_all_raw(l); |
181 | else { | | 181 | else { |
182 | cpufreq_set_all_raw(m); | | 182 | cpufreq_set_all_raw(m); |
183 | } | | 183 | } |
184 | | | 184 | |
185 | nta.tv_sec = nta.tv_nsec = 0; | | 185 | nta.tv_sec = nta.tv_usec = 0; |
186 | ntb.tv_sec = ntb.tv_nsec = 0; | | 186 | ntb.tv_sec = ntb.tv_usec = 0; |
187 | | | 187 | |
188 | nanotime(&nta); | | 188 | microtime(&nta); |
189 | cpufreq_set_all_raw(cf->cf_state[i].cfs_freq); | | 189 | cpufreq_set_all_raw(cf->cf_state[i].cfs_freq); |
190 | nanotime(&ntb); | | 190 | microtime(&ntb); |
191 | timespecsub(&ntb, &nta, &ntb); | | 191 | timersub(&ntb, &nta, &ntb); |
192 | | | 192 | |
193 | if (ntb.tv_sec != 0 || | | 193 | if (ntb.tv_sec != 0 || |
194 | ntb.tv_nsec > CPUFREQ_LATENCY_MAX) | | 194 | ntb.tv_usec > CPUFREQ_LATENCY_MAX) |
195 | continue; | | 195 | continue; |
196 | | | 196 | |
197 | if (s >= UINT64_MAX - CPUFREQ_LATENCY_MAX) | | 197 | if (s >= UINT64_MAX - CPUFREQ_LATENCY_MAX) |
198 | break; | | 198 | break; |
199 | | | 199 | |
200 | s += ntb.tv_nsec; | | 200 | s += ntb.tv_usec; |
201 | } | | 201 | } |
202 | | | 202 | |
203 | /* | | 203 | /* |
204 | * Consider the backend unsuitable if | | 204 | * Consider the backend unsuitable if |
205 | * the transition latency was too high. | | 205 | * the transition latency was too high. |
206 | */ | | 206 | */ |
207 | if (s == 0) | | 207 | if (s == 0) |
208 | return EMSGSIZE; | | 208 | return EMSGSIZE; |
209 | | | 209 | |
210 | cf->cf_state[i].cfs_latency = s / n; | | 210 | cf->cf_state[i].cfs_latency = s / n; |
211 | } | | 211 | } |
212 | | | 212 | |
213 | return 0; | | 213 | return 0; |