blob: 9d53605fe11d497d151904670393df749b26d4c9 [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
class graphics_KernelMemory(test.test):
version = 1
# These are sysfs fields that will be read by this test. For different
# architectures, the sysfs field paths are different. The "paths" are given
# as lists of strings because the actual path may vary depending on the
# system. This test will read from the first sysfs path in the list that is
# present.
# e.g. ".../memory" vs ".../gpu_memory" -- if the system has either one of
# these, the test will read from that path.
arm_exynos_fields = {
'gem_objects' : ['/sys/kernel/debug/dri/0/exynos_gem_objects'],
'memory' : ['/sys/devices/platform/mali.0/memory',
'/sys/devices/platform/mali.0/gpu_memory'],
}
arm_tegra_fields = {
'memory': ['/sys/kernel/debug/memblock/memory'],
}
x86_fields = {
'gem_objects' : ['/sys/kernel/debug/dri/0/i915_gem_objects'],
'memory' : ['/sys/kernel/debug/dri/0/i915_gem_gtt'],
}
arch_fields = {
'arm_exynos' : arm_exynos_fields,
'arm_tegra' : arm_tegra_fields,
'i386' : x86_fields,
'x86_64' : x86_fields,
}
def run_once(self):
num_errors = 0
keyvals = {}
# Get architecture type and list of sysfs fields to read.
arch = utils.get_cpu_arch()
if arch == 'arm':
if utils.system_output('cat /proc/cpuinfo | grep -i EXYNOS',
ignore_status=True):
arch = 'arm_exynos'
elif utils.system_output('cat /proc/cpuinfo | grep -i Tegra',
ignore_status=True):
arch = 'arm_tegra'
if not arch in self.arch_fields:
raise error.TestFail('Architecture "%s" not yet supported.' % arch)
test_fields = self.arch_fields[arch]
for field_name in test_fields:
possible_field_paths = test_fields[field_name]
field_value = None
for path in possible_field_paths:
if utils.system('ls %s' % path):
continue
field_value = utils.system_output('cat %s' % path)
break
if not field_value:
logging.error('Unable to find any sysfs paths for field "%s"'
% field_name)
num_errors += 1
continue
parsed_results = self._parse_sysfs(field_value);
for key in parsed_results:
keyvals['%s_%s' % (field_name, key)] = parsed_results[key]
if 'bytes' in parsed_results and parsed_results['bytes'] == 0:
logging.error('%s reported 0 bytes' % field_name)
num_errors += 1
self.write_perf_keyval(keyvals)
if num_errors > 0:
raise error.TestFail('Test failed with %d errors' % num_errors)
def _parse_sysfs(self, output):
"""
Parses output of graphics memory sysfs to determine the number of
buffer objects and bytes.
Arguments:
output Unprocessed sysfs output
Return value:
Dictionary containing integer values of number bytes and objects.
They may have the keys 'bytes' and 'objects', respectively. However
the result may not contain both of these values.
"""
results = {}
labels = ['bytes', 'objects']
for line in output.split('\n'):
# Strip any commas to make parsing easier.
line_words = line.replace(',', '').split()
prev_word = None
for word in line_words:
# When a label has been found, the previous word should be the
# value. e.g. "3200 bytes"
if word in labels and word not in results and prev_word:
logging.info(prev_word)
results[word] = int(prev_word)
prev_word = word
# Once all values has been parsed, return.
if len(results) == len(labels):
return results
return results