aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-01-09 21:49:56 +0100
committerArnd Bergmann <arnd@arndb.de>2011-01-09 21:49:56 +0100
commit8d57ecb0c175f0eca26fd489cc09464adbc73319 (patch)
tree8e6e3cea3a21ed6a4213fec793061ef33c32274f
parent085e8fd094293ad240a6cbb5d79acb7de5ed1dad (diff)
flashbench: implement erase operation using BLKDISCARD
Erasing blocks has a huge impact on timing, we need to test this. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--dev.c24
-rw-r--r--dev.h2
-rw-r--r--vm.c50
3 files changed, 55 insertions, 21 deletions
diff --git a/dev.c b/dev.c
index 4cb4a3a..319003a 100644
--- a/dev.c
+++ b/dev.c
@@ -4,6 +4,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
@@ -17,6 +18,8 @@
#include <getopt.h>
#include <stdbool.h>
+#include <linux/fs.h>
+
#include "dev.h"
#define MAX_BUFSIZE (64 * 1024 * 1024)
@@ -83,6 +86,25 @@ long long time_write(struct device *dev, off_t pos, size_t size, enum writebuf w
return get_ns() - now;
}
+long long time_erase(struct device *dev, off_t pos, size_t size)
+{
+ long long now = get_ns();
+ ssize_t ret;
+ unsigned long long args[2] = { size, pos % dev->size };
+
+ if (size > MAX_BUFSIZE)
+ return -ENOMEM;
+
+ ret = ioctl(dev->fd, BLKDISCARD, &args);
+
+ if (ret) {
+ perror("time_erase");
+ return 0;
+ }
+
+ return get_ns() - now;
+}
+
static void set_rtprio(void)
{
int ret;
@@ -97,7 +119,7 @@ static void set_rtprio(void)
int setup_dev(struct device *dev, const char *filename)
{
- int i, err;
+ int err;
void *p;
set_rtprio();
diff --git a/dev.h b/dev.h
index 865a7c8..9d30197 100644
--- a/dev.h
+++ b/dev.h
@@ -22,4 +22,6 @@ long long time_write(struct device *dev, off_t pos, size_t size, enum writebuf w
long long time_read(struct device *dev, off_t pos, size_t size);
+long long time_erase(struct device *dev, off_t pos, size_t size);
+
#endif /* FLASHBENCH_DEV_H */
diff --git a/vm.c b/vm.c
index e51e5e3..e65770c 100644
--- a/vm.c
+++ b/vm.c
@@ -172,24 +172,34 @@ static struct operation *do_read(struct operation *op, struct device *dev,
return op+1;
}
-static struct operation *do_write(struct operation *op, struct device *dev,
+static struct operation *do_write_zero(struct operation *op, struct device *dev,
off_t off, off_t max, size_t len)
{
- enum writebuf writebuf;
- switch (op->code) {
- case O_WRITE_ZERO:
- writebuf = WBUF_ZERO;
- break;
- case O_WRITE_ONE:
- writebuf = WBUF_ONE;
- break;
- case O_WRITE_RAND:
- writebuf = WBUF_RAND;
- break;
- default:
- return NULL;
- }
- op->result.l = time_write(dev, off, len, writebuf);
+ op->result.l = time_write(dev, off, len, WBUF_ZERO);
+ op->r_type = R_NS;
+ return op+1;
+}
+
+static struct operation *do_write_one(struct operation *op, struct device *dev,
+ off_t off, off_t max, size_t len)
+{
+ op->result.l = time_write(dev, off, len, WBUF_ONE);
+ op->r_type = R_NS;
+ return op+1;
+}
+
+static struct operation *do_write_rand(struct operation *op, struct device *dev,
+ off_t off, off_t max, size_t len)
+{
+ op->result.l = time_write(dev, off, len, WBUF_RAND);
+ op->r_type = R_NS;
+ return op+1;
+}
+
+static struct operation *do_erase(struct operation *op, struct device *dev,
+ off_t off, off_t max, size_t len)
+{
+ op->result.l = time_erase(dev, off, len);
op->r_type = R_NS;
return op+1;
}
@@ -688,10 +698,10 @@ static struct operation *drop(struct operation *op, struct device *dev,
static struct syntax syntax[] = {
{ O_END, "END", nop, },
{ O_READ, "READ", do_read, },
- { O_WRITE_ZERO, "WRITE_ZERO", do_write, },
- { O_WRITE_ONE, "WRITE_ONE", do_write, },
- { O_WRITE_RAND, "WRITE_RAND", do_write, },
- { O_ERASE, "ERASE", nop, },
+ { O_WRITE_ZERO, "WRITE_ZERO", do_write_zero, },
+ { O_WRITE_ONE, "WRITE_ONE", do_write_one, },
+ { O_WRITE_RAND, "WRITE_RAND", do_write_rand, },
+ { O_ERASE, "ERASE", do_erase, },
{ O_LENGTH, "LENGTH", length_or_offs },
{ O_OFFSET, "OFFSET", length_or_offs, },