Skip to content

Commit

Permalink
Merge pull request #2811 from FarooqAbdulla02/perf_lock
Browse files Browse the repository at this point in the history
Adding "perf_lock" Tests.
  • Loading branch information
Naresh-ibm authored Jun 8, 2024
2 parents 238adc7 + 16fb622 commit 2b8a3f0
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 0 deletions.
124 changes: 124 additions & 0 deletions perf/perf_lock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env python
#
# 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 LICENSE for more details.
#
# Copyright: 2024 IBM
# Author: Shaik Abdulla <[email protected]>

import os
import platform
from avocado import Test
from avocado.utils import distro, process, dmesg
from avocado.utils.software_manager.manager import SoftwareManager


class perf_lock(Test):

"""
Tests perf lock and it's options namely record, report, info, script
contention with all possible flags with the help of yaml file
:avocado: tags=perf
"""

def setUp(self):
'''
Install the basic packages to support perf
'''

# Check for basic utilities
smm = SoftwareManager()
detected_distro = distro.detect()
self.distro_name = detected_distro.name

deps = ['gcc', 'make']
if self.distro_name in ['rhel', 'SuSE', 'fedora', 'centos']:
deps.extend(['perf'])
else:
self.cancel("Install the package for perf supported \
by %s" % detected_distro.name)
for package in deps:
if not smm.check_installed(package) and not smm.install(package):
self.cancel('%s is needed for the test to be run' % package)

# output file to capture perf events
self.output_file = "perf.data"

# Check perf lock is available in the system.
output = process.getoutput('perf list', shell=True)
if 'lock:contention_begin' in output or \
'lock:contention_end' in output:
self.log.info("perf lock is available")
else:
self.cancel('perf lock is not available')

# Getting the parameters from yaml file
self.report = self.params.get('name', default='report')
self.option = self.params.get('option', default='')

# Clear the dmesg, by that we can capture the delta at
# the end of the test.
dmesg.clear_dmesg()

def run_cmd(self, cmd):
try:
process.run(cmd, ignore_status=False, sudo=True)
except process.CmdError as details:
self.fail("Command %s failed: %s" % (cmd, details))

def test_lock(self):
"""
'perf lock record' records lock events and this command produces the
file "perf.data" which contains tracing results of lock events. The
perf.data file is then used as input for report and other commands.
"""
# test perf lock with normal user
if self.report == 'normal_user_test':
# create temporary user
if process.system('useradd test', sudo=True, ignore_status=True):
self.log.warn('test useradd failed')
cmd = 'perf lock record -o %s -a -v sleep 3' % self.output_file
if not process.system('id test', ignore_status=True):
if not process.system("su -c '%s' test" % cmd, shell=True,
ignore_status=True):
self.fail("normal user has access to run perf lock")
process.system('userdel -f test', sudo=True)
else:
self.log.warn('User test does not exist, skipping test')
else:
# Record command
record_cmd = "perf lock record -o %s -- " \
"perf bench sched messaging" % self.output_file
self.run_cmd(record_cmd)
# Report command
if "-i" in self.option:
self.option += " " + self.output_file
if "--vmlinux" in self.option or "--kallsyms" in self.option:
if self.distro_name in ['rhel', 'fedora', 'centos']:
self.option += " /boot/vmlinuz-" + platform.uname()[2]
elif self.distro_name in ['SuSE', 'Ubuntu']:
self.option += " /boot/vmlinux-" + platform.uname()[2]
report_cmd = "perf lock %s %s" % (self.report, self.option)
# Validate the output of perf lock record
if os.path.exists(self.output_file):
if not os.stat(self.output_file).st_size:
self.fail("%s sample not captured" % self.output_file)
else:
self.run_cmd(report_cmd)

# Verify dmesg
dmesg.collect_errors_dmesg(['WARNING: CPU:', 'Oops', 'Segfault',
'soft lockup', 'Unable to handle'])

def tearDown(self):
# Delete the perf.data file
if os.path.isfile(self.output_file):
process.run('rm -f %s' % self.output_file)
21 changes: 21 additions & 0 deletions perf/perf_lock.py.data/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Overview

This automated script simplifies the usage of the perf lock command in Linux for analyzing system performance by capturing and analyzing lock contention events.
It streamlines the process of recording and reporting lock events with below mentioned features with supported options.

Features that handled by this script

1. Record
2. Report
3. info
4. Script
5. Contention


Feature options that handled by YAML

1. Record - all_cpus with verbose enabled.
2. Report - wait_field, all_fields, lock_with_entries and vmlinux_full.
3. info - Threads_list and map_instances.
4. script - input_data.
5. contention - contetion_fields,all_cpu_entries,average_wait_key,PID_trace,input_full and vmlinux_full.
51 changes: 51 additions & 0 deletions perf/perf_lock.py.data/record_report.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
subsystem: !mux
record:
name: record
variants: !mux
all_cpus:
option: -a -v sleep 3

report:
name: report
variants: !mux
wait_field:
option: -k wait_total -i
all_fields:
option: -t -F acquired,contended,avg_wait,wait_total
locks_with_entries:
option: -c -D -E 5
vmlinux_full:
option: -E 3 --kallsyms

info:
name: info
variants: !mux
threads_list:
option: -t
map_instances:
option: -m

script:
name: script
variants: !mux
input_data:
option: -f -i

contention:
name: contention
variants: !mux
contention_fields:
option: -C 0 -E 2 -F contended,wait_total -q
all_cpus_entires:
option: -a -t -E 1 -q
avg_wait_key:
option: -k avg_wait -l
trace_PID:
option: -p 1 -x ,
input_full:
option: -Y spinlock -q -i
vmlinux_full:
option: -E 2 --vmlinux

normal_user_test:
name: normal_user_test

0 comments on commit 2b8a3f0

Please sign in to comment.