diff options
author | Arnd Bergmann <arnd@arndb.de> | 2011-01-09 21:49:56 +0100 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2011-01-09 21:49:56 +0100 |
commit | 8d57ecb0c175f0eca26fd489cc09464adbc73319 (patch) | |
tree | 8e6e3cea3a21ed6a4213fec793061ef33c32274f | |
parent | 085e8fd094293ad240a6cbb5d79acb7de5ed1dad (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.c | 24 | ||||
-rw-r--r-- | dev.h | 2 | ||||
-rw-r--r-- | vm.c | 50 |
3 files changed, 55 insertions, 21 deletions
@@ -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(); @@ -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 */ @@ -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, }, |