svn commit: r282748 - in stable/10/sys: cddl/compat/opensolaris/sys cddl/contrib/opensolaris/uts/common/dtrace cddl/contrib/opensolaris/uts/common/sys cddl/dev/cyclic cddl/dev/fbt cddl/dev/profile ...
Andriy Gapon
avg at FreeBSD.org
Mon May 11 07:54:43 UTC 2015
Author: avg
Date: Mon May 11 07:54:39 2015
New Revision: 282748
URL: https://svnweb.freebsd.org/changeset/base/282748
Log:
MFC r275576: remove opensolaris cyclic code, replace with high-precision callouts
Deleted:
stable/10/sys/cddl/compat/opensolaris/sys/cyclic.h
stable/10/sys/cddl/compat/opensolaris/sys/cyclic_impl.h
stable/10/sys/cddl/dev/cyclic/
Modified:
stable/10/sys/cddl/compat/opensolaris/sys/cpuvar.h
stable/10/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
stable/10/sys/cddl/dev/fbt/fbt.c
stable/10/sys/cddl/dev/profile/profile.c
stable/10/sys/kern/kern_clocksource.c
stable/10/sys/modules/Makefile
stable/10/sys/modules/dtrace/Makefile.inc
stable/10/sys/modules/dtrace/dtraceall/dtraceall.c
stable/10/sys/sys/dtrace_bsd.h
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/cddl/compat/opensolaris/sys/cpuvar.h
==============================================================================
--- stable/10/sys/cddl/compat/opensolaris/sys/cpuvar.h Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/cddl/compat/opensolaris/sys/cpuvar.h Mon May 11 07:54:39 2015 (r282748)
@@ -38,11 +38,8 @@ struct cyc_cpu;
typedef struct {
int cpuid;
- struct cyc_cpu *cpu_cyclic;
uint32_t cpu_flags;
uint_t cpu_intr_actv;
- uintptr_t cpu_profile_pc;
- uintptr_t cpu_profile_upc;
uintptr_t cpu_dtrace_caller; /* DTrace: caller, if any */
hrtime_t cpu_dtrace_chillmark; /* DTrace: chill mark time */
hrtime_t cpu_dtrace_chilled; /* DTrace: total chill time */
Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Mon May 11 07:54:39 2015 (r282748)
@@ -17947,6 +17947,5 @@ SYSINIT(dtrace_anon_init, SI_SUB_DTRACE_
DEV_MODULE(dtrace, dtrace_modevent, NULL);
MODULE_VERSION(dtrace, 1);
-MODULE_DEPEND(dtrace, cyclic, 1, 1, 1);
MODULE_DEPEND(dtrace, opensolaris, 1, 1, 1);
#endif
Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Mon May 11 07:54:39 2015 (r282748)
@@ -57,6 +57,7 @@ extern "C" {
#if defined(sun)
#include <sys/systm.h>
#else
+#include <sys/cpuvar.h>
#include <sys/param.h>
#include <sys/linker.h>
#include <sys/ioccom.h>
@@ -64,8 +65,8 @@ extern "C" {
typedef int model_t;
#endif
#include <sys/ctf_api.h>
-#include <sys/cyclic.h>
#if defined(sun)
+#include <sys/cyclic.h>
#include <sys/int_limits.h>
#else
#include <sys/stdint.h>
Modified: stable/10/sys/cddl/dev/fbt/fbt.c
==============================================================================
--- stable/10/sys/cddl/dev/fbt/fbt.c Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/cddl/dev/fbt/fbt.c Mon May 11 07:54:39 2015 (r282748)
@@ -428,13 +428,6 @@ fbt_provide_module(void *arg, modctl_t *
return;
/*
- * The cyclic timer subsystem can be built as a module and DTrace
- * depends on that, so it is ineligible too.
- */
- if (strcmp(modname, "cyclic") == 0)
- return;
-
- /*
* To register with DTrace, a module must list 'dtrace' as a
* dependency in order for the kernel linker to resolve
* symbols like dtrace_register(). All modules with such a
Modified: stable/10/sys/cddl/dev/profile/profile.c
==============================================================================
--- stable/10/sys/cddl/dev/profile/profile.c Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/cddl/dev/profile/profile.c Mon May 11 07:54:39 2015 (r282748)
@@ -52,9 +52,9 @@
#include <sys/smp.h>
#include <sys/uio.h>
#include <sys/unistd.h>
+#include <machine/cpu.h>
#include <machine/stdarg.h>
-#include <sys/cyclic.h>
#include <sys/dtrace.h>
#include <sys/dtrace_bsd.h>
@@ -97,7 +97,7 @@
* allow for a manual override in case we get it completely wrong.
*/
#ifdef __amd64
-#define PROF_ARTIFICIAL_FRAMES 7
+#define PROF_ARTIFICIAL_FRAMES 10
#else
#ifdef __i386
#define PROF_ARTIFICIAL_FRAMES 6
@@ -126,18 +126,30 @@
#define PROF_ARTIFICIAL_FRAMES 3
#endif
+struct profile_probe_percpu;
+
typedef struct profile_probe {
char prof_name[PROF_NAMELEN];
dtrace_id_t prof_id;
int prof_kind;
+#ifdef illumos
hrtime_t prof_interval;
cyclic_id_t prof_cyclic;
+#else
+ sbintime_t prof_interval;
+ struct callout prof_cyclic;
+ sbintime_t prof_expected;
+ struct profile_probe_percpu **prof_pcpus;
+#endif
} profile_probe_t;
typedef struct profile_probe_percpu {
hrtime_t profc_expected;
hrtime_t profc_interval;
profile_probe_t *profc_probe;
+#ifdef __FreeBSD__
+ struct callout profc_cyclic;
+#endif
} profile_probe_percpu_t;
static d_open_t profile_open;
@@ -206,29 +218,92 @@ static dtrace_provider_id_t profile_id;
static hrtime_t profile_interval_min = NANOSEC / 5000; /* 5000 hz */
static int profile_aframes = 0; /* override */
+static sbintime_t
+nsec_to_sbt(hrtime_t nsec)
+{
+ time_t sec;
+
+ /*
+ * We need to calculate nsec * 2^32 / 10^9
+ * Seconds and nanoseconds are split to avoid overflow.
+ */
+ sec = nsec / NANOSEC;
+ nsec = nsec % NANOSEC;
+ return (((sbintime_t)sec << 32) | ((sbintime_t)nsec << 32) / NANOSEC);
+}
+
+static hrtime_t
+sbt_to_nsec(sbintime_t sbt)
+{
+
+ return ((sbt >> 32) * NANOSEC +
+ (((uint32_t)sbt * (hrtime_t)NANOSEC) >> 32));
+}
+
static void
profile_fire(void *arg)
{
profile_probe_percpu_t *pcpu = arg;
profile_probe_t *prof = pcpu->profc_probe;
hrtime_t late;
- solaris_cpu_t *c = &solaris_cpu[curcpu];
+ struct trapframe *frame;
+ uintfptr_t pc, upc;
+#ifdef illumos
late = gethrtime() - pcpu->profc_expected;
- pcpu->profc_expected += pcpu->profc_interval;
+#else
+ late = sbt_to_nsec(sbinuptime() - pcpu->profc_expected);
+#endif
- dtrace_probe(prof->prof_id, c->cpu_profile_pc,
- c->cpu_profile_upc, late, 0, 0);
+ pc = 0;
+ upc = 0;
+
+ /*
+ * td_intr_frame can be unset if this is a catch up event
+ * after waking up from idle sleep.
+ * This can only happen on a CPU idle thread.
+ */
+ frame = curthread->td_intr_frame;
+ if (frame != NULL) {
+ if (TRAPF_USERMODE(frame))
+ upc = TRAPF_PC(frame);
+ else
+ pc = TRAPF_PC(frame);
+ }
+ dtrace_probe(prof->prof_id, pc, upc, late, 0, 0);
+
+ pcpu->profc_expected += pcpu->profc_interval;
+ callout_schedule_sbt_curcpu(&pcpu->profc_cyclic,
+ pcpu->profc_expected, 0, C_DIRECT_EXEC | C_ABSOLUTE);
}
static void
profile_tick(void *arg)
{
profile_probe_t *prof = arg;
- solaris_cpu_t *c = &solaris_cpu[curcpu];
+ struct trapframe *frame;
+ uintfptr_t pc, upc;
+
+ pc = 0;
+ upc = 0;
+
+ /*
+ * td_intr_frame can be unset if this is a catch up event
+ * after waking up from idle sleep.
+ * This can only happen on a CPU idle thread.
+ */
+ frame = curthread->td_intr_frame;
+ if (frame != NULL) {
+ if (TRAPF_USERMODE(frame))
+ upc = TRAPF_PC(frame);
+ else
+ pc = TRAPF_PC(frame);
+ }
+ dtrace_probe(prof->prof_id, pc, upc, 0, 0, 0);
- dtrace_probe(prof->prof_id, c->cpu_profile_pc,
- c->cpu_profile_upc, 0, 0, 0);
+ prof->prof_expected += prof->prof_interval;
+ callout_schedule_sbt(&prof->prof_cyclic,
+ prof->prof_expected, 0, C_DIRECT_EXEC | C_ABSOLUTE);
}
static void
@@ -250,8 +325,13 @@ profile_create(hrtime_t interval, char *
prof = kmem_zalloc(sizeof (profile_probe_t), KM_SLEEP);
(void) strcpy(prof->prof_name, name);
+#ifdef illumos
prof->prof_interval = interval;
prof->prof_cyclic = CYCLIC_NONE;
+#else
+ prof->prof_interval = nsec_to_sbt(interval);
+ callout_init(&prof->prof_cyclic, CALLOUT_MPSAFE);
+#endif
prof->prof_kind = kind;
prof->prof_id = dtrace_probe_create(profile_id,
NULL, NULL, name,
@@ -396,13 +476,18 @@ profile_destroy(void *arg, dtrace_id_t i
{
profile_probe_t *prof = parg;
+#ifdef illumos
ASSERT(prof->prof_cyclic == CYCLIC_NONE);
+#else
+ ASSERT(!callout_active(&prof->prof_cyclic) && prof->prof_pcpus == NULL);
+#endif
kmem_free(prof, sizeof (profile_probe_t));
ASSERT(profile_total >= 1);
atomic_add_32(&profile_total, -1);
}
+#ifdef illumos
/*ARGSUSED*/
static void
profile_online(void *arg, cpu_t *cpu, cyc_handler_t *hdlr, cyc_time_t *when)
@@ -478,6 +563,81 @@ profile_disable(void *arg, dtrace_id_t i
prof->prof_cyclic = CYCLIC_NONE;
}
+#else
+
+static void
+profile_enable_omni(profile_probe_t *prof)
+{
+ profile_probe_percpu_t *pcpu;
+ int cpu;
+
+ prof->prof_pcpus = kmem_zalloc((mp_maxid + 1) * sizeof(pcpu), KM_SLEEP);
+ CPU_FOREACH(cpu) {
+ pcpu = kmem_zalloc(sizeof(profile_probe_percpu_t), KM_SLEEP);
+ prof->prof_pcpus[cpu] = pcpu;
+ pcpu->profc_probe = prof;
+ pcpu->profc_expected = sbinuptime() + prof->prof_interval;
+ pcpu->profc_interval = prof->prof_interval;
+ callout_init(&pcpu->profc_cyclic, CALLOUT_MPSAFE);
+ callout_reset_sbt_on(&pcpu->profc_cyclic,
+ pcpu->profc_expected, 0, profile_fire, pcpu,
+ cpu, C_DIRECT_EXEC | C_ABSOLUTE);
+ }
+}
+
+static void
+profile_disable_omni(profile_probe_t *prof)
+{
+ profile_probe_percpu_t *pcpu;
+ int cpu;
+
+ ASSERT(prof->prof_pcpus != NULL);
+ CPU_FOREACH(cpu) {
+ pcpu = prof->prof_pcpus[cpu];
+ ASSERT(pcpu->profc_probe == prof);
+ ASSERT(callout_active(&pcpu->profc_cyclic));
+ callout_stop(&pcpu->profc_cyclic);
+ callout_drain(&pcpu->profc_cyclic);
+ kmem_free(pcpu, sizeof(profile_probe_percpu_t));
+ }
+ kmem_free(prof->prof_pcpus, (mp_maxid + 1) * sizeof(pcpu));
+ prof->prof_pcpus = NULL;
+}
+
+/* ARGSUSED */
+static void
+profile_enable(void *arg, dtrace_id_t id, void *parg)
+{
+ profile_probe_t *prof = parg;
+
+ if (prof->prof_kind == PROF_TICK) {
+ prof->prof_expected = sbinuptime() + prof->prof_interval;
+ callout_reset_sbt(&prof->prof_cyclic,
+ prof->prof_expected, 0, profile_tick, prof,
+ C_DIRECT_EXEC | C_ABSOLUTE);
+ } else {
+ ASSERT(prof->prof_kind == PROF_PROFILE);
+ profile_enable_omni(prof);
+ }
+}
+
+/* ARGSUSED */
+static void
+profile_disable(void *arg, dtrace_id_t id, void *parg)
+{
+ profile_probe_t *prof = parg;
+
+ if (prof->prof_kind == PROF_TICK) {
+ ASSERT(callout_active(&prof->prof_cyclic));
+ callout_stop(&prof->prof_cyclic);
+ callout_drain(&prof->prof_cyclic);
+ } else {
+ ASSERT(prof->prof_kind == PROF_PROFILE);
+ profile_disable_omni(prof);
+ }
+}
+#endif
+
static void
profile_load(void *dummy)
{
@@ -541,5 +701,4 @@ SYSUNINIT(profile_unload, SI_SUB_DTRACE_
DEV_MODULE(profile, profile_modevent, NULL);
MODULE_VERSION(profile, 1);
MODULE_DEPEND(profile, dtrace, 1, 1, 1);
-MODULE_DEPEND(profile, cyclic, 1, 1, 1);
MODULE_DEPEND(profile, opensolaris, 1, 1, 1);
Modified: stable/10/sys/kern/kern_clocksource.c
==============================================================================
--- stable/10/sys/kern/kern_clocksource.c Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/kern/kern_clocksource.c Mon May 11 07:54:39 2015 (r282748)
@@ -55,11 +55,6 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/smp.h>
-#ifdef KDTRACE_HOOKS
-#include <sys/dtrace_bsd.h>
-cyclic_clock_func_t cyclic_clock_func = NULL;
-#endif
-
int cpu_deepest_sleep = 0; /* Deepest Cx state available. */
int cpu_disable_c2_sleep = 0; /* Timer dies in C2. */
int cpu_disable_c3_sleep = 0; /* Timer dies in C3. */
@@ -129,9 +124,6 @@ struct pcpu_state {
sbintime_t nextprof; /* Next profclock() event. */
sbintime_t nextcall; /* Next callout event. */
sbintime_t nextcallopt; /* Next optional callout event. */
-#ifdef KDTRACE_HOOKS
- sbintime_t nextcyc; /* Next OpenSolaris cyclics event. */
-#endif
int ipi; /* This CPU needs IPI. */
int idle; /* This CPU is in idle mode. */
};
@@ -223,13 +215,6 @@ handleevents(sbintime_t now, int fake)
callout_process(now);
}
-#ifdef KDTRACE_HOOKS
- if (fake == 0 && now >= state->nextcyc && cyclic_clock_func != NULL) {
- state->nextcyc = INT64_MAX;
- (*cyclic_clock_func)(frame);
- }
-#endif
-
t = getnextcpuevent(0);
ET_HW_LOCK(state);
if (!busy) {
@@ -275,10 +260,6 @@ getnextcpuevent(int idle)
if (profiling && event > state->nextprof)
event = state->nextprof;
}
-#ifdef KDTRACE_HOOKS
- if (event > state->nextcyc)
- event = state->nextcyc;
-#endif
return (event);
}
@@ -599,9 +580,6 @@ cpu_initclocks_bsp(void)
CPU_FOREACH(cpu) {
state = DPCPU_ID_PTR(cpu, timerstate);
mtx_init(&state->et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN);
-#ifdef KDTRACE_HOOKS
- state->nextcyc = INT64_MAX;
-#endif
state->nextcall = INT64_MAX;
state->nextcallopt = INT64_MAX;
}
@@ -820,41 +798,6 @@ cpu_et_frequency(struct eventtimer *et,
ET_UNLOCK();
}
-#ifdef KDTRACE_HOOKS
-void
-clocksource_cyc_set(const struct bintime *bt)
-{
- sbintime_t now, t;
- struct pcpu_state *state;
-
- /* Do not touch anything if somebody reconfiguring timers. */
- if (busy)
- return;
- t = bttosbt(*bt);
- state = DPCPU_PTR(timerstate);
- if (periodic)
- now = state->now;
- else
- now = sbinuptime();
-
- CTR5(KTR_SPARE2, "set_cyc at %d: now %d.%08x t %d.%08x",
- curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff),
- (int)(t >> 32), (u_int)(t & 0xffffffff));
-
- ET_HW_LOCK(state);
- if (t == state->nextcyc)
- goto done;
- state->nextcyc = t;
- if (t >= state->nextevent)
- goto done;
- state->nextevent = t;
- if (!periodic)
- loadtimer(now, 0);
-done:
- ET_HW_UNLOCK(state);
-}
-#endif
-
void
cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt)
{
Modified: stable/10/sys/modules/Makefile
==============================================================================
--- stable/10/sys/modules/Makefile Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/modules/Makefile Mon May 11 07:54:39 2015 (r282748)
@@ -85,7 +85,6 @@ SUBDIR= \
ctl \
${_cxgb} \
${_cxgbe} \
- ${_cyclic} \
dc \
dcons \
dcons_crom \
@@ -498,9 +497,6 @@ _cp= cp
_cpuctl= cpuctl
_cpufreq= cpufreq
_cs= cs
-.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
-_cyclic= cyclic
-.endif
_dpms= dpms
_drm= drm
_drm2= drm2
@@ -847,9 +843,6 @@ _cardbus= cardbus
_cbb= cbb
_cfi= cfi
_cpufreq= cpufreq
-.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
-_cyclic= cyclic
-.endif
_drm= drm
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
_dtrace= dtrace
Modified: stable/10/sys/modules/dtrace/Makefile.inc
==============================================================================
--- stable/10/sys/modules/dtrace/Makefile.inc Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/modules/dtrace/Makefile.inc Mon May 11 07:54:39 2015 (r282748)
@@ -3,7 +3,6 @@
IGNORE_PRAGMA= 1
load :
- -kldload cyclic
-kldload dtrace
.if ${MACHINE_CPUARCH} == "i386"
-kldload sdt
@@ -25,5 +24,4 @@ unload :
-kldunload sdt
.endif
-kldunload dtrace
- -kldunload cyclic
kldstat
Modified: stable/10/sys/modules/dtrace/dtraceall/dtraceall.c
==============================================================================
--- stable/10/sys/modules/dtrace/dtraceall/dtraceall.c Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/modules/dtrace/dtraceall/dtraceall.c Mon May 11 07:54:39 2015 (r282748)
@@ -63,7 +63,6 @@ DEV_MODULE(dtraceall, dtraceall_modevent
MODULE_VERSION(dtraceall, 1);
/* All the DTrace modules should be dependencies here: */
-MODULE_DEPEND(dtraceall, cyclic, 1, 1, 1);
MODULE_DEPEND(dtraceall, opensolaris, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtrace, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1);
Modified: stable/10/sys/sys/dtrace_bsd.h
==============================================================================
--- stable/10/sys/sys/dtrace_bsd.h Mon May 11 04:54:56 2015 (r282747)
+++ stable/10/sys/sys/dtrace_bsd.h Mon May 11 07:54:39 2015 (r282748)
@@ -42,15 +42,6 @@ struct devstat;
struct bio;
/*
- * Cyclic clock function type definition used to hook the cyclic
- * subsystem into the appropriate timer interrupt.
- */
-typedef void (*cyclic_clock_func_t)(struct trapframe *);
-extern cyclic_clock_func_t cyclic_clock_func;
-
-void clocksource_cyc_set(const struct bintime *t);
-
-/*
* The dtrace module handles traps that occur during a DTrace probe.
* This type definition is used in the trap handler to provide a
* hook for the dtrace module to register it's handler with.
More information about the svn-src-stable
mailing list