/************************************************************************** * * * Copyright (c) International Business Machines Corp., 2005 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * * Author: Guanglei Li (guanglei@cn.ibm.com) * **************************************************************************/ /********************************************************** * Dispatching when the cpu is idle or when a new process * * is chosen to run. * * * * The actual locations for these two kinds of events are * * the labels go_idle and switch_tasks inside the function * * schedule. But currently SystemTap doesn't support * * specifying probe points by label. * * * * Bugzilla shows that #1564 has been fixed * **********************************************************/ probe addevent.tskdispatch = addevent.tskdispatch.ctxswitch, addevent.tskdispatch.cpuidle { } /******************************************************* * Pls refer to #908 in bugzilla. * * * * Currently systemTap can't access arguments of inline * * functions. So we choose to probe __switch_to instead * * of context_switch() * *******************************************************/ probe addevent.tskdispatch.ctxswitch = kernel.function("__switch_to") { if(filter_by_pid() == 1 ) { log_tracedata_common(HOOKID_TASK_CTXSWITCH) /* multi-arches processing */ %( arch == "ppc64" %? log_ctxswitch_extra($prev, $new) %: %( arch == "i686" %? log_ctxswitch_extra($prev_p, $next_p) %: UNSUPPORTED %) %) } //end if } /* Only applicable to SMP systems */ probe addevent.tskdispatch.cpuidle = kernel.inline("idle_balance") { /* we didn't call filter_by_pid() here, so that we can get all the idle events despite how the cpu enters idle */ log_tracedata_common(HOOKID_TASK_CPUIDLE) log_cpuidle_extra() } function log_ctxswitch_extra(prev:long, next:long) %{ struct task_struct *prev_tsk, *next_tsk; prev_tsk = (struct task_struct *)((long)THIS->prev); next_tsk = (struct task_struct *)((long)THIS->next); _stp_printf("%ld|%ld|%ld|", prev_tsk->pid, next_tsk->pid, prev_tsk->state); %} function log_cpuidle_extra() %{ struct task_struct *cur = current; _stp_printf("%ld|", cur->pid); %}