All of lore.kernel.org
 help / color / mirror / Atom feed
From: ville.syrjala@linux.intel.com
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock()
Date: Fri, 18 Dec 2015 19:25:48 +0200	[thread overview]
Message-ID: <1450459550-16504-4-git-send-email-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <1450459550-16504-1-git-send-email-ville.syrjala@linux.intel.com>

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add support for reading the CRC in non-blocking mode. Useful for tests
that want to start the CRC capture, then do a bunch of operations, then
collect however many CRCs that got generated. The current
igt_pipe_crc_new() + igt_pipe_crc_get_crcs() method would block until
it gets the requested number of CRCs, whreas in non-blocking mode we
can just read as many as got generated thus far.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 lib/igt_debugfs.c | 136 +++++++++++++++++++++++++++++++++++-------------------
 lib/igt_debugfs.h |   4 +-
 2 files changed, 91 insertions(+), 49 deletions(-)

diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
index a3d015267e15..1d625ad4ba50 100644
--- a/lib/igt_debugfs.c
+++ b/lib/igt_debugfs.c
@@ -298,6 +298,7 @@ struct _igt_pipe_crc {
 	int crc_fd;
 	int line_len;
 	int buffer_len;
+	int flags;
 
 	enum pipe pipe;
 	enum intel_pipe_crc_source source;
@@ -389,19 +390,8 @@ void igt_require_pipe_crc(void)
 	fclose(ctl);
 }
 
-/**
- * igt_pipe_crc_new:
- * @pipe: display pipe to use as source
- * @source: CRC tap point to use as source
- *
- * This sets up a new pipe CRC capture object for the given @pipe and @source.
- *
- * Returns: A pipe CRC object if the given @pipe and @source. The library
- * assumes that the source is always available since recent kernels support at
- * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
- */
-igt_pipe_crc_t *
-igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
+static igt_pipe_crc_t *
+pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source, int flags)
 {
 	igt_pipe_crc_t *pipe_crc;
 	char buf[128];
@@ -414,18 +404,55 @@ igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
 	igt_assert(pipe_crc->ctl_fd != -1);
 
 	sprintf(buf, "i915_pipe_%s_crc", kmstest_pipe_name(pipe));
-	pipe_crc->crc_fd = igt_debugfs_open(buf, O_RDONLY);
+	pipe_crc->crc_fd = igt_debugfs_open(buf, flags);
 	igt_assert(pipe_crc->crc_fd != -1);
 
 	pipe_crc->line_len = PIPE_CRC_LINE_LEN;
 	pipe_crc->buffer_len = PIPE_CRC_BUFFER_LEN;
 	pipe_crc->pipe = pipe;
 	pipe_crc->source = source;
+	pipe_crc->flags = flags;
 
 	return pipe_crc;
 }
 
 /**
+ * igt_pipe_crc_new:
+ * @pipe: display pipe to use as source
+ * @source: CRC tap point to use as source
+ *
+ * This sets up a new pipe CRC capture object for the given @pipe and @source
+ * in blocking mode.
+ *
+ * Returns: A pipe CRC object if the given @pipe and @source. The library
+ * assumes that the source is always available since recent kernels support at
+ * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
+ */
+igt_pipe_crc_t *
+igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
+{
+	return pipe_crc_new(pipe, source, O_RDONLY);
+}
+
+/**
+ * igt_pipe_crc_new_nonblock:
+ * @pipe: display pipe to use as source
+ * @source: CRC tap point to use as source
+ *
+ * This sets up a new pipe CRC capture object for the given @pipe and @source
+ * in nonblocking mode.
+ *
+ * Returns: A pipe CRC object if the given @pipe and @source. The library
+ * assumes that the source is always available since recent kernels support at
+ * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
+ */
+igt_pipe_crc_t *
+igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source)
+{
+	return pipe_crc_new(pipe, source, O_RDONLY | O_NONBLOCK);
+}
+
+/**
  * igt_pipe_crc_free:
  * @pipe_crc: pipe CRC object
  *
@@ -441,6 +468,39 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
 	free(pipe_crc);
 }
 
+static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
+{
+	int n;
+
+	crc->n_words = 5;
+	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
+		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
+	return n == 6;
+}
+
+static int read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
+{
+	ssize_t bytes_read;
+	char buf[pipe_crc->buffer_len];
+
+	igt_set_timeout(5, "CRC reading");
+	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
+	igt_reset_timeout();
+
+	if (bytes_read < 0 && errno == EAGAIN) {
+		igt_assert(pipe_crc->flags & O_NONBLOCK);
+		bytes_read = 0;
+	} else {
+		igt_assert_eq(bytes_read, pipe_crc->line_len);
+	}
+	buf[bytes_read] = '\0';
+
+	if (bytes_read && !pipe_crc_init_from_string(out, buf))
+		return -EINVAL;
+
+	return bytes_read;
+}
+
 /**
  * igt_pipe_crc_start:
  * @pipe_crc: pipe CRC object
@@ -449,7 +509,7 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
  */
 void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
 {
-	igt_crc_t *crcs = NULL;
+	igt_crc_t crc;
 
 	igt_assert(igt_pipe_crc_do_start(pipe_crc));
 
@@ -460,8 +520,10 @@ void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
 	 * On CHV sometimes the second CRC is bonkers as well, so don't trust
 	 * that one either.
 	 */
-	igt_pipe_crc_get_crcs(pipe_crc, 2, &crcs);
-	free(crcs);
+	while (read_one_crc(pipe_crc, &crc) == 0)
+		usleep(1000);
+	while (read_one_crc(pipe_crc, &crc) == 0)
+		usleep(1000);
 }
 
 /**
@@ -478,34 +540,6 @@ void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc)
 	igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)), strlen(buf));
 }
 
-static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
-{
-	int n;
-
-	crc->n_words = 5;
-	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
-		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
-	return n == 6;
-}
-
-static bool read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
-{
-	ssize_t bytes_read;
-	char buf[pipe_crc->buffer_len];
-
-	igt_set_timeout(5, "CRC reading");
-	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
-	igt_reset_timeout();
-
-	igt_assert_eq(bytes_read, pipe_crc->line_len);
-	buf[bytes_read] = '\0';
-
-	if (!pipe_crc_init_from_string(out, buf))
-		return false;
-
-	return true;
-}
-
 /**
  * igt_pipe_crc_get_crcs:
  * @pipe_crc: pipe CRC object
@@ -519,7 +553,7 @@ static bool read_one_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
  * Callers must start and stop the capturing themselves by calling
  * igt_pipe_crc_start() and igt_pipe_crc_stop().
  */
-void
+int
 igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
 		      igt_crc_t **out_crcs)
 {
@@ -530,14 +564,19 @@ igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
 
 	do {
 		igt_crc_t *crc = &crcs[n];
+		int ret;
 
-		if (!read_one_crc(pipe_crc, crc))
+		ret = read_one_crc(pipe_crc, crc);
+		if (ret < 0)
 			continue;
+		if (ret == 0)
+			break;
 
 		n++;
 	} while (n < n_crcs);
 
 	*out_crcs = crcs;
+	return n;
 }
 
 static void crc_sanity_checks(igt_crc_t *crc)
@@ -576,7 +615,8 @@ void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc)
 	igt_debug_wait_for_keypress("crc");
 
 	igt_pipe_crc_start(pipe_crc);
-	read_one_crc(pipe_crc, out_crc);
+	while (read_one_crc(pipe_crc, out_crc) == 0)
+		usleep(1000);
 	igt_pipe_crc_stop(pipe_crc);
 
 	crc_sanity_checks(out_crc);
diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
index 24018eb355e4..6c6e2858d8f6 100644
--- a/lib/igt_debugfs.h
+++ b/lib/igt_debugfs.h
@@ -115,10 +115,12 @@ char *igt_crc_to_string(igt_crc_t *crc);
 void igt_require_pipe_crc(void);
 igt_pipe_crc_t *
 igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source);
+igt_pipe_crc_t *
+igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source);
 void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc);
 void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc);
 void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc);
-void igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
+int igt_pipe_crc_get_crcs(igt_pipe_crc_t *pipe_crc, int n_crcs,
 			   igt_crc_t **out_crcs);
 void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc);
 
-- 
2.4.10

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2015-12-18 17:26 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-18 17:25 [PATCH i-g-t 1/6] lib: Make 'extra_long_opts' const ville.syrjala
2015-12-18 17:25 ` [PATCH i-g-t 2/6] lib: Extract ssme common fb create+fill methods into helpers ville.syrjala
2015-12-21 10:42   ` Thomas Wood
2016-01-04 16:23     ` Ville Syrjälä
2015-12-18 17:25 ` [PATCH i-g-t 3/6] lib: Use igt_assert_eq() to check for crc component count ville.syrjala
2015-12-21 15:55   ` Daniel Vetter
2015-12-18 17:25 ` ville.syrjala [this message]
2015-12-21 15:53   ` [PATCH i-g-t 4/6] lib: Add igt_pipe_crc_new_nonblock() Daniel Vetter
2016-01-04 16:46     ` Ville Syrjälä
2015-12-18 17:25 ` [PATCH i-g-t 5/6] tests/kms_pipe_crc_basic: Add tests for O_NONBLOCK CRC reads ville.syrjala
2015-12-18 17:25 ` [PATCH i-g-t 6/6] tests/kms_chv_cursor_fail: Add a test to exercise CHV pipe C cursor fail ville.syrjala
2015-12-21 10:42   ` Thomas Wood
2016-01-04 15:59     ` Ville Syrjälä

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1450459550-16504-4-git-send-email-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.