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/amd64/dtrace_subr.c 296990 2016-03-17 18:55:54Z markj $
22 * $FreeBSD: head/sys/cddl/dev/dtrace/amd64/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/*

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

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

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

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

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

--- 80 unchanged lines hidden ---