Commit 5eafc3a2 authored by Indraneel M's avatar Indraneel M Committed by Ben Walker
Browse files

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: default avatarIndraneel M <Indraneel.Mukherjee@wdc.com>
Change-Id: If031e0742d68c55c35e95ddc33d478939bbd52fe
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14572


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
parent 958d196c
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -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);

		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;
+8 −0
Original line number Diff line number Diff line
@@ -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;
};

/**
+9 −0
Original line number Diff line number Diff line
@@ -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;
+24 −0
Original line number Diff line number Diff line
@@ -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++;
+1 −0
Original line number Diff line number Diff line
@@ -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;