lkml.org 
[lkml]   [2020]   [Aug]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V4 linux-next 04/12] vhost-vdpa: support IOTLB batching hints
    Date
    From: Jason Wang <jasowang@redhat.com>

    This patches extend the vhost IOTLB API to accept batch updating hints
    form userspace. When userspace wants update the device IOTLB in a
    batch, it may do:

    1) Write vhost_iotlb_msg with VHOST_IOTLB_BATCH_BEGIN flag
    2) Perform a batch of IOTLB updating via VHOST_IOTLB_UPDATE/INVALIDATE
    3) Write vhost_iotlb_msg with VHOST_IOTLB_BATCH_END flag

    Vhost-vdpa may decide to batch the IOMMU/IOTLB updating in step 3 when
    vDPA device support set_map() ops. This is useful for the vDPA device
    that want to know all the mappings to tweak their own DMA translation
    logic.

    For vDPA device that doesn't require set_map(), no behavior changes.

    This capability is advertised via VHOST_BACKEND_F_IOTLB_BATCH capability.

    Signed-off-by: Jason Wang <jasowang@redhat.com>
    ---
    drivers/vhost/vdpa.c | 36 ++++++++++++++++++++++++--------
    include/uapi/linux/vhost.h | 2 ++
    include/uapi/linux/vhost_types.h | 11 ++++++++++
    3 files changed, 40 insertions(+), 9 deletions(-)

    diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
    index 2f0310d1b914..0a143615e69d 100644
    --- a/drivers/vhost/vdpa.c
    +++ b/drivers/vhost/vdpa.c
    @@ -27,7 +27,9 @@
    #include "vhost.h"

    enum {
    - VHOST_VDPA_BACKEND_FEATURES = (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2)
    + VHOST_VDPA_BACKEND_FEATURES =
    + (1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2) |
    + (1ULL << VHOST_BACKEND_F_IOTLB_BATCH),
    };

    /* Currently, only network backend w/o multiqueue is supported. */
    @@ -48,6 +50,7 @@ struct vhost_vdpa {
    int virtio_id;
    int minor;
    struct eventfd_ctx *config_ctx;
    + int in_batch;
    };

    static DEFINE_IDA(vhost_vdpa_ida);
    @@ -140,6 +143,7 @@ static void vhost_vdpa_reset(struct vhost_vdpa *v)
    struct vdpa_device *vdpa = v->vdpa;

    vdpa_reset(vdpa);
    + v->in_batch = 0;
    }

    static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp)
    @@ -563,13 +567,15 @@ static int vhost_vdpa_map(struct vhost_vdpa *v,
    if (r)
    return r;

    - if (ops->dma_map)
    + if (ops->dma_map) {
    r = ops->dma_map(vdpa, iova, size, pa, perm);
    - else if (ops->set_map)
    - r = ops->set_map(vdpa, dev->iotlb);
    - else
    + } else if (ops->set_map) {
    + if (!v->in_batch)
    + r = ops->set_map(vdpa, dev->iotlb);
    + } else {
    r = iommu_map(v->domain, iova, pa, size,
    perm_to_iommu_flags(perm));
    + }

    return r;
    }
    @@ -582,12 +588,14 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v, u64 iova, u64 size)

    vhost_vdpa_iotlb_unmap(v, iova, iova + size - 1);

    - if (ops->dma_map)
    + if (ops->dma_map) {
    ops->dma_unmap(vdpa, iova, size);
    - else if (ops->set_map)
    - ops->set_map(vdpa, dev->iotlb);
    - else
    + } else if (ops->set_map) {
    + if (!v->in_batch)
    + ops->set_map(vdpa, dev->iotlb);
    + } else {
    iommu_unmap(v->domain, iova, size);
    + }
    }

    static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
    @@ -680,6 +688,8 @@ static int vhost_vdpa_process_iotlb_msg(struct vhost_dev *dev,
    struct vhost_iotlb_msg *msg)
    {
    struct vhost_vdpa *v = container_of(dev, struct vhost_vdpa, vdev);
    + struct vdpa_device *vdpa = v->vdpa;
    + const struct vdpa_config_ops *ops = vdpa->config;
    int r = 0;

    r = vhost_dev_check_owner(dev);
    @@ -693,6 +703,14 @@ static int vhost_vdpa_process_iotlb_msg(struct vhost_dev *dev,
    case VHOST_IOTLB_INVALIDATE:
    vhost_vdpa_unmap(v, msg->iova, msg->size);
    break;
    + case VHOST_IOTLB_BATCH_BEGIN:
    + v->in_batch = true;
    + break;
    + case VHOST_IOTLB_BATCH_END:
    + if (v->in_batch && ops->set_map)
    + ops->set_map(vdpa, dev->iotlb);
    + v->in_batch = false;
    + break;
    default:
    r = -EINVAL;
    break;
    diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
    index 5d9254e2a6b6..11a4948b6216 100644
    --- a/include/uapi/linux/vhost.h
    +++ b/include/uapi/linux/vhost.h
    @@ -91,6 +91,8 @@

    /* Use message type V2 */
    #define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1
    +/* IOTLB can accept batching hints */
    +#define VHOST_BACKEND_F_IOTLB_BATCH 0x2

    #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
    #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
    diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
    index 669457ce5c48..9a269a88a6ff 100644
    --- a/include/uapi/linux/vhost_types.h
    +++ b/include/uapi/linux/vhost_types.h
    @@ -60,6 +60,17 @@ struct vhost_iotlb_msg {
    #define VHOST_IOTLB_UPDATE 2
    #define VHOST_IOTLB_INVALIDATE 3
    #define VHOST_IOTLB_ACCESS_FAIL 4
    +/*
    + * VHOST_IOTLB_BATCH_BEGIN and VHOST_IOTLB_BATCH_END allow modifying
    + * multiple mappings in one go: beginning with
    + * VHOST_IOTLB_BATCH_BEGIN, followed by any number of
    + * VHOST_IOTLB_UPDATE messages, and ending with VHOST_IOTLB_BATCH_END.
    + * When one of these two values is used as the message type, the rest
    + * of the fields in the message are ignored. There's no guarantee that
    + * these changes take place automatically in the device.
    + */
    +#define VHOST_IOTLB_BATCH_BEGIN 5
    +#define VHOST_IOTLB_BATCH_END 6
    __u8 type;
    };

    --
    2.26.0
    \
     
     \ /
      Last update: 2020-08-04 18:24    [W:3.186 / U:0.096 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site