diff options
author | Ian Abbott <abbotti@mev.co.uk> | 2014-09-12 13:04:43 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-09-20 02:36:25 +0400 |
commit | f39f87e9ea944ca07b53d8261ba60bfbf4f097da (patch) | |
tree | b2f8014cd3c9bc232cc49f165f5146eef545520c | |
parent | d5733baf238533e9df41d92948e1ace5e0eae1de (diff) | |
download | linux-f39f87e9ea944ca07b53d8261ba60bfbf4f097da.tar.xz |
staging: comedi: adl_pci9118: don't overallocate DMA buffer
The last parameter of `__get_free_pages()` is log2 (the 'order') of the
number of pages to be allocated. This driver seems to think it is the
linear number of pages, so `pci9118_alloc_dma()` first tries to allocate
16 pages, but only uses 4 of them, setting the buffer size to PAGE_SIZE
multiplied by the 'order'. If the allocation fails, it tries
progressively smaller orders, down to 0. If the allocation at order 0
succeeds, the buffer size is set to 0, which is likely to cause
problems.
Set the buffer size to `PAGE_SIZE` shifted left by the allocation order.
Since the maximum buffer size previously used was 4, start with an
allocation order of 2 instead of 4. Rename the `pages` member of
`struct pci9118_dmabuf` (and the local variable in
`pci9118_alloc_dma()`) to `order` to make it clearer what it is.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/comedi/drivers/adl_pci9118.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 116910401067..6ab9e0a27588 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -208,7 +208,7 @@ struct pci9118_dmabuf { unsigned long hw; /* hardware (bus) address of buffer */ unsigned int size; /* size of dma buffer in bytes */ unsigned int use_size; /* which size we may now use for transfer */ - int pages; /* number of pages in buffer */ + int order; /* log2 number of pages in buffer */ }; struct pci9118_private { @@ -1479,20 +1479,20 @@ static void pci9118_alloc_dma(struct comedi_device *dev) { struct pci9118_private *devpriv = dev->private; struct pci9118_dmabuf *dmabuf; - int pages; + int order; int i; for (i = 0; i < 2; i++) { dmabuf = &devpriv->dmabuf[i]; - for (pages = 4; pages >= 0; pages--) { - dmabuf->virt = __get_free_pages(GFP_KERNEL, pages); + for (order = 2; order >= 0; order--) { + dmabuf->virt = __get_free_pages(GFP_KERNEL, order); if (dmabuf->virt) break; } if (!dmabuf->virt) break; - dmabuf->pages = pages; - dmabuf->size = PAGE_SIZE * pages; + dmabuf->order = order; + dmabuf->size = PAGE_SIZE << order; dmabuf->hw = virt_to_bus((void *)dmabuf->virt); if (i == 0) @@ -1514,7 +1514,7 @@ static void pci9118_free_dma(struct comedi_device *dev) for (i = 0; i < 2; i++) { dmabuf = &devpriv->dmabuf[i]; if (dmabuf->virt) - free_pages(dmabuf->virt, dmabuf->pages); + free_pages(dmabuf->virt, dmabuf->order); } } |