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:
parent
958d196c1d
commit
5eafc3a279
@ -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];
|
struct zbd_zone *zone_dest = &cb_arg->fio_zones[handled_zones];
|
||||||
uint32_t block_size = spdk_bdev_get_block_size(cb_arg->target->bdev);
|
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->len = spdk_bdev_get_zone_size(cb_arg->target->bdev) * block_size;
|
||||||
zone_dest->capacity = zone_src->capacity * block_size;
|
zone_dest->capacity = zone_src->capacity * block_size;
|
||||||
zone_dest->start = zone_src->zone_id * 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:
|
case SPDK_BDEV_ZONE_STATE_OFFLINE:
|
||||||
zone_dest->cond = ZBD_ZONE_COND_OFFLINE;
|
zone_dest->cond = ZBD_ZONE_COND_OFFLINE;
|
||||||
break;
|
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:
|
default:
|
||||||
spdk_bdev_free_io(bdev_io);
|
spdk_bdev_free_io(bdev_io);
|
||||||
cb_arg->completed = -EIO;
|
cb_arg->completed = -EIO;
|
||||||
@ -1144,7 +1164,9 @@ spdk_fio_handle_options(struct thread_data *td, struct fio_file *f, struct spdk_
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
return 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) {
|
if (rc) {
|
||||||
spdk_fio_cleanup(td);
|
spdk_fio_cleanup(td);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -21,6 +21,12 @@
|
|||||||
|
|
||||||
struct spdk_bdev;
|
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 {
|
enum spdk_bdev_zone_action {
|
||||||
SPDK_BDEV_ZONE_CLOSE,
|
SPDK_BDEV_ZONE_CLOSE,
|
||||||
SPDK_BDEV_ZONE_FINISH,
|
SPDK_BDEV_ZONE_FINISH,
|
||||||
@ -39,6 +45,7 @@ enum spdk_bdev_zone_state {
|
|||||||
SPDK_BDEV_ZONE_STATE_READ_ONLY = 0x4,
|
SPDK_BDEV_ZONE_STATE_READ_ONLY = 0x4,
|
||||||
SPDK_BDEV_ZONE_STATE_OFFLINE = 0x5,
|
SPDK_BDEV_ZONE_STATE_OFFLINE = 0x5,
|
||||||
SPDK_BDEV_ZONE_STATE_EXP_OPEN = 0x6,
|
SPDK_BDEV_ZONE_STATE_EXP_OPEN = 0x6,
|
||||||
|
SPDK_BDEV_ZONE_STATE_NOT_WP = 0x7,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spdk_bdev_zone_info {
|
struct spdk_bdev_zone_info {
|
||||||
@ -46,6 +53,7 @@ struct spdk_bdev_zone_info {
|
|||||||
uint64_t write_pointer;
|
uint64_t write_pointer;
|
||||||
uint64_t capacity;
|
uint64_t capacity;
|
||||||
enum spdk_bdev_zone_state state;
|
enum spdk_bdev_zone_state state;
|
||||||
|
enum spdk_bdev_zone_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5704,6 +5704,15 @@ bdev_nvme_queued_done(void *ref, const struct spdk_nvme_cpl *cpl)
|
|||||||
static int
|
static int
|
||||||
fill_zone_from_report(struct spdk_bdev_zone_info *info, struct spdk_nvme_zns_zone_desc *desc)
|
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) {
|
switch (desc->zs) {
|
||||||
case SPDK_NVME_ZONE_STATE_EMPTY:
|
case SPDK_NVME_ZONE_STATE_EMPTY:
|
||||||
info->state = SPDK_BDEV_ZONE_STATE_EMPTY;
|
info->state = SPDK_BDEV_ZONE_STATE_EMPTY;
|
||||||
|
@ -335,6 +335,26 @@ bdev_uring_read_sysfs_attr_long(const char *devname, const char *attr, long *val
|
|||||||
return 0;
|
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
|
static int
|
||||||
bdev_uring_fill_zone_state(struct spdk_bdev_zone_info *zone_info, struct blk_zone *zones_rep)
|
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:
|
case BLK_ZONE_COND_OFFLINE:
|
||||||
zone_info->state = SPDK_BDEV_ZONE_STATE_OFFLINE;
|
zone_info->state = SPDK_BDEV_ZONE_STATE_OFFLINE;
|
||||||
break;
|
break;
|
||||||
|
case BLK_ZONE_COND_NOT_WP:
|
||||||
|
zone_info->state = SPDK_BDEV_ZONE_STATE_NOT_WP;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
SPDK_ERRLOG("Invalid zone state: %#x in zone report\n", zones_rep->cond);
|
SPDK_ERRLOG("Invalid zone state: %#x in zone report\n", zones_rep->cond);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@ -457,6 +480,7 @@ bdev_uring_zone_get_info(struct spdk_bdev_io *bdev_io)
|
|||||||
zone_info->capacity = ((zones + i)->capacity >> shift);
|
zone_info->capacity = ((zones + i)->capacity >> shift);
|
||||||
|
|
||||||
bdev_uring_fill_zone_state(zone_info, zones + i);
|
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_id = ((zones + i)->start + (zones + i)->len) >> shift;
|
||||||
zone_info++;
|
zone_info++;
|
||||||
|
@ -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.capacity = bdev_node->zone_capacity;
|
||||||
zone->zone_info.write_pointer = zone->zone_info.zone_id + zone->zone_info.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.state = SPDK_BDEV_ZONE_STATE_FULL;
|
||||||
|
zone->zone_info.type = SPDK_BDEV_ZONE_TYPE_SEQWR;
|
||||||
if (pthread_spin_init(&zone->lock, PTHREAD_PROCESS_PRIVATE)) {
|
if (pthread_spin_init(&zone->lock, PTHREAD_PROCESS_PRIVATE)) {
|
||||||
SPDK_ERRLOG("pthread_spin_init() failed\n");
|
SPDK_ERRLOG("pthread_spin_init() failed\n");
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
|
Loading…
Reference in New Issue
Block a user