Deleted Added
full compact
dtrace_subr.c (296990) dtrace_subr.c (297770)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *

--- 5 unchanged lines hidden (view full) ---

14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 *
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *

--- 5 unchanged lines hidden (view full) ---

14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 *
22 * $FreeBSD: head/sys/cddl/dev/dtrace/i386/dtrace_subr.c 296990 2016-03-17 18:55:54Z markj $
22 * $FreeBSD: head/sys/cddl/dev/dtrace/i386/dtrace_subr.c 297770 2016-04-10 01:23:39Z markj $
23 *
24 */
25/*
26 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29
30/*

--- 212 unchanged lines hidden (view full) ---

243static int64_t tgt_cpu_tsc;
244static int64_t hst_cpu_tsc;
245static int64_t tsc_skew[MAXCPU];
246static uint64_t nsec_scale;
247
248/* See below for the explanation of this macro. */
249#define SCALE_SHIFT 28
250
23 *
24 */
25/*
26 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29
30/*

--- 212 unchanged lines hidden (view full) ---

243static int64_t tgt_cpu_tsc;
244static int64_t hst_cpu_tsc;
245static int64_t tsc_skew[MAXCPU];
246static uint64_t nsec_scale;
247
248/* See below for the explanation of this macro. */
249#define SCALE_SHIFT 28
250
251/*
252 * Get the frequency and scale factor as early as possible so that they can be
253 * used for boot-time tracing.
254 */
251static void
255static void
252dtrace_gethrtime_init_cpu(void *arg)
256dtrace_gethrtime_init_early(void *arg)
253{
257{
254 uintptr_t cpu = (uintptr_t) arg;
255
256 if (cpu == curcpu)
257 tgt_cpu_tsc = rdtsc();
258 else
259 hst_cpu_tsc = rdtsc();
260}
261
262static void
263dtrace_gethrtime_init(void *arg)
264{
265 cpuset_t map;
266 struct pcpu *pc;
267 uint64_t tsc_f;
258 uint64_t tsc_f;
268 int i;
269
270 /*
271 * Get TSC frequency known at this moment.
272 * This should be constant if TSC is invariant.
273 * Otherwise tick->time conversion will be inaccurate, but
274 * will preserve monotonic property of TSC.
275 */
276 tsc_f = atomic_load_acq_64(&tsc_freq);
277
278 /*
279 * The following line checks that nsec_scale calculated below
280 * doesn't overflow 32-bit unsigned integer, so that it can multiply
281 * another 32-bit integer without overflowing 64-bit.
282 * Thus minimum supported TSC frequency is 62.5MHz.
283 */
259
260 /*
261 * Get TSC frequency known at this moment.
262 * This should be constant if TSC is invariant.
263 * Otherwise tick->time conversion will be inaccurate, but
264 * will preserve monotonic property of TSC.
265 */
266 tsc_f = atomic_load_acq_64(&tsc_freq);
267
268 /*
269 * The following line checks that nsec_scale calculated below
270 * doesn't overflow 32-bit unsigned integer, so that it can multiply
271 * another 32-bit integer without overflowing 64-bit.
272 * Thus minimum supported TSC frequency is 62.5MHz.
273 */
284 KASSERT(tsc_f > (NANOSEC >> (32 - SCALE_SHIFT)), ("TSC frequency is too low"));
274 KASSERT(tsc_f > (NANOSEC >> (32 - SCALE_SHIFT)),
275 ("TSC frequency is too low"));
285
286 /*
287 * We scale up NANOSEC/tsc_f ratio to preserve as much precision
288 * as possible.
289 * 2^28 factor was chosen quite arbitrarily from practical
290 * considerations:
291 * - it supports TSC frequencies as low as 62.5MHz (see above);
292 * - it provides quite good precision (e < 0.01%) up to THz
293 * (terahertz) values;
294 */
295 nsec_scale = ((uint64_t)NANOSEC << SCALE_SHIFT) / tsc_f;
276
277 /*
278 * We scale up NANOSEC/tsc_f ratio to preserve as much precision
279 * as possible.
280 * 2^28 factor was chosen quite arbitrarily from practical
281 * considerations:
282 * - it supports TSC frequencies as low as 62.5MHz (see above);
283 * - it provides quite good precision (e < 0.01%) up to THz
284 * (terahertz) values;
285 */
286 nsec_scale = ((uint64_t)NANOSEC << SCALE_SHIFT) / tsc_f;
287}
288SYSINIT(dtrace_gethrtime_init_early, SI_SUB_CPU, SI_ORDER_ANY,
289 dtrace_gethrtime_init_early, NULL);
296
290
291static void
292dtrace_gethrtime_init_cpu(void *arg)
293{
294 uintptr_t cpu = (uintptr_t) arg;
295
296 if (cpu == curcpu)
297 tgt_cpu_tsc = rdtsc();
298 else
299 hst_cpu_tsc = rdtsc();
300}
301
302static void
303dtrace_gethrtime_init(void *arg)
304{
305 cpuset_t map;
306 struct pcpu *pc;
307 int i;
308
297 /* The current CPU is the reference one. */
298 sched_pin();
299 tsc_skew[curcpu] = 0;
300 CPU_FOREACH(i) {
301 if (i == curcpu)
302 continue;
303
304 pc = pcpu_find(i);
305 CPU_SETOF(PCPU_GET(cpuid), &map);
306 CPU_SET(pc->pc_cpuid, &map);
307
308 smp_rendezvous_cpus(map, NULL,
309 dtrace_gethrtime_init_cpu,
310 smp_no_rendevous_barrier, (void *)(uintptr_t) i);
311
312 tsc_skew[i] = tgt_cpu_tsc - hst_cpu_tsc;
313 }
314 sched_unpin();
315}
309 /* The current CPU is the reference one. */
310 sched_pin();
311 tsc_skew[curcpu] = 0;
312 CPU_FOREACH(i) {
313 if (i == curcpu)
314 continue;
315
316 pc = pcpu_find(i);
317 CPU_SETOF(PCPU_GET(cpuid), &map);
318 CPU_SET(pc->pc_cpuid, &map);
319
320 smp_rendezvous_cpus(map, NULL,
321 dtrace_gethrtime_init_cpu,
322 smp_no_rendevous_barrier, (void *)(uintptr_t) i);
323
324 tsc_skew[i] = tgt_cpu_tsc - hst_cpu_tsc;
325 }
326 sched_unpin();
327}
328SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init,
329 NULL);
316
330
317SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init, NULL);
318
319/*
320 * DTrace needs a high resolution time function which can
321 * be called from a probe context and guaranteed not to have
322 * instrumented with probes itself.
323 *
324 * Returns nanoseconds since boot.
325 */
326uint64_t

--- 80 unchanged lines hidden ---
331/*
332 * DTrace needs a high resolution time function which can
333 * be called from a probe context and guaranteed not to have
334 * instrumented with probes itself.
335 *
336 * Returns nanoseconds since boot.
337 */
338uint64_t

--- 80 unchanged lines hidden ---