From da625683a63f0d42690b14408646fd9c05839ced Mon Sep 17 00:00:00 2001 From: Jin Yu Date: Mon, 12 Oct 2020 23:33:36 +0800 Subject: [PATCH] bdev: virtio blk read max size and segs The backend device such as virtio-blk or virtio-scsi may support the SIZE_MAX and SEG_MAX. Then SPDK needs to split the big IO. Add this feature in bdev. Change-Id: I2442e14121ccf141682964425e96382fec482af3 Signed-off-by: Jin Yu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4600 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto --- include/spdk/bdev_module.h | 11 +++++++++ lib/bdev/Makefile | 4 ++-- module/bdev/virtio/bdev_virtio_blk.c | 35 +++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h index 52654017e..77f95c68e 100644 --- a/include/spdk/bdev_module.h +++ b/include/spdk/bdev_module.h @@ -305,6 +305,17 @@ struct spdk_bdev { */ uint32_t optimal_io_boundary; + /** + * Max io size in bytes of a single segment + * + * Note: both max_segment_size and max_num_segments + * should be zero or non-zero. + */ + uint32_t max_segment_size; + + /* Maximum number of segments in a I/O */ + uint32_t max_num_segments; + /** * UUID for this bdev. * diff --git a/lib/bdev/Makefile b/lib/bdev/Makefile index 6e20d6fdb..795fa6e1a 100644 --- a/lib/bdev/Makefile +++ b/lib/bdev/Makefile @@ -34,8 +34,8 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -SO_VER := 4 -SO_MINOR := 1 +SO_VER := 5 +SO_MINOR := 0 ifeq ($(CONFIG_VTUNE),y) CFLAGS += -I$(CONFIG_VTUNE_DIR)/include -I$(CONFIG_VTUNE_DIR)/sdk/src/ittnotify diff --git a/module/bdev/virtio/bdev_virtio_blk.c b/module/bdev/virtio/bdev_virtio_blk.c index 7d5d0298f..875353963 100644 --- a/module/bdev/virtio/bdev_virtio_blk.c +++ b/module/bdev/virtio/bdev_virtio_blk.c @@ -412,7 +412,7 @@ virtio_blk_dev_init(struct virtio_blk_dev *bvdev, uint16_t max_queues) struct virtio_dev *vdev = &bvdev->vdev; struct spdk_bdev *bdev = &bvdev->bdev; uint64_t capacity, num_blocks; - uint32_t block_size; + uint32_t block_size, size_max, seg_max; uint16_t host_max_queues; int rc; @@ -465,6 +465,39 @@ virtio_blk_dev_init(struct virtio_blk_dev *bvdev, uint16_t max_queues) host_max_queues = 1; } + if (virtio_dev_has_feature(vdev, VIRTIO_BLK_F_SIZE_MAX)) { + rc = virtio_dev_read_dev_config(vdev, offsetof(struct virtio_blk_config, size_max), + &size_max, sizeof(size_max)); + if (rc) { + SPDK_ERRLOG("%s: config read failed: %s\n", vdev->name, spdk_strerror(-rc)); + return rc; + } + + if (spdk_unlikely(size_max < block_size)) { + SPDK_WARNLOG("%s: minimum segment size is set to block size %u forcefully.\n", + vdev->name, block_size); + size_max = block_size; + } + + bdev->max_segment_size = size_max; + } + + if (virtio_dev_has_feature(vdev, VIRTIO_BLK_F_SEG_MAX)) { + rc = virtio_dev_read_dev_config(vdev, offsetof(struct virtio_blk_config, seg_max), + &seg_max, sizeof(seg_max)); + if (rc) { + SPDK_ERRLOG("%s: config read failed: %s\n", vdev->name, spdk_strerror(-rc)); + return rc; + } + + if (spdk_unlikely(seg_max == 0)) { + SPDK_ERRLOG("%s: virtio blk SEG_MAX can't be 0\n", vdev->name); + return -EINVAL; + } + + bdev->max_num_segments = seg_max; + } + if (virtio_dev_has_feature(vdev, VIRTIO_BLK_F_RO)) { bvdev->readonly = true; }