Commit 4a44a5ed authored by Stefano Garzarella's avatar Stefano Garzarella Committed by Michael S. Tsirkin
Browse files

vdpa_sim_blk: add support for discard and write-zeroes



Expose VIRTIO_BLK_F_DISCARD and VIRTIO_BLK_F_WRITE_ZEROES features
to the drivers and handle VIRTIO_BLK_T_DISCARD and
VIRTIO_BLK_T_WRITE_ZEROES requests checking ranges and flags.

The simulator behaves like a ramdisk, so for VIRTIO_BLK_F_DISCARD
does nothing, while for VIRTIO_BLK_T_WRITE_ZEROES sets to 0 the
specified region.

Signed-off-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Message-Id: <20220811083632.77525-5-sgarzare@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 518083d2
Loading
Loading
Loading
Loading
+73 −1
Original line number Diff line number Diff line
@@ -30,11 +30,14 @@
				 (1ULL << VIRTIO_BLK_F_SEG_MAX)  | \
				 (1ULL << VIRTIO_BLK_F_BLK_SIZE) | \
				 (1ULL << VIRTIO_BLK_F_TOPOLOGY) | \
				 (1ULL << VIRTIO_BLK_F_MQ))
				 (1ULL << VIRTIO_BLK_F_MQ)       | \
				 (1ULL << VIRTIO_BLK_F_DISCARD)  | \
				 (1ULL << VIRTIO_BLK_F_WRITE_ZEROES))

#define VDPASIM_BLK_CAPACITY	0x40000
#define VDPASIM_BLK_SIZE_MAX	0x1000
#define VDPASIM_BLK_SEG_MAX	32
#define VDPASIM_BLK_DWZ_MAX_SECTORS UINT_MAX

/* 1 virtqueue, 1 address space, 1 virtqueue group */
#define VDPASIM_BLK_VQ_NUM	1
@@ -193,6 +196,64 @@ static bool vdpasim_blk_handle_req(struct vdpasim *vdpasim,
		/* nothing to do */
		break;

	case VIRTIO_BLK_T_DISCARD:
	case VIRTIO_BLK_T_WRITE_ZEROES: {
		struct virtio_blk_discard_write_zeroes range;
		u32 num_sectors, flags;

		if (to_pull != sizeof(range)) {
			dev_dbg(&vdpasim->vdpa.dev,
				"discard/write_zeroes header len: 0x%zx [expected: 0x%zx]\n",
				to_pull, sizeof(range));
			status = VIRTIO_BLK_S_IOERR;
			break;
		}

		bytes = vringh_iov_pull_iotlb(&vq->vring, &vq->out_iov, &range,
					      to_pull);
		if (bytes < 0) {
			dev_dbg(&vdpasim->vdpa.dev,
				"vringh_iov_pull_iotlb() error: %zd offset: 0x%llx len: 0x%zx\n",
				bytes, offset, to_pull);
			status = VIRTIO_BLK_S_IOERR;
			break;
		}

		sector = le64_to_cpu(range.sector);
		offset = sector << SECTOR_SHIFT;
		num_sectors = le32_to_cpu(range.num_sectors);
		flags = le32_to_cpu(range.flags);

		if (type == VIRTIO_BLK_T_DISCARD && flags != 0) {
			dev_dbg(&vdpasim->vdpa.dev,
				"discard unexpected flags set - flags: 0x%x\n",
				flags);
			status = VIRTIO_BLK_S_UNSUPP;
			break;
		}

		if (type == VIRTIO_BLK_T_WRITE_ZEROES &&
		    flags & ~VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP) {
			dev_dbg(&vdpasim->vdpa.dev,
				"write_zeroes unexpected flags set - flags: 0x%x\n",
				flags);
			status = VIRTIO_BLK_S_UNSUPP;
			break;
		}

		if (!vdpasim_blk_check_range(vdpasim, sector, num_sectors,
					     VDPASIM_BLK_DWZ_MAX_SECTORS)) {
			status = VIRTIO_BLK_S_IOERR;
			break;
		}

		if (type == VIRTIO_BLK_T_WRITE_ZEROES) {
			memset(vdpasim->buffer + offset, 0,
			       num_sectors << SECTOR_SHIFT);
		}

		break;
	}
	default:
		dev_dbg(&vdpasim->vdpa.dev,
			"Unsupported request type %d\n", type);
@@ -281,6 +342,17 @@ static void vdpasim_blk_get_config(struct vdpasim *vdpasim, void *config)
	blk_config->min_io_size = cpu_to_vdpasim16(vdpasim, 1);
	blk_config->opt_io_size = cpu_to_vdpasim32(vdpasim, 1);
	blk_config->blk_size = cpu_to_vdpasim32(vdpasim, SECTOR_SIZE);
	/* VIRTIO_BLK_F_DISCARD */
	blk_config->discard_sector_alignment =
		cpu_to_vdpasim32(vdpasim, SECTOR_SIZE);
	blk_config->max_discard_sectors =
		cpu_to_vdpasim32(vdpasim, VDPASIM_BLK_DWZ_MAX_SECTORS);
	blk_config->max_discard_seg = cpu_to_vdpasim32(vdpasim, 1);
	/* VIRTIO_BLK_F_WRITE_ZEROES */
	blk_config->max_write_zeroes_sectors =
		cpu_to_vdpasim32(vdpasim, VDPASIM_BLK_DWZ_MAX_SECTORS);
	blk_config->max_write_zeroes_seg = cpu_to_vdpasim32(vdpasim, 1);

}

static void vdpasim_blk_mgmtdev_release(struct device *dev)