linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] virtio: allow per vq DMA domain
@ 2019-10-29 10:58 Jason Wang
  2019-10-29 10:58 ` [RFC PATCH 1/2] virtio: accept parent as a parameter when allocating virtqueue Jason Wang
  2019-10-29 10:58 ` [RFC PATCH 2/2] virtio: allow query vq parent device Jason Wang
  0 siblings, 2 replies; 3+ messages in thread
From: Jason Wang @ 2019-10-29 10:58 UTC (permalink / raw)
  To: mst, jasowang, virtualization, linux-kernel
  Cc: cunming.liang, zhihong.wang, lingshan.zhu, lulu

We used to have use a single parent for all DMA operations. This tends
to complicate the mdev based hardware virtio datapath offloading which
may not implement the control path over datapath like ctrl vq in the
case of virtio-net.

So this series tries to intorduce per DMA domain by allowing trasnport
to specify the parent device for each virtqueue. Then for the case of
virtio-mdev device, it can hook the DMA ops for control vq back to
itself and then using e.g VA or PA to emulate the control virtqueue
operation.

Vhost-mdev may use similar idea. Note, compiling test only.

Jason Wang (2):
  virtio: accept parent as a parameter when allocating virtqueue
  virtio: allow query vq parent device

 drivers/virtio/virtio_ring.c  | 36 +++++++++++++++++++++++++----------
 include/linux/virtio_config.h |  2 ++
 2 files changed, 28 insertions(+), 10 deletions(-)

-- 
2.19.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [RFC PATCH 1/2] virtio: accept parent as a parameter when allocating virtqueue
  2019-10-29 10:58 [RFC PATCH 0/2] virtio: allow per vq DMA domain Jason Wang
@ 2019-10-29 10:58 ` Jason Wang
  2019-10-29 10:58 ` [RFC PATCH 2/2] virtio: allow query vq parent device Jason Wang
  1 sibling, 0 replies; 3+ messages in thread
From: Jason Wang @ 2019-10-29 10:58 UTC (permalink / raw)
  To: mst, jasowang, virtualization, linux-kernel
  Cc: cunming.liang, zhihong.wang, lingshan.zhu, lulu

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 drivers/virtio/virtio_ring.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index bdc08244a648..51d83f4d7c32 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -269,12 +269,12 @@ size_t virtio_max_dma_size(struct virtio_device *vdev)
 }
 EXPORT_SYMBOL_GPL(virtio_max_dma_size);
 
-static void *vring_alloc_queue(struct virtio_device *vdev, size_t size,
-			      dma_addr_t *dma_handle, gfp_t flag)
+static void *vring_alloc_queue(struct virtio_device *vdev,
+			       struct device *parent, 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);
+		return dma_alloc_coherent(parent, size, dma_handle, flag);
 	} else {
 		void *queue = alloc_pages_exact(PAGE_ALIGN(size), flag);
 
@@ -859,6 +859,7 @@ static struct virtqueue *vring_create_virtqueue_split(
 	dma_addr_t dma_addr;
 	size_t queue_size_in_bytes;
 	struct vring vring;
+	struct device *parent = vdev->dev.parent;
 
 	/* We assume num is a power of 2. */
 	if (num & (num - 1)) {
@@ -868,7 +869,8 @@ static struct virtqueue *vring_create_virtqueue_split(
 
 	/* 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),
+		queue = vring_alloc_queue(vdev, parent,
+					  vring_size(num, vring_align),
 					  &dma_addr,
 					  GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO);
 		if (queue)
@@ -882,7 +884,8 @@ static struct virtqueue *vring_create_virtqueue_split(
 
 	if (!queue) {
 		/* Try to get a single page. You are my only hope! */
-		queue = vring_alloc_queue(vdev, vring_size(num, vring_align),
+		queue = vring_alloc_queue(vdev, parent,
+					  vring_size(num, vring_align),
 					  &dma_addr, GFP_KERNEL|__GFP_ZERO);
 	}
 	if (!queue)
@@ -1569,10 +1572,11 @@ static struct virtqueue *vring_create_virtqueue_packed(
 	dma_addr_t ring_dma_addr, driver_event_dma_addr, device_event_dma_addr;
 	size_t ring_size_in_bytes, event_size_in_bytes;
 	unsigned int i;
+	struct device *parent = vdev->dev.parent;
 
 	ring_size_in_bytes = num * sizeof(struct vring_packed_desc);
 
-	ring = vring_alloc_queue(vdev, ring_size_in_bytes,
+	ring = vring_alloc_queue(vdev, parent, ring_size_in_bytes,
 				 &ring_dma_addr,
 				 GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO);
 	if (!ring)
@@ -1580,13 +1584,13 @@ static struct virtqueue *vring_create_virtqueue_packed(
 
 	event_size_in_bytes = sizeof(struct vring_packed_desc_event);
 
-	driver = vring_alloc_queue(vdev, event_size_in_bytes,
+	driver = vring_alloc_queue(vdev, parent, event_size_in_bytes,
 				   &driver_event_dma_addr,
 				   GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO);
 	if (!driver)
 		goto err_driver;
 
-	device = vring_alloc_queue(vdev, event_size_in_bytes,
+	device = vring_alloc_queue(vdev, parent, event_size_in_bytes,
 				   &device_event_dma_addr,
 				   GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO);
 	if (!device)
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC PATCH 2/2] virtio: allow query vq parent device
  2019-10-29 10:58 [RFC PATCH 0/2] virtio: allow per vq DMA domain Jason Wang
  2019-10-29 10:58 ` [RFC PATCH 1/2] virtio: accept parent as a parameter when allocating virtqueue Jason Wang
@ 2019-10-29 10:58 ` Jason Wang
  1 sibling, 0 replies; 3+ messages in thread
From: Jason Wang @ 2019-10-29 10:58 UTC (permalink / raw)
  To: mst, jasowang, virtualization, linux-kernel
  Cc: cunming.liang, zhihong.wang, lingshan.zhu, lulu

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 drivers/virtio/virtio_ring.c  | 16 ++++++++++++++--
 include/linux/virtio_config.h |  2 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 51d83f4d7c32..ddeef7421d4d 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -183,6 +183,9 @@ struct vring_virtqueue {
 	/* DMA, allocation, and size information */
 	bool we_own_ring;
 
+	/* Parent device for doing DMA */
+	struct device *parent;
+
 #ifdef DEBUG
 	/* They're supposed to lock for us. */
 	unsigned int in_use;
@@ -318,7 +321,7 @@ static void vring_free_queue(struct virtio_device *vdev, size_t size,
  */
 static inline struct device *vring_dma_dev(const struct vring_virtqueue *vq)
 {
-	return vq->vq.vdev->dev.parent;
+	return vq->parent;
 }
 
 /* Map one sg entry. */
@@ -1554,6 +1557,14 @@ static void *virtqueue_detach_unused_buf_packed(struct virtqueue *_vq)
 	return NULL;
 }
 
+static struct device *vring_get_parent(struct virtio_device *vdev, int index)
+{
+	if (vdev->config->get_vq_parent)
+		return vdev->config->get_vq_parent(vdev, index);
+	else
+		return vdev->dev.parent;
+}
+
 static struct virtqueue *vring_create_virtqueue_packed(
 	unsigned int index,
 	unsigned int num,
@@ -1572,7 +1583,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
 	dma_addr_t ring_dma_addr, driver_event_dma_addr, device_event_dma_addr;
 	size_t ring_size_in_bytes, event_size_in_bytes;
 	unsigned int i;
-	struct device *parent = vdev->dev.parent;
+	struct device *parent = vring_get_parent(vdev, index);
 
 	ring_size_in_bytes = num * sizeof(struct vring_packed_desc);
 
@@ -1613,6 +1624,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
 	vq->num_added = 0;
 	vq->packed_ring = true;
 	vq->use_dma_api = vring_use_dma_api(vdev);
+	vq->parent = parent;
 	list_add_tail(&vq->vq.list, &vdev->vqs);
 #ifdef DEBUG
 	vq->in_use = false;
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index bb4cc4910750..a95af83aad9f 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -65,6 +65,7 @@ struct irq_affinity;
  *      the caller can then copy.
  * @set_vq_affinity: set the affinity for a virtqueue (optional).
  * @get_vq_affinity: get the affinity for a virtqueue (optional).
+ * @get_vq_parent: get the parent device for a virtqueue (optional).
  */
 typedef void vq_callback_t(struct virtqueue *);
 struct virtio_config_ops {
@@ -88,6 +89,7 @@ struct virtio_config_ops {
 			       const struct cpumask *cpu_mask);
 	const struct cpumask *(*get_vq_affinity)(struct virtio_device *vdev,
 			int index);
+	struct device *(*get_vq_parent)(struct virtio_device *vdev, int index);
 };
 
 /* If driver didn't advertise the feature, it will never appear. */
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-10-29 10:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-29 10:58 [RFC PATCH 0/2] virtio: allow per vq DMA domain Jason Wang
2019-10-29 10:58 ` [RFC PATCH 1/2] virtio: accept parent as a parameter when allocating virtqueue Jason Wang
2019-10-29 10:58 ` [RFC PATCH 2/2] virtio: allow query vq parent device Jason Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).