From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Subject: Re: [PATCH 2/2] tests: add kms_edp_vdd_race Date: Mon, 11 Nov 2013 19:15:46 +0100 Message-ID: <20131111181546.GD14978@phenom.ffwll.local> References: <1384189570-2955-1-git-send-email-przanoni@gmail.com> <1384189570-2955-2-git-send-email-przanoni@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mail-ee0-f41.google.com (mail-ee0-f41.google.com [74.125.83.41]) by gabe.freedesktop.org (Postfix) with ESMTP id 1961DFA84E for ; Mon, 11 Nov 2013 10:15:16 -0800 (PST) Received: by mail-ee0-f41.google.com with SMTP id e53so2650852eek.14 for ; Mon, 11 Nov 2013 10:15:15 -0800 (PST) Content-Disposition: inline In-Reply-To: <1384189570-2955-2-git-send-email-przanoni@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org To: Paulo Zanoni Cc: intel-gfx@lists.freedesktop.org, Paulo Zanoni List-Id: intel-gfx@lists.freedesktop.org On Mon, Nov 11, 2013 at 03:06:10PM -0200, Paulo Zanoni wrote: > From: Paulo Zanoni > = > We recently fixed a bug where it was impossible to do I2C transactions > on eDP panels when they were disabled. Now it should be possible to do > these transactions when the panel is disabled, but there's a race > condition that triggers dmesg errors if we try do do the I2C > transactions and set a mode on the panel at the same time. This > program should reproduce this bug and check dmesg for errors. > = > Signed-off-by: Paulo Zanoni Like I've said in the previous mail I think the generic dmesg error checking should be somewhere generic (and probably in piglit). Otherwise the test looks good. And the naming also matches the new convention ;-) -Daniel > --- > tests/.gitignore | 1 + > tests/Makefile.am | 2 + > tests/kms_edp_vdd_race.c | 226 +++++++++++++++++++++++++++++++++++++++++= ++++++ > 3 files changed, 229 insertions(+) > create mode 100644 tests/kms_edp_vdd_race.c > = > diff --git a/tests/.gitignore b/tests/.gitignore > index 09ea074..ddb61f9 100644 > --- a/tests/.gitignore > +++ b/tests/.gitignore > @@ -102,6 +102,7 @@ igt_no_exit_list_only > igt_no_subtest > kms_addfb > kms_cursor_crc > +kms_edp_vdd_race > kms_flip > kms_pipe_crc_basic > kms_render > diff --git a/tests/Makefile.am b/tests/Makefile.am > index 0426ec0..955d2a3 100644 > --- a/tests/Makefile.am > +++ b/tests/Makefile.am > @@ -52,6 +52,7 @@ TESTS_progs_M =3D \ > gem_write_read_ring_switch \ > kms_addfb \ > kms_cursor_crc \ > + kms_edp_vdd_race \ > kms_flip \ > kms_pipe_crc_basic \ > kms_render \ > @@ -236,6 +237,7 @@ gem_fence_thrash_LDADD =3D $(LDADD) -lpthread > gem_flink_race_LDADD =3D $(LDADD) -lpthread > gem_threaded_access_tiled_LDADD =3D $(LDADD) -lpthread > prime_self_import_LDADD =3D $(LDADD) -lpthread > +kms_edp_vdd_race_LDADD =3D $(LDADD) -lpthread > = > gem_wait_render_timeout_LDADD =3D $(LDADD) -lrt > kms_flip_LDADD =3D $(LDADD) -lrt > diff --git a/tests/kms_edp_vdd_race.c b/tests/kms_edp_vdd_race.c > new file mode 100644 > index 0000000..a6bff65 > --- /dev/null > +++ b/tests/kms_edp_vdd_race.c > @@ -0,0 +1,226 @@ > +/* > + * Copyright =A9 2013 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining= a > + * copy of this software and associated documentation files (the "Softwa= re"), > + * to deal in the Software without restriction, including without limita= tion > + * the rights to use, copy, modify, merge, publish, distribute, sublicen= se, > + * 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, EXPRE= SS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI= TY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SH= ALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR = OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISI= NG > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER D= EALINGS > + * IN THE SOFTWARE. > + * > + * Authors: Paulo Zanoni > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "drmtest.h" > + > +int drm_fd, kmsg_fd; > +drmModeResPtr res; > +drmModeConnectorPtr edp_connector; > +bool stop; > + > +static void disable_all_screens(void) > +{ > + int i, rc; > + > + for (i =3D 0; i < res->count_crtcs; i++) { > + rc =3D drmModeSetCrtc(drm_fd, res->crtcs[i], -1, 0, 0, > + NULL, 0, NULL); > + igt_assert(rc =3D=3D 0); > + } > +} > + > +static void find_edp_connector(void) > +{ > + int i; > + drmModeConnectorPtr c; > + > + edp_connector =3D NULL; > + for (i =3D 0; i < res->count_connectors; i++) { > + c =3D drmModeGetConnector(drm_fd, res->connectors[i]); > + > + if (c->connector_type =3D=3D DRM_MODE_CONNECTOR_eDP) { > + igt_require(c->connection =3D=3D DRM_MODE_CONNECTED); > + edp_connector =3D c; > + break; > + } > + > + drmModeFreeConnector(c); > + } > + igt_require(edp_connector); > +} > + > +static void read_edid_ioctl(int fd) > +{ > + unsigned char edid[128] =3D {}; > + struct i2c_msg msgs[] =3D { > + { /* Start at 0. */ > + .addr =3D 0x50, > + .flags =3D 0, > + .len =3D 1, > + .buf =3D edid, > + }, { /* Now read the EDID. */ > + .addr =3D 0x50, > + .flags =3D I2C_M_RD, > + .len =3D 128, > + .buf =3D edid, > + } > + }; > + struct i2c_rdwr_ioctl_data msgset =3D { > + .msgs =3D msgs, > + .nmsgs =3D 2, > + }; > + > + ioctl(fd, I2C_RDWR, &msgset); > +} > + > +/* TODO: We're currently just trying to read all the I2C files. We shoul= d try to > + * find which one is really the eDP I2C file and just read from it. */ > +static void read_i2c_edid(void) > +{ > + int fd; > + DIR *dir; > + > + struct dirent *dirent; > + char full_name[32]; > + > + dir =3D opendir("/dev/"); > + igt_assert(dir); > + > + while ((dirent =3D readdir(dir))) { > + if (strncmp(dirent->d_name, "i2c-", 4) =3D=3D 0) { > + snprintf(full_name, 32, "/dev/%s", dirent->d_name); > + fd =3D open(full_name, O_RDWR); > + igt_assert(fd !=3D -1); > + read_edid_ioctl(fd); > + close(fd); > + } > + } > + > + closedir(dir); > +} > + > +static void *i2c_thread_func(void *unused) > +{ > + while (!stop) > + read_i2c_edid(); > + > + pthread_exit(NULL); > +} > + > +static uint32_t create_fb(int width, int height) > +{ > + struct kmstest_fb fb; > + cairo_t *cr; > + uint32_t buffer_id; > + > + buffer_id =3D kmstest_create_fb(drm_fd, width, height, 32, 24, false, > + &fb); > + cr =3D kmstest_get_cairo_ctx(drm_fd, &fb); > + kmstest_paint_test_pattern(cr, width, height); > + return buffer_id; > +} > + > +static void enable_edp_screen(void) > +{ > + int rc; > + uint32_t buffer_id =3D 0, crtc_id, connector_id; > + drmModeModeInfoPtr mode; > + > + crtc_id =3D res->crtcs[0]; > + connector_id =3D edp_connector->connector_id; > + mode =3D &edp_connector->modes[0]; > + > + buffer_id =3D create_fb(mode->hdisplay, mode->vdisplay); > + > + rc =3D drmModeSetCrtc(drm_fd, crtc_id, buffer_id, 0, 0, &connector_id, > + 1, mode); > + igt_assert(rc =3D=3D 0); > +} > + > +static void *modeset_thread_func(void *unused) > +{ > + while (!stop) { > + disable_all_screens(); > + sleep(1); > + enable_edp_screen(); > + sleep(1); > + } > + > + pthread_exit(NULL); > +} > + > +/* This test exercises a race condition that happens when we're trying t= o read > + * the I2C data from an eDP panel at the same time we're trying to set a= mode on > + * the same panel. If we have the bug, we print error messages on dmesg,= which > + * we should catch with the kmsg functions. */ > +static void i2c_modeset_vdd_race(void) > +{ > + pthread_t i2c_thread, modeset_thread; > + void *status; > + > + kmsg_error_reset(kmsg_fd); > + > + stop =3D false; > + pthread_create(&i2c_thread, NULL, i2c_thread_func, NULL); > + pthread_create(&modeset_thread, NULL, modeset_thread_func, NULL); > + > + /* This effectively sleeps for 100 seconds, but kills the program in > + * case there's error on dmesg. */ > + kmsg_error_detect(kmsg_fd, 100 * 1000, ""); > + > + stop =3D true; > + pthread_join(i2c_thread, &status); > + pthread_join(modeset_thread, &status); > + > + /* Make sure we check everything after the threads have actually > + * stopped. */ > + kmsg_error_detect(kmsg_fd, 1 * 1000, ""); > +} > + > +igt_main > +{ > + igt_fixture { > + drm_fd =3D drm_open_any(); > + igt_require(drm_fd >=3D 0); > + > + res =3D drmModeGetResources(drm_fd); > + igt_assert(res); > + > + kmsg_fd =3D kmsg_error_setup(); > + > + find_edp_connector(); > + } > + > + igt_subtest("i2c-modeset-vdd-race") > + i2c_modeset_vdd_race(); > + > + igt_fixture { > + kmsg_error_teardown(kmsg_fd); > + drmModeFreeConnector(edp_connector); > + drmModeFreeResources(res); > + close(drm_fd); > + } > +} > -- = > 1.8.3.1 > = > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- = Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch