Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 May 2015 07:54:40 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   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 ...
Message-ID:  <201505110754.t4B7seVh088151@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505110754.t4B7seVh088151>