Skip to content

Commit abebb16

Browse files
stefano-garzarellamstsirkin
authored andcommitted
vdpa_sim_blk: support shared backend
The vdpa_sim_blk simulator uses a ramdisk as the backend. To test live migration, we need two devices that share the backend to have the data synchronized with each other. Add a new module parameter to make the buffer shared between all devices. The shared_buffer_mutex is used just to ensure that each operation is atomic, but it is up to the user to use the devices knowing that the underlying ramdisk is shared. For example, when we do a migration, the VMM (e.g., QEMU) will guarantee to write to the destination device, only after completing operations with the source device. Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Message-Id: <20230407133658.66339-3-sgarzare@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
1 parent 112f23c commit abebb16

1 file changed

Lines changed: 50 additions & 7 deletions

File tree

drivers/vdpa/vdpa_sim/vdpa_sim_blk.c

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
struct vdpasim_blk {
4747
struct vdpasim vdpasim;
4848
void *buffer;
49+
bool shared_backend;
4950
};
5051

5152
static struct vdpasim_blk *sim_to_blk(struct vdpasim *vdpasim)
@@ -55,6 +56,26 @@ static struct vdpasim_blk *sim_to_blk(struct vdpasim *vdpasim)
5556

5657
static char vdpasim_blk_id[VIRTIO_BLK_ID_BYTES] = "vdpa_blk_sim";
5758

59+
static bool shared_backend;
60+
module_param(shared_backend, bool, 0444);
61+
MODULE_PARM_DESC(shared_backend, "Enable the shared backend between virtio-blk devices");
62+
63+
static void *shared_buffer;
64+
/* mutex to synchronize shared_buffer access */
65+
static DEFINE_MUTEX(shared_buffer_mutex);
66+
67+
static void vdpasim_blk_buffer_lock(struct vdpasim_blk *blk)
68+
{
69+
if (blk->shared_backend)
70+
mutex_lock(&shared_buffer_mutex);
71+
}
72+
73+
static void vdpasim_blk_buffer_unlock(struct vdpasim_blk *blk)
74+
{
75+
if (blk->shared_backend)
76+
mutex_unlock(&shared_buffer_mutex);
77+
}
78+
5879
static bool vdpasim_blk_check_range(struct vdpasim *vdpasim, u64 start_sector,
5980
u64 num_sectors, u64 max_sectors)
6081
{
@@ -154,8 +175,10 @@ static bool vdpasim_blk_handle_req(struct vdpasim *vdpasim,
154175
break;
155176
}
156177

178+
vdpasim_blk_buffer_lock(blk);
157179
bytes = vringh_iov_push_iotlb(&vq->vring, &vq->in_iov,
158180
blk->buffer + offset, to_push);
181+
vdpasim_blk_buffer_unlock(blk);
159182
if (bytes < 0) {
160183
dev_dbg(&vdpasim->vdpa.dev,
161184
"vringh_iov_push_iotlb() error: %zd offset: 0x%llx len: 0x%zx\n",
@@ -175,8 +198,10 @@ static bool vdpasim_blk_handle_req(struct vdpasim *vdpasim,
175198
break;
176199
}
177200

201+
vdpasim_blk_buffer_lock(blk);
178202
bytes = vringh_iov_pull_iotlb(&vq->vring, &vq->out_iov,
179203
blk->buffer + offset, to_pull);
204+
vdpasim_blk_buffer_unlock(blk);
180205
if (bytes < 0) {
181206
dev_dbg(&vdpasim->vdpa.dev,
182207
"vringh_iov_pull_iotlb() error: %zd offset: 0x%llx len: 0x%zx\n",
@@ -256,8 +281,10 @@ static bool vdpasim_blk_handle_req(struct vdpasim *vdpasim,
256281
}
257282

258283
if (type == VIRTIO_BLK_T_WRITE_ZEROES) {
284+
vdpasim_blk_buffer_lock(blk);
259285
memset(blk->buffer + offset, 0,
260286
num_sectors << SECTOR_SHIFT);
287+
vdpasim_blk_buffer_unlock(blk);
261288
}
262289

263290
break;
@@ -366,7 +393,8 @@ static void vdpasim_blk_free(struct vdpasim *vdpasim)
366393
{
367394
struct vdpasim_blk *blk = sim_to_blk(vdpasim);
368395

369-
kvfree(blk->buffer);
396+
if (!blk->shared_backend)
397+
kvfree(blk->buffer);
370398
}
371399

372400
static void vdpasim_blk_mgmtdev_release(struct device *dev)
@@ -404,12 +432,17 @@ static int vdpasim_blk_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
404432
return PTR_ERR(simdev);
405433

406434
blk = sim_to_blk(simdev);
407-
408-
blk->buffer = kvmalloc(VDPASIM_BLK_CAPACITY << SECTOR_SHIFT,
409-
GFP_KERNEL);
410-
if (!blk->buffer) {
411-
ret = -ENOMEM;
412-
goto put_dev;
435+
blk->shared_backend = shared_backend;
436+
437+
if (blk->shared_backend) {
438+
blk->buffer = shared_buffer;
439+
} else {
440+
blk->buffer = kvmalloc(VDPASIM_BLK_CAPACITY << SECTOR_SHIFT,
441+
GFP_KERNEL);
442+
if (!blk->buffer) {
443+
ret = -ENOMEM;
444+
goto put_dev;
445+
}
413446
}
414447

415448
ret = _vdpa_register_device(&simdev->vdpa, VDPASIM_BLK_VQ_NUM);
@@ -461,6 +494,15 @@ static int __init vdpasim_blk_init(void)
461494
if (ret)
462495
goto parent_err;
463496

497+
if (shared_backend) {
498+
shared_buffer = kvmalloc(VDPASIM_BLK_CAPACITY << SECTOR_SHIFT,
499+
GFP_KERNEL);
500+
if (!shared_buffer) {
501+
ret = -ENOMEM;
502+
goto parent_err;
503+
}
504+
}
505+
464506
return 0;
465507

466508
parent_err:
@@ -470,6 +512,7 @@ static int __init vdpasim_blk_init(void)
470512

471513
static void __exit vdpasim_blk_exit(void)
472514
{
515+
kvfree(shared_buffer);
473516
vdpa_mgmtdev_unregister(&mgmt_dev);
474517
device_unregister(&vdpasim_blk_mgmtdev);
475518
}

0 commit comments

Comments
 (0)