Thu Apr 23 20:38:33 2020 UTC ()
When computing TSC skew make 8 measurements and use the average.


(ad)
diff -r1.41 -r1.42 src/sys/arch/x86/x86/tsc.c

cvs diff -r1.41 -r1.42 src/sys/arch/x86/x86/tsc.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/tsc.c 2020/04/21 02:56:37 1.41
+++ src/sys/arch/x86/x86/tsc.c 2020/04/23 20:38:33 1.42
@@ -1,43 +1,43 @@ @@ -1,43 +1,43 @@
1/* $NetBSD: tsc.c,v 1.41 2020/04/21 02:56:37 msaitoh Exp $ */ 1/* $NetBSD: tsc.c,v 1.42 2020/04/23 20:38:33 ad Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.41 2020/04/21 02:56:37 msaitoh Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.42 2020/04/23 20:38:33 ad Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/systm.h> 33#include <sys/systm.h>
34#include <sys/time.h> 34#include <sys/time.h>
35#include <sys/timetc.h> 35#include <sys/timetc.h>
36#include <sys/lwp.h> 36#include <sys/lwp.h>
37#include <sys/atomic.h> 37#include <sys/atomic.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/cpu.h> 39#include <sys/cpu.h>
40#include <sys/xcall.h> 40#include <sys/xcall.h>
41 41
42#include <machine/cpu_counter.h> 42#include <machine/cpu_counter.h>
43#include <machine/cpuvar.h> 43#include <machine/cpuvar.h>
@@ -219,33 +219,37 @@ tsc_read_bp(struct cpu_info *ci, uint64_ @@ -219,33 +219,37 @@ tsc_read_bp(struct cpu_info *ci, uint64_
219 x86_pause(); 219 x86_pause();
220 } 220 }
221 if (tsc_sync_cpu != NULL) { 221 if (tsc_sync_cpu != NULL) {
222 panic("tsc_sync_bp: 2"); 222 panic("tsc_sync_bp: 2");
223 } 223 }
224 224
225 *bptscp = bptsc; 225 *bptscp = bptsc;
226 *aptscp = tsc_sync_val; 226 *aptscp = tsc_sync_val;
227} 227}
228 228
229void 229void
230tsc_sync_bp(struct cpu_info *ci) 230tsc_sync_bp(struct cpu_info *ci)
231{ 231{
232 uint64_t bptsc, aptsc; 232 int64_t bptsc, aptsc, bsum = 0, asum = 0;
233 233
234 tsc_read_bp(ci, &bptsc, &aptsc); /* discarded - cache effects */ 234 tsc_read_bp(ci, &bptsc, &aptsc); /* discarded - cache effects */
235 tsc_read_bp(ci, &bptsc, &aptsc); 235 for (int i = 0; i < 8; i++) {
 236 tsc_read_bp(ci, &bptsc, &aptsc);
 237 bsum += bptsc;
 238 asum += aptsc;
 239 }
236 240
237 /* Compute final value to adjust for skew. */ 241 /* Compute final value to adjust for skew. */
238 ci->ci_data.cpu_cc_skew = bptsc - aptsc; 242 ci->ci_data.cpu_cc_skew = (bsum - asum) >> 3;
239} 243}
240 244
241/* 245/*
242 * Called during startup of AP, by the AP itself. Interrupts are 246 * Called during startup of AP, by the AP itself. Interrupts are
243 * disabled on entry. 247 * disabled on entry.
244 */ 248 */
245static void 249static void
246tsc_post_ap(struct cpu_info *ci) 250tsc_post_ap(struct cpu_info *ci)
247{ 251{
248 uint64_t tsc; 252 uint64_t tsc;
249 253
250 /* Wait for go-ahead from primary. */ 254 /* Wait for go-ahead from primary. */
251 while ((ci->ci_flags & CPUF_SYNCTSC) == 0) { 255 while ((ci->ci_flags & CPUF_SYNCTSC) == 0) {
@@ -260,27 +264,29 @@ tsc_post_ap(struct cpu_info *ci) @@ -260,27 +264,29 @@ tsc_post_ap(struct cpu_info *ci)
260 /* Post result. Ensure the whole value goes out atomically. */ 264 /* Post result. Ensure the whole value goes out atomically. */
261 (void)atomic_swap_64(&tsc_sync_val, tsc); 265 (void)atomic_swap_64(&tsc_sync_val, tsc);
262 266
263 if (atomic_swap_ptr(&tsc_sync_cpu, NULL) != ci) { 267 if (atomic_swap_ptr(&tsc_sync_cpu, NULL) != ci) {
264 panic("tsc_sync_ap"); 268 panic("tsc_sync_ap");
265 } 269 }
266} 270}
267 271
268void 272void
269tsc_sync_ap(struct cpu_info *ci) 273tsc_sync_ap(struct cpu_info *ci)
270{ 274{
271 275
272 tsc_post_ap(ci); 276 tsc_post_ap(ci);
273 tsc_post_ap(ci); 277 for (int i = 0; i < 8; i++) {
 278 tsc_post_ap(ci);
 279 }
274} 280}
275 281
276static void 282static void
277tsc_apply_cpu(void *arg1, void *arg2) 283tsc_apply_cpu(void *arg1, void *arg2)
278{ 284{
279 bool enable = arg1 != NULL; 285 bool enable = arg1 != NULL;
280 if (enable) { 286 if (enable) {
281 lcr4(rcr4() & ~CR4_TSD); 287 lcr4(rcr4() & ~CR4_TSD);
282 } else { 288 } else {
283 lcr4(rcr4() | CR4_TSD); 289 lcr4(rcr4() | CR4_TSD);
284 } 290 }
285} 291}
286 292