]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: get rid of dtrace_gethrtime()
authorKris Van Hees <kris.van.hees@oracle.com>
Wed, 8 Mar 2017 06:38:26 +0000 (01:38 -0500)
committerKris Van Hees <kris.van.hees@oracle.com>
Wed, 8 Mar 2017 17:35:52 +0000 (12:35 -0500)
Remove the need for dtrace_gethrtime() and dtrace_getwalltime() because
the current implementations are not deadlock safe.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
dtrace/Kbuild
dtrace/dtrace_dev.c
dtrace/dtrace_dif.c
dtrace/dtrace_isa.c
dtrace/dtrace_probe.c
dtrace/dtrace_state.c
dtrace/include/dtrace/dtrace_impl.h
dtrace/include/dtrace/types.h
dtrace/profile_dev.c

index 785bc2335c23302d0e9f7f0ed56f192187898ca3..63892057cc398161669ababd7f8c1303dd6cb07a 100644 (file)
@@ -34,7 +34,6 @@ obj-$(CONFIG_DT_PROFILE)      += profile.o
 obj-$(CONFIG_DT_SDT)           += sdt.o
 obj-$(CONFIG_DT_SYSTRACE)      += systrace.o
 obj-$(CONFIG_DT_DT_TEST)       += dt_test.o
-obj-$(CONFIG_DT_DT_PERF)       += dt_perf.o
 
 dtrace-y                       := dtrace_mod.o dtrace_dev.o \
                                   dtrace_asm_$(UTS_MACHINE).o \
@@ -53,4 +52,3 @@ profile-y                     := profile_mod.o profile_dev.o
 sdt-y                          := sdt_mod.o sdt_dev.o sdt_$(UTS_MACHINE).o
 systrace-y                     := systrace_mod.o systrace_dev.o
 dt_test-y                      := dt_test_mod.o dt_test_dev.o
-dt_perf-y                      := dt_perf_mod.o dt_perf_dev.o
index 4e08146519a50713a7d4b29ebb53a8d9fe829660..000dcc70b2c3a28bf8aa2626885ed4b84e5989cd 100644 (file)
@@ -840,12 +840,12 @@ static long dtrace_ioctl(struct file *file,
 
                /*
                 * See the comment in dtrace_state_deadman() for the reason
-                * for setting dts_laststatus to INT64_MAX before setting
+                * for setting dts_laststatus to UINT64_MAX before setting
                 * it to the correct value.
                 */
-               state->dts_laststatus = ns_to_ktime(INT64_MAX);
+               state->dts_laststatus = UINT64_MAX;
                dtrace_membar_producer();
-               state->dts_laststatus = dtrace_gethrtime();
+               state->dts_laststatus = jiffies;
 
                memset(&stat, 0, sizeof(stat));
 
index 6cd62dc63bc1b6e3ed772380137cc1a2bad2b897..046f314a40d169fc83216ce81e030b7e3b1bc5b9 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/hardirq.h>
 #include <linux/in6.h>
 #include <linux/inet.h>
+#include <linux/jiffies.h>
 #include <linux/kdev_t.h>
 #include <linux/slab.h>
 #include <linux/socket.h>
@@ -2079,8 +2080,9 @@ static uint64_t dtrace_dif_variable(dtrace_mstate_t *mstate,
                return (uint64_t)(uintptr_t)current;
 
        case DIF_VAR_TIMESTAMP:
+       case DIF_VAR_WALLTIMESTAMP:
                if (!(mstate->dtms_present & DTRACE_MSTATE_TIMESTAMP)) {
-                       mstate->dtms_timestamp = dtrace_gethrtime();
+                       mstate->dtms_timestamp = current->dtrace_start;
                        mstate->dtms_present |= DTRACE_MSTATE_TIMESTAMP;
                }
 
@@ -2091,9 +2093,6 @@ static uint64_t dtrace_dif_variable(dtrace_mstate_t *mstate,
 
                return ktime_to_ns(current->dtrace_vtime);
 
-       case DIF_VAR_WALLTIMESTAMP:
-               return ktime_to_ns(dtrace_getwalltime());
-
        case DIF_VAR_IPL:
                if (!dtrace_priv_kernel(state))
                        return 0;
@@ -2382,7 +2381,7 @@ static void dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
 
        switch (subr) {
        case DIF_SUBR_RAND:
-               regs[rd] = ktime_to_ns(dtrace_gethrtime()) * 2416 + 374441;
+               regs[rd] = jiffies * 2416 + 374441;
                regs[rd] = do_div(regs[rd], 1771875);
                break;
 
index cb29accd2782146ce92467a4aa028b3fdb41a02d..5642cedef9e009e7f7c5a88064e7ee9aac376019 100644 (file)
@@ -121,11 +121,6 @@ void dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
        dtrace_copyinstr_arch(uaddr, kaddr, size, flags);
 }
 
-ktime_t dtrace_gethrestime(void)
-{
-       return dtrace_gethrtime();
-}
-
 void dtrace_getpcstack(uint64_t *pcstack, int pcstack_limit, int aframes,
                       uint32_t *intrpc)
 {
index 3ace8ee087a039f6d839b17927433163a11dc54f..c06089ab0864b41f67608b2c1451fd5f1ea57c41 100644 (file)
@@ -393,49 +393,12 @@ static void dtrace_action_stop(void)
 
 static void dtrace_action_chill(dtrace_mstate_t *mstate, ktime_t val)
 {
-       ktime_t                 now;
-       volatile uint16_t       *flags;
-       cpu_core_t              *cpu = this_cpu_core;
-
        if (dtrace_destructive_disallow)
                return;
 
-       flags = (volatile uint16_t *)&cpu->cpuc_dtrace_flags;
-
-       now = dtrace_gethrtime();
-
-       if (ktime_gt(ktime_sub(now, cpu->cpu_dtrace_chillmark),
-                    dtrace_chill_interval)) {
-               /*
-                * We need to advance the mark to the current time.
-                */
-               cpu->cpu_dtrace_chillmark = now;
-               cpu->cpu_dtrace_chilled = ktime_set(0, 0);
-       }
+       dtrace_chill(val, dtrace_chill_interval, dtrace_chill_max);
 
-       /*
-        * Now check to see if the requested chill time would take us over
-        * the maximum amount of time allowed in the chill interval.  (Or
-        * worse, if the calculation itself induces overflow.)
-        */
-       if (ktime_gt(ktime_add(cpu->cpu_dtrace_chilled, val),
-                    dtrace_chill_max) ||
-           ktime_lt(ktime_add(cpu->cpu_dtrace_chilled, val),
-                    cpu->cpu_dtrace_chilled)) {
-               *flags |= CPU_DTRACE_ILLOP;
-               return;
-       }
-
-       while (ktime_lt(ktime_sub(dtrace_gethrtime(), now), val))
-               continue;
-
-       /*
-        * Normally, we assure that the value of the variable "timestamp" does
-        * not change within an ECB.  The presence of chill() represents an
-        * exception to this rule, however.
-        */
        mstate->dtms_present &= ~DTRACE_MSTATE_TIMESTAMP;
-       cpu->cpu_dtrace_chilled = ktime_add(cpu->cpu_dtrace_chilled, val);
 }
 
 static void dtrace_action_ustack(dtrace_mstate_t *mstate,
@@ -559,9 +522,8 @@ void dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
        dtrace_action_t         *act;
        intptr_t                offs;
        size_t                  size;
-       int                     vtime, onintr;
+       int                     onintr;
        volatile uint16_t       *flags;
-       ktime_t                 now;
        int                     pflag = 0;
 
 #ifdef FIXME
@@ -629,13 +591,8 @@ void dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
        *flags |= CPU_DTRACE_PROBE_CTX;
        this_cpu_core->cpu_dtrace_caller = id;
 
-       now = dtrace_gethrtime();
-       vtime = (dtrace_vtime_references > 0);
-
-       if (vtime && ktime_nz(current->dtrace_start))
-               current->dtrace_vtime =
-                       ktime_add(current->dtrace_vtime,
-                                 ktime_sub(now, current->dtrace_start));
+       if (id != dtrace_probeid_error)
+               dtrace_vtime_suspend();
 
        mstate.dtms_difo = NULL;
        mstate.dtms_probe = probe;
@@ -753,7 +710,7 @@ void dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
                        }
                }
 
-               if (ktime_gt(ktime_sub(now, state->dts_alive),
+               if (ktime_gt(ktime_sub(current->dtrace_start, state->dts_alive),
                             dtrace_deadman_timeout)) {
                        /*
                         * We seem to be dead.  Unless we (a) have kernel
@@ -1241,15 +1198,6 @@ void dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
                                continue;
                        }
 
-                       if (vtime)
-                               /*
-                                * Before recursing on dtrace_probe(), we
-                                * need to explicitly clear out our start
-                                * time to prevent it from being accumulated
-                                * into t_dtrace_vtime.
-                                */
-                               current->dtrace_start = ktime_set(0, 0);
-
                        /*
                         * Iterate over the actions to figure out which action
                         * we were processing when we experienced the error.
@@ -1283,8 +1231,7 @@ void dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
                             id, ecb->dte_epid);
        }
 
-       if (vtime)
-               current->dtrace_start = dtrace_gethrtime();
+       dtrace_vtime_resume();
 
        /*
         * Only clear the flag if this is not the ERROR probe.  We know that
index 837879dd7cdd8ec8b43080a3a9be4bc2bc063160..2098d4e29bd599c0261a96ea9bf97c8872fd0a4e 100644 (file)
@@ -54,11 +54,11 @@ dtrace_optval_t             dtrace_jstackstrsize_default = 512;
 #if 1
 ktime_t                        dtrace_deadman_interval = KTIME_INIT(10, 0);
 ktime_t                        dtrace_deadman_timeout = KTIME_INIT(120, 0);
-ktime_t                        dtrace_deadman_user = KTIME_INIT(120, 0);
+uint64_t               dtrace_deadman_user = SECS_TO_JIFFIES(120);
 #else
 ktime_t                        dtrace_deadman_interval = KTIME_INIT(1, 0);
 ktime_t                        dtrace_deadman_timeout = KTIME_INIT(10, 0);
-ktime_t                        dtrace_deadman_user = KTIME_INIT(30, 0);
+uint64_t               dtrace_deadman_user = SECS_TO_JIFFIES(30);
 #endif
 
 dtrace_id_t            dtrace_probeid_begin;
@@ -289,7 +289,7 @@ void dtrace_vstate_fini(dtrace_vstate_t *vstate)
                vfree(vstate->dtvs_locals);
 }
 
-static void dtrace_state_clean(dtrace_state_t *state)
+static void dtrace_state_clean(dtrace_state_t *state, ktime_t when)
 {
        if (state->dts_activity != DTRACE_ACTIVITY_ACTIVE &&
            state->dts_activity != DTRACE_ACTIVITY_DRAINING)
@@ -299,10 +299,8 @@ static void dtrace_state_clean(dtrace_state_t *state)
        dtrace_speculation_clean(state);
 }
 
-static void dtrace_state_deadman(dtrace_state_t *state)
+static void dtrace_state_deadman(dtrace_state_t *state, ktime_t when)
 {
-       ktime_t now;
-
 #ifdef FIXME
        /*
         * This may not be needed for Linux - we'll see.
@@ -310,11 +308,8 @@ static void dtrace_state_deadman(dtrace_state_t *state)
        dtrace_sync();
 #endif
 
-       now = dtrace_gethrtime();
-
        if (state != dtrace_anon.dta_state &&
-           ktime_ge(ktime_sub(now, state->dts_laststatus),
-                              dtrace_deadman_user))
+           time_after_eq(jiffies, state->dts_laststatus + dtrace_deadman_user))
                return;
 
        /*
@@ -328,7 +323,7 @@ static void dtrace_state_deadman(dtrace_state_t *state)
         */
        state->dts_alive = ktime_set(KTIME_SEC_MAX, 0);
        dtrace_membar_producer();
-       state->dts_alive = now;
+       state->dts_alive = when;
 }
 
 dtrace_state_t *dtrace_state_create(struct file *file)
@@ -801,8 +796,9 @@ int dtrace_state_go(dtrace_state_t *state, processorid_t *cpu)
        when.cyt_when = ktime_set(0, 0);
        when.cyt_interval = dtrace_deadman_interval;
 
-       state->dts_alive = state->dts_laststatus = dtrace_gethrtime();
        state->dts_deadman = cyclic_add(&hdlr, &when);
+       state->dts_alive = when.cyt_when;
+       state->dts_laststatus = jiffies;
 
        state->dts_activity = DTRACE_ACTIVITY_WARMUP;
 
index 8dcc36e447c5d1aa7107bb195a4eb642811e48e2..0eac655974dc48b3420ac8179cb74f7551ec02ad 100644 (file)
@@ -275,9 +275,9 @@ struct dtrace_state {
        uint32_t dts_stkstroverflows;
        uint32_t dts_dblerrors;
        uint32_t dts_reserve;
-       ktime_t dts_laststatus;
        cyclic_id_t dts_cleaner;
        cyclic_id_t dts_deadman;
+       uint64_t dts_laststatus;
        ktime_t dts_alive;
        char dts_speculates;
        char dts_destructive;
@@ -871,8 +871,6 @@ extern void dtrace_toxic_ranges(void (*)(uintptr_t, uintptr_t));
 extern void dtrace_vpanic(const char *, va_list);
 extern int dtrace_getipl(void);
 
-extern ktime_t dtrace_gethrestime(void);
-
 extern dtrace_icookie_t dtrace_interrupt_disable(void);
 extern void dtrace_interrupt_enable(dtrace_icookie_t);
 
index be23a34fc902ef66ee5b1d9ee744510a2b41b98d..58f0331b9475f25ba8b6f5b80c236bcc867d3cf9 100644 (file)
@@ -28,7 +28,7 @@
  *
  * CDDL HEADER END
  *
- * Copyright 2009 -- 2013 Oracle, Inc.  All rights reserved.
+ * Copyright 2009-2017 Oracle, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -51,6 +51,7 @@
 
 #include <asm/bitsperlong.h>
 #include <linux/dtrace_os.h>
+#include <linux/jiffies.h>
 
 typedef unsigned char  uchar_t;
 typedef unsigned int   uint_t;
@@ -127,6 +128,8 @@ typedef enum {
 #define ktime_gt(t0, t1)       ((t0).tv64 > (t1).tv64)
 #define ktime_cp(t0, t1)       ((t0).tv64 = (t1).tv64)
 
+#define SECS_TO_JIFFIES(s)     (((s) * SEC_CONVERSION) >> SEC_JIFFIE_SC)
+
 /*
  * Translate between kernel config options and userspace-compatible definitions.
  */
index 73aba6fd9d04f83fd413ca4e7cfe25c42b802c62..f855ed805db3ece4f6f7e48da5e496958baaf39e 100644 (file)
@@ -87,7 +87,7 @@ static int    profile_ticks[] = {
 static int     profile_max;            /* maximum number of profile probes */
 static atomic_t        profile_total;          /* current number of profile probes */
 
-static void profile_tick_fn(uintptr_t arg)
+static void profile_tick_fn(uintptr_t arg, ktime_t when)
 {
        profile_probe_t *prof = (profile_probe_t *)arg;
        unsigned long   pc = 0, upc = 0;
@@ -114,7 +114,7 @@ static void profile_tick_fn(uintptr_t arg)
        dtrace_probe(prof->prof_id, pc, upc, 0, 0, 0);
 }
 
-static void profile_prof_fn(uintptr_t arg)
+static void profile_prof_fn(uintptr_t arg, ktime_t when)
 {
        profile_probe_percpu_t  *pcpu = (profile_probe_percpu_t *)arg;
        profile_probe_t         *prof = pcpu->profc_probe;
@@ -122,7 +122,7 @@ static void profile_prof_fn(uintptr_t arg)
        struct pt_regs          *regs = get_irq_regs();
        unsigned long           pc = 0, upc = 0;
 
-       late = ktime_sub(dtrace_gethrtime(), pcpu->profc_expected);
+       late = ktime_sub(when, pcpu->profc_expected);
        pcpu->profc_expected = ktime_add(pcpu->profc_expected,
                                         pcpu->profc_interval);
 
@@ -161,7 +161,7 @@ static void profile_online(void *arg, processorid_t cpu, cyc_handler_t *hdlr,
        hdlr->cyh_level = CY_HIGH_LEVEL;
 
        when->cyt_interval = prof->prof_interval;
-       when->cyt_when = ktime_add(dtrace_gethrtime(), when->cyt_interval);
+       when->cyt_when = ktime_add(when->cyt_when, when->cyt_interval);
 
        pcpu->profc_expected = when->cyt_when;
        pcpu->profc_interval = when->cyt_interval;