Re: [PATCH net-next v3 00/13] virtio: support packed ring

2018-11-21 Thread David Miller
From: "Michael S. Tsirkin" 
Date: Wed, 21 Nov 2018 07:20:27 -0500

> Dave, given the holiday, attempts to wrap up the 1.1 spec and the
> patchset size I would very much appreciate a bit more time for
> review. Say until Nov 28?

Ok.
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH net-next v3 00/13] virtio: support packed ring

2018-11-21 Thread Jason Wang


On 2018/11/21 下午8:42, Tiwei Bie wrote:

On Wed, Nov 21, 2018 at 07:20:27AM -0500, Michael S. Tsirkin wrote:

On Wed, Nov 21, 2018 at 06:03:17PM +0800, Tiwei Bie wrote:

Hi,

This patch set implements packed ring support in virtio driver.

A performance test between pktgen (pktgen_sample03_burst_single_flow.sh)
and DPDK vhost (testpmd/rxonly/vhost-PMD) has been done, I saw
~30% performance gain in packed ring in this case.

Thanks a lot, this is very exciting!
Dave, given the holiday, attempts to wrap up the 1.1 spec and the
patchset size I would very much appreciate a bit more time for
review. Say until Nov 28?


To make this patch set work with below patch set for vhost,
some hacks are needed to set the _F_NEXT flag in indirect
descriptors (this should be fixed in vhost):

https://lkml.org/lkml/2018/7/3/33

Could you pls clarify - do you mean it doesn't yet work with vhost
because of a vhost bug, and to test it with the linked patches
you had to hack in _F_NEXT? Because I do not see _F_NEXT
in indirect descriptors in this patch (which is fine).
Or did I miss it?

You didn't miss anything. :)

I think it's a small bug in vhost, which Jason may fix very
quickly, so I didn't post it. Below is the hack I used:



Good catch. I didn't notice the subtle difference since split ring 
requires for it.


Let me fix it in next version.

Thanks.




diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index cd7e755484e3..42faea7d8cf8 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -980,6 +980,7 @@ static int virtqueue_add_indirect_packed(struct 
vring_virtqueue *vq,
unsigned int i, n, err_idx;
u16 head, id;
dma_addr_t addr;
+   int c = 0;
  
  	head = vq->packed.next_avail_idx;

desc = alloc_indirect_packed(total_sg, gfp);
@@ -1001,8 +1002,9 @@ static int virtqueue_add_indirect_packed(struct 
vring_virtqueue *vq,
if (vring_mapping_error(vq, addr))
goto unmap_release;
  
-			desc[i].flags = cpu_to_le16(n < out_sgs ?

-   0 : VRING_DESC_F_WRITE);
+   desc[i].flags = cpu_to_le16((n < out_sgs ?
+   0 : VRING_DESC_F_WRITE) |
+   (++c == total_sg ? 0 : VRING_DESC_F_NEXT));
desc[i].addr = cpu_to_le64(addr);
desc[i].len = cpu_to_le32(sg->length);
i++;

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [virtio-dev] Re: [PATCH v4 5/7] iommu: Add virtio-iommu driver

2018-11-21 Thread Auger Eric
Hi jean,

On 11/20/18 6:30 PM, Jean-Philippe Brucker wrote:
> On 16/11/2018 18:46, Jean-Philippe Brucker wrote:
 +/*
 + * __viommu_sync_req - Complete all in-flight requests
 + *
 + * Wait for all added requests to complete. When this function returns, 
 all
 + * requests that were in-flight at the time of the call have completed.
 + */
 +static int __viommu_sync_req(struct viommu_dev *viommu)
 +{
 +  int ret = 0;
 +  unsigned int len;
 +  size_t write_len;
 +  struct viommu_request *req;
 +  struct virtqueue *vq = viommu->vqs[VIOMMU_REQUEST_VQ];
 +
 +  assert_spin_locked(>request_lock);
 +
 +  virtqueue_kick(vq);
 +
 +  while (!list_empty(>requests)) {
 +  len = 0;
 +  req = virtqueue_get_buf(vq, );
 +  if (!req)
 +  continue;
 +
 +  if (!len)
 +  viommu_set_req_status(req->buf, req->len,
 +VIRTIO_IOMMU_S_IOERR);
 +
 +  write_len = req->len - req->write_offset;
 +  if (req->writeback && len >= write_len)
>>> I don't get "len >= write_len". Is it valid for the device to write more
>>> than write_len? If it writes less than write_len, the status is not set,
>>> is it?
> 
> Actually, len could well be three bytes smaller than write_len. The spec
> doesn't require the device to write the three padding bytes in
> virtio_iommu_req_tail, after the status byte.
> 
> Here the driver just assumes that the device wrote the reserved field.
> The QEMU device seems to write uninitialized data in there...

Indeed that's incorrect and I should fix it. tail struct should be
properly initialized to 0. Only probe request implementation is correct.
> 
> Any objection to changing the spec to require the device to initialize
> those bytes to zero? I think it makes things nicer overall and shouldn't
> have any performance impact.
No objection from me.
> 
> [...]
 +static struct iommu_domain *viommu_domain_alloc(unsigned type)
 +{
 +  struct viommu_domain *vdomain;
 +
 +  if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
>>> smmu drivers also support the IDENTITY type. Don't we want to support it
>>> as well?
>>
>> Eventually yes. The IDENTITY domain is useful when an IOMMU has been
>> forced upon you and gets in the way of performance, in which case you
>> get rid of it with CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y or
>> iommu.passthrough=y. For virtio-iommu though, you could simply not
>> instantiate the device.
>>
>> I don't think it's difficult to add: if the device supports
>> VIRTIO_IOMMU_F_BYPASS, then we simply don't send an ATTACH request.
>> Otherwise after ATTACH we send a MAP for the whole input range. If the
>> change isn't bigger than this, I'll add it to v5.
> 
> Not as straightforward as I hoped, when the device doesn't support
> VIRTIO_IOMMU_F_BYPASS:
> 
> * We can't simply create an ID map for the whole input range, we need to
> carve out the resv_mem regions.
> 
> * For a VFIO device, the host has no way of forwarding the identity
> mapping. For example the guest will attempt to map [0; 0x]
> -> [0; 0x], but VFIO only allows to map RAM and cannot take
> such request. One solution is to only create ID mapping for RAM, and
> register a notifier for memory hotplug, like intel-iommu does for IOMMUs
> that don't support HW pass-through.
> 
> Since it's not completely trivial and - I think - not urgent, I'll leave
> this for later.
OK makes sense to me too. It was just a head up.

Thanks

Eric
> 
> Thanks,
> Jean
> 
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH net-next v3 00/13] virtio: support packed ring

2018-11-21 Thread Michael S. Tsirkin
On Wed, Nov 21, 2018 at 06:03:17PM +0800, Tiwei Bie wrote:
> Hi,
> 
> This patch set implements packed ring support in virtio driver.
> 
> A performance test between pktgen (pktgen_sample03_burst_single_flow.sh)
> and DPDK vhost (testpmd/rxonly/vhost-PMD) has been done, I saw
> ~30% performance gain in packed ring in this case.

Thanks a lot, this is very exciting!
Dave, given the holiday, attempts to wrap up the 1.1 spec and the
patchset size I would very much appreciate a bit more time for
review. Say until Nov 28?

> To make this patch set work with below patch set for vhost,
> some hacks are needed to set the _F_NEXT flag in indirect
> descriptors (this should be fixed in vhost):
> 
> https://lkml.org/lkml/2018/7/3/33

Could you pls clarify - do you mean it doesn't yet work with vhost
because of a vhost bug, and to test it with the linked patches
you had to hack in _F_NEXT? Because I do not see _F_NEXT
in indirect descriptors in this patch (which is fine).
Or did I miss it?

> v2 -> v3:
> - Use leXX instead of virtioXX (MST);
> - Refactor split ring first (MST);
> - Add debug helpers (MST);
> - Put split/packed ring specific fields in sub structures (MST);
> - Handle normal descriptors and indirect descriptors differently (MST);
> - Track the DMA addr/len related info in a separate structure (MST);
> - Calculate AVAIL/USED flags only when wrap counter wraps (MST);
> - Define a struct/union to read event structure (MST);
> - Define a macro for wrap counter bit in uapi (MST);
> - Define the AVAIL/USED bits as shifts instead of values (MST);
> - s/_F_/_FLAG_/ in VRING_PACKED_EVENT_* as they are values (MST);
> - Drop the notify workaround for QEMU's tx-timer in packed ring (MST);
> 
> v1 -> v2:
> - Use READ_ONCE() to read event off_wrap and flags together (Jason);
> - Add comments related to ccw (Jason);
> 
> RFC v6 -> v1:
> - Avoid extra virtio_wmb() in virtqueue_enable_cb_delayed_packed()
>   when event idx is off (Jason);
> - Fix bufs calculation in virtqueue_enable_cb_delayed_packed() (Jason);
> - Test the state of the desc at used_idx instead of last_used_idx
>   in virtqueue_enable_cb_delayed_packed() (Jason);
> - Save wrap counter (as part of queue state) in the return value
>   of virtqueue_enable_cb_prepare_packed();
> - Refine the packed ring definitions in uapi;
> - Rebase on the net-next tree;
> 
> RFC v5 -> RFC v6:
> - Avoid tracking addr/len/flags when DMA API isn't used (MST/Jason);
> - Define wrap counter as bool (Jason);
> - Use ALIGN() in vring_init_packed() (Jason);
> - Avoid using pointer to track `next` in detach_buf_packed() (Jason);
> - Add comments for barriers (Jason);
> - Don't enable RING_PACKED on ccw for now (noticed by Jason);
> - Refine the memory barrier in virtqueue_poll();
> - Add a missing memory barrier in virtqueue_enable_cb_delayed_packed();
> - Remove the hacks in virtqueue_enable_cb_prepare_packed();
> 
> RFC v4 -> RFC v5:
> - Save DMA addr, etc in desc state (Jason);
> - Track used wrap counter;
> 
> RFC v3 -> RFC v4:
> - Make ID allocation support out-of-order (Jason);
> - Various fixes for EVENT_IDX support;
> 
> RFC v2 -> RFC v3:
> - Split into small patches (Jason);
> - Add helper virtqueue_use_indirect() (Jason);
> - Just set id for the last descriptor of a list (Jason);
> - Calculate the prev in virtqueue_add_packed() (Jason);
> - Fix/improve desc suppression code (Jason/MST);
> - Refine the code layout for XXX_split/packed and wrappers (MST);
> - Fix the comments and API in uapi (MST);
> - Remove the BUG_ON() for indirect (Jason);
> - Some other refinements and bug fixes;
> 
> RFC v1 -> RFC v2:
> - Add indirect descriptor support - compile test only;
> - Add event suppression supprt - compile test only;
> - Move vring_packed_init() out of uapi (Jason, MST);
> - Merge two loops into one in virtqueue_add_packed() (Jason);
> - Split vring_unmap_one() for packed ring and split ring (Jason);
> - Avoid using '%' operator (Jason);
> - Rename free_head -> next_avail_idx (Jason);
> - Add comments for virtio_wmb() in virtqueue_add_packed() (Jason);
> - Some other refinements and bug fixes;
> 
> 
> Tiwei Bie (13):
>   virtio: add packed ring types and macros
>   virtio_ring: add _split suffix for split ring functions
>   virtio_ring: put split ring functions together
>   virtio_ring: put split ring fields in a sub struct
>   virtio_ring: introduce debug helpers
>   virtio_ring: introduce helper for indirect feature
>   virtio_ring: allocate desc state for split ring separately
>   virtio_ring: extract split ring handling from ring creation
>   virtio_ring: cache whether we will use DMA API
>   virtio_ring: introduce packed ring support
>   virtio_ring: leverage event idx in packed ring
>   virtio_ring: disable packed ring on unsupported transports
>   virtio_ring: advertize packed ring layout
> 
>  drivers/misc/mic/vop/vop_main.c|   13 +
>  drivers/remoteproc/remoteproc_virtio.c |   13 +
>  drivers/s390/virtio/virtio_ccw.c   |   14 +
>  

[PATCH net-next v3 13/13] virtio_ring: advertize packed ring layout

2018-11-21 Thread Tiwei Bie
Advertize the packed ring layout support.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 40e4d3798d16..cd7e755484e3 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -2211,6 +2211,8 @@ void vring_transport_features(struct virtio_device *vdev)
break;
case VIRTIO_F_IOMMU_PLATFORM:
break;
+   case VIRTIO_F_RING_PACKED:
+   break;
default:
/* We don't understand this bit. */
__virtio_clear_bit(vdev, i);
-- 
2.14.5

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH net-next v3 12/13] virtio_ring: disable packed ring on unsupported transports

2018-11-21 Thread Tiwei Bie
Currently, ccw, vop and remoteproc need some legacy virtio
APIs to create or access virtio rings, which are not supported
by packed ring. So disable packed ring on these transports
for now.

Signed-off-by: Tiwei Bie 
---
 drivers/misc/mic/vop/vop_main.c| 13 +
 drivers/remoteproc/remoteproc_virtio.c | 13 +
 drivers/s390/virtio/virtio_ccw.c   | 14 ++
 3 files changed, 40 insertions(+)

diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c
index 3633202e18f4..6b212c8b78e7 100644
--- a/drivers/misc/mic/vop/vop_main.c
+++ b/drivers/misc/mic/vop/vop_main.c
@@ -129,6 +129,16 @@ static u64 vop_get_features(struct virtio_device *vdev)
return features;
 }
 
+static void vop_transport_features(struct virtio_device *vdev)
+{
+   /*
+* Packed ring isn't enabled on virtio_vop for now,
+* because virtio_vop uses vring_new_virtqueue() which
+* creates virtio rings on preallocated memory.
+*/
+   __virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED);
+}
+
 static int vop_finalize_features(struct virtio_device *vdev)
 {
unsigned int i, bits;
@@ -141,6 +151,9 @@ static int vop_finalize_features(struct virtio_device *vdev)
/* Give virtio_ring a chance to accept features. */
vring_transport_features(vdev);
 
+   /* Give virtio_vop a chance to accept features. */
+   vop_transport_features(vdev);
+
memset_io(out_features, 0, feature_len);
bits = min_t(unsigned, feature_len,
 sizeof(vdev->features)) * 8;
diff --git a/drivers/remoteproc/remoteproc_virtio.c 
b/drivers/remoteproc/remoteproc_virtio.c
index de21f620b882..183fc42a510a 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -214,6 +214,16 @@ static u64 rproc_virtio_get_features(struct virtio_device 
*vdev)
return rsc->dfeatures;
 }
 
+static void rproc_transport_features(struct virtio_device *vdev)
+{
+   /*
+* Packed ring isn't enabled on remoteproc for now,
+* because remoteproc uses vring_new_virtqueue() which
+* creates virtio rings on preallocated memory.
+*/
+   __virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED);
+}
+
 static int rproc_virtio_finalize_features(struct virtio_device *vdev)
 {
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
@@ -224,6 +234,9 @@ static int rproc_virtio_finalize_features(struct 
virtio_device *vdev)
/* Give virtio_ring a chance to accept features */
vring_transport_features(vdev);
 
+   /* Give virtio_rproc a chance to accept features. */
+   rproc_transport_features(vdev);
+
/* Make sure we don't have any features > 32 bits! */
BUG_ON((u32)vdev->features != vdev->features);
 
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index 97b6f197f007..406d1f64ad65 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -765,6 +765,17 @@ static u64 virtio_ccw_get_features(struct virtio_device 
*vdev)
return rc;
 }
 
+static void ccw_transport_features(struct virtio_device *vdev)
+{
+   /*
+* Packed ring isn't enabled on virtio_ccw for now,
+* because virtio_ccw uses some legacy accessors,
+* e.g. virtqueue_get_avail() and virtqueue_get_used()
+* which aren't available in packed ring currently.
+*/
+   __virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED);
+}
+
 static int virtio_ccw_finalize_features(struct virtio_device *vdev)
 {
struct virtio_ccw_device *vcdev = to_vc_device(vdev);
@@ -791,6 +802,9 @@ static int virtio_ccw_finalize_features(struct 
virtio_device *vdev)
/* Give virtio_ring a chance to accept features. */
vring_transport_features(vdev);
 
+   /* Give virtio_ccw a chance to accept features. */
+   ccw_transport_features(vdev);
+
features->index = 0;
features->features = cpu_to_le32((u32)vdev->features);
/* Write the first half of the feature bits to the host. */
-- 
2.14.5

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH net-next v3 11/13] virtio_ring: leverage event idx in packed ring

2018-11-21 Thread Tiwei Bie
Leverage the EVENT_IDX feature in packed ring to suppress
events when it's available.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 77 
 1 file changed, 71 insertions(+), 6 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index b63eee2034e7..40e4d3798d16 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1222,7 +1222,7 @@ static inline int virtqueue_add_packed(struct virtqueue 
*_vq,
 static bool virtqueue_kick_prepare_packed(struct virtqueue *_vq)
 {
struct vring_virtqueue *vq = to_vvq(_vq);
-   u16 flags;
+   u16 new, old, off_wrap, flags, wrap_counter, event_idx;
bool needs_kick;
union {
struct {
@@ -1240,6 +1240,8 @@ static bool virtqueue_kick_prepare_packed(struct 
virtqueue *_vq)
 */
virtio_mb(vq->weak_barriers);
 
+   old = vq->packed.next_avail_idx - vq->num_added;
+   new = vq->packed.next_avail_idx;
vq->num_added = 0;
 
snapshot.u32 = *(u32 *)vq->packed.vring.device;
@@ -1248,7 +1250,20 @@ static bool virtqueue_kick_prepare_packed(struct 
virtqueue *_vq)
LAST_ADD_TIME_CHECK(vq);
LAST_ADD_TIME_INVALID(vq);
 
-   needs_kick = (flags != VRING_PACKED_EVENT_FLAG_DISABLE);
+   if (flags != VRING_PACKED_EVENT_FLAG_DESC) {
+   needs_kick = (flags != VRING_PACKED_EVENT_FLAG_DISABLE);
+   goto out;
+   }
+
+   off_wrap = le16_to_cpu(snapshot.off_wrap);
+
+   wrap_counter = off_wrap >> VRING_PACKED_EVENT_F_WRAP_CTR;
+   event_idx = off_wrap & ~(1 << VRING_PACKED_EVENT_F_WRAP_CTR);
+   if (wrap_counter != vq->packed.avail_wrap_counter)
+   event_idx -= vq->packed.vring.num;
+
+   needs_kick = vring_need_event(event_idx, new, old);
+out:
END_USE(vq);
return needs_kick;
 }
@@ -1365,6 +1380,18 @@ static void *virtqueue_get_buf_ctx_packed(struct 
virtqueue *_vq,
vq->packed.used_wrap_counter ^= 1;
}
 
+   /*
+* If we expect an interrupt for the next entry, tell host
+* by writing event index and flush out the write before
+* the read in the next get_buf call.
+*/
+   if (vq->packed.event_flags_shadow == VRING_PACKED_EVENT_FLAG_DESC)
+   virtio_store_mb(vq->weak_barriers,
+   >packed.vring.driver->off_wrap,
+   cpu_to_le16(vq->last_used_idx |
+   (vq->packed.used_wrap_counter <<
+VRING_PACKED_EVENT_F_WRAP_CTR)));
+
LAST_ADD_TIME_INVALID(vq);
 
END_USE(vq);
@@ -1393,8 +1420,22 @@ static unsigned 
virtqueue_enable_cb_prepare_packed(struct virtqueue *_vq)
 * more to do.
 */
 
+   if (vq->event) {
+   vq->packed.vring.driver->off_wrap =
+   cpu_to_le16(vq->last_used_idx |
+   (vq->packed.used_wrap_counter <<
+VRING_PACKED_EVENT_F_WRAP_CTR));
+   /*
+* We need to update event offset and event wrap
+* counter first before updating event flags.
+*/
+   virtio_wmb(vq->weak_barriers);
+   }
+
if (vq->packed.event_flags_shadow == VRING_PACKED_EVENT_FLAG_DISABLE) {
-   vq->packed.event_flags_shadow = VRING_PACKED_EVENT_FLAG_ENABLE;
+   vq->packed.event_flags_shadow = vq->event ?
+   VRING_PACKED_EVENT_FLAG_DESC :
+   VRING_PACKED_EVENT_FLAG_ENABLE;
vq->packed.vring.driver->flags =
cpu_to_le16(vq->packed.event_flags_shadow);
}
@@ -1420,6 +1461,7 @@ static bool virtqueue_enable_cb_delayed_packed(struct 
virtqueue *_vq)
 {
struct vring_virtqueue *vq = to_vvq(_vq);
u16 used_idx, wrap_counter;
+   u16 bufs;
 
START_USE(vq);
 
@@ -1428,11 +1470,34 @@ static bool virtqueue_enable_cb_delayed_packed(struct 
virtqueue *_vq)
 * more to do.
 */
 
-   used_idx = vq->last_used_idx;
-   wrap_counter = vq->packed.used_wrap_counter;
+   if (vq->event) {
+   /* TODO: tune this threshold */
+   bufs = (vq->packed.vring.num - vq->vq.num_free) * 3 / 4;
+   wrap_counter = vq->packed.used_wrap_counter;
+
+   used_idx = vq->last_used_idx + bufs;
+   if (used_idx >= vq->packed.vring.num) {
+   used_idx -= vq->packed.vring.num;
+   wrap_counter ^= 1;
+   }
+
+   vq->packed.vring.driver->off_wrap = cpu_to_le16(used_idx |
+   (wrap_counter << VRING_PACKED_EVENT_F_WRAP_CTR));
+
+   /*
+* We need to update event offset and event wrap
+* counter first before 

[PATCH net-next v3 10/13] virtio_ring: introduce packed ring support

2018-11-21 Thread Tiwei Bie
Introduce the packed ring support. Packed ring can only be
created by vring_create_virtqueue() and each chunk of packed
ring will be allocated individually. Packed ring can not be
created on preallocated memory by vring_new_virtqueue() or
the likes currently.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 900 +--
 1 file changed, 870 insertions(+), 30 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index aafe1969b45e..b63eee2034e7 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -83,9 +83,26 @@ struct vring_desc_state_split {
struct vring_desc *indir_desc;  /* Indirect descriptor, if any. */
 };
 
+struct vring_desc_state_packed {
+   void *data; /* Data for callback. */
+   struct vring_packed_desc *indir_desc; /* Indirect descriptor, if any. */
+   u16 num;/* Descriptor list length. */
+   u16 next;   /* The next desc state in a list. */
+   u16 last;   /* The last desc state in a list. */
+};
+
+struct vring_desc_extra_packed {
+   dma_addr_t addr;/* Buffer DMA addr. */
+   u32 len;/* Buffer length. */
+   u16 flags;  /* Descriptor flags. */
+};
+
 struct vring_virtqueue {
struct virtqueue vq;
 
+   /* Is this a packed ring? */
+   bool packed_ring;
+
/* Is DMA API used? */
bool use_dma_api;
 
@@ -109,23 +126,64 @@ struct vring_virtqueue {
/* Last used index we've seen. */
u16 last_used_idx;
 
-   struct {
-   /* Actual memory layout for this queue */
-   struct vring vring;
+   union {
+   /* Available for split ring */
+   struct {
+   /* Actual memory layout for this queue. */
+   struct vring vring;
 
-   /* Last written value to avail->flags */
-   u16 avail_flags_shadow;
+   /* Last written value to avail->flags */
+   u16 avail_flags_shadow;
 
-   /* Last written value to avail->idx in guest byte order */
-   u16 avail_idx_shadow;
+   /*
+* Last written value to avail->idx in
+* guest byte order.
+*/
+   u16 avail_idx_shadow;
 
-   /* Per-descriptor state. */
-   struct vring_desc_state_split *desc_state;
+   /* Per-descriptor state. */
+   struct vring_desc_state_split *desc_state;
 
-   /* DMA, allocation, and size information */
-   size_t queue_size_in_bytes;
-   dma_addr_t queue_dma_addr;
-   } split;
+   /* DMA address and size information */
+   dma_addr_t queue_dma_addr;
+   size_t queue_size_in_bytes;
+   } split;
+
+   /* Available for packed ring */
+   struct {
+   /* Actual memory layout for this queue. */
+   struct vring_packed vring;
+
+   /* Driver ring wrap counter. */
+   bool avail_wrap_counter;
+
+   /* Device ring wrap counter. */
+   bool used_wrap_counter;
+
+   /* Avail used flags. */
+   u16 avail_used_flags;
+
+   /* Index of the next avail descriptor. */
+   u16 next_avail_idx;
+
+   /*
+* Last written value to driver->flags in
+* guest byte order.
+*/
+   u16 event_flags_shadow;
+
+   /* Per-descriptor state. */
+   struct vring_desc_state_packed *desc_state;
+   struct vring_desc_extra_packed *desc_extra;
+
+   /* DMA address and size information */
+   dma_addr_t ring_dma_addr;
+   dma_addr_t driver_event_dma_addr;
+   dma_addr_t device_event_dma_addr;
+   size_t ring_size_in_bytes;
+   size_t event_size_in_bytes;
+   } packed;
+   };
 
/* How to notify other side. FIXME: commonalize hcalls! */
bool (*notify)(struct virtqueue *vq);
@@ -840,6 +898,717 @@ static struct virtqueue *vring_create_virtqueue_split(
 }
 
 
+/*
+ * Packed ring specific functions - *_packed().
+ */
+
+static void vring_unmap_state_packed(const struct vring_virtqueue *vq,
+struct vring_desc_extra_packed *state)
+{
+   u16 flags;
+
+   if (!vq->use_dma_api)
+   return;
+
+   flags = 

[PATCH net-next v3 09/13] virtio_ring: cache whether we will use DMA API

2018-11-21 Thread Tiwei Bie
Cache whether we will use DMA API, instead of doing the
check every time. We are going to check whether DMA API
is used more often in packed ring.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index d00a87909a7e..aafe1969b45e 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -86,6 +86,9 @@ struct vring_desc_state_split {
 struct vring_virtqueue {
struct virtqueue vq;
 
+   /* Is DMA API used? */
+   bool use_dma_api;
+
/* Can we use weak barriers? */
bool weak_barriers;
 
@@ -262,7 +265,7 @@ static dma_addr_t vring_map_one_sg(const struct 
vring_virtqueue *vq,
   struct scatterlist *sg,
   enum dma_data_direction direction)
 {
-   if (!vring_use_dma_api(vq->vq.vdev))
+   if (!vq->use_dma_api)
return (dma_addr_t)sg_phys(sg);
 
/*
@@ -279,7 +282,7 @@ static dma_addr_t vring_map_single(const struct 
vring_virtqueue *vq,
   void *cpu_addr, size_t size,
   enum dma_data_direction direction)
 {
-   if (!vring_use_dma_api(vq->vq.vdev))
+   if (!vq->use_dma_api)
return (dma_addr_t)virt_to_phys(cpu_addr);
 
return dma_map_single(vring_dma_dev(vq),
@@ -289,7 +292,7 @@ static dma_addr_t vring_map_single(const struct 
vring_virtqueue *vq,
 static int vring_mapping_error(const struct vring_virtqueue *vq,
   dma_addr_t addr)
 {
-   if (!vring_use_dma_api(vq->vq.vdev))
+   if (!vq->use_dma_api)
return 0;
 
return dma_mapping_error(vring_dma_dev(vq), addr);
@@ -305,7 +308,7 @@ static void vring_unmap_one_split(const struct 
vring_virtqueue *vq,
 {
u16 flags;
 
-   if (!vring_use_dma_api(vq->vq.vdev))
+   if (!vq->use_dma_api)
return;
 
flags = virtio16_to_cpu(vq->vq.vdev, desc->flags);
@@ -1202,6 +1205,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int 
index,
vq->broken = false;
vq->last_used_idx = 0;
vq->num_added = 0;
+   vq->use_dma_api = vring_use_dma_api(vdev);
list_add_tail(>vq.list, >vqs);
 #ifdef DEBUG
vq->in_use = false;
-- 
2.14.5

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH net-next v3 08/13] virtio_ring: extract split ring handling from ring creation

2018-11-21 Thread Tiwei Bie
Introduce a specific function to create the split ring.
And also move the DMA allocation and size information to
the .split sub-structure.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 220 ---
 1 file changed, 121 insertions(+), 99 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index acd851f3105c..d00a87909a7e 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -118,6 +118,10 @@ struct vring_virtqueue {
 
/* Per-descriptor state. */
struct vring_desc_state_split *desc_state;
+
+   /* DMA, allocation, and size information */
+   size_t queue_size_in_bytes;
+   dma_addr_t queue_dma_addr;
} split;
 
/* How to notify other side. FIXME: commonalize hcalls! */
@@ -125,8 +129,6 @@ struct vring_virtqueue {
 
/* DMA, allocation, and size information */
bool we_own_ring;
-   size_t queue_size_in_bytes;
-   dma_addr_t queue_dma_addr;
 
 #ifdef DEBUG
/* They're supposed to lock for us. */
@@ -203,6 +205,48 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
return false;
 }
 
+static void *vring_alloc_queue(struct virtio_device *vdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+   if (vring_use_dma_api(vdev)) {
+   return dma_alloc_coherent(vdev->dev.parent, size,
+ dma_handle, flag);
+   } else {
+   void *queue = alloc_pages_exact(PAGE_ALIGN(size), flag);
+
+   if (queue) {
+   phys_addr_t phys_addr = virt_to_phys(queue);
+   *dma_handle = (dma_addr_t)phys_addr;
+
+   /*
+* Sanity check: make sure we dind't truncate
+* the address.  The only arches I can find that
+* have 64-bit phys_addr_t but 32-bit dma_addr_t
+* are certain non-highmem MIPS and x86
+* configurations, but these configurations
+* should never allocate physical pages above 32
+* bits, so this is fine.  Just in case, throw a
+* warning and abort if we end up with an
+* unrepresentable address.
+*/
+   if (WARN_ON_ONCE(*dma_handle != phys_addr)) {
+   free_pages_exact(queue, PAGE_ALIGN(size));
+   return NULL;
+   }
+   }
+   return queue;
+   }
+}
+
+static void vring_free_queue(struct virtio_device *vdev, size_t size,
+void *queue, dma_addr_t dma_handle)
+{
+   if (vring_use_dma_api(vdev))
+   dma_free_coherent(vdev->dev.parent, size, queue, dma_handle);
+   else
+   free_pages_exact(queue, PAGE_ALIGN(size));
+}
+
 /*
  * The DMA ops on various arches are rather gnarly right now, and
  * making all of the arch DMA ops work on the vring device itself
@@ -730,6 +774,68 @@ static void *virtqueue_detach_unused_buf_split(struct 
virtqueue *_vq)
return NULL;
 }
 
+static struct virtqueue *vring_create_virtqueue_split(
+   unsigned int index,
+   unsigned int num,
+   unsigned int vring_align,
+   struct virtio_device *vdev,
+   bool weak_barriers,
+   bool may_reduce_num,
+   bool context,
+   bool (*notify)(struct virtqueue *),
+   void (*callback)(struct virtqueue *),
+   const char *name)
+{
+   struct virtqueue *vq;
+   void *queue = NULL;
+   dma_addr_t dma_addr;
+   size_t queue_size_in_bytes;
+   struct vring vring;
+
+   /* We assume num is a power of 2. */
+   if (num & (num - 1)) {
+   dev_warn(>dev, "Bad virtqueue length %u\n", num);
+   return NULL;
+   }
+
+   /* TODO: allocate each queue chunk individually */
+   for (; num && vring_size(num, vring_align) > PAGE_SIZE; num /= 2) {
+   queue = vring_alloc_queue(vdev, vring_size(num, vring_align),
+ _addr,
+ GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO);
+   if (queue)
+   break;
+   }
+
+   if (!num)
+   return NULL;
+
+   if (!queue) {
+   /* Try to get a single page. You are my only hope! */
+   queue = vring_alloc_queue(vdev, vring_size(num, vring_align),
+ _addr, GFP_KERNEL|__GFP_ZERO);
+   }
+   if (!queue)
+   return NULL;
+
+   queue_size_in_bytes = vring_size(num, vring_align);
+   vring_init(, num, queue, vring_align);
+
+   vq = __vring_new_virtqueue(index, vring, vdev, weak_barriers, context,
+ 

[PATCH net-next v3 06/13] virtio_ring: introduce helper for indirect feature

2018-11-21 Thread Tiwei Bie
Introduce a helper to check whether we will use indirect
feature. It will be used by packed ring too.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 10d407910aa2..d1076f28c7e9 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -145,6 +145,18 @@ struct vring_virtqueue {
 
 #define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
 
+static inline bool virtqueue_use_indirect(struct virtqueue *_vq,
+ unsigned int total_sg)
+{
+   struct vring_virtqueue *vq = to_vvq(_vq);
+
+   /*
+* If the host supports indirect descriptor tables, and we have multiple
+* buffers, then go indirect. FIXME: tune this threshold
+*/
+   return (vq->indirect && total_sg > 1 && vq->vq.num_free);
+}
+
 /*
  * Modern virtio devices have feature bits to specify whether they need a
  * quirk and bypass the IOMMU. If not there, just use the DMA API.
@@ -324,9 +336,7 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
 
head = vq->free_head;
 
-   /* If the host supports indirect descriptor tables, and we have multiple
-* buffers, then go indirect. FIXME: tune this threshold */
-   if (vq->indirect && total_sg > 1 && vq->vq.num_free)
+   if (virtqueue_use_indirect(_vq, total_sg))
desc = alloc_indirect_split(_vq, total_sg, gfp);
else {
desc = NULL;
-- 
2.14.5

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH net-next v3 05/13] virtio_ring: introduce debug helpers

2018-11-21 Thread Tiwei Bie
Introduce debug helpers for last_add_time update, check and
invalid. They will be used by packed ring too.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 49 
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 0b97e5c79654..10d407910aa2 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -44,6 +44,26 @@
} while (0)
 #define END_USE(_vq) \
do { BUG_ON(!(_vq)->in_use); (_vq)->in_use = 0; } while(0)
+#define LAST_ADD_TIME_UPDATE(_vq)  \
+   do {\
+   ktime_t now = ktime_get();  \
+   \
+   /* No kick or get, with .1 second between?  Warn. */ \
+   if ((_vq)->last_add_time_valid) \
+   WARN_ON(ktime_to_ms(ktime_sub(now,  \
+   (_vq)->last_add_time)) > 100);  \
+   (_vq)->last_add_time = now; \
+   (_vq)->last_add_time_valid = true;  \
+   } while (0)
+#define LAST_ADD_TIME_CHECK(_vq)   \
+   do {\
+   if ((_vq)->last_add_time_valid) {   \
+   WARN_ON(ktime_to_ms(ktime_sub(ktime_get(), \
+ (_vq)->last_add_time)) > 100); \
+   }   \
+   } while (0)
+#define LAST_ADD_TIME_INVALID(_vq) \
+   ((_vq)->last_add_time_valid = false)
 #else
 #define BAD_RING(_vq, fmt, args...)\
do {\
@@ -53,6 +73,9 @@
} while (0)
 #define START_USE(vq)
 #define END_USE(vq)
+#define LAST_ADD_TIME_UPDATE(vq)
+#define LAST_ADD_TIME_CHECK(vq)
+#define LAST_ADD_TIME_INVALID(vq)
 #endif
 
 struct vring_desc_state {
@@ -295,18 +318,7 @@ static inline int virtqueue_add_split(struct virtqueue 
*_vq,
return -EIO;
}
 
-#ifdef DEBUG
-   {
-   ktime_t now = ktime_get();
-
-   /* No kick or get, with .1 second between?  Warn. */
-   if (vq->last_add_time_valid)
-   WARN_ON(ktime_to_ms(ktime_sub(now, vq->last_add_time))
-   > 100);
-   vq->last_add_time = now;
-   vq->last_add_time_valid = true;
-   }
-#endif
+   LAST_ADD_TIME_UPDATE(vq);
 
BUG_ON(total_sg == 0);
 
@@ -467,13 +479,8 @@ static bool virtqueue_kick_prepare_split(struct virtqueue 
*_vq)
new = vq->split.avail_idx_shadow;
vq->num_added = 0;
 
-#ifdef DEBUG
-   if (vq->last_add_time_valid) {
-   WARN_ON(ktime_to_ms(ktime_sub(ktime_get(),
- vq->last_add_time)) > 100);
-   }
-   vq->last_add_time_valid = false;
-#endif
+   LAST_ADD_TIME_CHECK(vq);
+   LAST_ADD_TIME_INVALID(vq);
 
if (vq->event) {
needs_kick = vring_need_event(virtio16_to_cpu(_vq->vdev,
@@ -597,9 +604,7 @@ static void *virtqueue_get_buf_ctx_split(struct virtqueue 
*_vq,
_used_event(>split.vring),
cpu_to_virtio16(_vq->vdev, vq->last_used_idx));
 
-#ifdef DEBUG
-   vq->last_add_time_valid = false;
-#endif
+   LAST_ADD_TIME_INVALID(vq);
 
END_USE(vq);
return ret;
-- 
2.14.5

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 0/9] drm: remove deprecated functions

2018-11-21 Thread Laurent Pinchart
Hi Daniel,

On Wednesday, 21 November 2018 11:42:33 EET Daniel Vetter wrote:
> On Thu, Nov 15, 2018 at 11:38:35PM +0100, Linus Walleij wrote:
> > On Thu, Nov 15, 2018 at 11:17 PM Fernando Ramos wrote:
> >> One of the things in the DRM TODO list ("Documentation/gpu/todo.rst")
> >> was to "switch from reference/unreference to get/put". That's what this
> >> patch series is about.
> > 
> > The series:
> > Reviewed-by: Linus Walleij 
> 
> Since your reviewed it all, and there's a pile of acks for the driver
> parts too: Want to go ahead and apply it too?

Please remember to give at least a week to reviewers, especially with LPC last 
week.

-- 
Regards,

Laurent Pinchart



___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH net-next v3 04/13] virtio_ring: put split ring fields in a sub struct

2018-11-21 Thread Tiwei Bie
Put the split ring specific fields in a sub-struct named
as "split" to avoid misuse after introducing packed ring.
There is no functional change.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 156 +--
 1 file changed, 91 insertions(+), 65 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 7cd40a2a0d21..0b97e5c79654 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -63,9 +63,6 @@ struct vring_desc_state {
 struct vring_virtqueue {
struct virtqueue vq;
 
-   /* Actual memory layout for this queue */
-   struct vring vring;
-
/* Can we use weak barriers? */
bool weak_barriers;
 
@@ -86,11 +83,16 @@ struct vring_virtqueue {
/* Last used index we've seen. */
u16 last_used_idx;
 
-   /* Last written value to avail->flags */
-   u16 avail_flags_shadow;
+   struct {
+   /* Actual memory layout for this queue */
+   struct vring vring;
 
-   /* Last written value to avail->idx in guest byte order */
-   u16 avail_idx_shadow;
+   /* Last written value to avail->flags */
+   u16 avail_flags_shadow;
+
+   /* Last written value to avail->idx in guest byte order */
+   u16 avail_idx_shadow;
+   } split;
 
/* How to notify other side. FIXME: commonalize hcalls! */
bool (*notify)(struct virtqueue *vq);
@@ -316,7 +318,7 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
desc = alloc_indirect_split(_vq, total_sg, gfp);
else {
desc = NULL;
-   WARN_ON_ONCE(total_sg > vq->vring.num && !vq->indirect);
+   WARN_ON_ONCE(total_sg > vq->split.vring.num && !vq->indirect);
}
 
if (desc) {
@@ -327,7 +329,7 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
descs_used = 1;
} else {
indirect = false;
-   desc = vq->vring.desc;
+   desc = vq->split.vring.desc;
i = head;
descs_used = total_sg;
}
@@ -383,10 +385,13 @@ static inline int virtqueue_add_split(struct virtqueue 
*_vq,
if (vring_mapping_error(vq, addr))
goto unmap_release;
 
-   vq->vring.desc[head].flags = cpu_to_virtio16(_vq->vdev, 
VRING_DESC_F_INDIRECT);
-   vq->vring.desc[head].addr = cpu_to_virtio64(_vq->vdev, addr);
+   vq->split.vring.desc[head].flags = cpu_to_virtio16(_vq->vdev,
+   VRING_DESC_F_INDIRECT);
+   vq->split.vring.desc[head].addr = cpu_to_virtio64(_vq->vdev,
+   addr);
 
-   vq->vring.desc[head].len = cpu_to_virtio32(_vq->vdev, total_sg 
* sizeof(struct vring_desc));
+   vq->split.vring.desc[head].len = cpu_to_virtio32(_vq->vdev,
+   total_sg * sizeof(struct vring_desc));
}
 
/* We're using some buffers from the free list. */
@@ -394,7 +399,8 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
 
/* Update free pointer */
if (indirect)
-   vq->free_head = virtio16_to_cpu(_vq->vdev, 
vq->vring.desc[head].next);
+   vq->free_head = virtio16_to_cpu(_vq->vdev,
+   vq->split.vring.desc[head].next);
else
vq->free_head = i;
 
@@ -407,14 +413,15 @@ static inline int virtqueue_add_split(struct virtqueue 
*_vq,
 
/* Put entry in available array (but don't update avail->idx until they
 * do sync). */
-   avail = vq->avail_idx_shadow & (vq->vring.num - 1);
-   vq->vring.avail->ring[avail] = cpu_to_virtio16(_vq->vdev, head);
+   avail = vq->split.avail_idx_shadow & (vq->split.vring.num - 1);
+   vq->split.vring.avail->ring[avail] = cpu_to_virtio16(_vq->vdev, head);
 
/* Descriptors and available array need to be set before we expose the
 * new available array entries. */
virtio_wmb(vq->weak_barriers);
-   vq->avail_idx_shadow++;
-   vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, vq->avail_idx_shadow);
+   vq->split.avail_idx_shadow++;
+   vq->split.vring.avail->idx = cpu_to_virtio16(_vq->vdev,
+   vq->split.avail_idx_shadow);
vq->num_added++;
 
pr_debug("Added buffer head %i to %p\n", head, vq);
@@ -435,7 +442,7 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
if (i == err_idx)
break;
vring_unmap_one_split(vq, [i]);
-   i = virtio16_to_cpu(_vq->vdev, vq->vring.desc[i].next);
+   i = virtio16_to_cpu(_vq->vdev, vq->split.vring.desc[i].next);
}
 
if (indirect)
@@ -456,8 +463,8 @@ static bool virtqueue_kick_prepare_split(struct 

[PATCH net-next v3 03/13] virtio_ring: put split ring functions together

2018-11-21 Thread Tiwei Bie
Put the xxx_split() functions together to make the
code more readable and avoid misuse after introducing
the packed ring. There is no functional change.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 587 ++-
 1 file changed, 302 insertions(+), 285 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 29fab2fb39cb..7cd40a2a0d21 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -113,6 +113,11 @@ struct vring_virtqueue {
struct vring_desc_state desc_state[];
 };
 
+
+/*
+ * Helpers.
+ */
+
 #define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
 
 /*
@@ -200,6 +205,20 @@ static dma_addr_t vring_map_single(const struct 
vring_virtqueue *vq,
  cpu_addr, size, direction);
 }
 
+static int vring_mapping_error(const struct vring_virtqueue *vq,
+  dma_addr_t addr)
+{
+   if (!vring_use_dma_api(vq->vq.vdev))
+   return 0;
+
+   return dma_mapping_error(vring_dma_dev(vq), addr);
+}
+
+
+/*
+ * Split ring specific functions - *_split().
+ */
+
 static void vring_unmap_one_split(const struct vring_virtqueue *vq,
  struct vring_desc *desc)
 {
@@ -225,15 +244,6 @@ static void vring_unmap_one_split(const struct 
vring_virtqueue *vq,
}
 }
 
-static int vring_mapping_error(const struct vring_virtqueue *vq,
-  dma_addr_t addr)
-{
-   if (!vring_use_dma_api(vq->vq.vdev))
-   return 0;
-
-   return dma_mapping_error(vring_dma_dev(vq), addr);
-}
-
 static struct vring_desc *alloc_indirect_split(struct virtqueue *_vq,
   unsigned int total_sg,
   gfp_t gfp)
@@ -435,121 +445,6 @@ static inline int virtqueue_add_split(struct virtqueue 
*_vq,
return -EIO;
 }
 
-static inline int virtqueue_add(struct virtqueue *_vq,
-   struct scatterlist *sgs[],
-   unsigned int total_sg,
-   unsigned int out_sgs,
-   unsigned int in_sgs,
-   void *data,
-   void *ctx,
-   gfp_t gfp)
-{
-   return virtqueue_add_split(_vq, sgs, total_sg,
-  out_sgs, in_sgs, data, ctx, gfp);
-}
-
-/**
- * virtqueue_add_sgs - expose buffers to other end
- * @vq: the struct virtqueue we're talking about.
- * @sgs: array of terminated scatterlists.
- * @out_num: the number of scatterlists readable by other side
- * @in_num: the number of scatterlists which are writable (after readable ones)
- * @data: the token identifying the buffer.
- * @gfp: how to do memory allocations (if necessary).
- *
- * Caller must ensure we don't call this with other virtqueue operations
- * at the same time (except where noted).
- *
- * Returns zero or a negative error (ie. ENOSPC, ENOMEM, EIO).
- */
-int virtqueue_add_sgs(struct virtqueue *_vq,
- struct scatterlist *sgs[],
- unsigned int out_sgs,
- unsigned int in_sgs,
- void *data,
- gfp_t gfp)
-{
-   unsigned int i, total_sg = 0;
-
-   /* Count them first. */
-   for (i = 0; i < out_sgs + in_sgs; i++) {
-   struct scatterlist *sg;
-   for (sg = sgs[i]; sg; sg = sg_next(sg))
-   total_sg++;
-   }
-   return virtqueue_add(_vq, sgs, total_sg, out_sgs, in_sgs,
-data, NULL, gfp);
-}
-EXPORT_SYMBOL_GPL(virtqueue_add_sgs);
-
-/**
- * virtqueue_add_outbuf - expose output buffers to other end
- * @vq: the struct virtqueue we're talking about.
- * @sg: scatterlist (must be well-formed and terminated!)
- * @num: the number of entries in @sg readable by other side
- * @data: the token identifying the buffer.
- * @gfp: how to do memory allocations (if necessary).
- *
- * Caller must ensure we don't call this with other virtqueue operations
- * at the same time (except where noted).
- *
- * Returns zero or a negative error (ie. ENOSPC, ENOMEM, EIO).
- */
-int virtqueue_add_outbuf(struct virtqueue *vq,
-struct scatterlist *sg, unsigned int num,
-void *data,
-gfp_t gfp)
-{
-   return virtqueue_add(vq, , num, 1, 0, data, NULL, gfp);
-}
-EXPORT_SYMBOL_GPL(virtqueue_add_outbuf);
-
-/**
- * virtqueue_add_inbuf - expose input buffers to other end
- * @vq: the struct virtqueue we're talking about.
- * @sg: scatterlist (must be well-formed and terminated!)
- * @num: the number of entries in @sg writable by other side
- * @data: the token identifying the buffer.
- * @gfp: how to do memory allocations (if necessary).
- *
- * Caller must ensure we don't call this with other 

[PATCH net-next v3 02/13] virtio_ring: add _split suffix for split ring functions

2018-11-21 Thread Tiwei Bie
Add _split suffix for split ring specific functions. This
is a preparation for introducing the packed ring support.
There is no functional change.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 269 ++-
 1 file changed, 164 insertions(+), 105 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 814b395007b2..29fab2fb39cb 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -200,8 +200,8 @@ static dma_addr_t vring_map_single(const struct 
vring_virtqueue *vq,
  cpu_addr, size, direction);
 }
 
-static void vring_unmap_one(const struct vring_virtqueue *vq,
-   struct vring_desc *desc)
+static void vring_unmap_one_split(const struct vring_virtqueue *vq,
+ struct vring_desc *desc)
 {
u16 flags;
 
@@ -234,8 +234,9 @@ static int vring_mapping_error(const struct vring_virtqueue 
*vq,
return dma_mapping_error(vring_dma_dev(vq), addr);
 }
 
-static struct vring_desc *alloc_indirect(struct virtqueue *_vq,
-unsigned int total_sg, gfp_t gfp)
+static struct vring_desc *alloc_indirect_split(struct virtqueue *_vq,
+  unsigned int total_sg,
+  gfp_t gfp)
 {
struct vring_desc *desc;
unsigned int i;
@@ -256,14 +257,14 @@ static struct vring_desc *alloc_indirect(struct virtqueue 
*_vq,
return desc;
 }
 
-static inline int virtqueue_add(struct virtqueue *_vq,
-   struct scatterlist *sgs[],
-   unsigned int total_sg,
-   unsigned int out_sgs,
-   unsigned int in_sgs,
-   void *data,
-   void *ctx,
-   gfp_t gfp)
+static inline int virtqueue_add_split(struct virtqueue *_vq,
+ struct scatterlist *sgs[],
+ unsigned int total_sg,
+ unsigned int out_sgs,
+ unsigned int in_sgs,
+ void *data,
+ void *ctx,
+ gfp_t gfp)
 {
struct vring_virtqueue *vq = to_vvq(_vq);
struct scatterlist *sg;
@@ -302,7 +303,7 @@ static inline int virtqueue_add(struct virtqueue *_vq,
/* If the host supports indirect descriptor tables, and we have multiple
 * buffers, then go indirect. FIXME: tune this threshold */
if (vq->indirect && total_sg > 1 && vq->vq.num_free)
-   desc = alloc_indirect(_vq, total_sg, gfp);
+   desc = alloc_indirect_split(_vq, total_sg, gfp);
else {
desc = NULL;
WARN_ON_ONCE(total_sg > vq->vring.num && !vq->indirect);
@@ -423,7 +424,7 @@ static inline int virtqueue_add(struct virtqueue *_vq,
for (n = 0; n < total_sg; n++) {
if (i == err_idx)
break;
-   vring_unmap_one(vq, [i]);
+   vring_unmap_one_split(vq, [i]);
i = virtio16_to_cpu(_vq->vdev, vq->vring.desc[i].next);
}
 
@@ -434,6 +435,19 @@ static inline int virtqueue_add(struct virtqueue *_vq,
return -EIO;
 }
 
+static inline int virtqueue_add(struct virtqueue *_vq,
+   struct scatterlist *sgs[],
+   unsigned int total_sg,
+   unsigned int out_sgs,
+   unsigned int in_sgs,
+   void *data,
+   void *ctx,
+   gfp_t gfp)
+{
+   return virtqueue_add_split(_vq, sgs, total_sg,
+  out_sgs, in_sgs, data, ctx, gfp);
+}
+
 /**
  * virtqueue_add_sgs - expose buffers to other end
  * @vq: the struct virtqueue we're talking about.
@@ -536,18 +550,7 @@ int virtqueue_add_inbuf_ctx(struct virtqueue *vq,
 }
 EXPORT_SYMBOL_GPL(virtqueue_add_inbuf_ctx);
 
-/**
- * virtqueue_kick_prepare - first half of split virtqueue_kick call.
- * @vq: the struct virtqueue
- *
- * Instead of virtqueue_kick(), you can do:
- * if (virtqueue_kick_prepare(vq))
- * virtqueue_notify(vq);
- *
- * This is sometimes useful because the virtqueue_kick_prepare() needs
- * to be serialized, but the actual virtqueue_notify() call does not.
- */
-bool virtqueue_kick_prepare(struct virtqueue *_vq)
+static bool virtqueue_kick_prepare_split(struct virtqueue *_vq)
 {
struct vring_virtqueue *vq = to_vvq(_vq);
u16 new, old;
@@ -579,6 +582,22 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq)
END_USE(vq);
return needs_kick;
 }
+
+/**
+ * 

[PATCH net-next v3 01/13] virtio: add packed ring types and macros

2018-11-21 Thread Tiwei Bie
Add types and macros for packed ring.

Signed-off-by: Tiwei Bie 
---
 include/uapi/linux/virtio_config.h |  3 +++
 include/uapi/linux/virtio_ring.h   | 52 ++
 2 files changed, 55 insertions(+)

diff --git a/include/uapi/linux/virtio_config.h 
b/include/uapi/linux/virtio_config.h
index 449132c76b1c..1196e1c1d4f6 100644
--- a/include/uapi/linux/virtio_config.h
+++ b/include/uapi/linux/virtio_config.h
@@ -75,6 +75,9 @@
  */
 #define VIRTIO_F_IOMMU_PLATFORM33
 
+/* This feature indicates support for the packed virtqueue layout. */
+#define VIRTIO_F_RING_PACKED   34
+
 /*
  * Does the device support Single Root I/O Virtualization?
  */
diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
index 6d5d5faa989b..2414f8af26b3 100644
--- a/include/uapi/linux/virtio_ring.h
+++ b/include/uapi/linux/virtio_ring.h
@@ -44,6 +44,13 @@
 /* This means the buffer contains a list of buffer descriptors. */
 #define VRING_DESC_F_INDIRECT  4
 
+/*
+ * Mark a descriptor as available or used in packed ring.
+ * Notice: they are defined as shifts instead of shifted values.
+ */
+#define VRING_PACKED_DESC_F_AVAIL  7
+#define VRING_PACKED_DESC_F_USED   15
+
 /* The Host uses this in used->flags to advise the Guest: don't kick me when
  * you add a buffer.  It's unreliable, so it's simply an optimization.  Guest
  * will still kick if it's out of buffers. */
@@ -53,6 +60,23 @@
  * optimization.  */
 #define VRING_AVAIL_F_NO_INTERRUPT 1
 
+/* Enable events in packed ring. */
+#define VRING_PACKED_EVENT_FLAG_ENABLE 0x0
+/* Disable events in packed ring. */
+#define VRING_PACKED_EVENT_FLAG_DISABLE0x1
+/*
+ * Enable events for a specific descriptor in packed ring.
+ * (as specified by Descriptor Ring Change Event Offset/Wrap Counter).
+ * Only valid if VIRTIO_RING_F_EVENT_IDX has been negotiated.
+ */
+#define VRING_PACKED_EVENT_FLAG_DESC   0x2
+
+/*
+ * Wrap counter bit shift in event suppression structure
+ * of packed ring.
+ */
+#define VRING_PACKED_EVENT_F_WRAP_CTR  15
+
 /* We support indirect buffer descriptors */
 #define VIRTIO_RING_F_INDIRECT_DESC28
 
@@ -171,4 +195,32 @@ static inline int vring_need_event(__u16 event_idx, __u16 
new_idx, __u16 old)
return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);
 }
 
+struct vring_packed_desc_event {
+   /* Descriptor Ring Change Event Offset/Wrap Counter. */
+   __le16 off_wrap;
+   /* Descriptor Ring Change Event Flags. */
+   __le16 flags;
+};
+
+struct vring_packed_desc {
+   /* Buffer Address. */
+   __le64 addr;
+   /* Buffer Length. */
+   __le32 len;
+   /* Buffer ID. */
+   __le16 id;
+   /* The flags depending on descriptor type. */
+   __le16 flags;
+};
+
+struct vring_packed {
+   unsigned int num;
+
+   struct vring_packed_desc *desc;
+
+   struct vring_packed_desc_event *driver;
+
+   struct vring_packed_desc_event *device;
+};
+
 #endif /* _UAPI_LINUX_VIRTIO_RING_H */
-- 
2.14.5

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH net-next v3 00/13] virtio: support packed ring

2018-11-21 Thread Tiwei Bie
On Wed, Nov 21, 2018 at 07:20:27AM -0500, Michael S. Tsirkin wrote:
> On Wed, Nov 21, 2018 at 06:03:17PM +0800, Tiwei Bie wrote:
> > Hi,
> > 
> > This patch set implements packed ring support in virtio driver.
> > 
> > A performance test between pktgen (pktgen_sample03_burst_single_flow.sh)
> > and DPDK vhost (testpmd/rxonly/vhost-PMD) has been done, I saw
> > ~30% performance gain in packed ring in this case.
> 
> Thanks a lot, this is very exciting!
> Dave, given the holiday, attempts to wrap up the 1.1 spec and the
> patchset size I would very much appreciate a bit more time for
> review. Say until Nov 28?
> 
> > To make this patch set work with below patch set for vhost,
> > some hacks are needed to set the _F_NEXT flag in indirect
> > descriptors (this should be fixed in vhost):
> > 
> > https://lkml.org/lkml/2018/7/3/33
> 
> Could you pls clarify - do you mean it doesn't yet work with vhost
> because of a vhost bug, and to test it with the linked patches
> you had to hack in _F_NEXT? Because I do not see _F_NEXT
> in indirect descriptors in this patch (which is fine).
> Or did I miss it?

You didn't miss anything. :)

I think it's a small bug in vhost, which Jason may fix very
quickly, so I didn't post it. Below is the hack I used:

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index cd7e755484e3..42faea7d8cf8 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -980,6 +980,7 @@ static int virtqueue_add_indirect_packed(struct 
vring_virtqueue *vq,
unsigned int i, n, err_idx;
u16 head, id;
dma_addr_t addr;
+   int c = 0;
 
head = vq->packed.next_avail_idx;
desc = alloc_indirect_packed(total_sg, gfp);
@@ -1001,8 +1002,9 @@ static int virtqueue_add_indirect_packed(struct 
vring_virtqueue *vq,
if (vring_mapping_error(vq, addr))
goto unmap_release;
 
-   desc[i].flags = cpu_to_le16(n < out_sgs ?
-   0 : VRING_DESC_F_WRITE);
+   desc[i].flags = cpu_to_le16((n < out_sgs ?
+   0 : VRING_DESC_F_WRITE) |
+   (++c == total_sg ? 0 : VRING_DESC_F_NEXT));
desc[i].addr = cpu_to_le64(addr);
desc[i].len = cpu_to_le32(sg->length);
i++;
-- 
2.14.1

> 
> > v2 -> v3:
> > - Use leXX instead of virtioXX (MST);
> > - Refactor split ring first (MST);
> > - Add debug helpers (MST);
> > - Put split/packed ring specific fields in sub structures (MST);
> > - Handle normal descriptors and indirect descriptors differently (MST);
> > - Track the DMA addr/len related info in a separate structure (MST);
> > - Calculate AVAIL/USED flags only when wrap counter wraps (MST);
> > - Define a struct/union to read event structure (MST);
> > - Define a macro for wrap counter bit in uapi (MST);
> > - Define the AVAIL/USED bits as shifts instead of values (MST);
> > - s/_F_/_FLAG_/ in VRING_PACKED_EVENT_* as they are values (MST);
> > - Drop the notify workaround for QEMU's tx-timer in packed ring (MST);
> > 
> > v1 -> v2:
> > - Use READ_ONCE() to read event off_wrap and flags together (Jason);
> > - Add comments related to ccw (Jason);
> > 
> > RFC v6 -> v1:
> > - Avoid extra virtio_wmb() in virtqueue_enable_cb_delayed_packed()
> >   when event idx is off (Jason);
> > - Fix bufs calculation in virtqueue_enable_cb_delayed_packed() (Jason);
> > - Test the state of the desc at used_idx instead of last_used_idx
> >   in virtqueue_enable_cb_delayed_packed() (Jason);
> > - Save wrap counter (as part of queue state) in the return value
> >   of virtqueue_enable_cb_prepare_packed();
> > - Refine the packed ring definitions in uapi;
> > - Rebase on the net-next tree;
> > 
> > RFC v5 -> RFC v6:
> > - Avoid tracking addr/len/flags when DMA API isn't used (MST/Jason);
> > - Define wrap counter as bool (Jason);
> > - Use ALIGN() in vring_init_packed() (Jason);
> > - Avoid using pointer to track `next` in detach_buf_packed() (Jason);
> > - Add comments for barriers (Jason);
> > - Don't enable RING_PACKED on ccw for now (noticed by Jason);
> > - Refine the memory barrier in virtqueue_poll();
> > - Add a missing memory barrier in virtqueue_enable_cb_delayed_packed();
> > - Remove the hacks in virtqueue_enable_cb_prepare_packed();
> > 
> > RFC v4 -> RFC v5:
> > - Save DMA addr, etc in desc state (Jason);
> > - Track used wrap counter;
> > 
> > RFC v3 -> RFC v4:
> > - Make ID allocation support out-of-order (Jason);
> > - Various fixes for EVENT_IDX support;
> > 
> > RFC v2 -> RFC v3:
> > - Split into small patches (Jason);
> > - Add helper virtqueue_use_indirect() (Jason);
> > - Just set id for the last descriptor of a list (Jason);
> > - Calculate the prev in virtqueue_add_packed() (Jason);
> > - Fix/improve desc suppression code (Jason/MST);
> > - Refine the code layout for 

[PATCH net-next v3 00/13] virtio: support packed ring

2018-11-21 Thread Tiwei Bie
Hi,

This patch set implements packed ring support in virtio driver.

A performance test between pktgen (pktgen_sample03_burst_single_flow.sh)
and DPDK vhost (testpmd/rxonly/vhost-PMD) has been done, I saw
~30% performance gain in packed ring in this case.

To make this patch set work with below patch set for vhost,
some hacks are needed to set the _F_NEXT flag in indirect
descriptors (this should be fixed in vhost):

https://lkml.org/lkml/2018/7/3/33

v2 -> v3:
- Use leXX instead of virtioXX (MST);
- Refactor split ring first (MST);
- Add debug helpers (MST);
- Put split/packed ring specific fields in sub structures (MST);
- Handle normal descriptors and indirect descriptors differently (MST);
- Track the DMA addr/len related info in a separate structure (MST);
- Calculate AVAIL/USED flags only when wrap counter wraps (MST);
- Define a struct/union to read event structure (MST);
- Define a macro for wrap counter bit in uapi (MST);
- Define the AVAIL/USED bits as shifts instead of values (MST);
- s/_F_/_FLAG_/ in VRING_PACKED_EVENT_* as they are values (MST);
- Drop the notify workaround for QEMU's tx-timer in packed ring (MST);

v1 -> v2:
- Use READ_ONCE() to read event off_wrap and flags together (Jason);
- Add comments related to ccw (Jason);

RFC v6 -> v1:
- Avoid extra virtio_wmb() in virtqueue_enable_cb_delayed_packed()
  when event idx is off (Jason);
- Fix bufs calculation in virtqueue_enable_cb_delayed_packed() (Jason);
- Test the state of the desc at used_idx instead of last_used_idx
  in virtqueue_enable_cb_delayed_packed() (Jason);
- Save wrap counter (as part of queue state) in the return value
  of virtqueue_enable_cb_prepare_packed();
- Refine the packed ring definitions in uapi;
- Rebase on the net-next tree;

RFC v5 -> RFC v6:
- Avoid tracking addr/len/flags when DMA API isn't used (MST/Jason);
- Define wrap counter as bool (Jason);
- Use ALIGN() in vring_init_packed() (Jason);
- Avoid using pointer to track `next` in detach_buf_packed() (Jason);
- Add comments for barriers (Jason);
- Don't enable RING_PACKED on ccw for now (noticed by Jason);
- Refine the memory barrier in virtqueue_poll();
- Add a missing memory barrier in virtqueue_enable_cb_delayed_packed();
- Remove the hacks in virtqueue_enable_cb_prepare_packed();

RFC v4 -> RFC v5:
- Save DMA addr, etc in desc state (Jason);
- Track used wrap counter;

RFC v3 -> RFC v4:
- Make ID allocation support out-of-order (Jason);
- Various fixes for EVENT_IDX support;

RFC v2 -> RFC v3:
- Split into small patches (Jason);
- Add helper virtqueue_use_indirect() (Jason);
- Just set id for the last descriptor of a list (Jason);
- Calculate the prev in virtqueue_add_packed() (Jason);
- Fix/improve desc suppression code (Jason/MST);
- Refine the code layout for XXX_split/packed and wrappers (MST);
- Fix the comments and API in uapi (MST);
- Remove the BUG_ON() for indirect (Jason);
- Some other refinements and bug fixes;

RFC v1 -> RFC v2:
- Add indirect descriptor support - compile test only;
- Add event suppression supprt - compile test only;
- Move vring_packed_init() out of uapi (Jason, MST);
- Merge two loops into one in virtqueue_add_packed() (Jason);
- Split vring_unmap_one() for packed ring and split ring (Jason);
- Avoid using '%' operator (Jason);
- Rename free_head -> next_avail_idx (Jason);
- Add comments for virtio_wmb() in virtqueue_add_packed() (Jason);
- Some other refinements and bug fixes;


Tiwei Bie (13):
  virtio: add packed ring types and macros
  virtio_ring: add _split suffix for split ring functions
  virtio_ring: put split ring functions together
  virtio_ring: put split ring fields in a sub struct
  virtio_ring: introduce debug helpers
  virtio_ring: introduce helper for indirect feature
  virtio_ring: allocate desc state for split ring separately
  virtio_ring: extract split ring handling from ring creation
  virtio_ring: cache whether we will use DMA API
  virtio_ring: introduce packed ring support
  virtio_ring: leverage event idx in packed ring
  virtio_ring: disable packed ring on unsupported transports
  virtio_ring: advertize packed ring layout

 drivers/misc/mic/vop/vop_main.c|   13 +
 drivers/remoteproc/remoteproc_virtio.c |   13 +
 drivers/s390/virtio/virtio_ccw.c   |   14 +
 drivers/virtio/virtio_ring.c   | 1811 +---
 include/uapi/linux/virtio_config.h |3 +
 include/uapi/linux/virtio_ring.h   |   52 +
 6 files changed, 1530 insertions(+), 376 deletions(-)

-- 
2.14.5

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 0/9] drm: remove deprecated functions

2018-11-21 Thread Daniel Vetter
On Thu, Nov 15, 2018 at 11:38:35PM +0100, Linus Walleij wrote:
> On Thu, Nov 15, 2018 at 11:17 PM Fernando Ramos  
> wrote:
> 
> > One of the things in the DRM TODO list ("Documentation/gpu/todo.rst") was to
> > "switch from reference/unreference to get/put". That's what this patch 
> > series is
> > about.
> 
> The series:
> Reviewed-by: Linus Walleij 

Since your reviewed it all, and there's a pile of acks for the driver
parts too: Want to go ahead and apply it too?

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH net-next v3 07/13] virtio_ring: allocate desc state for split ring separately

2018-11-21 Thread Tiwei Bie
Put the split ring's desc state into the .split sub-structure,
and allocate desc state for split ring separately, this makes
the code more readable and more consistent with what we will
do for packed ring.

Signed-off-by: Tiwei Bie 
---
 drivers/virtio/virtio_ring.c | 45 ++--
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index d1076f28c7e9..acd851f3105c 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -78,7 +78,7 @@
 #define LAST_ADD_TIME_INVALID(vq)
 #endif
 
-struct vring_desc_state {
+struct vring_desc_state_split {
void *data; /* Data for callback. */
struct vring_desc *indir_desc;  /* Indirect descriptor, if any. */
 };
@@ -115,6 +115,9 @@ struct vring_virtqueue {
 
/* Last written value to avail->idx in guest byte order */
u16 avail_idx_shadow;
+
+   /* Per-descriptor state. */
+   struct vring_desc_state_split *desc_state;
} split;
 
/* How to notify other side. FIXME: commonalize hcalls! */
@@ -133,9 +136,6 @@ struct vring_virtqueue {
bool last_add_time_valid;
ktime_t last_add_time;
 #endif
-
-   /* Per-descriptor state. */
-   struct vring_desc_state desc_state[];
 };
 
 
@@ -427,11 +427,11 @@ static inline int virtqueue_add_split(struct virtqueue 
*_vq,
vq->free_head = i;
 
/* Store token and indirect buffer state. */
-   vq->desc_state[head].data = data;
+   vq->split.desc_state[head].data = data;
if (indirect)
-   vq->desc_state[head].indir_desc = desc;
+   vq->split.desc_state[head].indir_desc = desc;
else
-   vq->desc_state[head].indir_desc = ctx;
+   vq->split.desc_state[head].indir_desc = ctx;
 
/* Put entry in available array (but don't update avail->idx until they
 * do sync). */
@@ -512,7 +512,7 @@ static void detach_buf_split(struct vring_virtqueue *vq, 
unsigned int head,
__virtio16 nextflag = cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT);
 
/* Clear data ptr. */
-   vq->desc_state[head].data = NULL;
+   vq->split.desc_state[head].data = NULL;
 
/* Put back on free list: unmap first-level descriptors and find end */
i = head;
@@ -532,7 +532,8 @@ static void detach_buf_split(struct vring_virtqueue *vq, 
unsigned int head,
vq->vq.num_free++;
 
if (vq->indirect) {
-   struct vring_desc *indir_desc = vq->desc_state[head].indir_desc;
+   struct vring_desc *indir_desc =
+   vq->split.desc_state[head].indir_desc;
u32 len;
 
/* Free the indirect table, if any, now that it's unmapped. */
@@ -550,9 +551,9 @@ static void detach_buf_split(struct vring_virtqueue *vq, 
unsigned int head,
vring_unmap_one_split(vq, _desc[j]);
 
kfree(indir_desc);
-   vq->desc_state[head].indir_desc = NULL;
+   vq->split.desc_state[head].indir_desc = NULL;
} else if (ctx) {
-   *ctx = vq->desc_state[head].indir_desc;
+   *ctx = vq->split.desc_state[head].indir_desc;
}
 }
 
@@ -597,13 +598,13 @@ static void *virtqueue_get_buf_ctx_split(struct virtqueue 
*_vq,
BAD_RING(vq, "id %u out of range\n", i);
return NULL;
}
-   if (unlikely(!vq->desc_state[i].data)) {
+   if (unlikely(!vq->split.desc_state[i].data)) {
BAD_RING(vq, "id %u is not a head!\n", i);
return NULL;
}
 
/* detach_buf_split clears data, so grab it now. */
-   ret = vq->desc_state[i].data;
+   ret = vq->split.desc_state[i].data;
detach_buf_split(vq, i, ctx);
vq->last_used_idx++;
/* If we expect an interrupt for the next entry, tell host
@@ -711,10 +712,10 @@ static void *virtqueue_detach_unused_buf_split(struct 
virtqueue *_vq)
START_USE(vq);
 
for (i = 0; i < vq->split.vring.num; i++) {
-   if (!vq->desc_state[i].data)
+   if (!vq->split.desc_state[i].data)
continue;
/* detach_buf_split clears data, so grab it now. */
-   buf = vq->desc_state[i].data;
+   buf = vq->split.desc_state[i].data;
detach_buf_split(vq, i, NULL);
vq->split.avail_idx_shadow--;
vq->split.vring.avail->idx = cpu_to_virtio16(_vq->vdev,
@@ -1080,8 +1081,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int 
index,
unsigned int i;
struct vring_virtqueue *vq;
 
-   vq = kmalloc(sizeof(*vq) + vring.num * sizeof(struct vring_desc_state),
-GFP_KERNEL);
+   vq = kmalloc(sizeof(*vq), GFP_KERNEL);
if (!vq)
return NULL;
 

Re: [PATCH v4 2/2] drm/virtio: add edid support

2018-11-21 Thread Gerd Hoffmann
On Tue, Oct 30, 2018 at 10:38:04AM +0100, Daniel Vetter wrote:
> On Tue, Oct 30, 2018 at 07:32:06AM +0100, Gerd Hoffmann wrote:
> > linux guest driver implementation of the VIRTIO_GPU_F_EDID feature.
> > 
> > Signed-off-by: Gerd Hoffmann 
> 
> Like with bochs, I think drm_do_get_edid() here is overkill and fairly
> pointless.

Like with bochs it makes sense to use drm_do_get_edid(), because it
handles edid override and other common stuff.  Not that this should
actually be needed for virtual devices, but I think it still makes sense
for consistency with other drivers, and it might be handy for testing
too.

cheers,
  Gerd

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH -next] drm/cirrus: Remove set but not used variable 'bo'

2018-11-21 Thread Gerd Hoffmann
On Thu, Nov 15, 2018 at 12:10:36PM +, YueHaibing wrote:
> Fixes gcc '-Wunused-but-set-variable' warning:
> 
> drivers/gpu/drm/cirrus/cirrus_fbdev.c: In function 'cirrusfb_create':
> drivers/gpu/drm/cirrus/cirrus_fbdev.c:172:20: warning:
>  variable 'bo' set but not used [-Wunused-but-set-variable]
> 
> It never used since introduction in commit
> f9aa76a85248 ("drm/kms: driver for virtual cirrus under qemu")

queued for -next.

thanks,
  Gerd

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v4 2/2] drm/virtio: add edid support

2018-11-21 Thread Daniel Vetter
On Wed, Nov 21, 2018 at 09:54:22AM +0100, Gerd Hoffmann wrote:
> On Tue, Oct 30, 2018 at 10:38:04AM +0100, Daniel Vetter wrote:
> > On Tue, Oct 30, 2018 at 07:32:06AM +0100, Gerd Hoffmann wrote:
> > > linux guest driver implementation of the VIRTIO_GPU_F_EDID feature.
> > > 
> > > Signed-off-by: Gerd Hoffmann 
> > 
> > Like with bochs, I think drm_do_get_edid() here is overkill and fairly
> > pointless.
> 
> Like with bochs it makes sense to use drm_do_get_edid(), because it
> handles edid override and other common stuff.  Not that this should
> actually be needed for virtual devices, but I think it still makes sense
> for consistency with other drivers, and it might be handy for testing
> too.

Yeah Jani corrected me here, I forgot that we reworked all this quite a
bit. I checked the kerneldoc, it's up-to-date, so all good. Ack: me fwiw.

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization