linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Mark Brown <broonie@kernel.org>
To: Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Shuah Khan <shuah@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org,
	linux-kselftest@vger.kernel.org, Mark Brown <broonie@kernel.org>
Subject: [PATCH v1 3/3] kselftest/arm64: Handle EINTR while reading data from children
Date: Wed, 21 Sep 2022 19:13:45 +0100	[thread overview]
Message-ID: <20220921181345.618085-4-broonie@kernel.org> (raw)
In-Reply-To: <20220921181345.618085-1-broonie@kernel.org>

Currently we treat any error when reading from the child as a failure and
don't read any more output from that child as a result. This ignores the
fact that it is valid for read() to return EINTR as the error code if there
is a signal pending so we could stop handling the output of children,
especially during exit when we will get some SIGCHLD signals delivered to
us. Fix this by pulling the read handling out into a separate function
which returns a flag if reads should be continued and wrapping it in a
loop.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 tools/testing/selftests/arm64/fp/fp-stress.c | 85 ++++++++++++--------
 1 file changed, 50 insertions(+), 35 deletions(-)

diff --git a/tools/testing/selftests/arm64/fp/fp-stress.c b/tools/testing/selftests/arm64/fp/fp-stress.c
index 03ce3936220a..4e62a9199f97 100644
--- a/tools/testing/selftests/arm64/fp/fp-stress.c
+++ b/tools/testing/selftests/arm64/fp/fp-stress.c
@@ -121,55 +121,70 @@ static void child_start(struct child_data *child, const char *program)
 	}
 }
 
-static void child_output(struct child_data *child, uint32_t events,
-			 bool flush)
+static bool child_output_read(struct child_data *child)
 {
 	char read_data[1024];
 	char work[1024];
 	int ret, len, cur_work, cur_read;
 
-	if (events & EPOLLIN) {
-		ret = read(child->stdout, read_data, sizeof(read_data));
-		if (ret < 0) {
-			ksft_print_msg("%s: read() failed: %s (%d)\n",
-				       child->name, strerror(errno), errno);
-			return;
-		}
-		len = ret;
+	ret = read(child->stdout, read_data, sizeof(read_data));
+	if (ret < 0) {
+		if (errno == EINTR)
+			return true;
 
-		child->output_seen = true;
+		ksft_print_msg("%s: read() failed: %s (%d)\n",
+			       child->name, strerror(errno),
+			       errno);
+		return false;
+	}
+	len = ret;
 
-		/* Pick up any partial read */
-		if (child->output) {
-			strncpy(work, child->output, sizeof(work) - 1);
-			cur_work = strnlen(work, sizeof(work));
-			free(child->output);
-			child->output = NULL;
-		} else {
-			cur_work = 0;
-		}
+	child->output_seen = true;
 
-		cur_read = 0;
-		while (cur_read < len) {
-			work[cur_work] = read_data[cur_read++];
+	/* Pick up any partial read */
+	if (child->output) {
+		strncpy(work, child->output, sizeof(work) - 1);
+		cur_work = strnlen(work, sizeof(work));
+		free(child->output);
+		child->output = NULL;
+	} else {
+		cur_work = 0;
+	}
 
-			if (work[cur_work] == '\n') {
-				work[cur_work] = '\0';
-				ksft_print_msg("%s: %s\n", child->name, work);
-				cur_work = 0;
-			} else {
-				cur_work++;
-			}
-		}
+	cur_read = 0;
+	while (cur_read < len) {
+		work[cur_work] = read_data[cur_read++];
 
-		if (cur_work) {
+		if (work[cur_work] == '\n') {
 			work[cur_work] = '\0';
-			ret = asprintf(&child->output, "%s", work);
-			if (ret == -1)
-				ksft_exit_fail_msg("Out of memory\n");
+			ksft_print_msg("%s: %s\n", child->name, work);
+			cur_work = 0;
+		} else {
+			cur_work++;
 		}
 	}
 
+	if (cur_work) {
+		work[cur_work] = '\0';
+		ret = asprintf(&child->output, "%s", work);
+		if (ret == -1)
+			ksft_exit_fail_msg("Out of memory\n");
+	}
+
+	return false;
+}
+
+static void child_output(struct child_data *child, uint32_t events,
+			 bool flush)
+{
+	bool read_more;
+
+	if (events & EPOLLIN) {
+		do {
+			read_more = child_output_read(child);
+		} while (read_more);
+	}
+
 	if (events & EPOLLHUP) {
 		close(child->stdout);
 		child->stdout = -1;
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2022-09-21 18:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-21 18:13 [PATCH v1 0/3] kselftest/arm64: fp-stress updates Mark Brown
2022-09-21 18:13 ` [PATCH v1 1/3] kselftest/arm64: Don't repeat termination handler for fp-stress Mark Brown
2022-09-21 18:13 ` [PATCH v1 2/3] kselftest/arm64: Flag fp-stress as exiting when we begin finishing up Mark Brown
2022-09-21 18:13 ` Mark Brown [this message]
2022-09-29 17:54 ` [PATCH v1 0/3] kselftest/arm64: fp-stress updates Catalin Marinas

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=20220921181345.618085-4-broonie@kernel.org \
    --to=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=shuah@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=will@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).