Changeset 139263 in webkit


Ignore:
Timestamp:
Jan 9, 2013 5:56:23 PM (11 years ago)
Author:
eric@webkit.org
Message:

run-perf-tests --chromium-android --profile should show symbols for the kernel
https://bugs.webkit.org/show_bug.cgi?id=106498

Reviewed by Adam Barth.

Turns out this was easy, once I finally read the output from "perf report".
It appears there may be a bug in "perf record" on android, as it complains
about not being able to read from /proc/kallsyms even when
/proc/sys/kernel/kptr_restrict is 0. For now I've not bothered
to keep /proc/sys/kernel/kptr_restrict as 0 during the actual record
but rather just flip it to 0 long enough to grab the /proc/kallsyms
and then flip it back to whatever the device had.

/proc/sys/kernel/kptr_restrict controls what /proc/kallsyms returns
on Linux. /proc/kallsyms contains a mapping of kernel addresses
to symbol names. Its world-readable, but will return all 0s if you
don't have permission to see the kernel symbols. kptr_restrict
supports values 0, 1, 2. Where 0 means "everyone can see the real symbols"
1 is only a specific group, and 2 is "no one, not even root".
By default kptr_restrict is 2 on Android it seems.
More kptr_restrict docs: http://lwn.net/Articles/420403/

I also took this opportunity to clean up how the perf record command
was built for use/display in AndroidPerf.profile_after_exit and
change to always using long-form names for the arguments (to hopefully help readability).

  • Scripts/webkitpy/layout_tests/port/chromium_android.py:

(AndroidPerf.init):
(profile_after_exit):
(ChromiumAndroidDriver.init):
(ChromiumAndroidDriver._update_kallsyms_cache):

  • Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py:
Location:
trunk/Tools
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r139260 r139263  
     12013-01-09  Eric Seidel  <eric@webkit.org>
     2
     3        run-perf-tests --chromium-android --profile should show symbols for the kernel
     4        https://bugs.webkit.org/show_bug.cgi?id=106498
     5
     6        Reviewed by Adam Barth.
     7
     8        Turns out this was easy, once I finally read the output from "perf report".
     9        It appears there may be a bug in "perf record" on android, as it complains
     10        about not being able to read from /proc/kallsyms even when
     11        /proc/sys/kernel/kptr_restrict is 0.  For now I've not bothered
     12        to keep /proc/sys/kernel/kptr_restrict as 0 during the actual record
     13        but rather just flip it to 0 long enough to grab the /proc/kallsyms
     14        and then flip it back to whatever the device had.
     15
     16        /proc/sys/kernel/kptr_restrict controls what /proc/kallsyms returns
     17        on Linux.  /proc/kallsyms contains a mapping of kernel addresses
     18        to symbol names.  Its world-readable, but will return all 0s if you
     19        don't have permission to see the kernel symbols.  kptr_restrict
     20        supports values 0, 1, 2.  Where 0 means "everyone can see the real symbols"
     21        1 is only a specific group, and 2 is "no one, not even root".
     22        By default kptr_restrict is 2 on Android it seems.
     23        More kptr_restrict docs: http://lwn.net/Articles/420403/
     24
     25        I also took this opportunity to clean up how the perf record command
     26        was built for use/display in AndroidPerf.profile_after_exit and
     27        change to always using long-form names for the arguments (to hopefully help readability).
     28
     29        * Scripts/webkitpy/layout_tests/port/chromium_android.py:
     30        (AndroidPerf.__init__):
     31        (profile_after_exit):
     32        (ChromiumAndroidDriver.__init__):
     33        (ChromiumAndroidDriver._update_kallsyms_cache):
     34        * Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py:
     35
    1362013-01-09  Julie Parent  <jparent@chromium.org>
    237
  • trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py

    r137692 r139263  
    6565
    6666SCALING_GOVERNORS_PATTERN = "/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor"
     67KPTR_RESTRICT_PATH = "/proc/sys/kernel/kptr_restrict"
    6768
    6869# All the test cases are still served to DumpRenderTree through file protocol,
     
    364365    _have_searched_for_perf_host = False
    365366
    366     def __init__(self, host, executable_path, output_dir, adb_path, device_serial, symfs_path, identifier=None):
     367    def __init__(self, host, executable_path, output_dir, adb_path, device_serial, symfs_path, kallsyms_path, identifier=None):
    367368        super(AndroidPerf, self).__init__(host, executable_path, output_dir, "data", identifier)
    368369        self._device_serial = device_serial
     
    370371        self._perf_process = None
    371372        self._symfs_path = symfs_path
     373        self._kallsyms_path = kallsyms_path
    372374
    373375    def check_configuration(self):
     
    452454
    453455        perfhost_path = self._perfhost_path()
     456        perfhost_report_command = [
     457            'report',
     458            '--input', self._output_path,
     459            '--symfs', self._symfs_path,
     460            '--kallsyms', self._kallsyms_path,
     461        ]
    454462        if perfhost_path:
    455             perfhost_args = [perfhost_path, 'report', '-g', 'none', '-i', self._output_path, '--symfs', self._symfs_path]
     463            perfhost_args = [perfhost_path] + perfhost_report_command + ['--call-graph', 'none']
    456464            perf_output = self._host.executive.run_command(perfhost_args)
    457465            # We could save off the full -g report to a file if users found that useful.
     
    474482        perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_linux'
    475483        print "To view the full profile, run:"
    476         print ' '.join([perfhost_display_patch, 'report', '-i', self._output_path, '--symfs', self._symfs_path])
     484        print ' '.join([perfhost_display_patch] + perfhost_report_command)
    477485
    478486
     
    489497        self._has_setup = False
    490498        self._original_governors = {}
     499        self._original_kptr_restrict = None
    491500        self._device_serial = port._get_device_serial(worker_number)
    492501        self._adb_command_base = None
     
    495504        # just use the logic in Driver instead of duplicating it here.
    496505        if self._port.get_option("profile"):
     506            # FIXME: This should be done once, instead of per-driver!
    497507            symfs_path = self._find_or_create_symfs()
     508            kallsyms_path = self._update_kallsyms_cache(symfs_path)
    498509            # FIXME: We should pass this some sort of "Bridge" object abstraction around ADB instead of a path/device pair.
    499510            self._profiler = AndroidPerf(self._port.host, self._port._path_to_driver(), self._port.results_directory(),
    500                 self._port.path_to_adb(), self._device_serial, symfs_path)\
     511                self._port.path_to_adb(), self._device_serial, symfs_path, kallsyms_path)
    501512            # FIXME: This is a layering violation and should be moved to Port.check_sys_deps
    502513            # once we have an abstraction around an adb_path/device_serial pair to make it
     
    511522        self._teardown_performance()
    512523        super(ChromiumAndroidDriver, self).__del__()
     524
     525    def _update_kallsyms_cache(self, output_dir):
     526        kallsyms_name = "%s-kallsyms" % self._device_serial
     527        kallsyms_cache_path = self._port.host.filesystem.join(output_dir, kallsyms_name)
     528
     529        self._restart_adb_as_root()
     530
     531        saved_kptr_restrict = self._run_adb_command(['shell', 'cat', KPTR_RESTRICT_PATH]).strip()
     532        self._run_adb_command(['shell', 'echo', '0', '>', KPTR_RESTRICT_PATH])
     533
     534        print "Updating kallsyms file (%s) from device" % kallsyms_cache_path
     535        self._pull_from_device("/proc/kallsyms", kallsyms_cache_path)
     536
     537        self._run_adb_command(['shell', 'echo', saved_kptr_restrict, '>', KPTR_RESTRICT_PATH])
     538
     539        return kallsyms_cache_path
    513540
    514541    def _find_or_create_symfs(self):
  • trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py

    r137550 r139263  
    310310"""
    311311        host = MockSystemHost()
    312         profiler = chromium_android.AndroidPerf(host, '/bin/executable', '/tmp/output', 'adb-path', 'device-serial', 'foo')
     312        profiler = chromium_android.AndroidPerf(host, '/bin/executable', '/tmp/output', 'adb-path', 'device-serial', '/tmp/symfs', '/tmp/kallsyms', 'foo')
    313313        self.assertEqual(profiler._first_ten_lines_of_profile(perf_output), expected_first_ten_lines)
    314314
Note: See TracChangeset for help on using the changeset viewer.