public inbox for [email protected]
 help / color / mirror / Atom feed
From: David Wei <[email protected]>
To: [email protected]
Cc: Jens Axboe <[email protected]>, Pavel Begunkov <[email protected]>
Subject: [PATCH v1 4/4] liburing: add unit test for io_uring_register_iowait()
Date: Fri, 23 Feb 2024 21:07:35 -0800	[thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>

From: David Wei <[email protected]>

Add a unit test for io_uring_register_iowait() by creating a thread that
writes into a pipe after a delay, checking iowait before and after.

Signed-off-by: David Wei <[email protected]>
---
 test/Makefile |   1 +
 test/iowait.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 158 insertions(+)
 create mode 100644 test/iowait.c

diff --git a/test/Makefile b/test/Makefile
index b09228f..779a7db 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -107,6 +107,7 @@ test_srcs := \
 	io_uring_passthrough.c \
 	io_uring_register.c \
 	io_uring_setup.c \
+	iowait.c \
 	lfs-openat.c \
 	lfs-openat-write.c \
 	link.c \
diff --git a/test/iowait.c b/test/iowait.c
new file mode 100644
index 0000000..fcd4004
--- /dev/null
+++ b/test/iowait.c
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: Test that waiting for CQ is accounted as iowait if enabled via
+ * io_uring_register_iowait(), and vice versa.
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <linux/kernel.h>
+
+#include "liburing.h"
+#include "helpers.h"
+
+struct data {
+	pthread_barrier_t startup;
+	int out_fd;
+};
+
+static unsigned long long get_iowait()
+{
+	FILE *fp;
+	char buf[256];
+	unsigned long long user, nice, system, idle, iowait;
+
+	fp = fopen("/proc/stat", "r");
+	if (!fp) {
+		perror("fopen");
+		exit(T_EXIT_FAIL);
+	}
+
+	if (fgets(buf, sizeof(buf), fp) == NULL) {
+		perror("fgets");
+		fclose(fp);
+		exit(T_EXIT_FAIL);
+	}
+	fclose(fp);
+
+	sscanf(buf, "cpu %llu %llu %llu %llu %llu", &user, &nice, &system,
+						    &idle, &iowait);
+
+	return iowait;
+}
+
+static void *pipe_write(void *data)
+{
+	struct data *d = data;
+	char buf[32];
+	int ret;
+
+	memset(buf, 0x55, sizeof(buf));
+	pthread_barrier_wait(&d->startup);
+	usleep(100000);
+
+	ret = write(d->out_fd, buf, sizeof(buf));
+	if (ret < 0) {
+		perror("write");
+		return NULL;
+	}
+
+	return NULL;
+}
+
+static int test_iowait(struct io_uring *ring, bool enabled)
+{
+	unsigned long long iowait_pre, iowait_post, iowait;
+	double iowait_ms_max_diff;
+	struct io_uring_cqe *cqe;
+	struct io_uring_sqe *sqe;
+	pthread_t thread;
+	double iowait_ms;
+	int ret, fds[2];
+	struct data d;
+	char buf[32];
+	void *tret;
+
+	if (pipe(fds) < 0) {
+		perror("pipe");
+		return T_EXIT_FAIL;
+	}
+	d.out_fd = fds[1];
+
+	pthread_barrier_init(&d.startup, NULL, 2);
+	pthread_create(&thread, NULL, pipe_write, &d);
+	pthread_barrier_wait(&d.startup);
+
+	io_uring_register_iowait(ring, enabled);
+
+	sqe = io_uring_get_sqe(ring);
+	io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0);
+
+	io_uring_submit(ring);
+
+	iowait_pre = get_iowait();
+	ret = io_uring_wait_cqe(ring, &cqe);
+	if (ret) {
+		fprintf(stderr, "wait_cqe: %d\n", ret);
+		return T_EXIT_FAIL;
+	}
+	io_uring_cq_advance(ring, 1);
+
+	iowait_post = get_iowait();
+
+	/* 
+	 * writer sleeps for 100 ms, so max diff is 100 plus a tolerance of
+	 * 10 ms
+	 */
+	iowait_ms_max_diff = (enabled ? 100.0 : 0.0) + 10.0;
+
+	if (iowait_post > iowait_pre)
+		iowait = iowait_post - iowait_pre;
+	else
+		iowait = iowait_pre - iowait_post;
+	iowait_ms = ((double)iowait / sysconf(_SC_CLK_TCK)) * 1000;
+
+	if (iowait_ms > iowait_ms_max_diff)
+		ret = T_EXIT_FAIL;
+	else
+		ret = T_EXIT_PASS;
+
+	pthread_join(thread, &tret);
+	close(fds[0]);
+	close(fds[1]);
+	return ret;
+}
+
+int main(int argc, char *argv[])
+{
+	struct io_uring ring;
+	struct io_uring_params p = { };
+	int ret;
+
+	if (argc > 1)
+		return 0;
+
+	ret = t_create_ring_params(8, &ring, &p);
+	if (ret == T_SETUP_SKIP)
+		return T_EXIT_SKIP;
+	else if (ret != T_SETUP_OK)
+		return ret;
+
+	ret = test_iowait(&ring, false);
+	if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+		return ret;
+
+	ret = test_iowait(&ring, true);
+	if (ret == T_EXIT_FAIL || ret == T_EXIT_SKIP)
+		return ret;
+
+	io_uring_queue_exit(&ring);
+	return T_EXIT_PASS;
+}
-- 
2.43.0


  parent reply	other threads:[~2024-02-24  5:07 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-24  5:07 [PATCH v1 1/4] io_uring: only account cqring wait time as iowait if enabled for a ring David Wei
2024-02-24  5:07 ` [PATCH v1 2/4] liburing: add examples/proxy to .gitignore David Wei
2024-02-24  5:07 ` [PATCH v1 3/4] liburing: add helper for IORING_REGISTER_IOWAIT David Wei
2024-02-24 15:29   ` Jens Axboe
2024-02-24 16:39     ` David Wei
2024-02-24  5:07 ` David Wei [this message]
2024-02-24 15:28 ` [PATCH v1 1/4] io_uring: only account cqring wait time as iowait if enabled for a ring Jens Axboe
2024-02-24 15:31 ` Pavel Begunkov
2024-02-24 17:20   ` David Wei
2024-02-24 18:55     ` Jens Axboe
2024-02-25  1:39       ` Pavel Begunkov
2024-02-25 16:43         ` Jens Axboe
2024-02-25 21:11           ` Jens Axboe
2024-02-25 21:33             ` Jens Axboe
2024-02-26 14:56             ` Pavel Begunkov
2024-02-26 15:22               ` Jens Axboe
2024-02-24 18:51   ` Jens Axboe
2024-02-25  0:58     ` Pavel Begunkov
2024-02-25 16:39       ` Jens Axboe
2024-03-05 14:59         ` Christian Loehle

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 \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    /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