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>
This commit is contained in:
parent
d5733baf23
commit
f39f87e9ea
1 changed files with 7 additions and 7 deletions
|
@ -208,7 +208,7 @@ struct pci9118_dmabuf {
|
||||||
unsigned long hw; /* hardware (bus) address of buffer */
|
unsigned long hw; /* hardware (bus) address of buffer */
|
||||||
unsigned int size; /* size of dma buffer in bytes */
|
unsigned int size; /* size of dma buffer in bytes */
|
||||||
unsigned int use_size; /* which size we may now use for transfer */
|
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 {
|
struct pci9118_private {
|
||||||
|
@ -1479,20 +1479,20 @@ static void pci9118_alloc_dma(struct comedi_device *dev)
|
||||||
{
|
{
|
||||||
struct pci9118_private *devpriv = dev->private;
|
struct pci9118_private *devpriv = dev->private;
|
||||||
struct pci9118_dmabuf *dmabuf;
|
struct pci9118_dmabuf *dmabuf;
|
||||||
int pages;
|
int order;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
dmabuf = &devpriv->dmabuf[i];
|
dmabuf = &devpriv->dmabuf[i];
|
||||||
for (pages = 4; pages >= 0; pages--) {
|
for (order = 2; order >= 0; order--) {
|
||||||
dmabuf->virt = __get_free_pages(GFP_KERNEL, pages);
|
dmabuf->virt = __get_free_pages(GFP_KERNEL, order);
|
||||||
if (dmabuf->virt)
|
if (dmabuf->virt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!dmabuf->virt)
|
if (!dmabuf->virt)
|
||||||
break;
|
break;
|
||||||
dmabuf->pages = pages;
|
dmabuf->order = order;
|
||||||
dmabuf->size = PAGE_SIZE * pages;
|
dmabuf->size = PAGE_SIZE << order;
|
||||||
dmabuf->hw = virt_to_bus((void *)dmabuf->virt);
|
dmabuf->hw = virt_to_bus((void *)dmabuf->virt);
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
|
@ -1514,7 +1514,7 @@ static void pci9118_free_dma(struct comedi_device *dev)
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
dmabuf = &devpriv->dmabuf[i];
|
dmabuf = &devpriv->dmabuf[i];
|
||||||
if (dmabuf->virt)
|
if (dmabuf->virt)
|
||||||
free_pages(dmabuf->virt, dmabuf->pages);
|
free_pages(dmabuf->virt, dmabuf->order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue