351 lines
9.6 KiB
Diff
351 lines
9.6 KiB
Diff
|
From 0a38b72d2ffb722f08c26dd734baef54ff788fde Mon Sep 17 00:00:00 2001
|
||
|
From: Colin Ian King <colin.king@canonical.com>
|
||
|
Date: Fri, 15 May 2020 23:23:43 +0100
|
||
|
Subject: [PATCH 01/28] stress-hdd: use preadv, preadv2, pwritev, pwritev2
|
||
|
|
||
|
Exercise iovec family of read/write system calls to get more
|
||
|
kernel coverage
|
||
|
|
||
|
Signed-off-by: Colin Ian King <colin.king@canonical.com>
|
||
|
---
|
||
|
Makefile.config | 24 ++++++++++++++++++++
|
||
|
stress-hdd.c | 47 +++++++++++++++++++++++++++++++++++++--
|
||
|
test/test-preadv.c | 52 ++++++++++++++++++++++++++++++++++++++++++++
|
||
|
test/test-preadv2.c | 52 ++++++++++++++++++++++++++++++++++++++++++++
|
||
|
test/test-pwritev.c | 14 +++++++++++-
|
||
|
test/test-pwritev2.c | 50 ++++++++++++++++++++++++++++++++++++++++++
|
||
|
6 files changed, 236 insertions(+), 3 deletions(-)
|
||
|
create mode 100644 test/test-preadv.c
|
||
|
create mode 100644 test/test-preadv2.c
|
||
|
create mode 100644 test/test-pwritev2.c
|
||
|
|
||
|
diff --git a/Makefile.config b/Makefile.config
|
||
|
index 0d306e1fbd32..826cf29e8158 100644
|
||
|
--- a/Makefile.config
|
||
|
+++ b/Makefile.config
|
||
|
@@ -2233,6 +2233,22 @@ $(info autoconfig: using prctl)
|
||
|
endif
|
||
|
endif
|
||
|
|
||
|
+ifndef $(HAVE_PREADV)
|
||
|
+HAVE_PREADV = $(shell $(MAKE) -f Makefile.config --no-print-directory $(HAVE_NOT) TEST_PROG=test-preadv have_test_prog)
|
||
|
+ifeq ($(HAVE_PREADV),1)
|
||
|
+ CONFIG_CFLAGS += -DHAVE_PREADV
|
||
|
+$(info autoconfig: using preadv)
|
||
|
+endif
|
||
|
+endif
|
||
|
+
|
||
|
+ifndef $(HAVE_PREADV2)
|
||
|
+HAVE_PREADV2 = $(shell $(MAKE) -f Makefile.config --no-print-directory $(HAVE_NOT) TEST_PROG=test-preadv2 have_test_prog)
|
||
|
+ifeq ($(HAVE_PREADV2),1)
|
||
|
+ CONFIG_CFLAGS += -DHAVE_PREADV2
|
||
|
+$(info autoconfig: using preadv2)
|
||
|
+endif
|
||
|
+endif
|
||
|
+
|
||
|
ifndef $(HAVE_PRLIMIT)
|
||
|
HAVE_PRLIMIT = $(shell $(MAKE) -f Makefile.config --no-print-directory $(HAVE_NOT) TEST_PROG=test-prlimit have_test_prog)
|
||
|
ifeq ($(HAVE_PRLIMIT),1)
|
||
|
@@ -2297,6 +2313,14 @@ $(info autoconfig: using pwritev)
|
||
|
endif
|
||
|
endif
|
||
|
|
||
|
+ifndef $(HAVE_PWRITEV2)
|
||
|
+HAVE_PWRITEV2 = $(shell $(MAKE) -f Makefile.config --no-print-directory $(HAVE_NOT) TEST_PROG=test-pwritev2 have_test_prog)
|
||
|
+ifeq ($(HAVE_PWRITEV2),1)
|
||
|
+ CONFIG_CFLAGS += -DHAVE_PWRITEV2
|
||
|
+$(info autoconfig: using pwritev2)
|
||
|
+endif
|
||
|
+endif
|
||
|
+
|
||
|
ifndef $(HAVE_RECVMMSG)
|
||
|
HAVE_RECVMMSG = $(shell $(MAKE) -f Makefile.config --no-print-directory $(HAVE_NOT) TEST_PROG=test-recvmmsg have_test_prog)
|
||
|
ifeq ($(HAVE_RECVMMSG),1)
|
||
|
diff --git a/stress-hdd.c b/stress-hdd.c
|
||
|
index 9bdf881e0f2e..a9a9dad53352 100644
|
||
|
--- a/stress-hdd.c
|
||
|
+++ b/stress-hdd.c
|
||
|
@@ -180,6 +180,9 @@ static ssize_t stress_hdd_write(
|
||
|
size_t i;
|
||
|
uint8_t *data = buf;
|
||
|
const uint64_t sz = hdd_write_size / HDD_IO_VEC_MAX;
|
||
|
+ off_t offset;
|
||
|
+
|
||
|
+ (void)offset;
|
||
|
|
||
|
for (i = 0; i < HDD_IO_VEC_MAX; i++) {
|
||
|
iov[i].iov_base = (void *)data;
|
||
|
@@ -187,7 +190,27 @@ static ssize_t stress_hdd_write(
|
||
|
|
||
|
data += sz;
|
||
|
}
|
||
|
- ret = writev(fd, iov, HDD_IO_VEC_MAX);
|
||
|
+ switch (stress_mwc8() & 3) {
|
||
|
+#if defined(HAVE_PWRITEV2)
|
||
|
+ case 0:
|
||
|
+ /* 25% */
|
||
|
+ ret = pwritev2(fd, iov, HDD_IO_VEC_MAX, -1, 0);
|
||
|
+ break;
|
||
|
+#endif
|
||
|
+#if defined(HAVE_PWRITEV)
|
||
|
+ case 1:
|
||
|
+ /* 25% */
|
||
|
+ offset = lseek(fd, SEEK_CUR, 0);
|
||
|
+ if (offset != (off_t)-1) {
|
||
|
+ ret = pwritev(fd, iov, HDD_IO_VEC_MAX, offset);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ CASE_FALLTHROUGH;
|
||
|
+#endif
|
||
|
+ default:
|
||
|
+ ret = writev(fd, iov, HDD_IO_VEC_MAX);
|
||
|
+ break;
|
||
|
+ }
|
||
|
} else {
|
||
|
ret = write(fd, buf, count);
|
||
|
}
|
||
|
@@ -229,6 +252,9 @@ static ssize_t stress_hdd_read(
|
||
|
size_t i;
|
||
|
uint8_t *data = buf;
|
||
|
const uint64_t sz = hdd_write_size / HDD_IO_VEC_MAX;
|
||
|
+ off_t offset;
|
||
|
+
|
||
|
+ (void)offset;
|
||
|
|
||
|
for (i = 0; i < HDD_IO_VEC_MAX; i++) {
|
||
|
iov[i].iov_base = (void *)data;
|
||
|
@@ -236,7 +262,24 @@ static ssize_t stress_hdd_read(
|
||
|
|
||
|
data += sz;
|
||
|
}
|
||
|
- return readv(fd, iov, HDD_IO_VEC_MAX);
|
||
|
+ switch (stress_mwc8() & 3) {
|
||
|
+#if defined(HAVE_PREADV2)
|
||
|
+ case 0:
|
||
|
+ /* 25% */
|
||
|
+ return preadv2(fd, iov, HDD_IO_VEC_MAX, -1, 0);
|
||
|
+#endif
|
||
|
+#if defined(HAVE_PREADV)
|
||
|
+ case 1:
|
||
|
+ /* 25% */
|
||
|
+ offset = lseek(fd, SEEK_CUR, 0);
|
||
|
+ if (offset != (off_t)-1)
|
||
|
+ return preadv(fd, iov, HDD_IO_VEC_MAX, offset);
|
||
|
+ CASE_FALLTHROUGH;
|
||
|
+#endif
|
||
|
+ default:
|
||
|
+ /* 50% */
|
||
|
+ return readv(fd, iov, HDD_IO_VEC_MAX);
|
||
|
+ }
|
||
|
} else {
|
||
|
return read(fd, buf, count);
|
||
|
}
|
||
|
diff --git a/test/test-preadv.c b/test/test-preadv.c
|
||
|
new file mode 100644
|
||
|
index 000000000000..6bcfea842a2d
|
||
|
--- /dev/null
|
||
|
+++ b/test/test-preadv.c
|
||
|
@@ -0,0 +1,52 @@
|
||
|
+/*
|
||
|
+ * Copyright (C) 2013-2020 Canonical, Ltd.
|
||
|
+ *
|
||
|
+ * This program is free software; you can redistribute it and/or
|
||
|
+ * modify it under the terms of the GNU General Public License
|
||
|
+ * as published by the Free Software Foundation; either version 2
|
||
|
+ * of the License, or (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This program is distributed in the hope that it will be useful,
|
||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU General Public License
|
||
|
+ * along with this program; if not, write to the Free Software
|
||
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
+ *
|
||
|
+ * This code is a complete clean re-write of the stress tool by
|
||
|
+ * Colin Ian King <colin.king@canonical.com> and attempts to be
|
||
|
+ * backwardly compatible with the stress tool by Amos Waterland
|
||
|
+ * <apw@rossby.metr.ou.edu> but has more stress tests and more
|
||
|
+ * functionality.
|
||
|
+ *
|
||
|
+ */
|
||
|
+#define _GNU_SOURCE
|
||
|
+
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/stat.h>
|
||
|
+#include <fcntl.h>
|
||
|
+#include <sys/uio.h>
|
||
|
+#include <unistd.h>
|
||
|
+
|
||
|
+#define IO_LEN (64)
|
||
|
+
|
||
|
+int main(void)
|
||
|
+{
|
||
|
+ struct iovec iov[1];
|
||
|
+ char data[IO_LEN];
|
||
|
+ int fd, rc;
|
||
|
+
|
||
|
+ fd = open("/dev/zero", O_RDONLY);
|
||
|
+ if (fd < 0)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ iov[0].iov_base = data;
|
||
|
+ iov[0].iov_len = (size_t)IO_LEN;
|
||
|
+
|
||
|
+ rc = preadv(fd, iov, 1, 0);
|
||
|
+ (void)close(fd);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
diff --git a/test/test-preadv2.c b/test/test-preadv2.c
|
||
|
new file mode 100644
|
||
|
index 000000000000..2f87933d2a02
|
||
|
--- /dev/null
|
||
|
+++ b/test/test-preadv2.c
|
||
|
@@ -0,0 +1,52 @@
|
||
|
+/*
|
||
|
+ * Copyright (C) 2013-2020 Canonical, Ltd.
|
||
|
+ *
|
||
|
+ * This program is free software; you can redistribute it and/or
|
||
|
+ * modify it under the terms of the GNU General Public License
|
||
|
+ * as published by the Free Software Foundation; either version 2
|
||
|
+ * of the License, or (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This program is distributed in the hope that it will be useful,
|
||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU General Public License
|
||
|
+ * along with this program; if not, write to the Free Software
|
||
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
+ *
|
||
|
+ * This code is a complete clean re-write of the stress tool by
|
||
|
+ * Colin Ian King <colin.king@canonical.com> and attempts to be
|
||
|
+ * backwardly compatible with the stress tool by Amos Waterland
|
||
|
+ * <apw@rossby.metr.ou.edu> but has more stress tests and more
|
||
|
+ * functionality.
|
||
|
+ *
|
||
|
+ */
|
||
|
+#define _GNU_SOURCE
|
||
|
+
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/stat.h>
|
||
|
+#include <fcntl.h>
|
||
|
+#include <sys/uio.h>
|
||
|
+#include <unistd.h>
|
||
|
+
|
||
|
+#define IO_LEN (64)
|
||
|
+
|
||
|
+int main(void)
|
||
|
+{
|
||
|
+ struct iovec iov[1];
|
||
|
+ char data[IO_LEN];
|
||
|
+ int fd, rc;
|
||
|
+
|
||
|
+ fd = open("/dev/zero", O_RDONLY);
|
||
|
+ if (fd < 0)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ iov[0].iov_base = data;
|
||
|
+ iov[0].iov_len = (size_t)IO_LEN;
|
||
|
+
|
||
|
+ rc = preadv2(fd, iov, 1, -1, 0);
|
||
|
+ (void)close(fd);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
diff --git a/test/test-pwritev.c b/test/test-pwritev.c
|
||
|
index 153f3ff9de09..64d38f403534 100644
|
||
|
--- a/test/test-pwritev.c
|
||
|
+++ b/test/test-pwritev.c
|
||
|
@@ -24,15 +24,27 @@
|
||
|
*/
|
||
|
#define _GNU_SOURCE
|
||
|
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/stat.h>
|
||
|
+#include <fcntl.h>
|
||
|
#include <sys/uio.h>
|
||
|
+#include <unistd.h>
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
struct iovec iov;
|
||
|
char buffer[] = "hello world\n";
|
||
|
+ int fd, rc;
|
||
|
+
|
||
|
+ fd = open("/dev/zero", O_WRONLY);
|
||
|
+ if (fd < 0)
|
||
|
+ return -1;
|
||
|
|
||
|
iov.iov_base = buffer;
|
||
|
iov.iov_len = sizeof(buffer);
|
||
|
|
||
|
- return pwritev(1, &iov, 1, 0);
|
||
|
+ rc = pwritev(fd, &iov, 1, 0);
|
||
|
+ (void)close(fd);
|
||
|
+
|
||
|
+ return rc;
|
||
|
}
|
||
|
diff --git a/test/test-pwritev2.c b/test/test-pwritev2.c
|
||
|
new file mode 100644
|
||
|
index 000000000000..1c7d5f52d477
|
||
|
--- /dev/null
|
||
|
+++ b/test/test-pwritev2.c
|
||
|
@@ -0,0 +1,50 @@
|
||
|
+/*
|
||
|
+ * Copyright (C) 2013-2020 Canonical, Ltd.
|
||
|
+ *
|
||
|
+ * This program is free software; you can redistribute it and/or
|
||
|
+ * modify it under the terms of the GNU General Public License
|
||
|
+ * as published by the Free Software Foundation; either version 2
|
||
|
+ * of the License, or (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This program is distributed in the hope that it will be useful,
|
||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU General Public License
|
||
|
+ * along with this program; if not, write to the Free Software
|
||
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
+ *
|
||
|
+ * This code is a complete clean re-write of the stress tool by
|
||
|
+ * Colin Ian King <colin.king@canonical.com> and attempts to be
|
||
|
+ * backwardly compatible with the stress tool by Amos Waterland
|
||
|
+ * <apw@rossby.metr.ou.edu> but has more stress tests and more
|
||
|
+ * functionality.
|
||
|
+ *
|
||
|
+ */
|
||
|
+#define _GNU_SOURCE
|
||
|
+
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/stat.h>
|
||
|
+#include <fcntl.h>
|
||
|
+#include <sys/uio.h>
|
||
|
+#include <unistd.h>
|
||
|
+
|
||
|
+int main(void)
|
||
|
+{
|
||
|
+ struct iovec iov;
|
||
|
+ char buffer[] = "hello world\n";
|
||
|
+ int fd, rc;
|
||
|
+
|
||
|
+ fd = open("/dev/zero", O_WRONLY);
|
||
|
+ if (fd < 0)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ iov.iov_base = buffer;
|
||
|
+ iov.iov_len = sizeof(buffer);
|
||
|
+
|
||
|
+ rc = pwritev2(fd, &iov, 1, -1, 0);
|
||
|
+ (void)close(fd);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
--
|
||
|
2.21.3
|
||
|
|