Re: [PATCH v2 06/21] platform: goldfish: pipe: Add DMA support to goldfish pipe
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
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
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
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) +