diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index 1d7c5f77a..d1c98aaf2 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -219,6 +219,15 @@ uint64_t spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev); */ size_t spdk_bdev_get_buf_align(const struct spdk_bdev *bdev); +/** + * Get optimal I/O boundary for a bdev. + * + * \param bdev Block device to query. + * \return Optimal I/O boundary in blocks that should not be crossed for best performance, or 0 if + * no optimal boundary is reported. + */ +uint32_t spdk_bdev_get_optimal_io_boundary(const struct spdk_bdev *bdev); + /** * Query whether block device has an enabled write cache. * diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index 8e5b2dc4b..7ee870380 100644 --- a/include/spdk_internal/bdev.h +++ b/include/spdk_internal/bdev.h @@ -192,6 +192,11 @@ struct spdk_bdev { */ int need_aligned_buffer; + /** + * Optimal I/O boundary in blocks, or 0 for no value reported. + */ + uint32_t optimal_io_boundary; + /** * Pointer to the bdev module that registered this bdev. */ diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index bb3a0f5ab..5ee523f77 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -740,6 +740,12 @@ spdk_bdev_get_buf_align(const struct spdk_bdev *bdev) return 1; } +uint32_t +spdk_bdev_get_optimal_io_boundary(const struct spdk_bdev *bdev) +{ + return bdev->optimal_io_boundary; +} + bool spdk_bdev_has_write_cache(const struct spdk_bdev *bdev) { diff --git a/lib/bdev/nvme/bdev_nvme.c b/lib/bdev/nvme/bdev_nvme.c index 90ac6f6f0..6f13b0371 100644 --- a/lib/bdev/nvme/bdev_nvme.c +++ b/lib/bdev/nvme/bdev_nvme.c @@ -1138,6 +1138,7 @@ nvme_ctrlr_create_bdevs(struct nvme_ctrlr *nvme_ctrlr) } bdev->disk.blocklen = spdk_nvme_ns_get_sector_size(ns); bdev->disk.blockcnt = spdk_nvme_ns_get_num_sectors(ns); + bdev->disk.optimal_io_boundary = spdk_nvme_ns_get_optimal_io_boundary(ns); bdev->disk.ctxt = bdev; bdev->disk.fn_table = &nvmelib_fn_table; bdev->disk.module = SPDK_GET_BDEV_MODULE(nvme);