From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Konrad Rzeszutek Wilk <konrad@darnok.org>
Cc: Sander Eikelenboom <linux@eikelenboom.it>,
xen-devel <xen-devel@lists.xensource.com>,
Jan Beulich <JBeulich@suse.com>
Subject: Re: Load increase after memory upgrade (part2)
Date: Mon, 23 Jan 2012 17:32:13 -0500 [thread overview]
Message-ID: <20120123223213.GA31929@phenom.dumpdata.com> (raw)
In-Reply-To: <20120118142923.GA6052@andromeda.dapyr.net>
[-- Attachment #1: Type: text/plain, Size: 1974 bytes --]
On Wed, Jan 18, 2012 at 10:29:23AM -0400, Konrad Rzeszutek Wilk wrote:
> On Wed, Jan 18, 2012 at 11:35:35AM +0000, Jan Beulich wrote:
> > >>> On 17.01.12 at 22:02, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> wrote:
> > > The issue as I understand is that the DVB drivers allocate their buffers
> > > from 0->4GB most (all the time?) so they never have to do bounce-buffering.
> > >
> > > While the pv-ops one ends up quite frequently doing the bounce-buffering,
> > > which
> > > implies that the DVB drivers end up allocating their buffers above the 4GB.
> > > This means we end up spending some CPU time (in the guest) copying the
> > > memory
> > > from >4GB to 0-4GB region (And vice-versa).
> >
> > This reminds me of something (not sure what XenoLinux you use for
> > comparison) - how are they allocating that memory? Not vmalloc_32()
>
> I was using the 2.6.18, then the one I saw on Google for Gentoo, and now
> I am going to look at the 2.6.38 from OpenSuSE.
>
> > by chance (I remember having seen numerous uses under - iirc -
> > drivers/media/)?
> >
> > Obviously, vmalloc_32() and any GFP_DMA32 allocations do *not* do
> > what their (driver) callers might expect in a PV guest (including the
> > contiguity assumption for the latter, recalling that you earlier said
> > you were able to see the problem after several guest starts), and I
> > had put into our kernels an adjustment to make vmalloc_32() actually
> > behave as expected.
>
> Aaah.. The plot thickens! Let me look in the sources! Thanks for the
> pointer.
Jan hints lead me to the videobuf-dma-sg.c which does indeed to vmalloc_32
and then performs PCI DMA operations on the allocted vmalloc_32
area.
So I cobbled up the attached patch (hadn't actually tested it and sadly
won't until next week) which removes the call to vmalloc_32 and instead
sets up DMA allocated set of pages.
If that fixes it for you that is awesome, but if it breaks please
send me your logs.
Cheers,
Konrad
[-- Attachment #2: vmalloc --]
[-- Type: text/plain, Size: 3726 bytes --]
commit 0b5428f4a22be4855b5f03aa1369f9e30e095014
Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Mon Jan 23 15:52:01 2012 -0500
vmalloc_sg: make sure all pages in vmalloc area are really DMA-ready
Under Xen, vmalloc_32() isn't guaranteed to return pages which are really
under 4G in machine physical addresses (only in virtual pseudo-physical
addresses). To work around this, implement a vmalloc variant which
allocates each page with dma_alloc_coherent() to guarantee that each
page is suitable for the device in question.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index f300dea..3da2428 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -211,13 +211,36 @@ EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
int nr_pages)
{
+ int i;
+
dprintk(1, "init kernel [%d pages]\n", nr_pages);
dma->direction = direction;
- dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
+ dma->vaddr_pages = kcalloc(nr_pages, sizeof(*dma->vaddr_pages),
+ GFP_KERNEL);
+ if (!dma->vaddr_pages)
+ return -ENOMEM;
+
+ dma->dma_addr = kcalloc(nr_pages, sizeof(*dma->dma_addr), GFP_KERNEL);
+ if (!dma->dma_addr) {
+ kfree(dma->vaddr_pages);
+ return -ENOMEM;
+ }
+ for (i = 0; i < nr_pages; i++) {
+ void *addr;
+
+ addr = dma_alloc_coherent(dma->dev, PAGE_SIZE,
+ &(dma->dma_addr[i]), GFP_KERNEL);
+ if (addr == NULL)
+ goto out_free_pages;
+
+ dma->vaddr_pages[i] = virt_to_page(addr);
+ }
+ dma->vaddr = vmap(dma->vaddr_pages, nr_pages, VM_MAP | VM_IOREMAP,
+ PAGE_KERNEL);
if (NULL == dma->vaddr) {
dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
- return -ENOMEM;
+ goto out_free_pages;
}
dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
@@ -228,6 +251,18 @@ int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
dma->nr_pages = nr_pages;
return 0;
+out_free_pages:
+ while (i > 0) {
+ void *addr = page_address(dma->vaddr_pages[i]);
+ dma_free_coherent(dma->dev, PAGE_SIZE, addr, dma->dma_addr[i]);
+ i--;
+ }
+ kfree(dma->dma_addr);
+ dma->dma_addr = NULL;
+ kfree(dma->vaddr_pages);
+ dma->vaddr_pages = NULL;
+
+ return -ENOMEM;
}
EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
@@ -322,8 +357,21 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
dma->pages = NULL;
}
- vfree(dma->vaddr);
- dma->vaddr = NULL;
+ if (dma->dma_addr) {
+ for (i = 0; i < dma->nr_pages; i++) {
+ void *addr;
+
+ addr = page_address(dma->vaddr_pages[i]);
+ dma_free_coherent(dma->dev, PAGE_SIZE, addr,
+ dma->dma_addr[i]);
+ }
+ kfree(dma->dma_addr);
+ dma->dma_addr = NULL;
+ kfree(dma->vaddr_pages);
+ dma->vaddr_pages = NULL;
+ vunmap(dma->vaddr);
+ dma->vaddr = NULL;
+ }
if (dma->bus_addr)
dma->bus_addr = 0;
@@ -461,6 +509,11 @@ static int __videobuf_iolock(struct videobuf_queue *q,
MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
+ if (!mem->dma.dev)
+ mem->dma.dev = q->dev;
+ else
+ WARN_ON(mem->dma.dev != q->dev);
+
switch (vb->memory) {
case V4L2_MEMORY_MMAP:
case V4L2_MEMORY_USERPTR:
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h
index d8fb601..870cb21 100644
--- a/include/media/videobuf-dma-sg.h
+++ b/include/media/videobuf-dma-sg.h
@@ -53,6 +53,9 @@ struct videobuf_dmabuf {
/* for kernel buffers */
void *vaddr;
+ struct page **vaddr_pages;
+ dma_addr_t *dma_addr;
+ struct device *dev;
/* for overlay buffers (pci-pci dma) */
dma_addr_t bus_addr;
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next prev parent reply other threads:[~2012-01-23 22:32 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-24 12:28 Load increase after memory upgrade (part2) Carsten Schiers
2011-11-25 18:42 ` Konrad Rzeszutek Wilk
2011-11-25 22:11 ` Carsten Schiers
2011-11-28 15:28 ` Konrad Rzeszutek Wilk
2011-11-28 15:40 ` Ian Campbell
2011-11-28 16:45 ` Konrad Rzeszutek Wilk
2011-11-29 8:31 ` Jan Beulich
2011-11-29 9:31 ` Carsten Schiers
2011-11-29 9:46 ` Carsten Schiers
2011-11-29 10:23 ` Ian Campbell
2011-11-29 15:33 ` Konrad Rzeszutek Wilk
2011-12-02 15:23 ` Konrad Rzeszutek Wilk
2011-12-04 11:59 ` Carsten Schiers
2011-12-04 12:09 ` Carsten Schiers
2011-12-06 3:26 ` Konrad Rzeszutek Wilk
2011-12-14 20:23 ` Konrad Rzeszutek Wilk
2011-12-14 22:07 ` Konrad Rzeszutek Wilk
2011-12-15 14:52 ` Carsten Schiers
2011-12-16 14:56 ` Carsten Schiers
2011-12-16 15:04 ` Konrad Rzeszutek Wilk
2011-12-16 15:51 ` Carsten Schiers
2011-12-16 16:19 ` Konrad Rzeszutek Wilk
2011-12-17 22:12 ` Carsten Schiers
2011-12-18 0:19 ` Sander Eikelenboom
2011-12-19 14:56 ` Konrad Rzeszutek Wilk
2012-01-10 21:55 ` Konrad Rzeszutek Wilk
2012-01-12 22:06 ` Sander Eikelenboom
2012-01-13 8:12 ` Jan Beulich
2012-01-13 15:13 ` Konrad Rzeszutek Wilk
2012-01-15 11:32 ` Sander Eikelenboom
2012-01-17 21:02 ` Konrad Rzeszutek Wilk
2012-01-18 11:28 ` Pasi Kärkkäinen
2012-01-18 11:39 ` Jan Beulich
2012-01-18 11:35 ` Jan Beulich
2012-01-18 14:29 ` Konrad Rzeszutek Wilk
2012-01-23 22:32 ` Konrad Rzeszutek Wilk [this message]
2012-01-24 8:58 ` Jan Beulich
2012-01-24 14:17 ` Konrad Rzeszutek Wilk
2012-01-24 21:32 ` Carsten Schiers
2012-01-25 12:02 ` Carsten Schiers
2012-01-25 19:06 ` Carsten Schiers
2012-01-25 21:02 ` Konrad Rzeszutek Wilk
2012-02-15 19:28 ` Konrad Rzeszutek Wilk
2012-02-16 8:56 ` Jan Beulich
2012-02-17 15:07 ` Konrad Rzeszutek Wilk
2012-02-28 14:35 ` Carsten Schiers
2012-02-29 12:10 ` Carsten Schiers
2012-02-29 12:56 ` Carsten Schiers
2012-05-11 9:39 ` Carsten Schiers
2012-05-11 19:41 ` Konrad Rzeszutek Wilk
2012-06-13 16:55 ` Konrad Rzeszutek Wilk
2012-06-14 7:07 ` Jan Beulich
2012-06-14 18:33 ` Konrad Rzeszutek Wilk
2012-06-14 18:43 ` Carsten Schiers
2012-06-14 8:38 ` David Vrabel
2012-06-14 18:31 ` Konrad Rzeszutek Wilk
2012-06-14 18:40 ` Carsten Schiers
2012-06-14 19:16 ` Carsten Schiers
2011-12-19 14:54 ` Konrad Rzeszutek Wilk
2011-12-04 12:18 ` Carsten Schiers
2011-11-28 16:58 ` Laszlo Ersek
2011-11-29 9:37 ` Carsten Schiers
2011-11-28 15:52 ` Carsten Schiers
2011-11-26 9:14 ` Carsten Schiers
2011-11-28 15:30 ` Konrad Rzeszutek Wilk
2011-11-29 9:42 ` Carsten Schiers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120123223213.GA31929@phenom.dumpdata.com \
--to=konrad.wilk@oracle.com \
--cc=JBeulich@suse.com \
--cc=konrad@darnok.org \
--cc=linux@eikelenboom.it \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).