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 --- |