public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
From: David Smith <dsmith@redhat.com>
To: Thiago Manel <thiago.manel@gmail.com>
Cc: "systemtap@sourceware.org" <systemtap@sourceware.org>
Subject: Re: problems with sched tapset on ubuntu precise 3.2.0
Date: Wed, 08 May 2013 14:15:00 -0000	[thread overview]
Message-ID: <518A5DF1.3010207@redhat.com> (raw)
In-Reply-To: <CAHiC6b0hO=fvwqkfHBaMC=UzCdSA4yKEJSYji-Nk2hSVF5H5dA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2188 bytes --]

On 05/08/2013 08:25 AM, Thiago Manel wrote:
> Hi David, sorry for the late response
> 
> - for the first check, I see an error:
> 
> stap -vv -l 'kernel.trace("sched_*")'
> Systemtap translator/driver (version 1.6/0.152 non-git sources)
> Copyright (C) 2005-2011 Red Hat, Inc. and others
> This is free software; see the source for copying conditions.
> enabled features: AVAHI LIBSQLITE3 NSS BOOST_SHARED_PTR TR1_UNORDERED_MAP NLS
> Created temporary directory "/tmp/stapNw4kVW"
> Session arch: x86_64 release: 3.2.0-23-generic
> Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4
> Searched: " /usr/share/systemtap/tapset/*.stp ", found: 73, processed: 73
> Pass 1: parsed user script and 77 library script(s) using
> 84096virt/22508res/2556shr kb, in 60usr/0sys/70real ms.
> semantic error: no match while resolving probe point kernel.trace("sched_*")
> Pass 2: analyzed script: 0 probe(s), 0 function(s), 0 embed(s), 0
> global(s) using 230984virt/23700res/2908shr kb, in
> 40usr/100sys/125real ms.
> Running rm -rf /tmp/stapNw4kVW
> Spawn waitpid result (0x0): 0
> 
> - whereas for the second one, it succeeds:
> 
>  stap -l 'kernel.function("context_switch")'
> kernel.function("context_switch@/build/buildd/linux-3.2.0/kernel/sched.c:3287")
> 
> Regarding the CONFIG_TRACEPOINTS (I'm not sure I'm looking to the
> right place) I have ...

On a fedora system, you'd look in /boot/config-`uname -r`. I don't know
where you'd find the kernel config file on ubuntu.

I see where the error is coming from now. The process/schedtimes.stp
script is written to only use tracepoints, it doesn't have the
kernel.function fallback like the scheduler.cpu_off tapset probe alias.
So, if your kernel doesn't have the sched kernel tracepoints the
schedtimes.stp script won't work as written. We could try adding in the
kernel.function fallback, but on many kernels that kernel function gets
inlined which makes it difficult to find the arguments.

Here's an (untested) version of schedtimes.stp with the kernel.function
fallbacks added. See if it works for you.

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

[-- Attachment #2: schedtimes.stp --]
[-- Type: text/plain, Size: 5493 bytes --]

#! /usr/bin/env stap

############################################################
# Schedtimes.stp
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.

# Author: Jason Baron <jbaron@redhat.com>
# profiles threads and displays their run times, queued times,
# wait times, including i/o wait times.
# Has two modes. When no arguments are given it profiles all
# threads. Alternatively, you can pass -c "program name"
############################################################

//constants
global RUNNING=0, QUEUED=1, SLEEPING=2

global traced_pid
global run_time, queued_time,  sleep_time, io_wait_time
global pid_state, pid_names
global previous_timestamp
global io_wait_count
global io_wait_incremented

function get_iowait:long(queue:long)
{
  return @cast(queue,"rq","kernel")->nr_iowait->counter;
}

probe kernel.trace("sched_switch")!, kernel.function("context_switch") {
  previous_pid = $prev->pid;
  next_pid = $next->pid;
  if (traced_pid) {
    if (previous_pid != traced_pid) {
      previous_pid = 0;
    }
    if (next_pid != traced_pid) {
      next_pid = 0;
    }
  }
  if (previous_pid) {
    if (!([previous_pid] in pid_state)) {
      //use this state as entry into state machine
      previous_timestamp[previous_pid] = gettimeofday_us();
      pid_names[previous_pid] = kernel_string($prev->comm);
      if ($prev->state > 0) {
        pid_state[previous_pid] = SLEEPING;
      } else if ($prev->state == 0) {
        pid_state[previous_pid] = QUEUED;
      } else {
        printf("unknown transition:\n");
        printf("pid state: %d our state: %d\n",
          $prev->state, pid_state[previous_pid]);
      }
    } else if (pid_state[previous_pid] == RUNNING) {
      pid_names[previous_pid] = kernel_string($prev->comm);
      t = gettimeofday_us();  
      run_time[previous_pid] += (t - previous_timestamp[previous_pid]);
      previous_timestamp[previous_pid] = t;
      if ($prev->state > 0) {
        if (@defined($rq) && (get_iowait($rq) - io_wait_count[previous_pid]) > 0)
          io_wait_incremented[previous_pid] = 1;  
        pid_state[previous_pid] = SLEEPING;
      } else if ($prev->state == 0) {
        pid_state[previous_pid] = QUEUED;
      } else {
        printf("unknown transition:\n");
        printf("pid state: %d our state: %d\n",
          $prev->state, pid_state[previous_pid]);
      }
    } else {
      printf("unknown transition:\n");
      printf("%s pid state: %d our state: %d\n",
           pid_names[previous_pid],
           $prev->state, pid_state[previous_pid]);
    }
  }
  if (next_pid) {
    if (@defined($rq))
      io_wait_count[next_pid] = get_iowait($rq);
    if (!([next_pid] in pid_state)) {
      //use this state as entry into state machine
      previous_timestamp[next_pid] =  gettimeofday_us();
      pid_state[next_pid] = RUNNING;
      pid_names[next_pid] = kernel_string($next->comm);
    } else if (pid_state[next_pid] == QUEUED) {
      t = gettimeofday_us();
      queued_time[next_pid] += (t - previous_timestamp[next_pid]);
      previous_timestamp[next_pid] = t;
      pid_state[next_pid] = RUNNING;
      pid_names[next_pid] = kernel_string($next->comm);
    } else {
      printf("unknown transition:\n");
      printf("%s pid state: %d our state: %d\n",
        pid_names[next_pid],
        $next->state, pid_state[next_pid]);
    }
  }
}

probe kernel.trace("sched_wakeup"), kernel.function("try_to_wake_up") {
  wakeup_pid = $p->pid;
  if (traced_pid && (wakeup_pid != traced_pid)) next
  if ((!$success) && (pid_state[wakeup_pid] != SLEEPING)) next
  if (!wakeup_pid) next

  if (!([wakeup_pid] in pid_state)) {
    //use this state as entry into state machine
    previous_timestamp[wakeup_pid] =  gettimeofday_us();
    pid_state[wakeup_pid] = QUEUED;
    pid_names[wakeup_pid] = kernel_string($p->comm);
  } else if (pid_state[wakeup_pid] == SLEEPING) {
    t = gettimeofday_us();
    sleep_time[wakeup_pid] += (t - previous_timestamp[wakeup_pid]);
    if (io_wait_incremented[wakeup_pid] == 1) {
      io_wait_time[wakeup_pid] += (t - previous_timestamp[wakeup_pid]);
      io_wait_incremented[wakeup_pid] = 0;
    }
    previous_timestamp[wakeup_pid] = t;
    pid_state[wakeup_pid] = QUEUED;
    pid_names[wakeup_pid] = kernel_string($p->comm);
  } else {
    printf("unknown transition:\n");
    printf("pid state: %d our state: %d\n",
      $p->state, pid_state[wakeup_pid]);
  }
}

probe begin {
  traced_pid = target();
  if (traced_pid == 0) {
    printf("all mode\n");
  } else {
    printf("target mode\n");
    printf("traced pid: %d\n", traced_pid);
  }
}

probe end {
  t = gettimeofday_us();
  foreach (pid in pid_state) {
    if (pid_state[pid] == SLEEPING)
      sleep_time[pid] += (t - previous_timestamp[pid]);
    if (pid_state[pid] == QUEUED)
      queued_time[pid] += (t - previous_timestamp[pid]);
    if (pid_state[pid] == RUNNING)
      run_time[pid] += (t - previous_timestamp[pid]);
  }
  printf ("%16s: %6s %10s %10s %10s %10s %10s\n\n",
         "execname", "pid", "run(us)", "sleep(us)", "io_wait(us)",
         "queued(us)", "total(us)")
  foreach (pid+ in run_time) {
    printf("%16s: %6d %10d %10d %10d %10d %10d\n", 
      pid_names[pid], pid, run_time[pid], sleep_time[pid], 
      io_wait_time[pid], queued_time[pid],
      (run_time[pid] + sleep_time[pid] + queued_time[pid]));
  }
}

  reply	other threads:[~2013-05-08 14:15 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-07 15:05 Thiago Manel
2013-05-07 18:28 ` David Smith
2013-05-08 13:26   ` Thiago Manel
2013-05-08 14:15     ` David Smith [this message]
2013-05-08 14:56       ` Thiago Manel
2013-05-13 21:21         ` David Smith
2013-05-14 19:46           ` Thiago Manel
2013-05-14 20:13             ` Josh Stone
2013-05-14 20:24     ` Josh Stone
2013-05-14 20:39       ` Thiago Manel
     [not found]       ` <CAHiC6b2rqiBjgVtMEo92sNQy0-AeEQxW8SY0WV38FnfqdAXgdA@mail.gmail.com>
2013-05-14 21:11         ` Josh Stone

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=518A5DF1.3010207@redhat.com \
    --to=dsmith@redhat.com \
    --cc=systemtap@sourceware.org \
    --cc=thiago.manel@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).