bdevperf: Use zcopy APIs for write I/O with verify or reset cases
When zcopy APIs are used, target->buf cannot be passed directly to the bdev layer. Hence in addition to the last patch, copy target->buf to the buffer allocated by spdk_bdev_zcopy_start() when g_verify or g_reset is true. When g_verify or g_reset is true, a little performance degradation will be acceptable. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: I2caa4d0423f727954220c4ceac6b37f1b532013d Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/467901 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
00dd9e8519
commit
de5c7b8a40
@ -151,6 +151,25 @@ generate_data(void *buf, int buf_len, int block_size, void *md_buf, int md_size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
copy_data(void *wr_buf, int wr_buf_len, void *rd_buf, int rd_buf_len, int block_size,
|
||||||
|
void *wr_md_buf, void *rd_md_buf, int md_size, int num_blocks)
|
||||||
|
{
|
||||||
|
if (wr_buf_len < num_blocks * block_size || rd_buf_len < num_blocks * block_size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert((wr_md_buf != NULL) == (rd_md_buf != NULL));
|
||||||
|
|
||||||
|
memcpy(wr_buf, rd_buf, block_size * num_blocks);
|
||||||
|
|
||||||
|
if (wr_md_buf != NULL) {
|
||||||
|
memcpy(wr_md_buf, rd_md_buf, md_size * num_blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
verify_data(void *wr_buf, int wr_buf_len, void *rd_buf, int rd_buf_len, int block_size,
|
verify_data(void *wr_buf, int wr_buf_len, void *rd_buf, int rd_buf_len, int block_size,
|
||||||
void *wr_md_buf, void *rd_md_buf, int md_size, int num_blocks, bool md_check)
|
void *wr_md_buf, void *rd_md_buf, int md_size, int num_blocks, bool md_check)
|
||||||
@ -617,7 +636,7 @@ bdevperf_submit_task(void *arg)
|
|||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
cb_fn = (g_verify || g_reset) ? bdevperf_verify_write_complete : bdevperf_complete;
|
cb_fn = (g_verify || g_reset) ? bdevperf_verify_write_complete : bdevperf_complete;
|
||||||
|
|
||||||
if (g_zcopy && !g_verify && !g_reset) {
|
if (g_zcopy) {
|
||||||
spdk_bdev_zcopy_end(task->bdev_io, true, cb_fn, task);
|
spdk_bdev_zcopy_end(task->bdev_io, true, cb_fn, task);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -688,6 +707,8 @@ bdevperf_zcopy_get_buf_complete(struct spdk_bdev_io *bdev_io, bool success, void
|
|||||||
{
|
{
|
||||||
struct bdevperf_task *task = cb_arg;
|
struct bdevperf_task *task = cb_arg;
|
||||||
struct io_target *target = task->target;
|
struct io_target *target = task->target;
|
||||||
|
struct iovec *iovs;
|
||||||
|
int iovcnt;
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
target->is_draining = true;
|
target->is_draining = true;
|
||||||
@ -698,6 +719,23 @@ bdevperf_zcopy_get_buf_complete(struct spdk_bdev_io *bdev_io, bool success, void
|
|||||||
task->bdev_io = bdev_io;
|
task->bdev_io = bdev_io;
|
||||||
task->io_type = SPDK_BDEV_IO_TYPE_WRITE;
|
task->io_type = SPDK_BDEV_IO_TYPE_WRITE;
|
||||||
|
|
||||||
|
if (g_verify || g_reset) {
|
||||||
|
/* When g_verify or g_reset is enabled, task->buf is used for
|
||||||
|
* verification of read after write. For write I/O, when zcopy APIs
|
||||||
|
* are used, task->buf cannot be used, and data must be written to
|
||||||
|
* the data buffer allocated underneath bdev layer instead.
|
||||||
|
* Hence we copy task->buf to the allocated data buffer here.
|
||||||
|
*/
|
||||||
|
spdk_bdev_io_get_iovec(bdev_io, &iovs, &iovcnt);
|
||||||
|
assert(iovcnt == 1);
|
||||||
|
assert(iovs != NULL);
|
||||||
|
|
||||||
|
copy_data(iovs[0].iov_base, iovs[0].iov_len, task->buf, g_buf_size,
|
||||||
|
spdk_bdev_get_block_size(target->bdev),
|
||||||
|
spdk_bdev_io_get_md_buf(bdev_io), task->md_buf,
|
||||||
|
spdk_bdev_get_md_size(target->bdev), target->io_size_blocks);
|
||||||
|
}
|
||||||
|
|
||||||
bdevperf_submit_task(task);
|
bdevperf_submit_task(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,9 +781,14 @@ bdevperf_prep_task(struct bdevperf_task *task)
|
|||||||
spdk_bdev_get_block_size(target->bdev),
|
spdk_bdev_get_block_size(target->bdev),
|
||||||
task->md_buf, spdk_bdev_get_md_size(target->bdev),
|
task->md_buf, spdk_bdev_get_md_size(target->bdev),
|
||||||
target->io_size_blocks, rand_r(&seed) % 256);
|
target->io_size_blocks, rand_r(&seed) % 256);
|
||||||
|
if (g_zcopy) {
|
||||||
|
bdevperf_prep_zcopy_write_task(task);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
task->iov.iov_base = task->buf;
|
task->iov.iov_base = task->buf;
|
||||||
task->iov.iov_len = g_buf_size;
|
task->iov.iov_len = g_buf_size;
|
||||||
task->io_type = SPDK_BDEV_IO_TYPE_WRITE;
|
task->io_type = SPDK_BDEV_IO_TYPE_WRITE;
|
||||||
|
}
|
||||||
} else if (g_flush) {
|
} else if (g_flush) {
|
||||||
task->io_type = SPDK_BDEV_IO_TYPE_FLUSH;
|
task->io_type = SPDK_BDEV_IO_TYPE_FLUSH;
|
||||||
} else if (g_unmap) {
|
} else if (g_unmap) {
|
||||||
|
Loading…
Reference in New Issue
Block a user