Skip to content

Commit 9350a09

Browse files
eugpermarmstsirkin
authored andcommitted
vduse: add vq group support
This allows separate the different virtqueues in groups that shares the same address space. Asking the VDUSE device for the groups of the vq at the beginning as they're needed for the DMA API. Allocating 3 vq groups as net is the device that need the most groups: * Dataplane (guest passthrough) * CVQ * Shadowed vrings. Future versions of the series can include dynamic allocation of the groups array so VDUSE can declare more groups. Acked-by: Jason Wang <jasowang@redhat.com> Reviewed-by: Xie Yongji <xieyongji@bytedance.com> Signed-off-by: Eugenio Pérez <eperezma@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260119143306.1818855-4-eperezma@redhat.com>
1 parent a006ed4 commit 9350a09

2 files changed

Lines changed: 51 additions & 8 deletions

File tree

drivers/vdpa/vdpa_user/vduse_dev.c

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define DRV_LICENSE "GPL v2"
4040

4141
#define VDUSE_DEV_MAX (1U << MINORBITS)
42+
#define VDUSE_DEV_MAX_GROUPS 0xffff
4243
#define VDUSE_MAX_BOUNCE_SIZE (1024 * 1024 * 1024)
4344
#define VDUSE_MIN_BOUNCE_SIZE (1024 * 1024)
4445
#define VDUSE_BOUNCE_SIZE (64 * 1024 * 1024)
@@ -58,6 +59,7 @@ struct vduse_virtqueue {
5859
struct vdpa_vq_state state;
5960
bool ready;
6061
bool kicked;
62+
u32 group;
6163
spinlock_t kick_lock;
6264
spinlock_t irq_lock;
6365
struct eventfd_ctx *kickfd;
@@ -114,6 +116,7 @@ struct vduse_dev {
114116
u8 status;
115117
u32 vq_num;
116118
u32 vq_align;
119+
u32 ngroups;
117120
struct vduse_umem *umem;
118121
struct mutex mem_lock;
119122
unsigned int bounce_size;
@@ -592,6 +595,16 @@ static int vduse_vdpa_set_vq_state(struct vdpa_device *vdpa, u16 idx,
592595
return 0;
593596
}
594597

598+
static u32 vduse_get_vq_group(struct vdpa_device *vdpa, u16 idx)
599+
{
600+
struct vduse_dev *dev = vdpa_to_vduse(vdpa);
601+
602+
if (dev->api_version < VDUSE_API_VERSION_1)
603+
return 0;
604+
605+
return dev->vqs[idx]->group;
606+
}
607+
595608
static int vduse_vdpa_get_vq_state(struct vdpa_device *vdpa, u16 idx,
596609
struct vdpa_vq_state *state)
597610
{
@@ -789,6 +802,7 @@ static const struct vdpa_config_ops vduse_vdpa_config_ops = {
789802
.set_vq_cb = vduse_vdpa_set_vq_cb,
790803
.set_vq_num = vduse_vdpa_set_vq_num,
791804
.get_vq_size = vduse_vdpa_get_vq_size,
805+
.get_vq_group = vduse_get_vq_group,
792806
.set_vq_ready = vduse_vdpa_set_vq_ready,
793807
.get_vq_ready = vduse_vdpa_get_vq_ready,
794808
.set_vq_state = vduse_vdpa_set_vq_state,
@@ -1252,12 +1266,24 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
12521266
if (config.index >= dev->vq_num)
12531267
break;
12541268

1255-
if (!is_mem_zero((const char *)config.reserved,
1256-
sizeof(config.reserved)))
1269+
if (dev->api_version < VDUSE_API_VERSION_1) {
1270+
if (config.group)
1271+
break;
1272+
} else {
1273+
if (config.group >= dev->ngroups)
1274+
break;
1275+
if (dev->status & VIRTIO_CONFIG_S_DRIVER_OK)
1276+
break;
1277+
}
1278+
1279+
if (config.reserved1 ||
1280+
!is_mem_zero((const char *)config.reserved2,
1281+
sizeof(config.reserved2)))
12571282
break;
12581283

12591284
index = array_index_nospec(config.index, dev->vq_num);
12601285
dev->vqs[index]->num_max = config.max_size;
1286+
dev->vqs[index]->group = config.group;
12611287
ret = 0;
12621288
break;
12631289
}
@@ -1737,12 +1763,20 @@ static bool features_is_valid(struct vduse_dev_config *config)
17371763
return true;
17381764
}
17391765

1740-
static bool vduse_validate_config(struct vduse_dev_config *config)
1766+
static bool vduse_validate_config(struct vduse_dev_config *config,
1767+
u64 api_version)
17411768
{
17421769
if (!is_mem_zero((const char *)config->reserved,
17431770
sizeof(config->reserved)))
17441771
return false;
17451772

1773+
if (api_version < VDUSE_API_VERSION_1 && config->ngroups)
1774+
return false;
1775+
1776+
if (api_version >= VDUSE_API_VERSION_1 &&
1777+
(!config->ngroups || config->ngroups > VDUSE_DEV_MAX_GROUPS))
1778+
return false;
1779+
17461780
if (config->vq_align > PAGE_SIZE)
17471781
return false;
17481782

@@ -1858,6 +1892,9 @@ static int vduse_create_dev(struct vduse_dev_config *config,
18581892
dev->device_features = config->features;
18591893
dev->device_id = config->device_id;
18601894
dev->vendor_id = config->vendor_id;
1895+
dev->ngroups = (dev->api_version < VDUSE_API_VERSION_1)
1896+
? 1
1897+
: config->ngroups;
18611898
dev->name = kstrdup(config->name, GFP_KERNEL);
18621899
if (!dev->name)
18631900
goto err_str;
@@ -1936,7 +1973,7 @@ static long vduse_ioctl(struct file *file, unsigned int cmd,
19361973
break;
19371974

19381975
ret = -EINVAL;
1939-
if (vduse_validate_config(&config) == false)
1976+
if (!vduse_validate_config(&config, control->api_version))
19401977
break;
19411978

19421979
buf = vmemdup_user(argp + size, config.config_size);
@@ -2017,7 +2054,7 @@ static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name)
20172054

20182055
vdev = vdpa_alloc_device(struct vduse_vdpa, vdpa, dev->dev,
20192056
&vduse_vdpa_config_ops, &vduse_map_ops,
2020-
1, 1, name, true);
2057+
dev->ngroups, 1, name, true);
20212058
if (IS_ERR(vdev))
20222059
return PTR_ERR(vdev);
20232060

include/uapi/linux/vduse.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* @features: virtio features
3232
* @vq_num: the number of virtqueues
3333
* @vq_align: the allocation alignment of virtqueue's metadata
34+
* @ngroups: number of vq groups that VDUSE device declares
3435
* @reserved: for future use, needs to be initialized to zero
3536
* @config_size: the size of the configuration space
3637
* @config: the buffer of the configuration space
@@ -45,7 +46,8 @@ struct vduse_dev_config {
4546
__u64 features;
4647
__u32 vq_num;
4748
__u32 vq_align;
48-
__u32 reserved[13];
49+
__u32 ngroups; /* if VDUSE_API_VERSION >= 1 */
50+
__u32 reserved[12];
4951
__u32 config_size;
5052
__u8 config[];
5153
};
@@ -122,14 +124,18 @@ struct vduse_config_data {
122124
* struct vduse_vq_config - basic configuration of a virtqueue
123125
* @index: virtqueue index
124126
* @max_size: the max size of virtqueue
125-
* @reserved: for future use, needs to be initialized to zero
127+
* @reserved1: for future use, needs to be initialized to zero
128+
* @group: virtqueue group
129+
* @reserved2: for future use, needs to be initialized to zero
126130
*
127131
* Structure used by VDUSE_VQ_SETUP ioctl to setup a virtqueue.
128132
*/
129133
struct vduse_vq_config {
130134
__u32 index;
131135
__u16 max_size;
132-
__u16 reserved[13];
136+
__u16 reserved1;
137+
__u32 group;
138+
__u16 reserved2[10];
133139
};
134140

135141
/*

0 commit comments

Comments
 (0)