summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-05-20 14:46:25 -0700
committerJosh Stone <jistone@redhat.com>2009-05-20 14:53:09 -0700
commit29e2616aeeb82605a6efe1dbc574b499781eafbe (patch)
tree99cf2ca2c3c10b2bd72733a5b10626e58779ad0c
parent7872a5b9d76dc78d8956de3d2a11757783121674 (diff)
downloadsystemtap-steved-29e2616aeeb82605a6efe1dbc574b499781eafbe.tar.gz
systemtap-steved-29e2616aeeb82605a6efe1dbc574b499781eafbe.tar.xz
systemtap-steved-29e2616aeeb82605a6efe1dbc574b499781eafbe.zip
PR10177: init/kill time in sleepy context only
Previously, _stp_init_time and _stp_kill_time were being called from begin/end/error probes, which will run with preemption disabled. The BUG reported on RT kernels showed that cpufreq_unregister_notifier can end up sleeping, which violates our preemption block. This patch moves the init/kill into systemtap_module_init/exit, where it is safe to sleep. The code maintains a new predicate with the define STAP_NEED_GETTIMEOFDAY, so we don't still incur any timer overhead if it's not used.
-rw-r--r--tapset/timestamp_gtod.stp17
-rwxr-xr-xtestsuite/buildok/gtod_init.stp13
-rwxr-xr-xtestsuite/buildok/gtod_noinit.stp13
-rw-r--r--testsuite/systemtap.base/gtod_init.exp29
-rw-r--r--translate.cxx14
5 files changed, 42 insertions, 44 deletions
diff --git a/tapset/timestamp_gtod.stp b/tapset/timestamp_gtod.stp
index 43b127dc..b916a3b1 100644
--- a/tapset/timestamp_gtod.stp
+++ b/tapset/timestamp_gtod.stp
@@ -7,23 +7,10 @@
// Public License (GPL); either version 2, or (at your option) any
// later version.
-function _gettimeofday_init:long() %{
- THIS->__retvalue = _stp_init_time(); /* Kick off the Big Bang. */
+%{
+#define STAP_NEED_GETTIMEOFDAY 1
%}
-probe begin(-0x8000000000000000) {
- if (_gettimeofday_init() != 0)
- error("couldn't initialize gettimeofday")
-}
-
-function _gettimeofday_kill() %{
- _stp_kill_time(); /* Go to a beach. Drink a beer. */
-%}
-
-probe end(0x7FFFFFFFFFFFFFFF), error(0x7FFFFFFFFFFFFFFF) {
- _gettimeofday_kill()
-}
-
/**
* sfunction gettimeofday_ns - Number of nanoseconds since UNIX epoch.
diff --git a/testsuite/buildok/gtod_init.stp b/testsuite/buildok/gtod_init.stp
new file mode 100755
index 00000000..1d76aeab
--- /dev/null
+++ b/testsuite/buildok/gtod_init.stp
@@ -0,0 +1,13 @@
+#! stap -gp4
+
+# check that STAP_NEED_GETTIMEOFDAY is defined with a gettimeofday
+function check() %{
+#ifndef STAP_NEED_GETTIMEOFDAY
+#error "gettimeofday should define STAP_NEED_GETTIMEOFDAY!"
+#endif
+%}
+
+probe begin {
+ check()
+ println(gettimeofday_s())
+}
diff --git a/testsuite/buildok/gtod_noinit.stp b/testsuite/buildok/gtod_noinit.stp
new file mode 100755
index 00000000..94a9dfdc
--- /dev/null
+++ b/testsuite/buildok/gtod_noinit.stp
@@ -0,0 +1,13 @@
+#! stap -gp4
+
+# check that STAP_NEED_GETTIMEOFDAY is NOT defined without a gettimeofday
+function check() %{
+#ifdef STAP_NEED_GETTIMEOFDAY
+#error "STAP_NEED_GETTIMEOFDAY should not be defined!"
+#endif
+%}
+
+probe begin {
+ check()
+ println(get_cycles())
+}
diff --git a/testsuite/systemtap.base/gtod_init.exp b/testsuite/systemtap.base/gtod_init.exp
deleted file mode 100644
index 48616b1f..00000000
--- a/testsuite/systemtap.base/gtod_init.exp
+++ /dev/null
@@ -1,29 +0,0 @@
-# test for checking initialization of the time subsystem
-set test "gtod_init"
-
-# check that init and kill are both present with a gettimeofday
-set time_init 0
-set time_kill 0
-spawn stap -p2 -e {probe begin { println(gettimeofday_s()) }}
-expect {
- -timeout 120
- -re {\n_gettimeofday_init:} { incr time_init; exp_continue }
- -re {\n_gettimeofday_kill:} { incr time_kill; exp_continue }
- timeout { fail "$test (timeout)" }
- eof {
- if {$time_init == 1} { pass "$test (init)" } { fail "$test (init $time_init)" }
- if {$time_kill == 1} { pass "$test (kill)" } { fail "$test (kill $time_kill)" }
- }
-}
-wait
-
-# check that init and kill are both NOT present without a gettimeofday
-spawn stap -p2 -e {probe begin { println(get_cycles()) }}
-expect {
- -timeout 120
- -re {\n_gettimeofday_init:} { fail "$test (bad init)" }
- -re {\n_gettimeofday_kill:} { fail "$test (bad kill)" }
- timeout { fail "$test (timeout)" }
- eof { pass "$test (no init/kill)" }
-}
-wait
diff --git a/translate.cxx b/translate.cxx
index 62c71aeb..9f45f5d1 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -1133,6 +1133,15 @@ c_unparser::emit_module_init ()
o->newline(-1) << "}";
o->newline() << "if (rc) goto out;";
+ // initialize gettimeofday (if needed)
+ o->newline() << "#ifdef STAP_NEED_GETTIMEOFDAY";
+ o->newline() << "rc = _stp_init_time();"; // Kick off the Big Bang.
+ o->newline() << "if (rc) {";
+ o->newline(1) << "_stp_error (\"couldn't initialize gettimeofday\");";
+ o->newline() << "goto out;";
+ o->newline(-1) << "}";
+ o->newline() << "#endif";
+
o->newline() << "(void) probe_point;";
o->newline() << "(void) i;";
o->newline() << "(void) j;";
@@ -1359,6 +1368,11 @@ c_unparser::emit_module_exit ()
o->newline() << "#endif";
}
+ // teardown gettimeofday (if needed)
+ o->newline() << "#ifdef STAP_NEED_GETTIMEOFDAY";
+ o->newline() << " _stp_kill_time();"; // Go to a beach. Drink a beer.
+ o->newline() << "#endif";
+
// print final error/skipped counts if non-zero
o->newline() << "if (atomic_read (& skipped_count) || "
<< "atomic_read (& error_count) || "