1cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr""" 2cefc0f9eb9996bc9da9098a886e659c0578dbe00lmrperf is a tool included in the linux kernel tree that 3cefc0f9eb9996bc9da9098a886e659c0578dbe00lmrsupports functionality similar to oprofile and more. 4cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 5cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr@see: http://lwn.net/Articles/310260/ 6cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr""" 7cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 86f27d4f22a1ba5063968b8c322fa0845f3279adeEric Liimport time, os, stat, subprocess, signal 96f27d4f22a1ba5063968b8c322fa0845f3279adeEric Liimport logging 10cefc0f9eb9996bc9da9098a886e659c0578dbe00lmrfrom autotest_lib.client.bin import profiler, os_dep, utils 11cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 12cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 13cefc0f9eb9996bc9da9098a886e659c0578dbe00lmrclass perf(profiler.profiler): 14cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr version = 1 15cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 1674a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis def initialize(self, events=["cycles","instructions"], trace=False): 17d656d56473f50b9c1a9f5e2b2f5a9472181ee342Eric Li if type(events) == str: 18d656d56473f50b9c1a9f5e2b2f5a9472181ee342Eric Li self.events = [events] 19d656d56473f50b9c1a9f5e2b2f5a9472181ee342Eric Li else: 20d656d56473f50b9c1a9f5e2b2f5a9472181ee342Eric Li self.events = events 2122434d4311581dde7a3bb51eef03a27d757aa263Eric Li self.trace = trace 22cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr self.perf_bin = os_dep.command('perf') 23cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr perf_help = utils.run('%s report help' % self.perf_bin, 24cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr ignore_status=True).stderr 25cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr self.sort_keys = None 26cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr for line in perf_help.split('\n'): 27cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr a = "sort by key(s):" 28cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr if a in line: 2922434d4311581dde7a3bb51eef03a27d757aa263Eric Li line = line.replace(a, "") 30cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr self.sort_keys = [k.rstrip(",") for k in line.split() if 31cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr k.rstrip(",") != 'dso'] 32cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr if not self.sort_keys: 33cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr self.sort_keys = ['comm', 'cpu'] 34cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 35cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 36cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr def start(self, test): 37cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr self.logfile = os.path.join(test.profdir, "perf") 3822434d4311581dde7a3bb51eef03a27d757aa263Eric Li cmd = ("exec %s record -a -o %s" % 39d656d56473f50b9c1a9f5e2b2f5a9472181ee342Eric Li (self.perf_bin, self.logfile)) 4074a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis if "parent" in self.sort_keys: 4122434d4311581dde7a3bb51eef03a27d757aa263Eric Li cmd += " -g" 4222434d4311581dde7a3bb51eef03a27d757aa263Eric Li if self.trace: 4322434d4311581dde7a3bb51eef03a27d757aa263Eric Li cmd += " -R" 44d656d56473f50b9c1a9f5e2b2f5a9472181ee342Eric Li for event in self.events: 45d656d56473f50b9c1a9f5e2b2f5a9472181ee342Eric Li cmd += " -e %s" % event 46cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr self._process = subprocess.Popen(cmd, shell=True, 47cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr stderr=subprocess.STDOUT) 48cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 49cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 50cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr def stop(self, test): 51cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr os.kill(self._process.pid, signal.SIGINT) 52cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr self._process.wait() 53cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 54cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr 55cefc0f9eb9996bc9da9098a886e659c0578dbe00lmr def report(self, test): 5674a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis for key in self.sort_keys: 5774a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis reportfile = os.path.join(test.profdir, '%s.comm' % key) 5874a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis cmd = ("%s report -i %s --sort %s,dso" % (self.perf_bin, 5974a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis self.logfile, 6074a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis key)) 6174a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis outfile = open(reportfile, 'w') 6274a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis p = subprocess.Popen(cmd, shell=True, stdout=outfile, 6374a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis stderr=subprocess.STDOUT) 6474a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis p.wait() 6522434d4311581dde7a3bb51eef03a27d757aa263Eric Li 6674a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis if self.trace: 6774a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis tracefile = os.path.join(test.profdir, 'trace') 6874a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis cmd = ("%s script -i %s" % (self.perf_bin, self.logfile,)) 6922434d4311581dde7a3bb51eef03a27d757aa263Eric Li 7074a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis outfile = open(tracefile, 'w') 7174a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis p = subprocess.Popen(cmd, shell=True, stdout=outfile, 7274a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis stderr=subprocess.STDOUT) 7374a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis p.wait() 7422434d4311581dde7a3bb51eef03a27d757aa263Eric Li 7574a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis # The raw detailed perf output is HUGE. We cannot store it by default. 7674a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis perf_log_size = os.stat(self.logfile)[stat.ST_SIZE] 7774a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis logging.info('Removing %s after generating reports (saving %s bytes).', 7874a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis self.logfile, perf_log_size) 7974a314b490ff542c4dd2ae4aa0d11c6394d92960Dale Curtis os.unlink(self.logfile) 80