This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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";

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]