Controlling probe overhead

David Smith dsmith@redhat.com
Wed Mar 14 21:39:00 GMT 2007


Frank Ch. Eigler wrote:
> David Smith <dsmith@redhat.com> writes:
> 
>> [...] BTW, I had to rework the STP_TIMING code a very small bit to make it
>> work correctly with the STP_OVERLOAD code.  The STP_TIMING code was
>> storing cycle counts as 32-bit values, where the STP_OVERLOAD code
>> wanted 64-bit cycle counts.  The STP_TIMING code now truncates down to
>> 32-bits a little later than it did originally.
> 
> Note that the current code doesn't (intend to) truncate cycle counts,
> just individual samples of the get_cycles() values.

Right, but the STP_OVERLOAD stuff needed full 64-bit values.  So, now we 
keep 64-bit get_cycles() values, but truncate down when figuring out the 
elapsed time for STP_TIMING purposes.  Since the STP_OVERLOAD_INTERVAL 
is greater than the max value of a 32-bit value, I needed full 64-bit 
get_cycles() values.

>> [...] I've have one stress test (that Frank wrote) that will make a
>> RHEL5 system non-responsive.  The system doesn't crash - just
>> decides to no longer take any input.  The overload code kills the
>> script in less than 3 minutes.
> 
> 3 minutes is almost certainly too long for a default overload
> detection interval.  I would expect something on the order of a few
> seconds.

Sorry, I wrote that from memory.  I went back and ran the test again, 
and I get the overload message in roughly 2 seconds.  It takes another 
60 seconds or so to deregister all the probes.

I was pleasantly surprised that this code didn't bother any of the test 
suite tests or my other stress tests - just the problem one.

>> Note that I haven't implemented the new error probes you and Frank
>> discussed.  I'd like to get the current code in (since it is quite
>> useful in its current state) before thinking about error probes.
> 
> Indeed, they are independent ideas.
> 
> 
>> [...]
>> +    << "   -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.

> If this code depends on the STP_TIMING stuff in the probe
> prologues/epilogues, than most of that code too could be on also,
> (with -t just controlling whether the final timing report is printed).

This code doesn't depend on the STP_TIMING stuff, it just uses the same 
cycles_atstart/cycles_atend counters (since it seemed silly to have two 
sets of counters doing exactly the same thing).

You can still turn STP_TIMING on/off independently of STP_OVERLOAD (and 
vice versa).

>> -  o->newline(1) << "int32_t cycles_atend = (int32_t) get_cycles ();";
>> -  // Handle 32-bit wraparound.
>> [...]
> 
> Perhaps you could excerpt the actual generated overload/timing code
> here.  It looks like there may be more being done here than necessary.

You want to see the generated code?  OK, here goes:

Ignoring all the support code (variable decls and #defines), in the 
original enter_kprpobe_probe() function you'll see this:

===================
   #ifdef STP_TIMING
   int32_t cycles_atstart = (int32_t) get_cycles ();
   #endif

...

   #ifdef STP_TIMING
   {
     int32_t cycles_atend = (int32_t) get_cycles ();
     int32_t cycles_elapsed = (cycles_atend > cycles_atstart)
       ? (cycles_atend - cycles_atstart)
       : (~(int32_t)0) - cycles_atstart + cycles_atend + 1;
       if (likely (c->statp)) _stp_stat_add(*c->statp, cycles_elapsed);
   }
   #endif

===================

In the new enter_kprpobe_probe() function, you'll see this:

===================
   #if defined(STP_TIMING) || defined(STP_OVERLOAD)
   cycles_t cycles_atstart = get_cycles ();
   #endif

...

   #if defined(STP_TIMING) || defined(STP_OVERLOAD)
   {
     cycles_t cycles_atend = get_cycles ();
     int32_t cycles_elapsed = ((int32_t)cycles_atend > 
(int32_t)cycles_atstart)
       ? ((int32_t)cycles_atend - (int32_t)cycles_atstart)
       : (~(int32_t)0) - (int32_t)cycles_atstart + (int32_t)cycles_atend 
+ 1;
     #ifdef STP_TIMING
     if (likely (c->statp)) _stp_stat_add(*c->statp, cycles_elapsed);
     #endif
     #ifdef STP_OVERLOAD
     {
       cycles_t interval = (cycles_atend > c->cycles_base)
         ? (cycles_atend - c->cycles_base)
         : (STP_OVERLOAD_INTERVAL + 1);
       c->cycles_sum += cycles_elapsed;
       if (interval > STP_OVERLOAD_INTERVAL) {
         if (c->cycles_sum > STP_OVERLOAD_THRESHOLD) {
           _stp_error ("probe overhead exceeded threshold");
           atomic_set (&session_state, STAP_SESSION_ERROR);
         }
         c->cycles_base = cycles_atend;
         c->cycles_sum = 0;
       }
     }
     #endif
   }
   #endif
=================

I tried to mess with the STP_TIMING code as little as possible.

>> +  o->newline() << "#ifndef STP_OVERLOAD_INTERVAL";
>> +  o->newline() << "#define STP_OVERLOAD_INTERVAL 1000000000LL";
>> +  o->newline() << "#endif";
>> +  o->newline() << "#ifndef STP_OVERLOAD_THRESHOLD";
>> +  o->newline() << "#define STP_OVERLOAD_THRESHOLD 500000000LL";
>> +  o->newline() << "#endif";
> 
> These quantities should probably depend on the processor, so that
> overload intervals are measured in units of time rather than cycles.

Hmm, those quantities do depend a bit on the processor, since cycles 
depend on the processor.  However, trying to map time into cycles is 
typically a losing game, especially on systems with variable clock speeds.

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)



More information about the Systemtap mailing list