aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/zpios/zpios.h11
-rw-r--r--cmd/zpios/zpios_main.c55
-rw-r--r--cmd/zpios/zpios_util.c19
-rw-r--r--include/zpios-ctl.h3
-rw-r--r--include/zpios-internal.h3
-rw-r--r--man/man1/zpios.135
-rw-r--r--module/zpios/pios.c18
7 files changed, 127 insertions, 17 deletions
diff --git a/cmd/zpios/zpios.h b/cmd/zpios/zpios.h
index 92d96fcbe..4a69b9e54 100644
--- a/cmd/zpios/zpios.h
+++ b/cmd/zpios/zpios.h
@@ -29,6 +29,8 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2015, Intel Corporation.
*/
#ifndef _ZPIOS_H
@@ -39,10 +41,10 @@
#define VERSION_SIZE 64
/* Regular expressions */
-#define REGEX_NUMBERS "^[0-9]*[0-9]$"
+#define REGEX_NUMBERS "^[0-9]+$"
#define REGEX_NUMBERS_COMMA "^([0-9]+,)*[0-9]+$"
-#define REGEX_SIZE "^[0-9][0-9]*[kmgt]$"
-#define REGEX_SIZE_COMMA "^([0-9][0-9]*[kmgt]+,)*[0-9][0-9]*[kmgt]$"
+#define REGEX_SIZE "^[0-9]+[kKmMgGtT]?$"
+#define REGEX_SIZE_COMMA "^([0-9]+[kKmMgGtT]?,)*[0-9]+[kKmMgGtT]?$"
/* Flags for low, high, incr */
#define FLAG_SET 0x01
@@ -82,10 +84,12 @@ typedef struct cmd_args {
range_repeat_t O; /* Offset count */
range_repeat_t C; /* Chunksize */
range_repeat_t S; /* Regionsize */
+ range_repeat_t B; /* Blocksize */
const char *pool; /* Pool */
const char *name; /* Name */
uint32_t flags; /* Flags */
+ uint32_t block_size; /* ZFS block size */
uint32_t io_type; /* DMUIO only */
uint32_t verbose; /* Verbose */
uint32_t human_readable; /* Human readable output */
@@ -105,6 +109,7 @@ typedef struct cmd_args {
uint64_t current_C;
uint64_t current_S;
uint64_t current_O;
+ uint64_t current_B;
uint32_t rc;
} cmd_args_t;
diff --git a/cmd/zpios/zpios_main.c b/cmd/zpios/zpios_main.c
index 971a886a3..e6e88f60d 100644
--- a/cmd/zpios/zpios_main.c
+++ b/cmd/zpios/zpios_main.c
@@ -29,6 +29,8 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2015, Intel Corporation.
*/
#include <stdlib.h>
@@ -44,7 +46,7 @@
static const char short_opt[] =
"t:l:h:e:n:i:j:k:o:m:q:r:c:a:b:g:s:A:B:C:"
- "L:p:M:xP:R:G:I:N:T:VzOfHv?";
+ "S:L:p:M:xP:R:G:I:N:T:VzOfHv?";
static const struct option long_opt[] = {
{"threadcount", required_argument, 0, 't' },
{"threadcount_low", required_argument, 0, 'l' },
@@ -66,6 +68,7 @@ static const struct option long_opt[] = {
{"regionsize_low", required_argument, 0, 'A' },
{"regionsize_high", required_argument, 0, 'B' },
{"regionsize_incr", required_argument, 0, 'C' },
+ {"blocksize", required_argument, 0, 'S' },
{"load", required_argument, 0, 'L' },
{"pool", required_argument, 0, 'p' },
{"name", required_argument, 0, 'M' },
@@ -116,6 +119,7 @@ usage(void)
" --regionsize_low -A =value\n"
" --regionsize_high -B =value\n"
" --regionsize_incr -C =value\n"
+ " --blocksize -S =values\n"
" --load -L =dmuio|ssf|fpp\n"
" --pool -p =pool name\n"
" --name -M =test name\n"
@@ -143,6 +147,11 @@ static void args_fini(cmd_args_t *args)
free(args);
}
+/* block size is 128K to 16M, power of 2 */
+#define MIN_BLKSIZE (128ULL << 10)
+#define MAX_BLKSIZE (16ULL << 20)
+#define POW_OF_TWO(x) (((x) & ((x) - 1)) == 0)
+
static cmd_args_t *
args_init(int argc, char **argv)
{
@@ -152,7 +161,8 @@ args_init(int argc, char **argv)
uint32_t fl_of = 0;
uint32_t fl_rs = 0;
uint32_t fl_cs = 0;
- int c, rc;
+ uint32_t fl_bs = 0;
+ int c, rc, i;
if (argc == 1) {
usage();
@@ -166,6 +176,11 @@ args_init(int argc, char **argv)
memset(args, 0, sizeof (*args));
+ /* provide a default block size of 128K */
+ args->B.next_val = 0;
+ args->B.val[0] = MIN_BLKSIZE;
+ args->B.val_count = 1;
+
while ((c = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
rc = 0;
@@ -250,6 +265,10 @@ args_init(int argc, char **argv)
rc = set_lhi(REGEX_NUMBERS, &args->S, optarg,
FLAG_INCR, &fl_rs, "regionsize_incr");
break;
+ case 'S': /* --blocksize */
+ rc = set_count(REGEX_SIZE, REGEX_SIZE_COMMA,
+ &args->B, optarg, &fl_bs, "blocksize");
+ break;
case 'L': /* --load */
rc = set_load_params(args, optarg);
break;
@@ -339,6 +358,17 @@ args_init(int argc, char **argv)
return (NULL);
}
+ /* validate block size(s) */
+ for (i = 0; i < args->B.val_count; i++) {
+ int bs = args->B.val[i];
+
+ if (bs < MIN_BLKSIZE || bs > MAX_BLKSIZE || !POW_OF_TWO(bs)) {
+ fprintf(stderr, "Error: invalid block size %d\n", bs);
+ args_fini(args);
+ return (NULL);
+ }
+ }
+
return (args);
}
@@ -480,7 +510,7 @@ get_next(uint64_t *val, range_repeat_t *range)
static int
run_one(cmd_args_t *args, uint32_t id, uint32_t T, uint32_t N,
- uint64_t C, uint64_t S, uint64_t O)
+ uint64_t C, uint64_t S, uint64_t O, uint64_t B)
{
zpios_cmd_t *cmd;
int rc, rc2, cmd_size;
@@ -506,6 +536,7 @@ run_one(cmd_args_t *args, uint32_t id, uint32_t T, uint32_t N,
cmd->cmd_region_count = N;
cmd->cmd_region_size = S;
cmd->cmd_offset = O;
+ cmd->cmd_block_size = B;
cmd->cmd_region_noise = args->regionnoise;
cmd->cmd_chunk_noise = args->chunknoise;
cmd->cmd_thread_delay = args->thread_delay;
@@ -541,7 +572,7 @@ run_offsets(cmd_args_t *args)
while (rc == 0 && get_next(&args->current_O, &args->O)) {
rc = run_one(args, args->current_id,
args->current_T, args->current_N, args->current_C,
- args->current_S, args->current_O);
+ args->current_S, args->current_O, args->current_B);
args->current_id++;
}
@@ -594,12 +625,26 @@ run_chunk_sizes(cmd_args_t *args)
}
static int
+run_block_sizes(cmd_args_t *args)
+{
+ int rc = 0;
+
+ while (rc == 0 && get_next(&args->current_B, &args->B)) {
+ rc = run_chunk_sizes(args);
+ }
+
+ args->B.next_val = 0;
+ return (rc);
+}
+
+
+static int
run_thread_counts(cmd_args_t *args)
{
int rc = 0;
while (rc == 0 && get_next((uint64_t *)&args->current_T, &args->T))
- rc = run_chunk_sizes(args);
+ rc = run_block_sizes(args);
return (rc);
}
diff --git a/cmd/zpios/zpios_util.c b/cmd/zpios/zpios_util.c
index b226322b0..2d248ed9a 100644
--- a/cmd/zpios/zpios_util.c
+++ b/cmd/zpios/zpios_util.c
@@ -29,6 +29,8 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2015, Intel Corporation.
*/
#include <stdlib.h>
@@ -185,6 +187,8 @@ int
set_count(char *pattern1, char *pattern2, range_repeat_t *range,
char *optarg, uint32_t *flags, char *arg)
{
+ uint64_t count = range->val_count;
+
if (flags)
*flags |= FLAG_SET;
@@ -197,6 +201,9 @@ set_count(char *pattern1, char *pattern2, range_repeat_t *range,
fprintf(stderr, "Error: Incorrect pattern for %s, '%s'\n",
arg, optarg);
return (EINVAL);
+ } else if (count == range->val_count) {
+ fprintf(stderr, "Error: input ignored for %s, '%s'\n",
+ arg, optarg);
}
return (0);
@@ -314,14 +321,14 @@ print_stats_header(cmd_args_t *args)
if (args->verbose) {
printf(
"status name id\tth-cnt\trg-cnt\trg-sz\t"
- "ch-sz\toffset\trg-no\tch-no\tth-dly\tflags\ttime\t"
+ "ch-sz\toffset\trg-no\tch-no\tth-dly\tflags\tblksz\ttime\t"
"cr-time\trm-time\twr-time\trd-time\twr-data\twr-ch\t"
"wr-bw\trd-data\trd-ch\trd-bw\n");
printf(
- "------------------------------------------------"
- "------------------------------------------------"
- "------------------------------------------------"
- "----------------------------------------------\n");
+ "-------------------------------------------------"
+ "-------------------------------------------------"
+ "-------------------------------------------------"
+ "--------------------------------------------------\n");
} else {
printf(
"status name id\t"
@@ -358,6 +365,7 @@ print_stats_human_readable(cmd_args_t *args, zpios_cmd_t *cmd)
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_chunk_noise));
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_thread_delay));
printf("%s\t", print_flags(str, cmd->cmd_flags));
+ printf("%s\t", uint64_to_kmgt(str, cmd->cmd_block_size));
}
if (args->rc) {
@@ -414,6 +422,7 @@ print_stats_table(cmd_args_t *args, zpios_cmd_t *cmd)
printf("%u\t", cmd->cmd_chunk_noise);
printf("%u\t", cmd->cmd_thread_delay);
printf("0x%x\t", cmd->cmd_flags);
+ printf("%u\t", cmd->cmd_block_size);
}
if (args->rc) {
diff --git a/include/zpios-ctl.h b/include/zpios-ctl.h
index 9a47ff91d..aee4f0a50 100644
--- a/include/zpios-ctl.h
+++ b/include/zpios-ctl.h
@@ -29,6 +29,8 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2015, Intel Corporation.
*/
#ifndef _ZPIOS_CTL_H
@@ -116,6 +118,7 @@ typedef struct zpios_cmd {
uint32_t cmd_chunk_noise; /* Chunk noise */
uint32_t cmd_thread_delay; /* Thread delay */
uint32_t cmd_flags; /* Test flags */
+ uint32_t cmd_block_size; /* ZFS block size */
char cmd_pre[ZPIOS_PATH_SIZE]; /* Pre-exec hook */
char cmd_post[ZPIOS_PATH_SIZE]; /* Post-exec hook */
char cmd_log[ZPIOS_PATH_SIZE]; /* Requested log dir */
diff --git a/include/zpios-internal.h b/include/zpios-internal.h
index 4b99b4ce3..dd2bd2343 100644
--- a/include/zpios-internal.h
+++ b/include/zpios-internal.h
@@ -29,6 +29,8 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2015, Intel Corporation.
*/
#ifndef _ZPIOS_INTERNAL_H
@@ -79,6 +81,7 @@ typedef struct run_args {
__u32 chunk_noise;
__u32 thread_delay;
__u32 flags;
+ __u32 block_size;
char pre[ZPIOS_PATH_SIZE];
char post[ZPIOS_PATH_SIZE];
char log[ZPIOS_PATH_SIZE];
diff --git a/man/man1/zpios.1 b/man/man1/zpios.1
index 4b362b09d..4334c03c0 100644
--- a/man/man1/zpios.1
+++ b/man/man1/zpios.1
@@ -22,6 +22,8 @@
.\"
.\" Copyright 2013 Darik Horn <[email protected]>. All rights reserved.
.\"
+.\" Copyright (c) 2015, Intel Corporation.
+.\"
.TH zpios 1 "2013 FEB 28" "ZFS on Linux" "User Commands"
.SH NAME
@@ -36,10 +38,10 @@ not depend on the ZFS Posix Layer ("ZPL").
.SH OPTIONS
.HP
-.BI "\-s" " regex" ", \-\-threadcount" " regex"
+.BI "\-t" " regex" ", \-\-threadcount" " regex"
.IP
Start this many threads for each test series, specified as a comma
-delimited regular expression. (eg: "-s 1,2,3")
+delimited regular expression. (eg: "-t 1,2,3")
.IP
This option is mutually exclusive with the \fBthreadcount_*\fR
options.
@@ -120,6 +122,35 @@ chunk size for the last test.
These three options must be specified together and are mutually
exclusive with the \fBchunksize\fR option.
.HP
+.BI "\-s" " size" ", \-\-regionsize" " size"
+.IP
+Use \fIsize\fR regions for each test, specified as a comma delimited
+regular expression with an optional unit suffix. (eg: "-s 1M" means
+one megabyte.)
+.IP
+This option is mutually exclusive with the \fBregionsize_*\fB options.
+.HP
+.BI "\-A" " size_low" ", \-\-regionsize_low" " size_low"
+.HP
+.BI "\-B" " size_high" ", \-\-regionsize_high" " size_high"
+.HP
+.BI "\-C" " size_incr" ", \-\-regionsize_incr" " size_incr"
+.IP
+Use a \fIsize_low\fR region size for the first test, add \fIsize_incr\fR
+to the region size for each subsequent test, and use a \fIsize_high\fR
+region size for the last test.
+.IP
+These three options must be specified together and are mutually
+exclusive with the \fBregionsize\fR option.
+.HP
+.BI "\-S" " size | sizes" ", \-\-blocksize" " size | sizes"
+.IP
+Use \fIsize\fR ZFS blocks for each test, specified as a comma delimited
+regular expression with an optional unit suffix. (eg: "-S 1M" means
+one megabyte.) The supported range is powers of two from 128K through 16M.
+A range of blocks can be tested as follows: "-S 128K,256K,512K,1M".
+.IP
+.HP
.BI "\-L" " dmu_flags" ", \-\-load" " dmu_flags"
.IP
Specify \fIdmuio\fR for regular DMU_IO, \fIssf\fR for single shared
diff --git a/module/zpios/pios.c b/module/zpios/pios.c
index e3a85c168..8f4a8fd69 100644
--- a/module/zpios/pios.c
+++ b/module/zpios/pios.c
@@ -29,10 +29,13 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2015, Intel Corporation.
*/
#include <sys/zfs_context.h>
#include <sys/dmu.h>
+#include <sys/spa.h>
#include <sys/txg.h>
#include <sys/dsl_destroy.h>
#include <linux/miscdevice.h>
@@ -129,8 +132,17 @@ zpios_dmu_object_create(run_args_t *run_args, objset_t *os)
{
struct dmu_tx *tx;
uint64_t obj = 0ULL;
+ uint64_t blksize = run_args->block_size;
int rc;
+ if (blksize < SPA_MINBLOCKSIZE ||
+ blksize > spa_maxblocksize(dmu_objset_spa(os)) ||
+ !ISP2(blksize)) {
+ zpios_print(run_args->file,
+ "invalid block size for pool: %d\n", (int)blksize);
+ return (obj);
+ }
+
tx = dmu_tx_create(os);
dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, OBJ_SIZE);
rc = dmu_tx_assign(tx, TXG_WAIT);
@@ -142,10 +154,11 @@ zpios_dmu_object_create(run_args_t *run_args, objset_t *os)
}
obj = dmu_object_alloc(os, DMU_OT_UINT64_OTHER, 0, DMU_OT_NONE, 0, tx);
- rc = dmu_object_set_blocksize(os, obj, 128ULL << 10, 0, tx);
+ rc = dmu_object_set_blocksize(os, obj, blksize, 0, tx);
if (rc) {
zpios_print(run_args->file,
- "dmu_object_set_blocksize() failed: %d\n", rc);
+ "dmu_object_set_blocksize to %d failed: %d\n",
+ (int)blksize, rc);
dmu_tx_abort(tx);
return (obj);
}
@@ -295,6 +308,7 @@ zpios_setup_run(run_args_t **run_args, zpios_cmd_t *kcmd, struct file *file)
ra->chunk_noise = kcmd->cmd_chunk_noise;
ra->thread_delay = kcmd->cmd_thread_delay;
ra->flags = kcmd->cmd_flags;
+ ra->block_size = kcmd->cmd_block_size;
ra->stats.wr_data = 0;
ra->stats.wr_chunks = 0;
ra->stats.rd_data = 0;