summaryrefslogtreecommitdiffstats
path: root/tapset
diff options
context:
space:
mode:
Diffstat (limited to 'tapset')
-rw-r--r--tapset/indent.stp6
-rw-r--r--tapset/proc_mem.stp194
-rw-r--r--tapset/scheduler.stp353
3 files changed, 497 insertions, 56 deletions
diff --git a/tapset/indent.stp b/tapset/indent.stp
index 1dbbebd4..2f850bfd 100644
--- a/tapset/indent.stp
+++ b/tapset/indent.stp
@@ -9,11 +9,7 @@ function _generic_indent (idx, desc, delta)
x = _indent_counters[idx] + (delta > 0 ? delta : 0)
_indent_counters[idx] += delta
- r = sprintf("%6d %s:", (ts - _indent_timestamps[idx]), desc)
-
- for (i=1; i<x; i++) r .= " "
-
- return r
+ return sprintf("%6d %s:%-*s", (ts - _indent_timestamps[idx]), desc, (x>0 ? x-1 : 0), "")
}
/**
diff --git a/tapset/proc_mem.stp b/tapset/proc_mem.stp
new file mode 100644
index 00000000..1493bd92
--- /dev/null
+++ b/tapset/proc_mem.stp
@@ -0,0 +1,194 @@
+// Process memory query and utility functions.
+// Copyright (C) 2009 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+// <tapsetdescription>
+// Process memory query and utility functions provide information about
+// the memory usage of the current application. These functions provide
+// information about the full size, resident, shared, code and data used
+// by the current process. And provide utility functions to query the
+// page size of the current architecture and create human readable string
+// representations of bytes and pages used.
+// </tapsetdescription>
+
+%{
+/* PF_BORROWED_MM got renamed to PF_KTHREAD with same semantics somewhere. */
+#ifdef PF_BORROWED_MM
+#define _STP_PF_KTHREAD PF_BORROWED_MM
+#else
+#define _STP_PF_KTHREAD PF_KTHREAD
+#endif
+ /* Returns the mm for the current proc. Slightly paranoid. Only returns
+ if the task isn't starting, exiting or (coopted by) a kernel thread. */
+ static struct mm_struct *_stp_proc_mm(void)
+ {
+ if (current->flags & (_STP_PF_KTHREAD | PF_EXITING | PF_STARTING))
+ return NULL;
+ return current->mm;
+ }
+%}
+
+/**
+ * sfunction proc_mem_size - Total program virtual memory size in pages.
+ *
+ * Description: Returns the total virtual memory size in pages of the
+ * current process, or zero when there is no current process or the
+ * number of pages couldn't be retrieved.
+ */
+function proc_mem_size:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = mm->total_vm;
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction proc_mem_rss - Program resident set size in pages.
+ *
+ * Description: Returns the resident set size in pages of the current
+ * process, or zero when there is no current process or the number of
+ * pages couldn't be retrieved.
+ */
+function proc_mem_rss:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = (get_mm_counter(mm, file_rss)
+ + get_mm_counter(mm, anon_rss));
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction proc_mem_shr - Program shared pages (from shared mappings).
+ *
+ * Description: Returns the shared pages (from shared mappings) of the
+ * current process, or zero when there is no current process or the
+ * number of pages couldn't be retrieved.
+ */
+function proc_mem_shr:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = get_mm_counter(mm, file_rss);
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction proc_mem_txt - Program text (code) size in pages.
+ *
+ * Description: Returns the current process text (code) size in pages,
+ * or zero when there is no current process or the number of pages
+ * couldn't be retrieved.
+ */
+function proc_mem_txt:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = (PAGE_ALIGN(mm->end_code)
+ - (mm->start_code & PAGE_MASK)) >> PAGE_SHIFT;
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction proc_mem_data - Program data size (data + stack) in pages.
+ *
+ * Description: Returns the current process data size (data + stack)
+ * in pages, or zero when there is no current process or the number of
+ * pages couldn't be retrieved.
+ */
+function proc_mem_data:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = mm->total_vm - mm->shared_vm;
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction mem_page_size - Number of bytes in a page for this architecture.
+ */
+function mem_page_size:long ()
+%{ /* pure */ /* unprivileged */
+ THIS->__retvalue = PAGE_SIZE;
+%}
+
+// Return a 5 character wide string " x.yyp", " xx.yp", " xxxp", "xxxxp".
+function _stp_number_to_string_postfix:string (x:long, y:long, p:string)
+{
+ if (x < 10)
+ return sprintf("%d.%.2d%s", x, y * 100 / 1024, p);
+ if (x < 100)
+ return sprintf("%2d.%d%s", x, y * 10 / 1024, p);
+ return sprintf("%4d%s", x, p);
+}
+
+/**
+ * sfunction bytes_to_string - Human readable string for given bytes.
+ *
+ * Description: Returns a string representing the number of bytes (up
+ * to 1024 bytes), the number of kilobytes (when less than 1024K)
+ * postfixed by 'K', the number of megabytes (when less than 1024M)
+ * postfixed by 'M' or the number of gigabytes postfixed by 'G'. If
+ * representing K, M or G, and the number is amount is less than 100,
+ * it includes a '.' plus the remainer. The returned string will be 5
+ * characters wide (padding with whitespace at the front) unless
+ * negative or representing more than 9999G bytes.
+ */
+function bytes_to_string:string (bytes:long)
+{
+ if (bytes < 1024)
+ return sprintf("%5d", bytes);
+
+ remain = bytes % 1024;
+ bytes = bytes / 1024;
+ if (bytes < 1024)
+ return _stp_number_to_string_postfix(bytes, remain, "K");
+
+ remain = bytes % 1024;
+ bytes = bytes / 1024;
+ if (bytes < 1024)
+ return _stp_number_to_string_postfix(bytes, remain, "M");
+
+ remain = bytes % 1024;
+ bytes = bytes / 1024;
+ return _stp_number_to_string_postfix(bytes, remain, "G");
+}
+
+/**
+ * sfunction pages_to_string - Turns pages into a human readable string.
+ *
+ * Description: Multiplies pages by page_size() to get the number of
+ * bytes and returns the result of bytes_to_string().
+ */
+function pages_to_string:string (pages:long)
+{
+ bytes = pages * mem_page_size();
+ return bytes_to_string (bytes);
+}
+
+/**
+ * sfunction proc_mem_string - Human readable string of current proc memory usage.
+ *
+ * Description: Returns a human readable string showing the size, rss,
+ * shr, txt and data of the memory used by the current process.
+ * For example "size: 301m, rss: 11m, shr: 8m, txt: 52k, data: 2248k".
+ */
+function proc_mem_string:string ()
+{
+ return sprintf ("size: %s, rss: %s, shr: %s, txt: %s, data: %s",
+ pages_to_string(proc_mem_size()),
+ pages_to_string(proc_mem_rss()),
+ pages_to_string(proc_mem_shr()),
+ pages_to_string(proc_mem_txt()),
+ pages_to_string(proc_mem_data()));
+}
diff --git a/tapset/scheduler.stp b/tapset/scheduler.stp
index 3c3d504e..b1911ac2 100644
--- a/tapset/scheduler.stp
+++ b/tapset/scheduler.stp
@@ -20,7 +20,7 @@ function __is_idle:long()
%}
-/* probe scheduler.cpu_off
+/** probe scheduler.cpu_off
*
* Fires when a process is about to stop running on a cpu.
*
@@ -41,7 +41,7 @@ probe scheduler.cpu_off
}
-/* probe scheduler.cpu_on
+/** probe scheduler.cpu_on
*
* Fires when a process is beginning execution on a cpu.
*
@@ -76,26 +76,6 @@ probe scheduler.tick = kernel.function("scheduler_tick")
idle = __is_idle()
}
-
-/* probe scheduler.migrate
- *
- * Fires whenever a task is moved to a different cpu's runqueue.
- *
- * Context:
- * Unknown (sometimes migration thread, sometimes cpu_to)
- *
- * Arguments:
- * task - the process that is being migrated
- * cpu_from - the cpu that is losing the task
- * cpu_to - the cpu that is claiming the task
- */
-probe scheduler.migrate = kernel.function("pull_task")? {
- task = $p
- cpu_from = task_cpu($p) /*thread_info renamed to stack since 2.6.22*/
- cpu_to = $this_cpu
-}
-
-
/* probe scheduler.balance
*
* Fires when a cpu attempts to find more work.
@@ -107,43 +87,314 @@ probe scheduler.migrate = kernel.function("pull_task")? {
probe scheduler.balance = kernel.function("idle_balance")? {}
-/* probe scheduler.ctxswitch
- *
- * Fires when there is a context switch
+/**
+ * probe scheduler.ctxswitch - Fires when there is a context switch. Currently
+ * systemTap can't access arguments of inline
+ * functions. So we choose to probe __switch_to instead
+ * of context_switch()
+ * @prev_pid: The pid of the process to be switched out
+ * @next_pid: The pid of the process to be switched in
+ * @prev_tid: The tid of the process to be switched out
+ * @next_tid: The tid of the process to be switched in
+ * @prev_task_name: The name of the process to be switched out
+ * @next_task_name: The name of the process to be switched in
+ * @prev_priority: The priority of the process to be switched out
+ * @next_priority: The priority of the process to be switched in
+ * @prevtsk_state: the state of the process to be switched out
+ * @nexttsk_state: the state of the process to be switched in
+ */
- * Currently systemTap can't access arguments of inline
- * functions. So we choose to probe __switch_to instead
- * of context_switch()
+probe __scheduler.ctxswitch.tp = kernel.trace("sched_switch")
+{
+ next_pid = $next->tgid
+ next_tid = $next->pid
+ next_task = $next
+ next_task_name = task_execname($next)
+ nexttsk_state = $next->state
+ next_priority = $next->prio
+ prev_priority = $prev->prio
+ prev_pid = $prev->tgid
+ prev_tid = $prev->pid
+ prev_task = $prev
+ prev_task_name = task_execname($prev)
+ prevtsk_state = $prev->state
+}
- * Arguments:
- * prev_pid: The pid of the process to be switched out
- * next_pid: The pid of the process to be switched in
- * prevtsk_state: the state of the process to be switched out
- */
-probe scheduler.ctxswitch =
+probe __scheduler.ctxswitch.kp =
%( arch != "x86_64" && arch != "ia64" %?
- kernel.trace("sched_switch") !, kernel.function("__switch_to")
+ kernel.function("__switch_to")
%:
- kernel.trace("sched_switch") !, kernel.function("context_switch")
+ kernel.function("context_switch")
%)
{
%( arch == "powerpc" %?
- prev_pid = $prev->pid
- next_pid = $new->pid
- prev_task = $prev
- next_task = $new
- prevtsk_state = $prev->state
+ prev_pid = $prev->tgid
+ next_pid = $new->tgid
+ prev_tid = $prev->pid
+ next_tid = $new->pid
+ prev_task = $prev
+ next_task = $new
+ next_priority = $new->prio
+ prev_priority = $prev->prio
+ prev_task_name = task_execname($prev)
+ next_task_name = task_execname($new)
+ prevtsk_state = $prev->state
+ nexttsk_state = $new->state
+
%: %( arch == "x86_64" || arch == "ia64" %?
- prev_pid = $prev->pid
- next_pid = $next->pid
- prev_task = $prev
- next_task = $next
- prevtsk_state = $prev->state
+ prev_pid = $prev->tgid
+ next_pid = $next->tgid
+ prev_tid = $prev->pid
+ next_tid = $next->pid
+ prev_task = $prev
+ next_task = $next
+ next_priority = $next->prio
+ prev_priority = $prev->prio
+ prev_task_name = task_execname($prev)
+ next_task_name = task_execname($next)
+ prevtsk_state = $prev->state
+ nexttsk_state = $next->state
%:
- prev_pid = $prev_p->pid
- next_pid = $next_p->pid
- prev_task = $prev_p
- next_task = $next_p
- prevtsk_state = $prev_p->state
+ prev_pid = $prev_p->tgid
+ next_pid = $next_p->tgid
+ prev_tid = $prev_p->pid
+ next_tid = $next_p->pid
+ prev_task = $prev_p
+ next_task = $next_p
+ next_priority = $next_p->prio
+ prev_priority = $prev_p->prio
+ prev_task_name = task_execname($prev_p)
+ next_task_name = task_execname($next_p)
+ prevtsk_state = $prev_p->state
+ nexttsk_state = $next_p->state
%) %)
}
+
+probe scheduler.ctxswitch
+ = __scheduler.ctxswitch.tp !, __scheduler.ctxswitch.kp
+{}
+
+
+/**
+ * probe scheduler.kthread_stop - Fires when a thread created by kthread_create is stopped.
+ * @thread_pid: pid of the thread being stopped.
+ * @thread_priority: priority of the thread.
+ */
+probe __scheduler.kthread_stop.kp = kernel.function("kthread_stop")
+{
+ thread_pid = $k->tgid
+ thread_priority = $k->priority
+}
+probe __scheduler.kthread_stop.tp = kernel.trace("sched_kthread_stop")
+{
+ thread_pid = $t->tgid
+ thread_priority = $t->prio
+}
+probe scheduler.kthread_stop
+ = __scheduler.kthread_stop.tp !,
+ __scheduler.kthread_stop.kp
+{}
+
+
+/**
+ * probe scheduler.kthread_stop.return - Fires once the kthread is stopped and gets the return value
+ * @return_value: return value after stopping the thread.
+ */
+
+probe __scheduler.kthread_stop.return.kp = kernel.function("kthread_stop").return
+{
+ return_value = $k->exit_code
+}
+probe __scheduler.kthread_stop.return.tp = kernel.trace("sched_kthread_stop_ret")
+{
+ return_value = $ret
+}
+
+probe scheduler.kthread_stop.return
+ = __scheduler.kthread_stop.return.tp !,
+ __scheduler.kthread_stop.return.kp
+{}
+
+/**
+ * probe scheduler.wait_task - Fires when waiting on a task to unschedule.
+ * It waits till the task becomes inactive.
+ * @task_pid: pid of the task the scheduler is waiting on.
+ * @task_priority: priority of the task
+ */
+
+probe scheduler.wait_task
+ = kernel.trace("sched_wait_task") !,
+ kernel.function("wait_task_inactive")
+{
+ task_pid = $p->tgid
+ task_priority = $p->prio
+}
+
+/**
+ * probe scheduler.wakeup - Fires when a task is woken up
+ * @task_pid: pid of the task being woken up
+ * @task_priority: priority of the task being woken up
+ * @task_cpu: cpu of the task being woken up
+ * @task_state: state of the task being woken up
+ * @task_tid: tid of the task being woken up
+ */
+
+probe scheduler.wakeup
+ = kernel.trace("sched_wakeup") !,
+ kernel.function("try_to_wake_up")
+{
+ task = $p
+ task_pid = $p->tgid
+ task_tid = $p->pid
+ task_priority = $p->prio
+ task_cpu = task_cpu($p)
+ task_state = task_state($p)
+}
+
+/**
+ * probe scheduler.wakeup_new - Fires when a newly created task is woken up for the first time
+ * @task_pid: pid of the new task woken up
+ * @task_priority: priority of the new task
+ * @task_tid: tid of the new task woken up
+ * @task_state: state of the task woken up
+ * @task_cpu: cpu of the task woken up
+ */
+probe scheduler.wakeup_new
+ = kernel.trace("sched_wakeup_new") !,
+ kernel.function("wake_up_new_task")
+{
+ task_pid = $p->tgid
+ task_priority = $p->prio
+ task_cpu = task_cpu($p)
+ task_state = task_state($p)
+ task = $p
+ task_tid = $p->pid
+}
+
+/**
+ * probe scheduler.migrate - Traces the migration of the tasks across cpus by the scheduler.
+ * @task: the process that is being migrated.
+ * @pid: pid of the task being migrated.
+ * @priority: priority of the task being migrated.
+ * @cpu_from: the original cpu
+ * @cpu_to: the destination cpu
+ */
+probe __scheduler.migrate.kp1 = kernel.function("pull_task")
+{
+ cpu_to = $this_cpu
+}
+probe __scheduler.migrate.kp = kernel.function("set_task_cpu")
+{
+ cpu_to = $new_cpu
+}
+probe __scheduler.migrate.tp = kernel.trace("sched_migrate_task")
+{
+ cpu_to = $dest_cpu
+}
+probe scheduler.migrate
+ = __scheduler.migrate.tp !,
+ __scheduler.migrate.kp !,
+ __scheduler.migrate.kp1
+{
+ task = $p
+ pid = $p->tgid
+ priority = $p->prio
+ cpu_from = task_cpu($p)
+}
+/**
+ * probe scheduler.process_free - Traces the process of freeing up of a process
+ * @pid: PID of the process getting freed
+ * @priority: priority of the process getting freed
+ */
+probe __scheduler.process_free.kp = kernel.function("delayed_put_task_struct")
+{
+ pid = $tsk->tgid
+ priority = $tsk->prio
+}
+probe __scheduler.process_free.tp = kernel.trace("sched_process_free")
+{
+ pid = $p->tgid
+ priority = $p->prio
+}
+probe scheduler.process_free
+ = __scheduler.process_free.tp !,
+ __scheduler.process_free.kp
+{}
+
+/**
+ * probe scheduler.process_exit - Fires when a process exits
+ * @pid: pid of the process exiting
+ * @priority: priority of the process exiting
+ */
+probe __scheduler.process_exit.kp = kernel.function("do_exit")
+{
+ pid = $tsk->tgid
+ priority = $tsk->priority
+}
+probe __scheduler.process_exit.tp = kernel.trace("sched_process_exit")
+{
+ pid = $p->tgid
+ priority = $p->prio
+}
+
+probe scheduler.process_exit
+ = __scheduler.process_exit.tp !,
+ __scheduler.process_exit.kp
+{}
+
+/**
+ * probe scheduler.process_wait - Fires when scheduler waits on a process
+ * @pid: PID of the process scheduler is waiting on
+ */
+probe __scheduler.process_wait.kp = kernel.function("do_wait")
+{
+ pid = $wo->wo_pid
+}
+probe __scheduler.process_wait.tp = kernel.trace("sched_process_wait")
+{
+ pid = $pid
+}
+probe scheduler.process_wait
+ = __scheduler.process_wait.tp !,
+ __scheduler.process_wait.kp
+{}
+
+/**
+ * probe scheduler.process_fork - Probes the tracepoint for forking a process
+ * @parent_pid: PID of the parent process
+ * @child_pid: PID of the child process
+ */
+probe __scheduler.process_fork.kp = kernel.function("do_fork")
+{
+ parent_pid = $current->tgid
+ child_pid = $p->tgid
+}
+probe __scheduler.process_fork.tp = kernel.trace("sched_process_fork")
+{
+ parent_pid = $parent->tgid
+ child_pid = $child->tgid
+}
+
+probe scheduler.process_fork
+ = __scheduler.process_fork.tp !,
+ __scheduler.process_fork.kp
+{}
+/**
+ * probe scheduler.signal_send - Probes the tracepoint for sending a signal
+ * @pid: pid of the process sending signal
+ * @signal_number: signal number
+ */
+probe __scheduler.signal_send.kp = kernel.function("__send_signal")
+{
+ pid = $t->tgid
+}
+probe __scheduler.signal_send.tp = kernel.trace("sched_signal_send")
+{
+ pid = $p->tgid
+}
+probe scheduler.signal_send
+ = __scheduler.signal_send.tp !,
+ __scheduler.signal_send.kp
+{
+ signal_number = $sig
+}