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: Stefano Garzarella <sgarzare@redhat.com>
Message-Id: <20220811083632.77525-5-sgarzare@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Stefano Garzarella 2022-08-11 10:36:32 +02:00 committed by Michael S. Tsirkin
parent 518083d2f5
commit 4a44a5eda2
1 changed files with 73 additions and 1 deletions

View File

@ -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)