From 1eb06bd6001da5e20fe5e523da185489ee66ca14 Mon Sep 17 00:00:00 2001 From: "Panfil, Wojciech" Date: Tue, 14 Feb 2023 09:12:08 -0500 Subject: [PATCH] malloc_bdev: Add physical block size optional argument In the past, we didn't use the distinction between logical block size and physical block size. Now it's possible to optionally set the physical block size to be different then logical block size. It's useful for NVMe 512e Advanced Format tests. Change-Id: I1b596da471031ee90dafc6ba6276cebf769b5ea2 Signed-off-by: Panfil, Wojciech Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16793 Reviewed-by: Tomasz Zawadzki Reviewed-by: Jacek Kalwas Reviewed-by: Konrad Sztyber Tested-by: SPDK CI Jenkins --- module/bdev/malloc/bdev_malloc.c | 7 +++++++ module/bdev/malloc/bdev_malloc.h | 1 + module/bdev/malloc/bdev_malloc_rpc.c | 1 + python/spdk/rpc/bdev.py | 5 ++++- scripts/rpc.py | 2 ++ 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/module/bdev/malloc/bdev_malloc.c b/module/bdev/malloc/bdev_malloc.c index 65115465e..95ef07dd6 100644 --- a/module/bdev/malloc/bdev_malloc.c +++ b/module/bdev/malloc/bdev_malloc.c @@ -499,6 +499,7 @@ bdev_malloc_write_json_config(struct spdk_bdev *bdev, struct spdk_json_write_ctx spdk_json_write_named_string(w, "name", bdev->name); spdk_json_write_named_uint64(w, "num_blocks", bdev->blockcnt); spdk_json_write_named_uint32(w, "block_size", bdev->blocklen); + spdk_json_write_named_uint32(w, "physical_block_size", bdev->phys_blocklen); spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &bdev->uuid); spdk_json_write_named_string(w, "uuid", uuid_str); spdk_json_write_named_uint32(w, "optimal_io_boundary", bdev->optimal_io_boundary); @@ -576,6 +577,11 @@ create_malloc_disk(struct spdk_bdev **bdev, const struct malloc_bdev_opts *opts) return -EINVAL; } + if (opts->physical_block_size % 512) { + SPDK_ERRLOG("Physical block must be 512 bytes aligned\n"); + return -EINVAL; + } + switch (opts->md_size) { case 0: case 8: @@ -650,6 +656,7 @@ create_malloc_disk(struct spdk_bdev **bdev, const struct malloc_bdev_opts *opts) mdisk->disk.write_cache = 1; mdisk->disk.blocklen = block_size; + mdisk->disk.phys_blocklen = opts->physical_block_size; mdisk->disk.blockcnt = opts->num_blocks; mdisk->disk.md_len = opts->md_size; mdisk->disk.md_interleave = opts->md_interleave; diff --git a/module/bdev/malloc/bdev_malloc.h b/module/bdev/malloc/bdev_malloc.h index 16d1f3b71..044463419 100644 --- a/module/bdev/malloc/bdev_malloc.h +++ b/module/bdev/malloc/bdev_malloc.h @@ -18,6 +18,7 @@ struct malloc_bdev_opts { struct spdk_uuid uuid; uint64_t num_blocks; uint32_t block_size; + uint32_t physical_block_size; uint32_t optimal_io_boundary; uint32_t md_size; bool md_interleave; diff --git a/module/bdev/malloc/bdev_malloc_rpc.c b/module/bdev/malloc/bdev_malloc_rpc.c index 6e79d6900..49ade1366 100644 --- a/module/bdev/malloc/bdev_malloc_rpc.c +++ b/module/bdev/malloc/bdev_malloc_rpc.c @@ -35,6 +35,7 @@ static const struct spdk_json_object_decoder rpc_construct_malloc_decoders[] = { {"uuid", offsetof(struct malloc_bdev_opts, uuid), decode_mdisk_uuid, true}, {"num_blocks", offsetof(struct malloc_bdev_opts, num_blocks), spdk_json_decode_uint64}, {"block_size", offsetof(struct malloc_bdev_opts, block_size), spdk_json_decode_uint32}, + {"physical_block_size", offsetof(struct malloc_bdev_opts, physical_block_size), spdk_json_decode_uint32, true}, {"optimal_io_boundary", offsetof(struct malloc_bdev_opts, optimal_io_boundary), spdk_json_decode_uint32, true}, {"md_size", offsetof(struct malloc_bdev_opts, md_size), spdk_json_decode_uint32, true}, {"md_interleave", offsetof(struct malloc_bdev_opts, md_interleave), spdk_json_decode_bool, true}, diff --git a/python/spdk/rpc/bdev.py b/python/spdk/rpc/bdev.py index f3721c093..4e44a779c 100644 --- a/python/spdk/rpc/bdev.py +++ b/python/spdk/rpc/bdev.py @@ -268,13 +268,14 @@ def bdev_ocf_flush_status(client, name): return client.call('bdev_ocf_flush_status', params) -def bdev_malloc_create(client, num_blocks, block_size, name=None, uuid=None, optimal_io_boundary=None, +def bdev_malloc_create(client, num_blocks, block_size, physical_block_size=None, name=None, uuid=None, optimal_io_boundary=None, md_size=None, md_interleave=None, dif_type=None, dif_is_head_of_md=None): """Construct a malloc block device. Args: num_blocks: size of block device in blocks block_size: Data block size of device; must be a power of 2 and at least 512 + physical_block_size: Physical block size of device; must be a power of 2 and at least 512 (optional) name: name of block device (optional) uuid: UUID of block device (optional) optimal_io_boundary: Split on optimal IO boundary, in number of blocks, default 0 (disabled, optional) @@ -287,6 +288,8 @@ def bdev_malloc_create(client, num_blocks, block_size, name=None, uuid=None, opt Name of created block device. """ params = {'num_blocks': num_blocks, 'block_size': block_size} + if physical_block_size: + params['physical_block_size'] = physical_block_size if name: params['name'] = name if uuid: diff --git a/scripts/rpc.py b/scripts/rpc.py index 8f01925e8..04cd6354b 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -379,6 +379,7 @@ if __name__ == "__main__": print_json(rpc.bdev.bdev_malloc_create(args.client, num_blocks=int(num_blocks), block_size=args.block_size, + physical_block_size=args.physical_block_size, name=args.name, uuid=args.uuid, optimal_io_boundary=args.optimal_io_boundary, @@ -392,6 +393,7 @@ if __name__ == "__main__": p.add_argument( 'total_size', help='Size of malloc bdev in MB (float > 0)', type=float) p.add_argument('block_size', help='Data block size for this bdev', type=int) + p.add_argument('-p', '--physical-block-size', help='Physical block size for this bdev.', type=int) p.add_argument('-o', '--optimal-io-boundary', help="""Split on optimal IO boundary, in number of blocks, default 0 (disabled)""", type=int) p.add_argument('-m', '--md-size', type=int,