Title: [139263] trunk/Tools
Revision
139263
Author
[email protected]
Date
2013-01-09 17:56:23 -0800 (Wed, 09 Jan 2013)

Log 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:

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (139262 => 139263)


--- trunk/Tools/ChangeLog	2013-01-10 01:40:44 UTC (rev 139262)
+++ trunk/Tools/ChangeLog	2013-01-10 01:56:23 UTC (rev 139263)
@@ -1,3 +1,38 @@
+2013-01-09  Eric Seidel  <[email protected]>
+
+        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:
+
 2013-01-09  Julie Parent  <[email protected]>
 
         Dashboard cleanup: remove dead code.

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py (139262 => 139263)


--- trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py	2013-01-10 01:40:44 UTC (rev 139262)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py	2013-01-10 01:56:23 UTC (rev 139263)
@@ -64,6 +64,7 @@
 DRT_LIBRARY_NAME = 'libDumpRenderTree.so'
 
 SCALING_GOVERNORS_PATTERN = "/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor"
+KPTR_RESTRICT_PATH = "/proc/sys/kernel/kptr_restrict"
 
 # All the test cases are still served to DumpRenderTree through file protocol,
 # but we use a file-to-http feature to bridge the file request to host's http
@@ -363,12 +364,13 @@
     _cached_perf_host_path = None
     _have_searched_for_perf_host = False
 
-    def __init__(self, host, executable_path, output_dir, adb_path, device_serial, symfs_path, identifier=None):
+    def __init__(self, host, executable_path, output_dir, adb_path, device_serial, symfs_path, kallsyms_path, identifier=None):
         super(AndroidPerf, self).__init__(host, executable_path, output_dir, "data", identifier)
         self._device_serial = device_serial
         self._adb_command = [adb_path, '-s', self._device_serial]
         self._perf_process = None
         self._symfs_path = symfs_path
+        self._kallsyms_path = kallsyms_path
 
     def check_configuration(self):
         # Check that perf is installed
@@ -451,8 +453,14 @@
         self._run_adb_command(['pull', '/data/perf.data', self._output_path])
 
         perfhost_path = self._perfhost_path()
+        perfhost_report_command = [
+            'report',
+            '--input', self._output_path,
+            '--symfs', self._symfs_path,
+            '--kallsyms', self._kallsyms_path,
+        ]
         if perfhost_path:
-            perfhost_args = [perfhost_path, 'report', '-g', 'none', '-i', self._output_path, '--symfs', self._symfs_path]
+            perfhost_args = [perfhost_path] + perfhost_report_command + ['--call-graph', 'none']
             perf_output = self._host.executive.run_command(perfhost_args)
             # We could save off the full -g report to a file if users found that useful.
             print self._first_ten_lines_of_profile(perf_output)
@@ -473,7 +481,7 @@
 
         perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_linux'
         print "To view the full profile, run:"
-        print ' '.join([perfhost_display_patch, 'report', '-i', self._output_path, '--symfs', self._symfs_path])
+        print ' '.join([perfhost_display_patch] + perfhost_report_command)
 
 
 class ChromiumAndroidDriver(driver.Driver):
@@ -488,16 +496,19 @@
         self._forwarder_process = None
         self._has_setup = False
         self._original_governors = {}
+        self._original_kptr_restrict = None
         self._device_serial = port._get_device_serial(worker_number)
         self._adb_command_base = None
 
         # FIXME: If we taught ProfileFactory about "target" devices we could
         # just use the logic in Driver instead of duplicating it here.
         if self._port.get_option("profile"):
+            # FIXME: This should be done once, instead of per-driver!
             symfs_path = self._find_or_create_symfs()
+            kallsyms_path = self._update_kallsyms_cache(symfs_path)
             # FIXME: We should pass this some sort of "Bridge" object abstraction around ADB instead of a path/device pair.
             self._profiler = AndroidPerf(self._port.host, self._port._path_to_driver(), self._port.results_directory(),
-                self._port.path_to_adb(), self._device_serial, symfs_path)\
+                self._port.path_to_adb(), self._device_serial, symfs_path, kallsyms_path)
             # FIXME: This is a layering violation and should be moved to Port.check_sys_deps
             # once we have an abstraction around an adb_path/device_serial pair to make it
             # easy to make these class methods on AndroidPerf.
@@ -511,6 +522,22 @@
         self._teardown_performance()
         super(ChromiumAndroidDriver, self).__del__()
 
+    def _update_kallsyms_cache(self, output_dir):
+        kallsyms_name = "%s-kallsyms" % self._device_serial
+        kallsyms_cache_path = self._port.host.filesystem.join(output_dir, kallsyms_name)
+
+        self._restart_adb_as_root()
+
+        saved_kptr_restrict = self._run_adb_command(['shell', 'cat', KPTR_RESTRICT_PATH]).strip()
+        self._run_adb_command(['shell', 'echo', '0', '>', KPTR_RESTRICT_PATH])
+
+        print "Updating kallsyms file (%s) from device" % kallsyms_cache_path
+        self._pull_from_device("/proc/kallsyms", kallsyms_cache_path)
+
+        self._run_adb_command(['shell', 'echo', saved_kptr_restrict, '>', KPTR_RESTRICT_PATH])
+
+        return kallsyms_cache_path
+
     def _find_or_create_symfs(self):
         environment = self._port.host.copy_current_environment()
         env = environment.to_dictionary()

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py (139262 => 139263)


--- trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py	2013-01-10 01:40:44 UTC (rev 139262)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py	2013-01-10 01:56:23 UTC (rev 139263)
@@ -309,7 +309,7 @@
      2.73%   DumpRenderTree  DumpRenderTree               [.] WebCore::DocumentV8Internal::getElementsByTagNameCallback(v8::Arguments const&)
 """
         host = MockSystemHost()
-        profiler = chromium_android.AndroidPerf(host, '/bin/executable', '/tmp/output', 'adb-path', 'device-serial', 'foo')
+        profiler = chromium_android.AndroidPerf(host, '/bin/executable', '/tmp/output', 'adb-path', 'device-serial', '/tmp/symfs', '/tmp/kallsyms', 'foo')
         self.assertEqual(profiler._first_ten_lines_of_profile(perf_output), expected_first_ten_lines)
 
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to