diff options
author | Josh Stone <jistone@redhat.com> | 2009-05-20 14:46:25 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-05-20 14:53:09 -0700 |
commit | 29e2616aeeb82605a6efe1dbc574b499781eafbe (patch) | |
tree | 99cf2ca2c3c10b2bd72733a5b10626e58779ad0c | |
parent | 7872a5b9d76dc78d8956de3d2a11757783121674 (diff) | |
download | systemtap-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.stp | 17 | ||||
-rwxr-xr-x | testsuite/buildok/gtod_init.stp | 13 | ||||
-rwxr-xr-x | testsuite/buildok/gtod_noinit.stp | 13 | ||||
-rw-r--r-- | testsuite/systemtap.base/gtod_init.exp | 29 | ||||
-rw-r--r-- | translate.cxx | 14 |
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) || " |