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";
 249 const char *g_msg_freq_state = "Frequency Levels";
 250 const char *g_msg_freq_enable = "P - Enable CPU PM";