diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index 7f621abfa..dec0e0c05 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -199,6 +199,14 @@ bool spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type int spdk_bdev_dump_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w); +/** + * Get minimum I/O buffer address alignment for a bdev. + * + * \param bdev Block device to query. + * \return Required alignment of I/O buffers in bytes. + */ +size_t spdk_bdev_get_buf_align(const struct spdk_bdev *bdev); + struct spdk_bdev_io *spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch, void *buf, uint64_t offset, uint64_t nbytes, spdk_bdev_io_completion_cb cb, void *cb_arg); diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 237bda75c..75d53bdbd 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -532,6 +532,17 @@ spdk_bdev_get_io_channel(struct spdk_bdev *bdev, uint32_t priority) return spdk_get_io_channel(bdev, priority, false, NULL); } +size_t +spdk_bdev_get_buf_align(const struct spdk_bdev *bdev) +{ + /* TODO: push this logic down to the bdev modules */ + if (bdev->need_aligned_buffer) { + return bdev->blocklen; + } + + return 1; +} + static int spdk_bdev_io_valid(struct spdk_bdev *bdev, uint64_t offset, uint64_t nbytes) { diff --git a/test/lib/bdev/bdevperf/bdevperf.c b/test/lib/bdev/bdevperf/bdevperf.c index efbef9a5a..638dfaeec 100644 --- a/test/lib/bdev/bdevperf/bdevperf.c +++ b/test/lib/bdev/bdevperf/bdevperf.c @@ -44,6 +44,7 @@ #include "spdk/env.h" #include "spdk/event.h" #include "spdk/log.h" +#include "spdk/util.h" #include "spdk/io_channel.h" struct bdevperf_task { @@ -96,7 +97,7 @@ static int g_target_count = 0; * require alignment based on block length - for example, * AIO blockdevs. */ -static uint32_t g_min_alignment = 8; +static size_t g_min_alignment = 8; static void blockdev_heads_init(void) @@ -114,6 +115,7 @@ bdevperf_construct_targets(void) int index = 0; struct spdk_bdev *bdev; struct io_target *target; + size_t align; bdev = spdk_bdev_first(); while (bdev != NULL) { @@ -145,9 +147,12 @@ bdevperf_construct_targets(void) target->offset_in_ios = 0; target->size_in_ios = (bdev->blockcnt * bdev->blocklen) / g_io_size; - if (bdev->need_aligned_buffer && g_min_alignment < bdev->blocklen) { - g_min_alignment = bdev->blocklen; - } + align = spdk_bdev_get_buf_align(bdev); + /* + * TODO: This should actually use the LCM of align and g_min_alignment, but + * it is fairly safe to assume all alignments are powers of two for now. + */ + g_min_alignment = spdk_max(g_min_alignment, align); target->is_draining = false; target->run_timer = NULL;