This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: Controlling probe overhead
David Smith wrote:
[...]
+ << " -O turn off automatic probe overload handling" <<
endl
IMO, there is no need for this option. Overload detection should
always be present, and tunable with the (documented?) -D parameters.
I see your point and the option would be easy enough to remove. I just
thought it would be easier to make one knob to turn everything off if
the STP_OVERLOAD bothered your systemtap use.
Hmm, another way to completely disable the STP_OVERLOAD stuff could be
to do "stap -DSTP_OVERLOAD=0" (if I make one small change to the patch).
I'll do that and delete the option itself.
I've made this change, but I ended up slightly modifying the above idea.
Now you can say "stap -DSTP_NO_OVERLOAD" to completely disable the
overload processing. I've attached a new patch.
--
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)
Index: tapsets.cxx
===================================================================
RCS file: /cvs/systemtap/src/tapsets.cxx,v
retrieving revision 1.184
diff -u -p -r1.184 tapsets.cxx
--- tapsets.cxx 7 Mar 2007 15:45:23 -0000 1.184
+++ tapsets.cxx 15 Mar 2007 15:26:30 -0000
@@ -128,16 +128,17 @@ be_derived_probe::join_group (systemtap_
// ------------------------------------------------------------------------
void
-common_probe_entryfn_prologue (translator_output* o, string statestr)
+common_probe_entryfn_prologue (translator_output* o, string statestr,
+ bool overload_processing = true)
{
o->newline() << "struct context* __restrict__ c;";
o->newline() << "unsigned long flags;";
- o->newline() << "#ifdef STP_TIMING";
- // NB: we truncate cycles counts to 32 bits. Perhaps it should be
- // fewer, if the hardware counter rolls over really quickly. See
- // also ...epilogue().
- o->newline() << "int32_t cycles_atstart = (int32_t) get_cycles ();";
+ if (overload_processing)
+ o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
+ else
+ o->newline() << "#ifdef STP_TIMING";
+ o->newline() << "cycles_t cycles_atstart = get_cycles ();";
o->newline() << "#endif";
#if 0 /* XXX: PERFMON */
@@ -192,18 +193,51 @@ common_probe_entryfn_prologue (translato
void
-common_probe_entryfn_epilogue (translator_output* o)
+common_probe_entryfn_epilogue (translator_output* o,
+ bool overload_processing = true)
{
- o->newline() << "#ifdef STP_TIMING";
+ if (overload_processing)
+ o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
+ else
+ o->newline() << "#ifdef STP_TIMING";
o->newline() << "{";
- o->newline(1) << "int32_t cycles_atend = (int32_t) get_cycles ();";
- // Handle 32-bit wraparound.
- o->newline() << "int32_t cycles_elapsed = (cycles_atend > cycles_atstart)";
- o->newline(1) << "? (cycles_atend - cycles_atstart)";
- o->newline() << ": (~(int32_t)0) - cycles_atstart + cycles_atend + 1;";
+ o->newline(1) << "cycles_t cycles_atend = get_cycles ();";
+ // NB: we truncate cycles counts to 32 bits. Perhaps it should be
+ // fewer, if the hardware counter rolls over really quickly. We
+ // handle 32-bit wraparound here.
+ o->newline() << "int32_t cycles_elapsed = ((int32_t)cycles_atend > (int32_t)cycles_atstart)";
+ o->newline(1) << "? ((int32_t)cycles_atend - (int32_t)cycles_atstart)";
+ o->newline() << ": (~(int32_t)0) - (int32_t)cycles_atstart + (int32_t)cycles_atend + 1;";
+ o->indent(-1);
+ o->newline() << "#ifdef STP_TIMING";
o->newline() << "if (likely (c->statp)) _stp_stat_add(*c->statp, cycles_elapsed);";
- o->indent(-1);
+ o->newline() << "#endif";
+
+ if (overload_processing)
+ {
+ o->newline() << "#ifdef STP_OVERLOAD";
+ o->newline() << "{";
+ // If the cycle count has wrapped (cycles_atend > cycles_base),
+ // let's go ahead and pretend the interval has been reached.
+ // This should reset cycles_base and cycles_sum.
+ o->newline(1) << "cycles_t interval = (cycles_atend > c->cycles_base)";
+ o->newline(1) << "? (cycles_atend - c->cycles_base)";
+ o->newline() << ": (STP_OVERLOAD_INTERVAL + 1);";
+ o->newline(-1) << "c->cycles_sum += cycles_elapsed;";
+ o->newline() << "if (interval > STP_OVERLOAD_INTERVAL) {";
+ o->newline(1) << "if (c->cycles_sum > STP_OVERLOAD_THRESHOLD) {";
+ o->newline(1) << "_stp_error (\"probe overhead exceeded threshold\");";
+ o->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);";
+ o->newline(-1) << "}";
+
+ o->newline() << "c->cycles_base = cycles_atend;";
+ o->newline() << "c->cycles_sum = 0;";
+ o->newline(-1) << "}";
+ o->newline(-1) << "}";
+ o->newline() << "#endif";
+ }
+
o->newline(-1) << "}";
o->newline() << "#endif";
@@ -238,17 +272,17 @@ be_derived_probe_group::emit_module_decl
s.op->newline() << "/* ---- begin/end probes ---- */";
s.op->newline() << "void enter_begin_probe (void (*fn)(struct context*)) {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING");
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false);
s.op->newline() << "c->probe_point = \"begin\";";
s.op->newline() << "(*fn) (c);";
- common_probe_entryfn_epilogue (s.op);
+ common_probe_entryfn_epilogue (s.op, false);
s.op->newline(-1) << "}";
s.op->newline() << "void enter_end_probe (void (*fn)(struct context*)) {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING");
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false);
s.op->newline() << "c->probe_point = \"end\";";
s.op->newline() << "(*fn) (c);";
- common_probe_entryfn_epilogue (s.op);
+ common_probe_entryfn_epilogue (s.op, false);
s.op->newline(-1) << "}";
}
Index: translate.cxx
===================================================================
RCS file: /cvs/systemtap/src/translate.cxx,v
retrieving revision 1.160
diff -u -p -r1.160 translate.cxx
--- translate.cxx 14 Mar 2007 16:19:37 -0000 1.160
+++ translate.cxx 15 Mar 2007 15:26:30 -0000
@@ -822,6 +822,10 @@ c_unparser::emit_common_header ()
o->newline() << "#ifdef STP_TIMING";
o->newline() << "Stat *statp;";
o->newline() << "#endif";
+ o->newline() << "#ifdef STP_OVERLOAD";
+ o->newline() << "cycles_t cycles_base;";
+ o->newline() << "cycles_t cycles_sum;";
+ o->newline() << "#endif";
o->newline() << "union {";
o->indent(1);
@@ -4082,11 +4086,25 @@ translate_pass (systemtap_session& s)
s.op->newline() << "#define MINSTACKSPACE 1024";
s.op->newline() << "#endif";
+ // Overload processing
+ s.op->newline() << "#ifndef STP_OVERLOAD_INTERVAL";
+ s.op->newline() << "#define STP_OVERLOAD_INTERVAL 1000000000LL";
+ s.op->newline() << "#endif";
+ s.op->newline() << "#ifndef STP_OVERLOAD_THRESHOLD";
+ s.op->newline() << "#define STP_OVERLOAD_THRESHOLD 500000000LL";
+ s.op->newline() << "#endif";
+ // We allow the user to completely turn overload processing off
+ // (as opposed to tuning it by overriding the values above) by
+ // running: stap -DSTP_NO_OVERLOAD {other options}
+ s.op->newline() << "#ifndef STP_NO_OVERLOAD";
+ s.op->newline() << "#define STP_OVERLOAD";
+ s.op->newline() << "#endif";
+
if (s.bulk_mode)
s.op->newline() << "#define STP_BULKMODE";
if (s.timing)
- s.op->newline() << "#define STP_TIMING" << " " << s.timing ;
+ s.op->newline() << "#define STP_TIMING";
if (s.perfmon)
s.op->newline() << "#define STP_PERFMON";