iscsi-perf: add a switch to send requests of random size

Signed-off-by: Peter Lieven <pl@kamp.de>
This commit is contained in:
Peter Lieven
2015-03-27 12:18:58 +01:00
parent 9d6f0690f8
commit b9dc3749c9

View File

@@ -48,6 +48,7 @@ struct client {
int finished;
int in_flight;
int random;
int random_blocks;
struct iscsi_context *iscsi;
struct scsi_iovec perf_iov;
@@ -60,6 +61,8 @@ struct client {
uint64_t first_ns;
uint64_t iops;
uint64_t last_iops;
uint64_t bytes;
uint64_t last_bytes;
int ignore_errors;
int busy_cnt;
@@ -97,40 +100,44 @@ void progress(struct client *client) {
if (runtime) _runtime = runtime - _runtime;
printf ("\r");
uint64_t aiops = 1000000000UL * (client->iops) / (now - client->first_ns);
uint64_t aiops = 1000000000.0 * (client->iops) / (now - client->first_ns);
uint64_t ambps = 1000000000.0 * (client->bytes) / (now - client->first_ns);
if (!_runtime) {
finished = 1;
printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s) ", aiops, (aiops * blocks_per_io * client->blocksize) >> 20);
} else {
uint64_t iops = 1000000000UL * (client->iops - client->last_iops) / (now - client->last_ns);
uint64_t mbps = 1000000000UL * (client->bytes - client->last_bytes) / (now - client->last_ns);
printf ("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 " - ", _runtime / 3600, (_runtime % 3600) / 60, _runtime % 60);
printf ("lba %" PRIu64 ", iops current %" PRIu64 " (%" PRIu64 " MB/s), ", client->pos, iops, (iops * blocks_per_io * client->blocksize) >> 20);
printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s), in_flight %d, busy %d ", aiops, (aiops * blocks_per_io * client->blocksize) >> 20, client->in_flight, client->busy_cnt);
printf ("lba %" PRIu64 ", iops current %" PRIu64 " (%" PRIu64 " MB/s), ", client->pos, iops, mbps >> 20);
printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s), in_flight %d, busy %d ", aiops, ambps >> 20, client->in_flight, client->busy_cnt);
}
fflush(stdout);
client->last_ns = now;
client->last_iops = client->iops;
client->last_bytes = client->bytes;
}
void cb(struct iscsi_context *iscsi _U_, int status, void *command_data, void *private_data)
{
struct client *client = (struct client *)private_data;
struct scsi_task *task = command_data, *task2 = NULL;
struct scsi_read16_cdb *read16_cdb = NULL;
read16_cdb = scsi_cdb_unmarshall(task, SCSI_OPCODE_READ16);
if (read16_cdb == NULL) {
fprintf(stderr, "Failed to unmarshall READ16 CDB.\n");
client->err_cnt++;
goto out;
}
if (status == SCSI_STATUS_BUSY ||
(status == SCSI_STATUS_CHECK_CONDITION && task->sense.key == SCSI_SENSE_UNIT_ATTENTION)) {
struct scsi_read16_cdb *read16_cdb = NULL;
if (client->retry_cnt++ > 4 * max_in_flight) {
fprintf(stderr, "maxium number of command retries reached...\n");
client->err_cnt++;
goto out;
}
read16_cdb = scsi_cdb_unmarshall(task, SCSI_OPCODE_READ16);
if (read16_cdb == NULL) {
fprintf(stderr, "Failed to unmarshall READ16 CDB.\n");
client->err_cnt++;
goto out;
}
task2 = iscsi_read16_task(client->iscsi,
client->lun, read16_cdb->lba,
read16_cdb->transfer_length * client->blocksize,
@@ -148,6 +155,7 @@ void cb(struct iscsi_context *iscsi _U_, int status, void *command_data, void *p
client->err_cnt++;
} else if (status == SCSI_STATUS_GOOD) {
client->retry_cnt = 0;
client->bytes += read16_cdb->transfer_length * client->blocksize;
} else {
fprintf(stderr, "Read16 failed with %s\n", iscsi_get_error(iscsi));
if (!client->ignore_errors) {
@@ -186,6 +194,10 @@ void fill_read_queue(struct client *client)
if (num_blocks > blocks_per_io) {
num_blocks = blocks_per_io;
}
if (client->random_blocks) {
num_blocks = rand() % num_blocks + 1;
}
task = iscsi_read16_task(client->iscsi,
client->lun, client->pos,
@@ -236,6 +248,7 @@ int main(int argc, char *argv[])
{"blocks", required_argument, NULL, 'b'},
{"runtime", required_argument, NULL, 't'},
{"random", no_argument, NULL, 'r'},
{"random-blocks", no_argument, NULL, 'R'},
{"ignore-errors", no_argument, NULL, 'n'},
{0, 0, 0, 0}
};
@@ -247,7 +260,7 @@ int main(int argc, char *argv[])
printf("iscsi-perf version %s - (c) 2014-2015 by Peter Lieven <pl@ĸamp.de>\n\n", VERSION);
while ((c = getopt_long(argc, argv, "i:m:b:t:nr", long_options,
while ((c = getopt_long(argc, argv, "i:m:b:t:nrR", long_options,
&option_index)) != -1) {
switch (c) {
case 'i':
@@ -268,6 +281,9 @@ int main(int argc, char *argv[])
case 'r':
client.random = 1;
break;
case 'R':
client.random_blocks = 1;
break;
default:
fprintf(stderr, "Unrecognized option '%c'\n\n", c);
usage();
@@ -338,8 +354,13 @@ int main(int argc, char *argv[])
printf("capacity is %" PRIu64 " blocks or %" PRIu64 " byte (%" PRIu64 " MB)\n", client.num_blocks, client.num_blocks * client.blocksize,
(client.num_blocks * client.blocksize) >> 20);
printf("performing %s READ with %d parallel requests\nfixed transfer size of %d blocks (%d byte)\n",
client.random ? "random" : "sequential", max_in_flight, blocks_per_io, blocks_per_io * client.blocksize);
printf("performing %s READ with %d parallel requests\n", client.random ? "RANDOM" : "SEQUENTIAL", max_in_flight);
if (client.random_blocks) {
printf("RANDOM transfer size of 1 - %d blocks (%d - %d byte)\n", blocks_per_io, client.blocksize, blocks_per_io * client.blocksize);
} else {
printf("FIXED transfer size of %d blocks (%d byte)\n", blocks_per_io, blocks_per_io * client.blocksize);
}
if (runtime) {
printf("will run for %" PRIu64 " seconds.\n", runtime);