comedi: remove the mapping of the Comedi buffer in vmalloc address space

Now that all the code that accesses the Comedi buffer data does so
page-by-page, using the `virt_addr` member of `struct comedi_buf_page`
to point to the data of each page, do not linearly map the buffer into
vmalloc address space (pointed to by the `prealloc_buf` member of
`struct comedi_async`).  That was only done for convenience, but was not
done for those drivers that need a DMA coherent buffer, which is
allocated in a single chunk.  Remove the `prealloc_buf` member as it is
no longer used.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://lore.kernel.org/r/20250415114008.5977-4-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Ian Abbott
2025-04-15 12:35:58 +01:00
committed by Greg Kroah-Hartman
parent e7199b6b59
commit 5117f28a7d
2 changed files with 6 additions and 49 deletions

View File

@@ -56,13 +56,7 @@ static void __comedi_buf_free(struct comedi_device *dev,
struct comedi_buf_map *bm;
unsigned long flags;
if (async->prealloc_buf) {
if (s->async_dma_dir == DMA_NONE)
vunmap(async->prealloc_buf);
async->prealloc_buf = NULL;
async->prealloc_bufsz = 0;
}
async->prealloc_bufsz = 0;
spin_lock_irqsave(&s->spin_lock, flags);
bm = async->buf_map;
async->buf_map = NULL;
@@ -141,11 +135,8 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
unsigned int n_pages)
{
struct comedi_async *async = s->async;
struct page **pages = NULL;
struct comedi_buf_map *bm;
struct comedi_buf_page *buf;
unsigned long flags;
unsigned int i;
if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
dev_err(dev->class_dev,
@@ -160,30 +151,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
spin_lock_irqsave(&s->spin_lock, flags);
async->buf_map = bm;
spin_unlock_irqrestore(&s->spin_lock, flags);
if (bm->dma_dir != DMA_NONE) {
/*
* DMA buffer was allocated as a single block.
* Address is in page_list[0].
*/
buf = &bm->page_list[0];
async->prealloc_buf = buf->virt_addr;
} else {
pages = vmalloc(sizeof(struct page *) * n_pages);
if (!pages)
return;
for (i = 0; i < n_pages; i++) {
buf = &bm->page_list[i];
pages[i] = virt_to_page(buf->virt_addr);
}
/* vmap the pages to prealloc_buf */
async->prealloc_buf = vmap(pages, n_pages, VM_MAP,
COMEDI_PAGE_PROTECTION);
vfree(pages);
}
async->prealloc_bufsz = n_pages << PAGE_SHIFT;
}
void comedi_buf_map_get(struct comedi_buf_map *bm)
@@ -264,7 +232,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
/* if no change is required, do nothing */
if (async->prealloc_buf && async->prealloc_bufsz == new_size)
if (async->prealloc_bufsz == new_size)
return 0;
/* deallocate old buffer */
@@ -275,14 +243,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int n_pages = new_size >> PAGE_SHIFT;
__comedi_buf_alloc(dev, s, n_pages);
if (!async->prealloc_buf) {
/* allocation failed */
__comedi_buf_free(dev, s);
if (!async->prealloc_bufsz)
return -ENOMEM;
}
}
async->prealloc_bufsz = new_size;
return 0;
}

View File

@@ -234,16 +234,12 @@ struct comedi_buf_page {
*
* A COMEDI data buffer is allocated as individual pages, either in
* conventional memory or DMA coherent memory, depending on the attached,
* low-level hardware device. (The buffer pages also get mapped into the
* kernel's contiguous virtual address space pointed to by the 'prealloc_buf'
* member of &struct comedi_async.)
* low-level hardware device.
*
* The buffer is normally freed when the COMEDI device is detached from the
* low-level driver (which may happen due to device removal), but if it happens
* to be mmapped at the time, the pages cannot be freed until the buffer has
* been munmapped. That is what the reference counter is for. (The virtual
* address space pointed by 'prealloc_buf' is freed when the COMEDI device is
* detached.)
* been munmapped. That is what the reference counter is for.
*/
struct comedi_buf_map {
struct device *dma_hw_dev;
@@ -255,7 +251,6 @@ struct comedi_buf_map {
/**
* struct comedi_async - Control data for asynchronous COMEDI commands
* @prealloc_buf: Kernel virtual address of allocated acquisition buffer.
* @prealloc_bufsz: Buffer size (in bytes).
* @buf_map: Map of buffer pages.
* @max_bufsize: Maximum allowed buffer size (in bytes).
@@ -344,7 +339,6 @@ struct comedi_buf_map {
* less than or equal to UINT_MAX).
*/
struct comedi_async {
void *prealloc_buf;
unsigned int prealloc_bufsz;
struct comedi_buf_map *buf_map;
unsigned int max_bufsize;