History

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.

Ian Abbott committed 1 year ago

Commit 5117f281 parent e7199b62 files · +6 −49Browse files

Unified · Split

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