Re: [PATCH v2 06/21] platform: goldfish: pipe: Add DMA support to goldfish pipe

2018-09-26 Thread Greg KH
On Wed, Sep 26, 2018 at 04:02:19PM -0700, r...@google.com wrote:
> From: Roman Kiryanov 
> 
> Goldfish DMA is an extension to the pipe device and is designed
> to facilitate high-speed RAM->RAM transfers from guest to host.
> 
> See uapi/linux/goldfish/goldfish_dma.h for more details.
> 
> Signed-off-by: Roman Kiryanov 
> Signed-off-by: Lingfeng Yang 
> ---
> Changes in v2:
>  - Got sign-off from Lingfeng Yang.
>  - Removed the license boilerplate from goldfish_dma.h.
>  - Rebased.

I don't understand this series.  Please start over with 01/XX as your
other patches were all merged.

And I still think you need a better justification for this, given the
many other ways the kernel already has for this feature...

thanks,

greg k-h


Re: [PATCH v2 06/21] platform: goldfish: pipe: Add DMA support to goldfish pipe

2018-09-26 Thread Greg KH
On Wed, Sep 26, 2018 at 04:02:19PM -0700, r...@google.com wrote:
> From: Roman Kiryanov 
> 
> Goldfish DMA is an extension to the pipe device and is designed
> to facilitate high-speed RAM->RAM transfers from guest to host.
> 
> See uapi/linux/goldfish/goldfish_dma.h for more details.
> 
> Signed-off-by: Roman Kiryanov 
> Signed-off-by: Lingfeng Yang 
> ---
> Changes in v2:
>  - Got sign-off from Lingfeng Yang.
>  - Removed the license boilerplate from goldfish_dma.h.
>  - Rebased.

I don't understand this series.  Please start over with 01/XX as your
other patches were all merged.

And I still think you need a better justification for this, given the
many other ways the kernel already has for this feature...

thanks,

greg k-h


[PATCH v2 06/21] platform: goldfish: pipe: Add DMA support to goldfish pipe

2018-09-26 Thread rkir
From: Roman Kiryanov 

Goldfish DMA is an extension to the pipe device and is designed
to facilitate high-speed RAM->RAM transfers from guest to host.

See uapi/linux/goldfish/goldfish_dma.h for more details.

Signed-off-by: Roman Kiryanov 
Signed-off-by: Lingfeng Yang 
---
Changes in v2:
 - Got sign-off from Lingfeng Yang.
 - Removed the license boilerplate from goldfish_dma.h.
 - Rebased.

 drivers/platform/goldfish/goldfish_pipe.c | 312 +-
 .../platform/goldfish/goldfish_pipe_qemu.h|   2 +
 include/uapi/linux/goldfish/goldfish_dma.h|  71 
 3 files changed, 383 insertions(+), 2 deletions(-)
 create mode 100644 include/uapi/linux/goldfish/goldfish_dma.h

diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
index 56665e879e5a..7eb5436d7c35 100644
--- a/drivers/platform/goldfish/goldfish_pipe.c
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -63,21 +63,28 @@
 #include 
 #include 
 #include 
+#include 
 #include "goldfish_pipe_qemu.h"
 
 /*
  * Update this when something changes in the driver's behavior so the host
  * can benefit from knowing it
+ * Notes:
+ * version 2 was an intermediate release and isn't supported anymore.
+ * version 3 is goldfish_pipe_v2 without DMA support.
+ * version 4 (current) is goldfish_pipe_v2 with DMA support.
  */
 enum {
-   PIPE_DRIVER_VERSION = 2,
+   PIPE_DRIVER_VERSION = 4,
PIPE_CURRENT_DEVICE_VERSION = 2
 };
 
 enum {
MAX_BUFFERS_PER_COMMAND = 336,
MAX_SIGNALLED_PIPES = 64,
-   INITIAL_PIPES_CAPACITY = 64
+   INITIAL_PIPES_CAPACITY = 64,
+   DMA_REGION_MIN_SIZE = PAGE_SIZE,
+   DMA_REGION_MAX_SIZE = 256 << 20
 };
 
 struct goldfish_pipe_dev;
@@ -100,6 +107,11 @@ struct goldfish_pipe_command {
/* buffer sizes, guest -> host */
u32 sizes[MAX_BUFFERS_PER_COMMAND];
} rw_params;
+   /* Parameters for PIPE_CMD_DMA_HOST_(UN)MAP */
+   struct {
+   u64 dma_paddr;
+   u64 sz;
+   } dma_maphost_params;
};
 };
 
@@ -122,6 +134,24 @@ struct goldfish_pipe_dev_buffers {
signalled_pipe_buffers[MAX_SIGNALLED_PIPES];
 };
 
+/*
+ * The main data structure tracking state is
+ * struct goldfish_dma_context, which is included
+ * as an extra pointer field in struct goldfish_pipe.
+ * Each such context is associated with possibly
+ * one physical address and size describing the
+ * allocated DMA region, and only one allocation
+ * is allowed for each pipe fd. Further allocations
+ * require more open()'s of pipe fd's.
+ */
+struct goldfish_dma_context {
+   struct device *pdev_dev;/* pointer to feed to dma_*_coherent */
+   void *dma_vaddr;/* kernel vaddr of dma region */
+   size_t dma_size;/* size of dma region */
+   dma_addr_t phys_begin;  /* paddr of dma region */
+   dma_addr_t phys_end;/* paddr of dma region + dma_size */
+};
+
 /* This data type models a given pipe instance */
 struct goldfish_pipe {
/* pipe ID - index into goldfish_pipe_dev::pipes array */
@@ -162,6 +192,9 @@ struct goldfish_pipe {
 
/* A buffer of pages, too large to fit into a stack frame */
struct page *pages[MAX_BUFFERS_PER_COMMAND];
+
+   /* Holds information about reserved DMA region for this pipe */
+   struct goldfish_dma_context *dma;
 };
 
 /* The global driver data. Holds a reference to the i/o page used to
@@ -208,6 +241,9 @@ struct goldfish_pipe_dev {
int irq;
int version;
unsigned char __iomem *base;
+
+   /* DMA info */
+   size_t dma_alloc_total;
 };
 
 static struct goldfish_pipe_dev goldfish_pipe_dev;
@@ -739,6 +775,8 @@ static int goldfish_pipe_open(struct inode *inode, struct 
file *file)
spin_unlock_irqrestore(>lock, flags);
if (status < 0)
goto err_cmd;
+   pipe->dma = NULL;
+
/* All is done, save the pipe into the file's private data field */
file->private_data = pipe;
return 0;
@@ -754,6 +792,40 @@ static int goldfish_pipe_open(struct inode *inode, struct 
file *file)
return status;
 }
 
+static void goldfish_pipe_dma_release_host(struct goldfish_pipe *pipe)
+{
+   struct goldfish_dma_context *dma = pipe->dma;
+   struct device *pdev_dev;
+
+   if (!dma)
+   return;
+
+   pdev_dev = pipe->dev->pdev_dev;
+
+   if (dma->dma_vaddr) {
+   pipe->command_buffer->dma_maphost_params.dma_paddr =
+   dma->phys_begin;
+   pipe->command_buffer->dma_maphost_params.sz = dma->dma_size;
+   goldfish_pipe_cmd(pipe, PIPE_CMD_DMA_HOST_UNMAP);
+   }
+}
+
+static void goldfish_pipe_dma_release_guest(struct goldfish_pipe *pipe)
+{
+   struct goldfish_dma_context *dma = pipe->dma;
+
+   if (!dma)
+   

[PATCH v2 06/21] platform: goldfish: pipe: Add DMA support to goldfish pipe

2018-09-26 Thread rkir
From: Roman Kiryanov 

Goldfish DMA is an extension to the pipe device and is designed
to facilitate high-speed RAM->RAM transfers from guest to host.

See uapi/linux/goldfish/goldfish_dma.h for more details.

Signed-off-by: Roman Kiryanov 
Signed-off-by: Lingfeng Yang 
---
Changes in v2:
 - Got sign-off from Lingfeng Yang.
 - Removed the license boilerplate from goldfish_dma.h.
 - Rebased.

 drivers/platform/goldfish/goldfish_pipe.c | 312 +-
 .../platform/goldfish/goldfish_pipe_qemu.h|   2 +
 include/uapi/linux/goldfish/goldfish_dma.h|  71 
 3 files changed, 383 insertions(+), 2 deletions(-)
 create mode 100644 include/uapi/linux/goldfish/goldfish_dma.h

diff --git a/drivers/platform/goldfish/goldfish_pipe.c 
b/drivers/platform/goldfish/goldfish_pipe.c
index 56665e879e5a..7eb5436d7c35 100644
--- a/drivers/platform/goldfish/goldfish_pipe.c
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -63,21 +63,28 @@
 #include 
 #include 
 #include 
+#include 
 #include "goldfish_pipe_qemu.h"
 
 /*
  * Update this when something changes in the driver's behavior so the host
  * can benefit from knowing it
+ * Notes:
+ * version 2 was an intermediate release and isn't supported anymore.
+ * version 3 is goldfish_pipe_v2 without DMA support.
+ * version 4 (current) is goldfish_pipe_v2 with DMA support.
  */
 enum {
-   PIPE_DRIVER_VERSION = 2,
+   PIPE_DRIVER_VERSION = 4,
PIPE_CURRENT_DEVICE_VERSION = 2
 };
 
 enum {
MAX_BUFFERS_PER_COMMAND = 336,
MAX_SIGNALLED_PIPES = 64,
-   INITIAL_PIPES_CAPACITY = 64
+   INITIAL_PIPES_CAPACITY = 64,
+   DMA_REGION_MIN_SIZE = PAGE_SIZE,
+   DMA_REGION_MAX_SIZE = 256 << 20
 };
 
 struct goldfish_pipe_dev;
@@ -100,6 +107,11 @@ struct goldfish_pipe_command {
/* buffer sizes, guest -> host */
u32 sizes[MAX_BUFFERS_PER_COMMAND];
} rw_params;
+   /* Parameters for PIPE_CMD_DMA_HOST_(UN)MAP */
+   struct {
+   u64 dma_paddr;
+   u64 sz;
+   } dma_maphost_params;
};
 };
 
@@ -122,6 +134,24 @@ struct goldfish_pipe_dev_buffers {
signalled_pipe_buffers[MAX_SIGNALLED_PIPES];
 };
 
+/*
+ * The main data structure tracking state is
+ * struct goldfish_dma_context, which is included
+ * as an extra pointer field in struct goldfish_pipe.
+ * Each such context is associated with possibly
+ * one physical address and size describing the
+ * allocated DMA region, and only one allocation
+ * is allowed for each pipe fd. Further allocations
+ * require more open()'s of pipe fd's.
+ */
+struct goldfish_dma_context {
+   struct device *pdev_dev;/* pointer to feed to dma_*_coherent */
+   void *dma_vaddr;/* kernel vaddr of dma region */
+   size_t dma_size;/* size of dma region */
+   dma_addr_t phys_begin;  /* paddr of dma region */
+   dma_addr_t phys_end;/* paddr of dma region + dma_size */
+};
+
 /* This data type models a given pipe instance */
 struct goldfish_pipe {
/* pipe ID - index into goldfish_pipe_dev::pipes array */
@@ -162,6 +192,9 @@ struct goldfish_pipe {
 
/* A buffer of pages, too large to fit into a stack frame */
struct page *pages[MAX_BUFFERS_PER_COMMAND];
+
+   /* Holds information about reserved DMA region for this pipe */
+   struct goldfish_dma_context *dma;
 };
 
 /* The global driver data. Holds a reference to the i/o page used to
@@ -208,6 +241,9 @@ struct goldfish_pipe_dev {
int irq;
int version;
unsigned char __iomem *base;
+
+   /* DMA info */
+   size_t dma_alloc_total;
 };
 
 static struct goldfish_pipe_dev goldfish_pipe_dev;
@@ -739,6 +775,8 @@ static int goldfish_pipe_open(struct inode *inode, struct 
file *file)
spin_unlock_irqrestore(>lock, flags);
if (status < 0)
goto err_cmd;
+   pipe->dma = NULL;
+
/* All is done, save the pipe into the file's private data field */
file->private_data = pipe;
return 0;
@@ -754,6 +792,40 @@ static int goldfish_pipe_open(struct inode *inode, struct 
file *file)
return status;
 }
 
+static void goldfish_pipe_dma_release_host(struct goldfish_pipe *pipe)
+{
+   struct goldfish_dma_context *dma = pipe->dma;
+   struct device *pdev_dev;
+
+   if (!dma)
+   return;
+
+   pdev_dev = pipe->dev->pdev_dev;
+
+   if (dma->dma_vaddr) {
+   pipe->command_buffer->dma_maphost_params.dma_paddr =
+   dma->phys_begin;
+   pipe->command_buffer->dma_maphost_params.sz = dma->dma_size;
+   goldfish_pipe_cmd(pipe, PIPE_CMD_DMA_HOST_UNMAP);
+   }
+}
+
+static void goldfish_pipe_dma_release_guest(struct goldfish_pipe *pipe)
+{
+   struct goldfish_dma_context *dma = pipe->dma;
+
+   if (!dma)
+