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