Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Ian Abbott and committed by
Greg Kroah-Hartman
5117f28a e7199b6b

+6 -49
+4 -41
drivers/comedi/comedi_buf.c
··· 56 56 struct comedi_buf_map *bm; 57 57 unsigned long flags; 58 58 59 - if (async->prealloc_buf) { 60 - if (s->async_dma_dir == DMA_NONE) 61 - vunmap(async->prealloc_buf); 62 - async->prealloc_buf = NULL; 63 - async->prealloc_bufsz = 0; 64 - } 65 - 59 + async->prealloc_bufsz = 0; 66 60 spin_lock_irqsave(&s->spin_lock, flags); 67 61 bm = async->buf_map; 68 62 async->buf_map = NULL; ··· 135 141 unsigned int n_pages) 136 142 { 137 143 struct comedi_async *async = s->async; 138 - struct page **pages = NULL; 139 144 struct comedi_buf_map *bm; 140 - struct comedi_buf_page *buf; 141 145 unsigned long flags; 142 - unsigned int i; 143 146 144 147 if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) { 145 148 dev_err(dev->class_dev, ··· 151 160 spin_lock_irqsave(&s->spin_lock, flags); 152 161 async->buf_map = bm; 153 162 spin_unlock_irqrestore(&s->spin_lock, flags); 154 - 155 - if (bm->dma_dir != DMA_NONE) { 156 - /* 157 - * DMA buffer was allocated as a single block. 158 - * Address is in page_list[0]. 159 - */ 160 - buf = &bm->page_list[0]; 161 - async->prealloc_buf = buf->virt_addr; 162 - } else { 163 - pages = vmalloc(sizeof(struct page *) * n_pages); 164 - if (!pages) 165 - return; 166 - 167 - for (i = 0; i < n_pages; i++) { 168 - buf = &bm->page_list[i]; 169 - pages[i] = virt_to_page(buf->virt_addr); 170 - } 171 - 172 - /* vmap the pages to prealloc_buf */ 173 - async->prealloc_buf = vmap(pages, n_pages, VM_MAP, 174 - COMEDI_PAGE_PROTECTION); 175 - 176 - vfree(pages); 177 - } 163 + async->prealloc_bufsz = n_pages << PAGE_SHIFT; 178 164 } 179 165 180 166 void comedi_buf_map_get(struct comedi_buf_map *bm) ··· 232 264 new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; 233 265 234 266 /* if no change is required, do nothing */ 235 - if (async->prealloc_buf && async->prealloc_bufsz == new_size) 267 + if (async->prealloc_bufsz == new_size) 236 268 return 0; 237 269 238 270 /* deallocate old buffer */ ··· 243 275 unsigned int n_pages = new_size >> PAGE_SHIFT; 244 276 245 277 __comedi_buf_alloc(dev, s, n_pages); 246 - 247 - if (!async->prealloc_buf) { 248 - /* allocation failed */ 249 - __comedi_buf_free(dev, s); 278 + if (!async->prealloc_bufsz) 250 279 return -ENOMEM; 251 - } 252 280 } 253 - async->prealloc_bufsz = new_size; 254 281 255 282 return 0; 256 283 }
+2 -8
include/linux/comedi/comedidev.h
··· 234 234 * 235 235 * A COMEDI data buffer is allocated as individual pages, either in 236 236 * conventional memory or DMA coherent memory, depending on the attached, 237 - * low-level hardware device. (The buffer pages also get mapped into the 238 - * kernel's contiguous virtual address space pointed to by the 'prealloc_buf' 239 - * member of &struct comedi_async.) 237 + * low-level hardware device. 240 238 * 241 239 * The buffer is normally freed when the COMEDI device is detached from the 242 240 * low-level driver (which may happen due to device removal), but if it happens 243 241 * to be mmapped at the time, the pages cannot be freed until the buffer has 244 - * been munmapped. That is what the reference counter is for. (The virtual 245 - * address space pointed by 'prealloc_buf' is freed when the COMEDI device is 246 - * detached.) 242 + * been munmapped. That is what the reference counter is for. 247 243 */ 248 244 struct comedi_buf_map { 249 245 struct device *dma_hw_dev; ··· 251 255 252 256 /** 253 257 * struct comedi_async - Control data for asynchronous COMEDI commands 254 - * @prealloc_buf: Kernel virtual address of allocated acquisition buffer. 255 258 * @prealloc_bufsz: Buffer size (in bytes). 256 259 * @buf_map: Map of buffer pages. 257 260 * @max_bufsize: Maximum allowed buffer size (in bytes). ··· 339 344 * less than or equal to UINT_MAX). 340 345 */ 341 346 struct comedi_async { 342 - void *prealloc_buf; 343 347 unsigned int prealloc_bufsz; 344 348 struct comedi_buf_map *buf_map; 345 349 unsigned int max_bufsize;