kernel_stats.cc revision 754
111660Stushar@ece.gatech.edu/* 211660Stushar@ece.gatech.edu * Copyright (c) 2003 The Regents of The University of Michigan 311660Stushar@ece.gatech.edu * All rights reserved. 411660Stushar@ece.gatech.edu * 511660Stushar@ece.gatech.edu * Redistribution and use in source and binary forms, with or without 611660Stushar@ece.gatech.edu * modification, are permitted provided that the following conditions are 711660Stushar@ece.gatech.edu * met: redistributions of source code must retain the above copyright 811660Stushar@ece.gatech.edu * notice, this list of conditions and the following disclaimer; 911660Stushar@ece.gatech.edu * redistributions in binary form must reproduce the above copyright 1011660Stushar@ece.gatech.edu * notice, this list of conditions and the following disclaimer in the 1111660Stushar@ece.gatech.edu * documentation and/or other materials provided with the distribution; 1211660Stushar@ece.gatech.edu * neither the name of the copyright holders nor the names of its 1311660Stushar@ece.gatech.edu * contributors may be used to endorse or promote products derived from 1411660Stushar@ece.gatech.edu * this software without specific prior written permission. 1511660Stushar@ece.gatech.edu * 1611660Stushar@ece.gatech.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711660Stushar@ece.gatech.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811660Stushar@ece.gatech.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911660Stushar@ece.gatech.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011660Stushar@ece.gatech.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111660Stushar@ece.gatech.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211660Stushar@ece.gatech.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311660Stushar@ece.gatech.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411660Stushar@ece.gatech.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511660Stushar@ece.gatech.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611660Stushar@ece.gatech.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711660Stushar@ece.gatech.edu */ 2811660Stushar@ece.gatech.edu 2911660Stushar@ece.gatech.edu#include <map> 3011660Stushar@ece.gatech.edu#include <stack> 3111660Stushar@ece.gatech.edu#include <string> 3211660Stushar@ece.gatech.edu 3311660Stushar@ece.gatech.edu#include "base/statistics.hh" 3411660Stushar@ece.gatech.edu#include "base/trace.hh" 3512065Snikos.nikoleris@arm.com#include "cpu/exec_context.hh" 3611660Stushar@ece.gatech.edu#include "kern/kernel_stats.hh" 3711660Stushar@ece.gatech.edu#include "sim/stats.hh" 3811660Stushar@ece.gatech.edu#include "sim/sw_context.hh" 3911660Stushar@ece.gatech.edu#include "targetarch/isa_traits.hh" 4011660Stushar@ece.gatech.edu#include "targetarch/osfpal.hh" 4111660Stushar@ece.gatech.edu#include "targetarch/syscalls.hh" 4211660Stushar@ece.gatech.edu 4311660Stushar@ece.gatech.eduusing namespace std; 4411660Stushar@ece.gatech.eduusing namespace Stats; 4512598Snikos.nikoleris@arm.com 4612598Snikos.nikoleris@arm.comclass KSData 4711660Stushar@ece.gatech.edu{ 4811660Stushar@ece.gatech.edu private: 4911660Stushar@ece.gatech.edu string _name; 5011660Stushar@ece.gatech.edu ExecContext *xc; 5111660Stushar@ece.gatech.edu BaseCPU *cpu; 5211660Stushar@ece.gatech.edu 5311660Stushar@ece.gatech.edu public: 5411660Stushar@ece.gatech.edu KSData(ExecContext *_xc, BaseCPU *_cpu) 5511660Stushar@ece.gatech.edu : xc(_xc), cpu(_cpu), iplLast(0), iplLastTick(0), lastUser(false), 5611660Stushar@ece.gatech.edu lastModeTick(0) 5711660Stushar@ece.gatech.edu {} 5811660Stushar@ece.gatech.edu 5911660Stushar@ece.gatech.edu const string &name() { return _name; } 6011660Stushar@ece.gatech.edu void regStats(const string &name); 6111660Stushar@ece.gatech.edu 6211660Stushar@ece.gatech.edu public: 6311660Stushar@ece.gatech.edu Scalar<> _arm; 6411660Stushar@ece.gatech.edu Scalar<> _quiesce; 6511660Stushar@ece.gatech.edu Scalar<> _ivlb; 6611660Stushar@ece.gatech.edu Scalar<> _ivle; 6711660Stushar@ece.gatech.edu Scalar<> _hwrei; 6811660Stushar@ece.gatech.edu 6913731Sandreas.sandberg@arm.com Vector<> _iplCount; 7011660Stushar@ece.gatech.edu Vector<> _iplGood; 7111660Stushar@ece.gatech.edu Vector<> _iplTicks; 7211660Stushar@ece.gatech.edu Formula _iplUsed; 7311660Stushar@ece.gatech.edu 7411660Stushar@ece.gatech.edu Vector<> _callpal; 7511660Stushar@ece.gatech.edu Vector<> _syscall; 7611660Stushar@ece.gatech.edu Vector<> _faults; 7711660Stushar@ece.gatech.edu 7811660Stushar@ece.gatech.edu Vector<> _mode; 7911660Stushar@ece.gatech.edu Vector<> _modeGood; 8011660Stushar@ece.gatech.edu Formula _modeFraction; 8111660Stushar@ece.gatech.edu Vector<> _modeTicks; 8211660Stushar@ece.gatech.edu 8311660Stushar@ece.gatech.edu Scalar<> _swap_context; 8411660Stushar@ece.gatech.edu 8511660Stushar@ece.gatech.edu private: 8611660Stushar@ece.gatech.edu int iplLast; 8711660Stushar@ece.gatech.edu Tick iplLastTick; 8811660Stushar@ece.gatech.edu 8911660Stushar@ece.gatech.edu bool lastUser; 9011660Stushar@ece.gatech.edu Tick lastModeTick; 9111660Stushar@ece.gatech.edu 9211660Stushar@ece.gatech.edu public: 9311660Stushar@ece.gatech.edu void swpipl(int ipl); 9411660Stushar@ece.gatech.edu void mode(bool user); 9511660Stushar@ece.gatech.edu void callpal(int code); 9611660Stushar@ece.gatech.edu}; 9711660Stushar@ece.gatech.edu 9811660Stushar@ece.gatech.eduKernelStats::KernelStats(ExecContext *xc, BaseCPU *cpu) 9911660Stushar@ece.gatech.edu{ data = new KSData(xc, cpu); } 10011660Stushar@ece.gatech.edu 10111660Stushar@ece.gatech.eduKernelStats::~KernelStats() 10211660Stushar@ece.gatech.edu{ delete data; } 10312598Snikos.nikoleris@arm.com 10412976Snikos.nikoleris@arm.comvoid 10512598Snikos.nikoleris@arm.comKernelStats::regStats(const string &name) 10612598Snikos.nikoleris@arm.com{ data->regStats(name); } 10712598Snikos.nikoleris@arm.com 10812065Snikos.nikoleris@arm.comvoid 10911660Stushar@ece.gatech.eduKSData::regStats(const string &name) 11011660Stushar@ece.gatech.edu{ 11111660Stushar@ece.gatech.edu _name = name; 11211660Stushar@ece.gatech.edu 11311660Stushar@ece.gatech.edu _arm 11411660Stushar@ece.gatech.edu .name(name + ".inst.arm") 11511660Stushar@ece.gatech.edu .desc("number of arm instructions executed") 11611660Stushar@ece.gatech.edu ; 11711660Stushar@ece.gatech.edu 11812598Snikos.nikoleris@arm.com _quiesce 119 .name(name + ".inst.quiesce") 120 .desc("number of quiesce instructions executed") 121 ; 122 123 _ivlb 124 .name(name + ".inst.ivlb") 125 .desc("number of ivlb instructions executed") 126 ; 127 128 _ivle 129 .name(name + ".inst.ivle") 130 .desc("number of ivle instructions executed") 131 ; 132 133 _hwrei 134 .name(name + ".inst.hwrei") 135 .desc("number of hwrei instructions executed") 136 ; 137 138 _iplCount 139 .init(32) 140 .name(name + ".ipl_count") 141 .desc("number of times we switched to this ipl") 142 .flags(total | pdf | nozero | nonan) 143 ; 144 145 _iplGood 146 .init(32) 147 .name(name + ".ipl_good") 148 .desc("number of times we switched to this ipl from a different ipl") 149 .flags(total | pdf | nozero | nonan) 150 ; 151 152 _iplTicks 153 .init(32) 154 .name(name + ".ipl_ticks") 155 .desc("number of cycles we spent at this ipl") 156 .flags(total | pdf | nozero | nonan) 157 ; 158 159 _iplUsed 160 .name(name + ".ipl_used") 161 .desc("fraction of swpipl calls that actually changed the ipl") 162 .flags(total | nozero | nonan) 163 ; 164 165 _iplUsed = _iplGood / _iplCount; 166 167 _callpal 168 .init(256) 169 .name(name + ".callpal") 170 .desc("number of callpals executed") 171 .flags(total | pdf | nozero | nonan) 172 ; 173 174 for (int i = 0; i < PAL::NumCodes; ++i) { 175 const char *str = PAL::name(i); 176 if (str) 177 _callpal.subname(i, str); 178 } 179 180 _syscall 181 .init(SystemCalls<Tru64>::Number) 182 .name(name + ".syscall") 183 .desc("number of syscalls executed") 184 .flags(total | pdf | nozero | nonan) 185 ; 186 187 for (int i = 0; i < SystemCalls<Tru64>::Number; ++i) { 188 const char *str = SystemCalls<Tru64>::name(i); 189 if (str) { 190 _syscall.subname(i, str); 191 } 192 } 193 194 _faults 195 .init(Num_Faults) 196 .name(name + ".faults") 197 .desc("number of faults") 198 .flags(total | pdf | nozero | nonan) 199 ; 200 201 for (int i = 1; i < Num_Faults; ++i) { 202 const char *str = FaultName(i); 203 if (str) 204 _faults.subname(i, str); 205 } 206 207 _mode 208 .init(2) 209 .name(name + ".mode_switch") 210 .subname(0, "kernel") 211 .subname(1, "user") 212 .desc("number of protection mode switches") 213 ; 214 215 _modeGood 216 .init(2) 217 ; 218 219 _modeFraction 220 .name(name + ".mode_switch_good") 221 .subname(0, "kernel") 222 .subname(1, "user") 223 .desc("fraction of useful protection mode switches") 224 .flags(total) 225 ; 226 _modeFraction = _modeGood / _mode; 227 228 _modeTicks 229 .init(2) 230 .name(name + ".mode_ticks") 231 .subname(0, "kernel") 232 .subname(1, "user") 233 .desc("number of ticks spent at the given mode") 234 .flags(pdf) 235 ; 236 237 _swap_context 238 .name(name + ".swap_context") 239 .desc("number of times the context was actually changed") 240 ; 241} 242 243void 244KernelStats::arm() 245{ data->_arm++; } 246 247void 248KernelStats::quiesce() 249{ data->_quiesce++; } 250 251void 252KernelStats::ivlb() 253{ data->_ivlb++; } 254 255void 256KernelStats::ivle() 257{ data->_ivle++; } 258 259void 260KernelStats::hwrei() 261{ data->_hwrei++; } 262 263void 264KernelStats::fault(Fault fault) 265{ data->_faults[fault]++; } 266 267void 268KernelStats::swpipl(int ipl) 269{ data->swpipl(ipl); } 270 271void 272KernelStats::mode(bool user) 273{ data->mode(user); } 274 275void 276KernelStats::context(Addr old_pcbb, Addr new_pcbb) 277{ data->_swap_context++; } 278 279void 280KernelStats::callpal(int code) 281{ data->callpal(code); } 282 283 284void 285KSData::swpipl(int ipl) 286{ 287 assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n"); 288 289 _iplCount[ipl]++; 290 291 if (ipl == iplLast) 292 return; 293 294 _iplGood[ipl]++; 295 _iplTicks[iplLast] += curTick - iplLastTick; 296 iplLastTick = curTick; 297 iplLast = ipl; 298} 299 300void 301KSData::mode(bool user) 302{ 303 _mode[user]++; 304 if (user == lastUser) 305 return; 306 307 _modeGood[user]++; 308 _modeTicks[lastUser] += curTick - lastModeTick; 309 310 lastModeTick = curTick; 311 lastUser = user; 312 313 if (xc->system->bin) { 314 if (!xc->swCtx || xc->swCtx->callStack.empty()) { 315 if (user) 316 xc->system->User->activate(); 317 else 318 xc->system->Kernel->activate(); 319 } 320 } 321} 322 323void 324KSData::callpal(int code) 325{ 326 if (!PAL::name(code)) 327 return; 328 329 _callpal[code]++; 330 331 switch (code) { 332 case PAL::callsys: 333 { 334 int number = xc->regs.intRegFile[0]; 335 if (SystemCalls<Tru64>::validSyscallNumber(number)) { 336 int cvtnum = SystemCalls<Tru64>::convert(number); 337 _syscall[cvtnum]++; 338 } 339 } 340 break; 341 } 342 343 if (code == PAL::swpctx) { 344 SWContext *out = xc->swCtx; 345 System *sys = xc->system; 346 if (!sys->bin) 347 return; 348 DPRINTF(TCPIP, "swpctx event\n"); 349 if (out) { 350 DPRINTF(TCPIP, "swapping context out with this stack!\n"); 351 xc->system->dumpState(xc); 352 Addr oldPCB = xc->regs.ipr[TheISA::IPR_PALtemp23]; 353 354 if (out->callStack.empty()) { 355 DPRINTF(TCPIP, "but removing it, cuz empty!\n"); 356 SWContext *find = sys->findContext(oldPCB); 357 if (find) { 358 assert(sys->findContext(oldPCB) == out); 359 sys->remContext(oldPCB); 360 } 361 delete out; 362 } else { 363 DPRINTF(TCPIP, "switching out context with pcb %#x, top fn %s\n", 364 oldPCB, out->callStack.top()->name); 365 if (!sys->findContext(oldPCB)) { 366 if (!sys->addContext(oldPCB, out)) 367 panic("could not add context"); 368 } 369 } 370 } 371 372 Addr newPCB = xc->regs.intRegFile[16]; 373 SWContext *in = sys->findContext(newPCB); 374 xc->swCtx = in; 375 376 if (in) { 377 assert(!in->callStack.empty() && 378 "should not be switching in empty context"); 379 DPRINTF(TCPIP, "swapping context in with this callstack!\n"); 380 xc->system->dumpState(xc); 381 sys->remContext(newPCB); 382 fnCall *top = in->callStack.top(); 383 DPRINTF(TCPIP, "switching in to pcb %#x, %s\n", newPCB, top->name); 384 assert(top->myBin && "should not switch to context with no Bin"); 385 top->myBin->activate(); 386 } else { 387 sys->Kernel->activate(); 388 } 389 DPRINTF(TCPIP, "end swpctx\n"); 390 } 391} 392