bdev/uring: Proper handling for conventional zones

Identify and properly handle conventional zones (in smr drives) by using
zone type and WP state. Bdevs supporting zoned devices(like uring, nvme and
vbdev_zone_block) now update the zone type information. As a result, the
fio plugin now uses this info instead of hard coding the zone type.
Also adds new WP state(ZONE_STATE_NOT_WP) for handling zones w/o WP.

Signed-off-by: Indraneel M <Indraneel.Mukherjee@wdc.com>
Change-Id: If031e0742d68c55c35e95ddc33d478939bbd52fe
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14572
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>
Community-CI: Mellanox Build Bot
This commit is contained in:
Indraneel M 2022-09-15 20:17:15 +05:30 committed by Ben Walker
parent 958d196c1d
commit 5eafc3a279
5 changed files with 66 additions and 2 deletions

View File

@ -918,7 +918,22 @@ spdk_fio_bdev_get_zone_info_done(struct spdk_bdev_io *bdev_io, bool success, voi
struct zbd_zone *zone_dest = &cb_arg->fio_zones[handled_zones];
uint32_t block_size = spdk_bdev_get_block_size(cb_arg->target->bdev);
zone_dest->type = ZBD_ZONE_TYPE_SWR;
switch (zone_src->type) {
case SPDK_BDEV_ZONE_TYPE_SEQWR:
zone_dest->type = ZBD_ZONE_TYPE_SWR;
break;
case SPDK_BDEV_ZONE_TYPE_SEQWP:
zone_dest->type = ZBD_ZONE_TYPE_SWP;
break;
case SPDK_BDEV_ZONE_TYPE_CNV:
zone_dest->type = ZBD_ZONE_TYPE_CNV;
break;
default:
spdk_bdev_free_io(bdev_io);
cb_arg->completed = -EIO;
return;
}
zone_dest->len = spdk_bdev_get_zone_size(cb_arg->target->bdev) * block_size;
zone_dest->capacity = zone_src->capacity * block_size;
zone_dest->start = zone_src->zone_id * block_size;
@ -946,6 +961,11 @@ spdk_fio_bdev_get_zone_info_done(struct spdk_bdev_io *bdev_io, bool success, voi
case SPDK_BDEV_ZONE_STATE_OFFLINE:
zone_dest->cond = ZBD_ZONE_COND_OFFLINE;
break;
case SPDK_BDEV_ZONE_STATE_NOT_WP:
zone_dest->cond = ZBD_ZONE_COND_NOT_WP;
/* Set WP to end of zone for zone types w/o WP (e.g. Conv. zones in SMR) */
zone_dest->wp = zone_dest->start + zone_dest->capacity;
break;
default:
spdk_bdev_free_io(bdev_io);
cb_arg->completed = -EIO;
@ -1144,7 +1164,9 @@ spdk_fio_handle_options(struct thread_data *td, struct fio_file *f, struct spdk_
if (rc) {
return rc;
}
rc = spdk_fio_reset_zones(td->io_ops_data, f->engine_data, 0, f->real_file_size);
/* offset used to indicate conventional zones that need to be skipped (reset not allowed) */
rc = spdk_fio_reset_zones(td->io_ops_data, f->engine_data, td->o.start_offset,
f->real_file_size - td->o.start_offset);
if (rc) {
spdk_fio_cleanup(td);
return rc;

View File

@ -21,6 +21,12 @@
struct spdk_bdev;
enum spdk_bdev_zone_type {
SPDK_BDEV_ZONE_TYPE_CNV = 0x1,
SPDK_BDEV_ZONE_TYPE_SEQWR = 0x2,
SPDK_BDEV_ZONE_TYPE_SEQWP = 0x3,
};
enum spdk_bdev_zone_action {
SPDK_BDEV_ZONE_CLOSE,
SPDK_BDEV_ZONE_FINISH,
@ -39,6 +45,7 @@ enum spdk_bdev_zone_state {
SPDK_BDEV_ZONE_STATE_READ_ONLY = 0x4,
SPDK_BDEV_ZONE_STATE_OFFLINE = 0x5,
SPDK_BDEV_ZONE_STATE_EXP_OPEN = 0x6,
SPDK_BDEV_ZONE_STATE_NOT_WP = 0x7,
};
struct spdk_bdev_zone_info {
@ -46,6 +53,7 @@ struct spdk_bdev_zone_info {
uint64_t write_pointer;
uint64_t capacity;
enum spdk_bdev_zone_state state;
enum spdk_bdev_zone_type type;
};
/**

View File

@ -5704,6 +5704,15 @@ bdev_nvme_queued_done(void *ref, const struct spdk_nvme_cpl *cpl)
static int
fill_zone_from_report(struct spdk_bdev_zone_info *info, struct spdk_nvme_zns_zone_desc *desc)
{
switch (desc->zt) {
case SPDK_NVME_ZONE_TYPE_SEQWR:
info->type = SPDK_BDEV_ZONE_TYPE_SEQWR;
break;
default:
SPDK_ERRLOG("Invalid zone type: %#x in zone report\n", desc->zt);
return -EIO;
}
switch (desc->zs) {
case SPDK_NVME_ZONE_STATE_EMPTY:
info->state = SPDK_BDEV_ZONE_STATE_EMPTY;

View File

@ -335,6 +335,26 @@ bdev_uring_read_sysfs_attr_long(const char *devname, const char *attr, long *val
return 0;
}
static int
bdev_uring_fill_zone_type(struct spdk_bdev_zone_info *zone_info, struct blk_zone *zones_rep)
{
switch (zones_rep->type) {
case BLK_ZONE_TYPE_CONVENTIONAL:
zone_info->type = SPDK_BDEV_ZONE_TYPE_CNV;
break;
case BLK_ZONE_TYPE_SEQWRITE_REQ:
zone_info->type = SPDK_BDEV_ZONE_TYPE_SEQWR;
break;
case BLK_ZONE_TYPE_SEQWRITE_PREF:
zone_info->type = SPDK_BDEV_ZONE_TYPE_SEQWP;
break;
default:
SPDK_ERRLOG("Invalid zone type: %#x in zone report\n", zones_rep->type);
return -EIO;
}
return 0;
}
static int
bdev_uring_fill_zone_state(struct spdk_bdev_zone_info *zone_info, struct blk_zone *zones_rep)
{
@ -360,6 +380,9 @@ bdev_uring_fill_zone_state(struct spdk_bdev_zone_info *zone_info, struct blk_zon
case BLK_ZONE_COND_OFFLINE:
zone_info->state = SPDK_BDEV_ZONE_STATE_OFFLINE;
break;
case BLK_ZONE_COND_NOT_WP:
zone_info->state = SPDK_BDEV_ZONE_STATE_NOT_WP;
break;
default:
SPDK_ERRLOG("Invalid zone state: %#x in zone report\n", zones_rep->cond);
return -EIO;
@ -457,6 +480,7 @@ bdev_uring_zone_get_info(struct spdk_bdev_io *bdev_io)
zone_info->capacity = ((zones + i)->capacity >> shift);
bdev_uring_fill_zone_state(zone_info, zones + i);
bdev_uring_fill_zone_type(zone_info, zones + i);
zone_id = ((zones + i)->start + (zones + i)->len) >> shift;
zone_info++;

View File

@ -678,6 +678,7 @@ zone_block_init_zone_info(struct bdev_zone_block *bdev_node)
zone->zone_info.capacity = bdev_node->zone_capacity;
zone->zone_info.write_pointer = zone->zone_info.zone_id + zone->zone_info.capacity;
zone->zone_info.state = SPDK_BDEV_ZONE_STATE_FULL;
zone->zone_info.type = SPDK_BDEV_ZONE_TYPE_SEQWR;
if (pthread_spin_init(&zone->lock, PTHREAD_PROCESS_PRIVATE)) {
SPDK_ERRLOG("pthread_spin_init() failed\n");
rc = -ENOMEM;