1 /* 2 * Copyright 2009, Intel Corporation 3 * Copyright 2009, Sun Microsystems, Inc 4 * 5 * This file is part of PowerTOP 6 * 7 * This program file is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; version 2 of the License. 10 * 11 * This program is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program in a file named COPYING; if not, write to the 18 * Free Software Foundation, Inc., 19 * 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301 USA 21 * 22 * Authors: 23 * Arjan van de Ven <arjan@linux.intel.com> 24 * Eric C Saxe <eric.saxe@sun.com> 25 * Aubrey Li <aubrey.li@intel.com> 26 */ 27 28 /* 29 * GPL Disclaimer 30 * 31 * For the avoidance of doubt, except that if any license choice other 32 * than GPL or LGPL is available it will apply instead, Sun elects to 33 * use only the General Public License version 2 (GPLv2) at this time 34 * for any software where a choice of GPL license versions is made 35 * available with the language indicating that GPLv2 or any later 36 * version may be used, or where a choice of which version of the GPL 37 * is applied is otherwise unspecified. 38 */ 39 40 /* 41 * DTrace scripts for observing interrupts, callouts and cyclic events 42 * that cause CPU activity. Such activity prevents the processor from 43 * entering lower power states and reducing power consumption. 44 * 45 * g_dtp_events is the default script 46 */ 47 const char *g_dtp_events = 48 "interrupt-complete" 49 "/arg0 != NULL && arg3 !=0/" 50 "{" 51 " this->devi = (struct dev_info *)arg0;" 52 " @interrupts[stringof(`devnamesp[this->devi->devi_major].dn_name)," 53 " this->devi->devi_instance] = count();" 54 "}" 55 "" 56 "sdt:::callout-start" 57 "/(caddr_t)((callout_t *)arg0)->c_func == (caddr_t)&`setrun/" 58 "{" 59 " this->thr = (kthread_t *)(((callout_t *)arg0)->c_arg);" 60 " @events_u[stringof(this->thr->t_procp->p_user.u_comm)] = count();" 61 "}" 62 "" 63 "sdt:::callout-start" 64 "/(caddr_t)((callout_t *)arg0)->c_func != (caddr_t)&`setrun/" 65 "{" 66 " @events_k[(caddr_t)((callout_t *)arg0)->c_func] = count();" 67 "}" 68 "" 69 "sdt:::cyclic-start" 70 "/(caddr_t)((cyclic_t *)arg0)->cy_handler == (caddr_t)&`clock/" 71 "{" 72 " @events_k[(caddr_t)((cyclic_t *)arg0)->cy_handler] = count();" 73 "}" 74 "" 75 "fbt::xt_all:entry," 76 "fbt::xc_all:entry" 77 "{" 78 " self->xc_func = arg0;" 79 "}" 80 "" 81 "fbt::xt_one_unchecked:entry," 82 "fbt::xt_some:entry," 83 "fbt::xc_one:entry," 84 "fbt::xc_some:entry" 85 "{" 86 " self->xc_func = arg1;" 87 "}" 88 "" 89 "sysinfo:::xcalls" 90 "/pid != $pid/" 91 "{" 92 " @events_x[execname, self->xc_func] = sum(arg0);" 93 " self->xc_func = 0;" 94 "}"; 95 96 /* 97 * g_dtp_events_v is enabled through the -v option, it includes cyclic events 98 * in the report, allowing a complete view of system activity 99 */ 100 const char *g_dtp_events_v = 101 "interrupt-complete" 102 "/arg0 != NULL && arg3 !=0/" 103 "{" 104 " this->devi = (struct dev_info *)arg0;" 105 " @interrupts[stringof(`devnamesp[this->devi->devi_major].dn_name)," 106 " this->devi->devi_instance] = count();" 107 "}" 108 "" 109 "sdt:::callout-start" 110 "/(caddr_t)((callout_t *)arg0)->c_func == (caddr_t)&`setrun/" 111 "{" 112 " this->thr = (kthread_t *)(((callout_t *)arg0)->c_arg);" 113 " @events_u[stringof(this->thr->t_procp->p_user.u_comm)] = count();" 114 "}" 115 "" 116 "sdt:::callout-start" 117 "/(caddr_t)((callout_t *)arg0)->c_func != (caddr_t)&`setrun/" 118 "{" 119 " @events_k[(caddr_t)((callout_t *)arg0)->c_func] = count();" 120 "}" 121 "" 122 "sdt:::cyclic-start" 123 "/(caddr_t)((cyclic_t *)arg0)->cy_handler != (caddr_t)&`dtrace_state_deadman &&" 124 " (caddr_t)((cyclic_t *)arg0)->cy_handler != (caddr_t)&`dtrace_state_clean/" 125 "{" 126 " @events_k[(caddr_t)((cyclic_t *)arg0)->cy_handler] = count();" 127 "}" 128 "" 129 "fbt::xt_all:entry," 130 "fbt::xc_all:entry" 131 "{" 132 " self->xc_func = arg0;" 133 "}" 134 "" 135 "fbt::xt_one_unchecked:entry," 136 "fbt::xt_some:entry," 137 "fbt::xc_one:entry," 138 "fbt::xc_some:entry" 139 "{" 140 " self->xc_func = arg1;" 141 "}" 142 "" 143 "sysinfo:::xcalls" 144 "/pid != $pid/" 145 "{" 146 " @events_x[execname, self->xc_func] = sum(arg0);" 147 " self->xc_func = 0;" 148 "}"; 149 150 /* 151 * This script is selected through the -c option, it takes the CPU id as 152 * argument and observes activity generated by that CPU 153 */ 154 const char *g_dtp_events_c = 155 "interrupt-complete" 156 "/cpu == $0 &&" 157 " arg0 != NULL && arg3 != 0/" 158 "{" 159 " this->devi = (struct dev_info *)arg0;" 160 " @interrupts[stringof(`devnamesp[this->devi->devi_major].dn_name)," 161 " this->devi->devi_instance] = count();" 162 "}" 163 "" 164 "sdt:::callout-start" 165 "/cpu == $0 &&" 166 " (caddr_t)((callout_t *)arg0)->c_func == (caddr_t)&`setrun/" 167 "{" 168 " this->thr = (kthread_t *)(((callout_t *)arg0)->c_arg);" 169 " @events_u[stringof(this->thr->t_procp->p_user.u_comm)] = count();" 170 "}" 171 "" 172 "sdt:::callout-start" 173 "/cpu == $0 &&" 174 " (caddr_t)((callout_t *)arg0)->c_func != (caddr_t)&`setrun/" 175 "{" 176 " @events_k[(caddr_t)((callout_t *)arg0)->c_func] = count();" 177 "}" 178 "" 179 "sdt:::cyclic-start" 180 "/cpu == $0 &&" 181 " (caddr_t)((cyclic_t *)arg0)->cy_handler == (caddr_t)&`clock/" 182 "{" 183 " @events_k[(caddr_t)((cyclic_t *)arg0)->cy_handler] = count();" 184 "}" 185 "" 186 /* 187 * xcalls to all CPUs. We're only interested in firings from other CPUs since 188 * the system doesn't xcall itself 189 */ 190 "fbt::xt_all:entry," 191 "fbt::xc_all:entry" 192 "/pid != $pid &&" 193 " cpu != $0/" 194 "{" 195 " self->xc_func = arg0;" 196 " self->xc_cpu = cpu;" 197 " self->cpu_known = 1;" 198 "}" 199 "" 200 /* 201 * xcalls to a subset of CPUs. No way of knowing if the observed CPU is in 202 * it, so account it in the generic @events_x aggregation. Again, we don't 203 * xcall the current CPU. 204 */ 205 "fbt::xt_some:entry," 206 "fbt::xc_some:entry" 207 "/pid != $pid &&" 208 " cpu != $0/" 209 "{" 210 " self->xc_func = arg1;" 211 "}" 212 "" 213 /* 214 * xcalls to a specific CPU, with all the necessary information 215 */ 216 "fbt::xt_one_unchecked:entry," 217 "fbt::xc_one:entry" 218 "/arg0 == $0/" 219 "{" 220 " self->xc_func = arg1;" 221 " self->xc_cpu = arg0;" 222 " self->cpu_known = 1;" 223 "}" 224 "" 225 "sysinfo:::xcalls" 226 "/pid != $pid &&" 227 " self->xc_func &&" 228 " !self->cpu_known/" 229 "{" 230 " @events_x[execname, self->xc_func] = sum(arg0);" 231 " self->xc_func = 0;" 232 "}" 233 "" 234 "sysinfo:::xcalls" 235 "/pid != $pid &&" 236 " self->xc_func &&" 237 " self->cpu_known/" 238 "{" 239 " @events_xc[execname, self->xc_func, self->xc_cpu] = sum(arg0);" 240 " self->xc_func = 0;" 241 " self->xc_cpu = 0;" 242 " self->cpu_known = 0;" 243 "}"; 244 245 /* 246 * sparcv9 platform specific display messages 247 */ 248 const char *g_msg_idle_state = "Idle Power States\t"; 249 const char *g_msg_freq_state = "Frequency Levels"; 250