diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-14 00:44:26 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-14 00:44:26 +0000 |
commit | bc9ff16e7a7af88866688fc46f788dbc974b25f1 (patch) | |
tree | 1532999add43e4b3c9d79b6fcaee864c06873603 | |
parent | cb3381988ec1617f3d794162410c54bc5521a8ed (diff) | |
parent | 6b06e7807dcb0c6226397cb8f453caa087775373 (diff) | |
download | igt-gpu-tools-android12-mainline-permission-release.tar.gz |
Snap for 7547121 from 6b06e7807dcb0c6226397cb8f453caa087775373 to mainline-permission-releaseandroid-mainline-12.0.0_r93android-mainline-12.0.0_r79android-mainline-12.0.0_r64android-mainline-12.0.0_r51android-mainline-12.0.0_r34android-mainline-12.0.0_r15android-mainline-12.0.0_r123android-mainline-12.0.0_r107android12-mainline-permission-release
Change-Id: I98b156dea687a122df3076330500bbb8c5517807
-rw-r--r-- | Android.bp | 73 | ||||
-rw-r--r-- | METADATA | 9 | ||||
l--------- | NOTICE | 1 | ||||
-rw-r--r-- | benchmarks/kms_throughput.c | 467 | ||||
-rw-r--r-- | scripts/test_igt_gpu_tools.py | 119 | ||||
-rw-r--r-- | scripts/test_igt_gpu_tools.xml | 40 | ||||
-rwxr-xr-x | tests/kms_flip.c | 2 |
7 files changed, 708 insertions, 3 deletions
diff --git a/Android.bp b/Android.bp index 477efe2ef..cb0fda9c1 100644 --- a/Android.bp +++ b/Android.bp @@ -1,3 +1,37 @@ +package { + default_applicable_licenses: ["external_igt-gpu-tools_license"], +} + +// Added automatically by a large-scale-change that took the approach of +// 'apply every license found to every target'. While this makes sure we respect +// every license restriction, it may not be entirely correct. +// +// e.g. GPL in an MIT project might only apply to the contrib/ directory. +// +// Please consider splitting the single license below into multiple licenses, +// taking care not to lose any license_kind information, and overriding the +// default license using the 'licenses: [...]' property on targets as needed. +// +// For unused files, consider creating a 'fileGroup' with "//visibility:private" +// to attach the license to, and including a comment whether the files may be +// used in the current project. +// See: http://go/android-license-faq +license { + name: "external_igt-gpu-tools_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "SPDX-license-identifier-GPL", + "SPDX-license-identifier-GPL-2.0", + "SPDX-license-identifier-ISC", + "SPDX-license-identifier-LGPL", + "SPDX-license-identifier-MIT", + ], + license_text: [ + "COPYING", + ], +} + cc_defaults { name: "igt-gpu-tools-defaults", cflags: [ @@ -12,6 +46,15 @@ cc_defaults { ], static_libs: ["libelf", "libkmod", "libion", "liblog"], shared_libs: ["libdrm"], + compile_multilib: "both", + multilib: { + lib32: { + suffix: "32", + }, + lib64: { + suffix: "64" + }, + }, } cc_library_static { @@ -58,28 +101,58 @@ cc_test { name: "gem_blt", defaults: ["igt-gpu-tools-test-defaults"], srcs: ["benchmarks/gem_blt.c"], + gtest: false, } cc_test { name: "kms_flip", defaults: ["igt-gpu-tools-test-defaults"], srcs: ["tests/kms_flip.c"], + gtest: false, } cc_test { name: "kms_atomic", defaults: ["igt-gpu-tools-test-defaults"], srcs: ["tests/kms_atomic.c"], + gtest: false, } cc_test { name: "ion_fb", defaults: ["igt-gpu-tools-test-defaults"], srcs: ["tests/ion_fb.c"], + gtest: false, } cc_test { name: "kms_vblank", defaults: ["igt-gpu-tools-test-defaults"], srcs: ["tests/kms_vblank.c"], + gtest: false, +} + +python_test_host { + name: "igt_gpu_tools", + main: "scripts/test_igt_gpu_tools.py", + srcs: [ "scripts/test_igt_gpu_tools.py", ], + data: [ "scripts/test_igt_gpu_tools.xml" ], + test_config: "scripts/test_igt_gpu_tools.xml", + version: { + py2: { + enabled: false, + }, + py3: { + enabled: true, + }, + }, + test_options: { + unit_test: false, + }, +} + +cc_test { + name: "kms_throughput", + defaults: ["igt-gpu-tools-test-defaults"], + srcs: ["benchmarks/kms_throughput.c"], } @@ -6,7 +6,14 @@ third_party { value: "https://gitlab.freedesktop.org/drm/igt-gpu-tools" } version: "357dbe1869d88a2f08bcee4eebceff4ee9014424" - license_type: NOTICE + # would be NOTICE save for: + # include/drm-uapi/armada_drm.h + # include/drm-uapi/etnaviv_drm.h + # include/drm-uapi/exynos_drm.h + # include/drm-uapi/i810_drm.h + # include/drm-uapi/omap_drm.h + # include/drm-uapi/sync_file.h + license_type: RESTRICTED last_upgrade_date { year: 2019 month: 8 diff --git a/NOTICE b/NOTICE deleted file mode 120000 index 7a694c969..000000000 --- a/NOTICE +++ /dev/null @@ -1 +0,0 @@ -LICENSE
\ No newline at end of file diff --git a/benchmarks/kms_throughput.c b/benchmarks/kms_throughput.c new file mode 100644 index 000000000..692304518 --- /dev/null +++ b/benchmarks/kms_throughput.c @@ -0,0 +1,467 @@ +/* + * Copyright © 2019 Google LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** @file kms_throughput.c + */ + +#include <drm.h> +#include <sys/time.h> +#include <xf86drm.h> +#include "drmtest.h" +#include "igt.h" +#include "ion.h" + +static void make_display(igt_display_t *display) +{ + display->drm_fd = drm_open_driver_master(DRIVER_ANY); + igt_display_require(display, display->drm_fd); + igt_require(display->is_atomic); + igt_display_require_output(display); +} + +static bool get_output(igt_display_t *display, + enum pipe *pipe, igt_output_t **output) +{ + igt_info("Display %p has %d pipes\n", display, display->n_pipes); + for (int i = 0; i < display->n_pipes; ++i) + { + igt_info("Pipe %d (crtc %u) has %d planes\n", + i, display->pipes[i].crtc_id, + display->pipes[i].n_planes); + } + + for_each_pipe_with_valid_output(display, *pipe, *output) + { + /* we are happy with the first one */ + return true; + } + + return false; +} + +static void get_pipe(igt_display_t *display, + igt_pipe_t **p, igt_output_t **output) +{ + enum pipe pipe_idx = PIPE_NONE; + *output = NULL; + igt_require(get_output(display, &pipe_idx, output)); + igt_info("Using output id %u, name %s\n", + (*output)->id, (*output)->name); + + /* I'd love to call this 'pipe' but pipe(2) is in the way */ + *p = &display->pipes[pipe_idx]; + igt_require(*p); + + igt_info("Chosen pipe (crtc %u) has %d planes\n", + (*p)->crtc_id, (*p)->n_planes); +} + +static void prepare(igt_display_t *display, igt_pipe_t *p, igt_output_t *output) +{ + igt_display_reset(display); + igt_output_set_pipe(output, p->pipe); +} + +static igt_plane_t *plane_for_index(igt_pipe_t *p, size_t index) +{ + return &p->planes[index]; +} + +struct histogram +{ + struct timeval last_commit; + size_t num_buckets; + size_t *buckets; +}; + +static void histogram_init(struct histogram *h) +{ + gettimeofday(&h->last_commit, NULL); + h->num_buckets = 100; + h->buckets = calloc(h->num_buckets, sizeof(*h->buckets)); +} + +static void histogram_update(struct histogram *h) +{ + struct timeval this_commit; + gettimeofday(&this_commit, NULL); + + struct timeval diff; + timersub(&this_commit, &h->last_commit, &diff); + const size_t ms = (diff.tv_sec * 1000) + (diff.tv_usec / 1000); + size_t bucket = ms; + if (bucket >= h->num_buckets) + { + // the last bucket is a catch-all + bucket = h->num_buckets - 1; + } + h->buckets[bucket]++; + + memcpy(&h->last_commit, &this_commit, sizeof(this_commit)); +} + +static void histogram_print(struct histogram *h) +{ + igt_info("Histogram buckets with 1 or more entries:\n"); + + for (size_t i = 0; i < h->num_buckets; ++i) + { + size_t value = h->buckets[i]; + + if (value) + { + if (i == h->num_buckets - 1) + { + igt_info("%zu+ ms: %zu\n", i, value); + } + else + { + igt_info("%zu ms: %zu\n", i, value); + } + } + } +} + +static void histogram_cleanup(struct histogram *h) +{ + free(h->buckets); +} + +static const size_t max_num_fbs = 32; + +struct tuning +{ + drmModeModeInfoPtr mode; + size_t num_iterations; + size_t num_fb_sets; + size_t num_fbs; + struct fbgeom { + size_t width; + size_t height; + } fb_geom[max_num_fbs]; +}; + +static void info_timestamp(const char *text) +{ + struct timeval ts; + gettimeofday(&ts, NULL); + igt_debug("%ld: %s\n", ts.tv_usec, text); +} + +static void flip_overlays(igt_pipe_t *p, struct igt_fb **fb_sets, + const struct tuning *tuning, + size_t iter) +{ + size_t fb_set = iter % tuning->num_fb_sets; + struct igt_fb *fbs = fb_sets[fb_set]; + + for (size_t i = 0; i < tuning->num_fbs; ++i) + { + igt_plane_t *plane = plane_for_index(p, i); + igt_plane_set_prop_value(plane, IGT_PLANE_ZPOS, i); + igt_plane_set_fb(plane, &fbs[i]); + } + + igt_pipe_obj_set_prop_value(p, IGT_CRTC_ACTIVE, 1); + + info_timestamp("start commit"); + igt_display_commit2(p->display, COMMIT_ATOMIC); + info_timestamp("end commit"); +} + +static void repeat_flip(igt_pipe_t *p, struct igt_fb **fb_sets, + const struct tuning *tuning) +{ + struct histogram h; + histogram_init(&h); + + for (size_t iter = 0; iter < tuning->num_iterations; ++iter) + { + igt_debug("Iteration %zu\n", iter); + flip_overlays(p, fb_sets, tuning, iter); + histogram_update(&h); + } + + igt_debug("About to clear fbs\n"); + + for (size_t i = 0; i < tuning->num_fbs; ++i) + { + igt_plane_t *plane = plane_for_index(p, i); + igt_plane_set_fb(plane, NULL); + } + + igt_debug("About to flip with no fbs\n"); + + igt_display_commit2(p->display, COMMIT_ATOMIC); + igt_wait_for_vblank(p->display->drm_fd, p->pipe); + + igt_debug("About to deactivate the crtc\n"); + + igt_pipe_obj_set_prop_value(p, IGT_CRTC_ACTIVE, 0); + igt_display_commit2(p->display, COMMIT_ATOMIC); + + histogram_print(&h); + histogram_cleanup(&h); +} + +static void create_dumb_fb(igt_display_t *display, + size_t width, size_t height, + struct igt_fb *fb) +{ + igt_create_fb(display->drm_fd, + width, height, + DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE, fb); +} + + +static int get_num_planes(igt_display_t *display) +{ + const int drm_fd = display->drm_fd; + int ret; + + drmModePlaneRes *const plane_resources = + drmModeGetPlaneResources(drm_fd); + + ret = plane_resources->count_planes; + + drmModeFreePlaneResources(plane_resources); + + return ret; +} + +static int get_max_zpos(igt_display_t *display, igt_pipe_t *p) +{ + igt_plane_t *primary = plane_for_index(p, 0); + + drmModePropertyPtr zpos_prop = NULL; + + if (kmstest_get_property(display->drm_fd, + primary->drm_plane->plane_id, + DRM_MODE_OBJECT_PLANE, + "zpos", NULL, NULL, + &zpos_prop) && + zpos_prop && + zpos_prop->flags & DRM_MODE_PROP_RANGE) + { + return zpos_prop->values[1]; + } + else + { + return -1; + } +} + +size_t get_num_fbs(igt_display_t *display, igt_pipe_t *p) +{ + const char *NUM_FBS = getenv("NUM_FBS"); + + if (NUM_FBS) + { + return (size_t)atoi(NUM_FBS); + } + else + { + const int num_planes = get_num_planes(display); + const int max_zpos = get_max_zpos(display, p); + + if (max_zpos >= 0 && max_zpos + 1 < num_planes) + { + return (size_t)max_zpos + 1; + } + else + { + return (size_t)num_planes; + } + } +} + +size_t calculate_complexity(const drmModeModeInfoPtr mode) +{ + return (size_t)mode->hdisplay * (size_t)mode->vdisplay * (size_t)mode->vrefresh; +} + +drmModeModeInfoPtr get_peak_mode(igt_output_t *output) +{ + drmModeConnector *const connector = output->config.connector; + if (!connector || connector->count_modes == 0) + { + return NULL; + } + + drmModeModeInfoPtr peak_mode = &connector->modes[0]; + size_t peak_complexity = calculate_complexity(peak_mode); + + for (drmModeModeInfoPtr mode = &connector->modes[0]; + mode < &connector->modes[connector->count_modes]; ++mode) + { + const size_t complexity = calculate_complexity(mode); + igt_debug("Mode %zu is %hux%hu@%u\n", + (size_t)(mode - connector->modes), + mode->hdisplay, mode->vdisplay, mode->vrefresh); + if (complexity > peak_complexity) + { + peak_mode = mode; + peak_complexity = complexity; + } + } + + return peak_mode; +} + +void get_tuning(struct tuning *tuning, + igt_display_t *display, igt_pipe_t *p, + igt_output_t *output) +{ + tuning->mode = get_peak_mode(output); + igt_require(tuning->mode); + + tuning->num_iterations = 1000; + tuning->num_fb_sets = 2; + + tuning->num_fbs = get_num_fbs(display, p); + igt_require(tuning->num_fbs <= max_num_fbs); + + drmModeModeInfo *mode = igt_output_get_mode(output); + const char *FB_WIDTH = getenv("FB_WIDTH"); + const char *FB_HEIGHT = getenv("FB_HEIGHT"); + + const size_t requested_fb_width = FB_WIDTH ? + (size_t)atoi(FB_WIDTH) : + mode->hdisplay; + + const size_t requested_fb_height = FB_HEIGHT ? + (size_t)atoi(FB_HEIGHT) : + mode->vdisplay; + + igt_display_commit2(p->display, COMMIT_ATOMIC); + + struct igt_fb fb; + create_dumb_fb(p->display, requested_fb_width, requested_fb_height, &fb); + + for (size_t i = 0; i < tuning->num_fbs; ++i) + { + igt_plane_t *const plane = plane_for_index(p, i); + igt_plane_set_prop_value(plane, IGT_PLANE_ZPOS, i); + igt_plane_set_fb(plane, &fb); + + int ret = igt_display_try_commit_atomic(p->display, + DRM_MODE_ATOMIC_TEST_ONLY, + NULL); + + if (ret) + { + tuning->fb_geom[i].width = mode->hdisplay; + tuning->fb_geom[i].height = mode->vdisplay; + } + else + { + tuning->fb_geom[i].width = requested_fb_width; + tuning->fb_geom[i].height = requested_fb_height; + } + + igt_info("Plane %zu is %zux%zu\n", i, + tuning->fb_geom[i].width, + tuning->fb_geom[i].height); + + igt_plane_set_fb(plane, NULL); + } + + igt_remove_fb(p->display->drm_fd, &fb); +} + +igt_main +{ + igt_display_t display = {}; + make_display(&display); + + igt_pipe_t *p = NULL; + igt_output_t *output = NULL; + get_pipe(&display, &p, &output); + + do_or_die(drmSetClientCap( + display.drm_fd, + DRM_CLIENT_CAP_ATOMIC, + 1)); + + do_or_die(drmSetClientCap( + display.drm_fd, + DRM_CLIENT_CAP_UNIVERSAL_PLANES, + 1)); + + igt_pipe_refresh(&display, p->pipe, true); + + prepare(&display, p, output); + + struct tuning tuning; + get_tuning(&tuning, &display, p, output); + + drmModeModeInfoPtr orig_mode = igt_output_get_mode(output); + if (orig_mode != tuning.mode) + { + igt_output_override_mode(output, tuning.mode); + igt_display_commit2(&display, COMMIT_ATOMIC); + } + + igt_info("Chosen mode:\n"); + kmstest_dump_mode(tuning.mode); + + { + struct igt_fb **fb_sets = + malloc(sizeof(struct igt_fb*[tuning.num_fb_sets])); + + for (size_t i = 0; i < tuning.num_fb_sets; ++i) + { + fb_sets[i] = malloc(sizeof(struct igt_fb[tuning.num_fbs])); + struct igt_fb *fbs = fb_sets[i]; + for (size_t j = 0; j < tuning.num_fbs; ++j) + { + create_dumb_fb(&display, + tuning.fb_geom[j].width, + tuning.fb_geom[j].height, + &fbs[j]); + }; + } + + + repeat_flip(p, fb_sets, &tuning); + + for (size_t i = 0; i < tuning.num_fb_sets; ++i) + { + struct igt_fb *fbs = fb_sets[i]; + for (size_t j = 0; j < tuning.num_fbs; ++j) + { + igt_remove_fb(display.drm_fd, &fbs[j]); + }; + free(fbs); + } + free(fb_sets); + } + + if (orig_mode != tuning.mode) + { + igt_output_override_mode(output, orig_mode); + igt_display_commit2(&display, COMMIT_ATOMIC); + } + + igt_info("Success\n"); +} diff --git a/scripts/test_igt_gpu_tools.py b/scripts/test_igt_gpu_tools.py new file mode 100644 index 000000000..4597836f6 --- /dev/null +++ b/scripts/test_igt_gpu_tools.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2020 The Android Open Source Project + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import unittest +from xml.etree import ElementTree +import subprocess +import sys + +VERBOSE = True +TEST_CONFIG = os.path.join(os.path.dirname(__file__), "test_igt_gpu_tools.xml") + +""" Extracts tests from AndroidTest.xml compatible file + param: xmlfile str containing path to AndroidTest.xml compatible xml file +""" +def extract_tests_from_xml(xmlfile): + tree = ElementTree.parse(xmlfile) + root = tree.getroot() + return [(o.attrib['key'], o.attrib['value']) + for o in root.findall("./target_preparer/option") + if o.attrib['name'] == "push-file"] + +def run_command(command): + serial_number = os.environ.get("ANDROID_SERIAL", "") + if not serial_number: + raise "$ANDROID_SERIAL is empty, device must be specified" + full_command = ["adb", "-s", serial_number, "shell"] + command + if VERBOSE: + print("+" + " ".join(full_command)) + ret = subprocess.run(full_command, capture_output=True, universal_newlines=True) + if VERBOSE: + print(ret.stdout) + return ret.stdout + +class IGTGpuToolsBinary(): + """Harness object for a specific IGT GPU test binary. """ + + """ param: ondevice_test_path The IGT binary path on device """ + def __init__(self, ondevice_test_path): + self._path = ondevice_test_path + subtests = run_command([self._path, "--list-subtests"]) + self._subtests = list(filter(lambda x: x != "", subtests.split("\n"))) + + """lists subtests detected in tests. + return: list of strings indicating subtests found in binary. + """ + def subtests(self): + return self._subtests; + + """Runs a subtest. + + param: subtest_name One of the subtests listed by self.subtest() + return: a subprocess.CompletedProcess + """ + def run_subtest(self, subtest_name): + if subtest_name not in self._subtests: + error + return run_command([self._path, "--run-subtest", subtest_name]) + +class IGTGpuToolsTest(unittest.TestCase): + """Tests for DRM/KMS using Intel Graphics Tests suite""" + + """ param: subtest A valid subtest for the binary + param: the IGT binary to run as a unit test. + """ + def __init__(self, subtest, binary): + self._subtest_name = subtest + self._test_binary = binary + setattr(self, self._subtest_name, self.runTest) + super(IGTGpuToolsTest, self).__init__(methodName=self._subtest_name) + + """ Runs the test set in the constructor """ + def runTest(self): + output = self._test_binary.run_subtest(self._subtest_name) + for line in output.split("\n"): + if "Subtest" not in line: + continue; + if "SKIP" in line: + self.skipTest("{} - skipped".format(self._subtest_name)) + break + if "SUCCESS" in line: + break + if "FAIL" in line: + self.fail(output) + break + self.fail("could not parse test output; test runner failure") + +ANDROID_RUNNER_REQUIRED_VERBOSITY = 2 + +def main(): + """main entrypoint for test runner""" + + runner = unittest.TextTestRunner(stream=sys.stderr, verbosity=ANDROID_RUNNER_REQUIRED_VERBOSITY) + suite = unittest.TestSuite() + for test, test_path in extract_tests_from_xml(TEST_CONFIG): + print("Found IGT-GPU-tools test {}".format(test)) + subsuite = unittest.TestSuite() + binary = IGTGpuToolsBinary(test_path) + for subtest in binary.subtests(): + print("\tFound subtest {}".format(subtest)) + subsuite.addTest(IGTGpuToolsTest(subtest, binary)) + suite.addTest(subsuite) + runner.run(suite) + +if __name__=="__main__": + main() diff --git a/scripts/test_igt_gpu_tools.xml b/scripts/test_igt_gpu_tools.xml new file mode 100644 index 000000000..63a5febe1 --- /dev/null +++ b/scripts/test_igt_gpu_tools.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<configuration description="Config to run IGT GPU tests"> + <option name="logcat-on-failure" value="false" /> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> + <option name="run-command" value="stop" /> + <option name="run-command" value="stop $(grep -rn composer /vendor/etc/init | grep service | cut -d ' ' -f 2)" /> + <option name="teardown-command" value="stop $(grep -rn composer /vendor/etc/init | grep service | cut -d ' ' -f 2)" /> + <option name="teardown-command" value="start" /> + </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <option name="cleanup" value="true"/> + <option name="append-bitness" value="true"/> + <option name="push-file" + key="kms_atomic" value="/data/local/tmp/kms_atomic"/> + <option name="push-file" + key="kms_flip" value="/data/local/tmp/kms_flip"/> + <option name="push-file" + key="kms_vblank" value="/data/local/tmp/kms_vblank"/> + </target_preparer> + <test class="com.android.tradefed.testtype.python.PythonBinaryHostTest" > + <option name="par-file-name" value="igt_gpu_tools" /> + <option name="inject-android-serial" value="true" /> + <option name="test-timeout" value="30m" /> + </test> +</configuration> diff --git a/tests/kms_flip.c b/tests/kms_flip.c index 28ecc217a..574d038cd 100755 --- a/tests/kms_flip.c +++ b/tests/kms_flip.c @@ -1153,7 +1153,7 @@ static void calibrate_ts(struct test_output *o, int crtc_idx) * be interrupted with -EINTR, handle this by restarting * until we poll timeout or success. */ - poll_ret = poll(&(struct pollfd){drm_fd, POLLIN}, 1, -1); + poll_ret = poll(&(struct pollfd){drm_fd, POLLIN}, 1, 1000); if (poll_ret == 1) break; |