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>