[PATCH 0/4] comedi: non-contiguous buffer pages changes

From: Ian Abbott
Date: Tue Apr 15 2025 - 07:47:33 EST


This patch series changes the way the Comedi core code accesses the
acquisition buffer contents, so that rather than use an overall, linear
mapping of the whole buffer, it uses existing per-buffer-page pointers.

(@Christoph, I'm mostly interested in your take on calling
`dma_mmap_coherent()` in a loop, as described in the final(-ish)
paragraph, and in patch 4.)

Currently, the buffer is either allocated a page at a time from normal
kernel memory, which is then vmap'ed to a linear address range for
convenience, or it is allocated as a single block from DMA coherent
memory. (The low-level Comedi driver indicates the type of memory to be
used.) In either case, an array of `struct comedi_buf_page` is filled
in with the underlying (non-vmap'ed) addresses of each page (and the
corresponding DMA addresses, and the `prealloc_buf` member of `struct
comedi_async` is set to the overall linear address (from `vmap` or
`dma_alloc_coherent` as appropriate).

For buffers in normal kernel memory, this patch series removes the
vmap'ing of the buffer pages.

For buffers in DMA coherent memory, patch 4 splits the allocation into
page-sized allocations. We used to do that before commit e36472145aa7
("staging: comedi: use dma_mmap_coherent for DMA-able buffer mmap"), but
there was the problem of how to mmap a buffer consisting of
non-contiguous pages of DMA coherent memory. At the time, I considered
calling `dma_mmap_coherent()` in a loop with manipulated `vm_start` and
`vm_end` values (see <https://lkml.org/lkml/2019/6/17/534>), and that is
what patch 4 does. It seems to work (although I've only tested in on
x86_64 so far), and I'm not the only person in the wild to discover this
trick (see <https://stackoverflow.com/a/67220955/5264491>), although I
am not aware of any other use of this trick in the kernel source. The
closest equivalent is the manipulation of the VMA's `vm_pgoff` value
before calling `dma_mmap_coherent()`, for example in the UIO driver.

Patch list:

1) comedi: ni_pcidio: Do not bother filling buffer with 0xaa byte values
2) comedi: access buffer data page-by-page
3) comedi: remove the mapping of the Comedi buffer in vmalloc address space
4) comedi: allocate DMA coherent buffer as individual pages

drivers/comedi/comedi_buf.c | 155 ++++++++++++++-----------------------
drivers/comedi/comedi_fops.c | 120 ++++++++++++++++++++--------
drivers/comedi/drivers/ni_pcidio.c | 2 -
include/linux/comedi/comedidev.h | 10 +--
4 files changed, 144 insertions(+), 143 deletions(-)