2023-09-13 12:10:56

by Cindy Lu

[permalink] [raw]
Subject: [RFC v2 0/4] Support reconnection in vduse

These patches add the reconnect support in vduse, The steps
is map the pages from kernel to userspace, userspace
app will sync the reconnection status and vq_info in the pages
Also, add the new IOCTL VDUSE_GET_RECONNECT_INFO
userspace app will use this information to mmap the memory

Will send the patch for DPDK later

Tested in vduse + dpdk test-pmd

Signed-off-by: Cindy Lu <[email protected]>

Cindy Lu (4):
vduse: Add function to get/free the pages for reconnection
vduse: Add file operation for mmap
vduse: update the vq_info in ioctl
vduse: Add new ioctl VDUSE_GET_RECONNECT_INFO

drivers/vdpa/vdpa_user/vduse_dev.c | 177 +++++++++++++++++++++++++++++
include/uapi/linux/vduse.h | 21 ++++
2 files changed, 198 insertions(+)

--
2.34.3


2023-09-13 15:12:15

by Cindy Lu

[permalink] [raw]
Subject: [RFC v2 2/4] vduse: Add file operation for mmap

Add the operation for mmap, The user space APP will
use this function to map the pages to userspace

Signed-off-by: Cindy Lu <[email protected]>
---
drivers/vdpa/vdpa_user/vduse_dev.c | 63 ++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)

diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c
index 4c256fa31fc4..2c69f4004a6e 100644
--- a/drivers/vdpa/vdpa_user/vduse_dev.c
+++ b/drivers/vdpa/vdpa_user/vduse_dev.c
@@ -1388,6 +1388,67 @@ static struct vduse_dev *vduse_dev_get_from_minor(int minor)
return dev;
}

+static vm_fault_t vduse_vm_fault(struct vm_fault *vmf)
+{
+ struct vduse_dev *dev = vmf->vma->vm_file->private_data;
+ struct vm_area_struct *vma = vmf->vma;
+ u16 index = vma->vm_pgoff;
+ struct vduse_virtqueue *vq;
+ struct vdpa_reconnect_info *info;
+
+ if (index == 0) {
+ info = &dev->reconnect_status;
+ } else {
+ vq = &dev->vqs[index - 1];
+ info = &vq->reconnect_info;
+ }
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (remap_pfn_range(vma, vmf->address & PAGE_MASK, PFN_DOWN(info->addr),
+ PAGE_SIZE, vma->vm_page_prot))
+ return VM_FAULT_SIGBUS;
+ return VM_FAULT_NOPAGE;
+}
+
+static const struct vm_operations_struct vduse_vm_ops = {
+ .fault = vduse_vm_fault,
+};
+
+static int vduse_dev_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct vduse_dev *dev = file->private_data;
+ struct vdpa_reconnect_info *info;
+ unsigned long index = vma->vm_pgoff;
+ struct vduse_virtqueue *vq;
+
+ if (vma->vm_end - vma->vm_start != PAGE_SIZE)
+ return -EINVAL;
+ if ((vma->vm_flags & VM_SHARED) == 0)
+ return -EINVAL;
+
+ if (index > 65535)
+ return -EINVAL;
+
+ if (index == 0) {
+ info = &dev->reconnect_status;
+ } else {
+ vq = &dev->vqs[index - 1];
+ info = &vq->reconnect_info;
+ }
+
+ if (info->index != index)
+ return -EINVAL;
+
+ if (info->addr & (PAGE_SIZE - 1))
+ return -EINVAL;
+ if (vma->vm_end - vma->vm_start != info->size)
+ return -EOPNOTSUPP;
+
+ vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTDUMP);
+ vma->vm_ops = &vduse_vm_ops;
+
+ return 0;
+}
+
static int vduse_dev_open(struct inode *inode, struct file *file)
{
int ret;
@@ -1420,6 +1481,8 @@ static const struct file_operations vduse_dev_fops = {
.unlocked_ioctl = vduse_dev_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.llseek = noop_llseek,
+ .mmap = vduse_dev_mmap,
+
};

static struct vduse_dev *vduse_dev_create(void)
--
2.34.3

2023-09-18 17:12:13

by Jason Wang

[permalink] [raw]
Subject: Re: [RFC v2 2/4] vduse: Add file operation for mmap

On Tue, Sep 12, 2023 at 11:00 AM Cindy Lu <[email protected]> wrote:
>
> Add the operation for mmap, The user space APP will
> use this function to map the pages to userspace
>
> Signed-off-by: Cindy Lu <[email protected]>
> ---
> drivers/vdpa/vdpa_user/vduse_dev.c | 63 ++++++++++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
>
> diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c
> index 4c256fa31fc4..2c69f4004a6e 100644
> --- a/drivers/vdpa/vdpa_user/vduse_dev.c
> +++ b/drivers/vdpa/vdpa_user/vduse_dev.c
> @@ -1388,6 +1388,67 @@ static struct vduse_dev *vduse_dev_get_from_minor(int minor)
> return dev;
> }
>
> +static vm_fault_t vduse_vm_fault(struct vm_fault *vmf)
> +{
> + struct vduse_dev *dev = vmf->vma->vm_file->private_data;
> + struct vm_area_struct *vma = vmf->vma;
> + u16 index = vma->vm_pgoff;
> + struct vduse_virtqueue *vq;
> + struct vdpa_reconnect_info *info;
> +
> + if (index == 0) {
> + info = &dev->reconnect_status;
> + } else {
> + vq = &dev->vqs[index - 1];
> + info = &vq->reconnect_info;
> + }
> + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> + if (remap_pfn_range(vma, vmf->address & PAGE_MASK, PFN_DOWN(info->addr),
> + PAGE_SIZE, vma->vm_page_prot))
> + return VM_FAULT_SIGBUS;
> + return VM_FAULT_NOPAGE;
> +}
> +
> +static const struct vm_operations_struct vduse_vm_ops = {
> + .fault = vduse_vm_fault,
> +};
> +
> +static int vduse_dev_mmap(struct file *file, struct vm_area_struct *vma)
> +{
> + struct vduse_dev *dev = file->private_data;
> + struct vdpa_reconnect_info *info;
> + unsigned long index = vma->vm_pgoff;
> + struct vduse_virtqueue *vq;
> +
> + if (vma->vm_end - vma->vm_start != PAGE_SIZE)
> + return -EINVAL;
> + if ((vma->vm_flags & VM_SHARED) == 0)
> + return -EINVAL;
> +
> + if (index > 65535)
> + return -EINVAL;
> +
> + if (index == 0) {
> + info = &dev->reconnect_status;
> + } else {
> + vq = &dev->vqs[index - 1];
> + info = &vq->reconnect_info;
> + }
> +
> + if (info->index != index)
> + return -EINVAL;

Under which case could we meet this?

> +
> + if (info->addr & (PAGE_SIZE - 1))
> + return -EINVAL;

And this?

> + if (vma->vm_end - vma->vm_start != info->size)
> + return -EOPNOTSUPP;
> +
> + vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTDUMP);

Why do you use VM_IO, VM_PFNMAP and VM_DONTDUMP?

Thanks

> + vma->vm_ops = &vduse_vm_ops;
> +
> + return 0;
> +}
> +
> static int vduse_dev_open(struct inode *inode, struct file *file)
> {
> int ret;
> @@ -1420,6 +1481,8 @@ static const struct file_operations vduse_dev_fops = {
> .unlocked_ioctl = vduse_dev_ioctl,
> .compat_ioctl = compat_ptr_ioctl,
> .llseek = noop_llseek,
> + .mmap = vduse_dev_mmap,
> +
> };
>
> static struct vduse_dev *vduse_dev_create(void)
> --
> 2.34.3
>