mm: improve remapping of vmalloc regions
Subsystems (7)
cover mm: improve remapping of vmalloc regions
Hi,
I'd like some feedback about this patchset -- whether it is the right design, and the implementation (e.g. people might dislike patch 4).
vm_insert_page and remap_pfn_range loops are really clever, bit probably asking a bit too much of most drivers. I was able to get rid of most of them without too much trouble.
Not tested, because I don't have any of the hardware, but it seems compiles OK.
Nick
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/5 mm: remap_vmalloc_range
Add a remap_vmalloc_range and get rid of as many remap_pfn_range and vm_insert_page loops as possible.
remap_vmalloc_range can do a whole lot of nice range checking even if the caller gets it wrong (which it looks like one or two do).
drivers/media/video/cpia.c +3 -15
@@ -3750,9 +3750,7 @@ static int cpia_ioctl(struct inode *inodstatic int cpia_mmap (struct file *file,struct vm_area_struct *vma) {struct video_device *dev = file->private_data; -unsigned long start = vma->vm_start;unsigned long size = vma->vm_end - vma->vm_start; -unsigned long page, pos;struct cam_data *cam = dev->priv;int retval;
@@ -3778,19 +3776,9 @@ static int cpia_mmap(struct file *file, } } - pos = (unsigned long )(cam->frame_buf); -while (size >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page,PAGE_SIZE ,PAGE_SHARED )) { -mutex_unlock (&cam->busy_lock); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; -if (size >PAGE_SIZE ) - size -=PAGE_SIZE ; -else - size =0 ; +if (remap_vmalloc_range (vma, cam->frame_buf,0 )) { +mutex_unlock (&cam->busy_lock); +return -EAGAIN ; }DBG ("cpia_mmap: %ld\n" , size);
drivers/media/video/meye.c +4 -17
@@ -1699,13 +1699,10 @@ static struct vm_operations_struct meye_static int meye_mmap (struct file *file,struct vm_area_struct *vma) { -unsigned long start = vma->vm_start;unsigned long size = vma->vm_end - vma->vm_start; -unsigned long offset = vma->vm_pgoff <<PAGE_SHIFT ; -unsigned long page, pos;mutex_lock (&meye.lock); -if (size > gbuffers * gbufsize) { +if (size > gbuffers * gbufsize) {/* XXX: should be size + vm_pgoff? */ mutex_unlock (&meye.lock);return -EINVAL ; }
@@ -1722,20 +1719,10 @@ static int meye_mmap(struct file *file,for (i =0 ; i < gbuffers; i++) meye.vma_use_count[i] =0 ; } - pos = (unsigned long )meye.grab_fbuffer + offset; -while (size >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page,PAGE_SIZE ,PAGE_SHARED )) { -mutex_unlock (&meye.lock); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; -if (size >PAGE_SIZE ) - size -=PAGE_SIZE ; -else - size =0 ; +if (remap_vmalloc_range (vma, meye.grab_fbuffer, vma->vm_pgoff)) { +mutex_unlock (&meye.lock); +return -EAGAIN ; } vma->vm_ops = &meye_vm_ops;
drivers/media/video/ov511.c +3 -15
@@ -4616,10 +4616,8 @@ static int ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) { struct video_device *vdev = file->private_data; -unsigned long start = vma->vm_start;unsigned long size = vma->vm_end - vma->vm_start;struct usb_ov511 *ov =video_get_drvdata (vdev); -unsigned long page, pos;if (ov->dev ==NULL )return -EIO ;
@@ -4634,19 +4632,9 @@ ov51x_v4l1_mmap(struct file *file, strucif (mutex_lock_interruptible (&ov->lock))return -EINTR ; - pos = (unsigned long )ov->fbuf; -while (size >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page,PAGE_SIZE ,PAGE_SHARED )) { -mutex_unlock (&ov->lock); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; -if (size >PAGE_SIZE ) - size -=PAGE_SIZE ; -else - size =0 ; +if (remap_vmalloc_range (vma, ov->fbuf,0 )) { +mutex_unlock (&ov->lock); +return -EAGAIN ; }mutex_unlock (&ov->lock);
drivers/media/video/pwc/pwc-if.c +5 -17
@@ -1602,28 +1602,16 @@ static int pwc_video_mmap(struct file *f {struct video_device *vdev = file->private_data;struct pwc_device *pdev; -unsigned long start = vma->vm_start; -unsigned long size = vma->vm_end-vma->vm_start; -unsigned long page, pos; -Trace (TRACE_MEMORY ,"mmap(0x%p, 0x%lx, %lu) called.\n" , vdev, start, size); +/* XXX: should check ranges */ +Trace (TRACE_MEMORY ,"mmap(0x%p, 0x%lx, %lu) called.\n" , vdev, + vma->vm_start, vma->vm_end - vma->vm_start); pdev = vdev->priv; vma->vm_flags |=VM_IO ; - pos = (unsigned long )pdev->image_data; -while (size >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page,PAGE_SIZE ,PAGE_SHARED )) -return -EAGAIN ; - - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; -if (size >PAGE_SIZE ) - size -=PAGE_SIZE ; -else - size =0 ; - } +if (remap_vmalloc_range (vma, pdev->image_data,0 )) +return -EAGAIN ;return 0 ; }
drivers/media/video/se401.c +3 -15
@@ -1153,9 +1153,7 @@ static int se401_mmap(struct file *file, {struct video_device *dev = file->private_data;struct usb_se401 *se401 = (struct usb_se401 *)dev; -unsigned long start = vma->vm_start;unsigned long size = vma->vm_end-vma->vm_start; -unsigned long page, pos;mutex_lock (&se401->lock);
@@ -1167,19 +1165,9 @@ static int se401_mmap(struct file *file,mutex_unlock (&se401->lock);return -EINVAL ; } - pos = (unsigned long )se401->fbuf; -while (size >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page,PAGE_SIZE ,PAGE_SHARED )) { -mutex_unlock (&se401->lock); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; -if (size >PAGE_SIZE ) - size -=PAGE_SIZE ; -else - size =0 ; +if (remap_vmalloc_range (vma, se401->fbuf,0 )) { +mutex_unlock (&se401->lock); +return -EAGAIN ; }mutex_unlock (&se401->lock);
drivers/media/video/stv680.c +3 -15
@@ -1254,9 +1254,7 @@ static int stv680_mmap (struct file *fil {struct video_device *dev = file->private_data;struct usb_stv *stv680 =video_get_drvdata (dev); -unsigned long start = vma->vm_start;unsigned long size = vma->vm_end-vma->vm_start; -unsigned long page, pos;mutex_lock (&stv680->lock);
@@ -1269,19 +1267,9 @@ static int stv680_mmap (struct file *filmutex_unlock (&stv680->lock);return -EINVAL ; } - pos = (unsigned long ) stv680->fbuf; -while (size >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page,PAGE_SIZE ,PAGE_SHARED )) { -mutex_unlock (&stv680->lock); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; -if (size >PAGE_SIZE ) - size -=PAGE_SIZE ; -else - size =0 ; +if (remap_vmalloc_range (vma, stv680->fbuf,0 )) { +mutex_unlock (&stv680->lock); +return -EAGAIN ; }mutex_unlock (&stv680->lock);
drivers/media/video/usbvideo/usbvideo.c +2 -15
@@ -1068,9 +1068,7 @@ EXPORT_SYMBOL(usbvideo_RegisterVideoDevistatic int usbvideo_v4l_mmap (struct file *file,struct vm_area_struct *vma) {struct uvd *uvd = file->private_data; -unsigned long start = vma->vm_start;unsigned long size = vma->vm_end-vma->vm_start; -unsigned long page, pos;if (!CAMERA_IS_OPERATIONAL (uvd))return -EFAULT ;
@@ -1078,19 +1076,8 @@ static int usbvideo_v4l_mmap(struct fileif (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) +PAGE_SIZE -1 ) & ~(PAGE_SIZE -1 )))return -EINVAL ; - pos = (unsigned long ) uvd->fbuf; -while (size >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page,PAGE_SIZE ,PAGE_SHARED )) -return -EAGAIN ; - - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; -if (size >PAGE_SIZE ) - size -=PAGE_SIZE ; -else - size =0 ; - } +if (remap_vmalloc_range (vma, uvd->fbuf,0 )) +return -EAGAIN ;return 0 ; }
drivers/media/video/usbvideo/vicam.c +8 -19
@@ -1029,8 +1029,6 @@ static int vicam_mmap(struct file *file, struct vm_area_struct *vma) {// TODO: allocate the raw frame buffer if necessary -unsigned long page, pos; -unsigned long start = vma->vm_start;unsigned long size = vma->vm_end-vma->vm_start;struct vicam_camera *cam = file->private_data;
@@ -1039,25 +1037,16 @@ vicam_mmap(struct file *file, struct vm_DBG ("vicam_mmap: %ld\n" , size); -/* We let mmap allocate as much as it wants because Linux was adding 2048 bytes -* to the size the application requested for mmap and it was screwing apps up. -if (size > VICAM_FRAMES*VICAM_MAX_FRAME_SIZE) -return -EINVAL; +/* We let mmap allocate as much as it wants because Linux was adding +* 2048 bytes to the size the application requested for mmap and it was +* screwing apps up. +* +* It shouldn't have been, so let's try this check again -np */ +if (size >VICAM_FRAMES *VICAM_MAX_FRAME_SIZE ) - pos = (unsigned long )cam->framebuf; -while (size >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page,PAGE_SIZE ,PAGE_SHARED )) -return -EAGAIN ; - - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; -if (size >PAGE_SIZE ) - size -=PAGE_SIZE ; -else - size =0 ; - } +if (remap_vmalloc_range (vma, cam->framebuf,0 )) +return -EAGAIN ;return 0 ; }
drivers/media/video/w9968cf.c +3 -13
@@ -2861,10 +2861,7 @@ static int w9968cf_mmap(struct file* filstruct w9968cf_device * cam = (struct w9968cf_device *)video_get_drvdata (video_devdata (filp));unsigned long vsize = vma->vm_end - vma->vm_start, - psize = cam->nbuffers * cam->frame[0 ].size, - start = vma->vm_start, - pos = (unsigned long )cam->frame[0 ].buffer, - page; + psize = cam->nbuffers * cam->frame[0 ].size;if (cam->disconnected) {DBG (2 ,"Device not present" )
@@ -2881,15 +2878,8 @@ static int w9968cf_mmap(struct file* filif (vsize > psize - (vma->vm_pgoff <<PAGE_SHIFT ))return -EINVAL ; -while (vsize >0 ) { - page =vmalloc_to_pfn ((void *)pos); -if (remap_pfn_range (vma, start, page + vma->vm_pgoff, -PAGE_SIZE , vma->vm_page_prot)) -return -EAGAIN ; - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; - vsize -=PAGE_SIZE ; - } +if (remap_vmalloc_range (vma, cam->frame[0 ].buffer, vma->vm_pgoff)) +return -EAGAIN ; DBG(5, "mmap method successfully called")return 0 ;
arch/ia64/kernel/perfmon.c +1 -20
@@ -2237,25 +2237,6 @@ pfm_free_fd(int fd, struct file *file)put_unused_fd (fd); } -static int -pfm_remap_buffer (struct vm_area_struct *vma,unsigned long buf,unsigned long addr,unsigned long size) -{ -DPRINT (("CPU%d buf=0x%lx addr=0x%lx size=%ld\n" ,smp_processor_id (), buf, addr, size)); - -while (size >0 ) { -unsigned long pfn =ia64_tpa (buf) >>PAGE_SHIFT ; - - -if (remap_pfn_range (vma, addr, pfn,PAGE_SIZE ,PAGE_READONLY )) -return -ENOMEM ; - - addr +=PAGE_SIZE ; - buf +=PAGE_SIZE ; - size -=PAGE_SIZE ; - } -return 0 ; -} -/* * allocate a sampling buffer and remaps it into the user address space of the task */
@@ -2343,7 +2324,7 @@ pfm_smpl_buffer_alloc(struct task_structDPRINT (("aligned size=%ld, hdr=%p mapped @0x%lx\n" , size, ctx->ctx_smpl_hdr, vma->vm_start));/* can only be applied to current task, need to have the mm semaphore held when called */ -if (pfm_remap_buffer (vma, (unsigned long )smpl_buf, vma->vm_start, size)) { +if (remap_vmalloc_range (vma, smpl_buf,0 )) {DPRINT (("Can't remap buffer\n" ));up_write (&task->mm->mmap_sem); goto error;
include/linux/vmalloc.h +3 -0
@@ -45,6 +45,9 @@ extern void vfree(void *addr);extern void *vmap (struct page **pages,unsigned int count,unsigned long flags,pgprot_t prot);extern void vunmap (void *addr); + +extern int remap_vmalloc_range (struct vm_area_struct *vma,void *addr, +unsigned long pgoff);/* * Lowlevel-APIs (not for driver use!)
mm/vmalloc.c +66 -0
75 lines not on this page · raw message
drivers/media/video/em28xx/em28xx-video.c +6 -13
@@ -34,6 +34,7 @@#include <linux/version.h> #include <linux/video_decoder.h> #include <linux/mutex.h> +#include <linux/vmalloc.h> #include "em28xx.h" #include <media/tuner.h>
@@ -582,9 +583,7 @@ static struct vm_operations_struct em28x*/ static int em28xx_v4l2_mmap (struct file *filp,struct vm_area_struct *vma) { -unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start; -void *pos; +unsigned long size = vma->vm_end - vma->vm_start;u32 i;struct em28xx *dev = filp->private_data;
@@ -625,16 +624,10 @@ static int em28xx_v4l2_mmap(struct file vma->vm_flags |=VM_IO ; vma->vm_flags |=VM_RESERVED ;/* avoid to swap out this VMA */ - pos = dev->frame[i].bufmem; -while (size >0 ) {/* size is page-aligned */ -if (vm_insert_page (vma, start,vmalloc_to_page (pos))) { -em28xx_videodbg ("mmap: vm_insert_page failed\n" ); -mutex_unlock (&dev->fileop_lock); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; - size -=PAGE_SIZE ; +if (remap_vmalloc_range (vma, dev->frame[i].bufmem,0 )) { +em28xx_videodbg ("mmap: remap_vmalloc_range failed\n" ); +mutex_unlock (&dev->fileop_lock); +return -EAGAIN ; } vma->vm_ops = &em28xx_vm_ops;
drivers/media/video/et61x251/et61x251_core.c +4 -12
@@ -1464,9 +1464,7 @@ static struct vm_operations_struct et61xstatic int et61x251_mmap (struct file * filp,struct vm_area_struct *vma) {struct et61x251_device * cam =video_get_drvdata (video_devdata (filp)); -unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start; -void *pos; +unsigned long size = vma->vm_end - vma->vm_start;u32 i;if (mutex_lock_interruptible (&cam->fileop_mutex))
@@ -1503,15 +1501,9 @@ static int et61x251_mmap(struct file* fi vma->vm_flags |=VM_IO ; vma->vm_flags |=VM_RESERVED ; - pos = cam->frame[i].bufmem; -while (size >0 ) {/* size is page-aligned */ -if (vm_insert_page (vma, start,vmalloc_to_page (pos))) { -mutex_unlock (&cam->fileop_mutex); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; - size -=PAGE_SIZE ; +if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) { +mutex_unlock (&cam->fileop_mutex); +return -EAGAIN ; } vma->vm_ops = &et61x251_vm_ops;
drivers/media/video/sn9c102/sn9c102_core.c +4 -12
@@ -1728,9 +1728,7 @@ static struct vm_operations_struct sn9c1static int sn9c102_mmap (struct file * filp,struct vm_area_struct *vma) {struct sn9c102_device * cam =video_get_drvdata (video_devdata (filp)); -unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start; -void *pos; +unsigned long size = vma->vm_end - vma->vm_start;u32 i;if (mutex_lock_interruptible (&cam->fileop_mutex))
@@ -1767,15 +1765,9 @@ static int sn9c102_mmap(struct file* fil vma->vm_flags |=VM_IO ; vma->vm_flags |=VM_RESERVED ; - pos = cam->frame[i].bufmem; -while (size >0 ) {/* size is page-aligned */ -if (vm_insert_page (vma, start,vmalloc_to_page (pos))) { -mutex_unlock (&cam->fileop_mutex); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; - size -=PAGE_SIZE ; +if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) { +mutex_unlock (&cam->fileop_mutex); +return -EAGAIN ; } vma->vm_ops = &sn9c102_vm_ops;
drivers/media/video/zc0301/zc0301_core.c +4 -12
@@ -929,9 +929,7 @@ static struct vm_operations_struct zc030static int zc0301_mmap (struct file * filp,struct vm_area_struct *vma) {struct zc0301_device * cam =video_get_drvdata (video_devdata (filp)); -unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start; -void *pos; +unsigned long size = vma->vm_end - vma->vm_start;u32 i;if (mutex_lock_interruptible (&cam->fileop_mutex))
@@ -968,15 +966,9 @@ static int zc0301_mmap(struct file* filp vma->vm_flags |=VM_IO ; vma->vm_flags |=VM_RESERVED ; - pos = cam->frame[i].bufmem; -while (size >0 ) {/* size is page-aligned */ -if (vm_insert_page (vma, start,vmalloc_to_page (pos))) { -mutex_unlock (&cam->fileop_mutex); -return -EAGAIN ; - } - start +=PAGE_SIZE ; - pos +=PAGE_SIZE ; - size -=PAGE_SIZE ; +if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) { +mutex_unlock (&cam->fileop_mutex); +return -EAGAIN ; } vma->vm_ops = &zc0301_vm_ops;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 1/5] mm: remap_vmalloc_range
Quoted 5 lines · Nick Piggin
Add a
remap_vmalloc_rangeand get rid of as manyremap_pfn_rangeandvm_insert_pageloops as possible.
remap_vmalloc_rangecan do a whole lot of nice range checking even if the caller gets it wrong (which it looks like one or two do).
This looks very nice, thanks! Although it might be better to split it into one patch to introduce remap_vmalloc_range and various patches to switch over one susbsyetm for merging purposes.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 1/5] mm: remap_vmalloc_range
Quoted 8 lines · Christoph Hellwig
Quoted 5 lines · Nick Piggin
Add a
remap_vmalloc_rangeand get rid of as manyremap_pfn_rangeandvm_insert_pageloops as possible.
remap_vmalloc_rangecan do a whole lot of nice range checking even if the caller gets it wrong (which it looks like one or two do).This looks very nice, thanks!
Thank you
Quoted 3 lines
Although it might be better to split it
into one patch to introduceremap_vmalloc_rangeand various patches to switch over one susbsyetm for merging purposes.
Sure, if anyone insists ;)
I tend to agree. I would tend to do it in just 2 patches (1 for implementation, 1 for conversion) to make administrative overheads smaller -- the conversions are small and very well contained. Is there a good reason to split further?
Nick
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 1/5] mm: remap_vmalloc_range
In reply to Nick PigginHotfix #1
drivers/media/video/usbvideo/vicam.c +1 -0
@@ -1000,6 +1000,7 @@ vicam_mmap(struct file *file, struct vm_* It shouldn't have been, so let's try this check again -np */ if (size >VICAM_FRAMES *VICAM_MAX_FRAME_SIZE ) +return -EINVAL ;if (remap_vmalloc_range (vma, cam->framebuf,0 ))return -EAGAIN ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/5 mm: deprecate vmalloc_to_pfn
In reply to Nick PigginDeprecate vmalloc_to_pfn.
Documentation/feature-removal-schedule.txt +9 -0
@@ -238,3 +238,12 @@ Why: The interface no longer has any cal Who: Nick Piggin <[email protected]> --------------------------- + +What: vmalloc_to_pfn +When: April 2007 +Why: The interface no longer has any callers left in the kernel. It + was previously used so remap_pfn_range can be used on vmalloc memory, + but is deprecated with the introduction of remap_vmalloc_range. +Who: Nick Piggin <[email protected]> + +---------------------------
include/linux/mm.h +1 -1
@@ -1002,7 +1002,7 @@ static inline unsigned long vma_pages(ststruct vm_area_struct *find_extend_vma (struct mm_struct *,unsigned long addr);struct page *vmalloc_to_page (void *addr); -unsigned long vmalloc_to_pfn (void *addr); +__deprecated_for_modules unsigned long vmalloc_to_pfn (void *addr);int remap_pfn_range (struct vm_area_struct *,unsigned long addr,unsigned long pfn,unsigned long size,pgprot_t );int vm_insert_page (struct vm_area_struct *,unsigned long addr,struct page *);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 2/5] mm: deprecate vmalloc_to_pfn
Quoted 1 line · Nick Piggin
Deprecate
vmalloc_to_pfn.
I don't think there's any point to even keep it. There's a trivial replcement.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 2/5] mm: deprecate vmalloc_to_pfn
Quoted 4 lines · Christoph Hellwig
Quoted 1 line · Nick Piggin
Deprecate
vmalloc_to_pfn.I don't think there's any point to even keep it. There's a trivial replcement.
It is exported, is the only thing. I tend to stick my head in the sand with these matters, and try to go with whatever I think will help Andrew merge it.
If nobody cares, I'd just as soon remove it completely.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 2/5] mm: deprecate vmalloc_to_pfn
Quoted 5 lines · Nick Piggin
Quoted 3 lines · Christoph Hellwig
Quoted 1 line · Nick Piggin
Deprecate
vmalloc_to_pfn.
Quoted 7 lines
Quoted 1 line
I don't think there's any point to even keep it. There's a trivial replcement.
It is exported, is the only thing. I tend to stick my head in the sand with these matters, and try to go with whatever I think will help Andrew merge it.
If nobody cares, I'd just as soon remove it completely.
It's been in there for a long time. Theoretically we should mark it deprecated, kill it in six months or so.
But vmalloc_to_page() is EXPORT_SYMBOLed, so fixing up downstream breakage will be so trivial it's hardly worth bothering. So let's zap vmalloc_to_pfn() in 2.6.18.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/5 mm: remove rvmalloc
In reply to Nick PigginSome distros will be using 2.6.16ish kernels, which gives us a good chance to start getting rid of the SetPageReserved which has stuck around until now for its ability to catch paper bag type reference counting bugs.
drivers/ieee1394/dv1394-private.h +1 -1
@@ -478,7 +478,7 @@ struct video_card {/* support asynchronous I/O signals (SIGIO) */ struct fasync_struct *fasync; -/* the large, non-contiguous (rvmalloc()) ringbuffer for DV +/* the large, non-contiguous (vmalloc()) ringbuffer for DV data, exposed to user-space via mmap() */ unsigned long dv_buf_size;struct dma_region dv_buf;
drivers/media/video/cpia.c +8 -50
106 lines not on this page · raw message
drivers/media/video/cpia2/cpia2_core.c +3 -43
64 lines not on this page · raw message
drivers/media/video/meye.c +4 -41
73 lines not on this page · raw message
drivers/media/video/ov511.c +2 -46
72 lines not on this page · raw message
drivers/media/video/pwc/pwc-if.c +2 -43
63 lines not on this page · raw message
drivers/media/video/se401.c +2 -46
66 lines not on this page · raw message
drivers/media/video/stv680.c +4 -59
82 lines not on this page · raw message
drivers/media/video/usbvideo/usbvideo.c +5 -45
86 lines not on this page · raw message
drivers/media/video/usbvideo/vicam.c +3 -47
74 lines not on this page · raw message
drivers/media/video/w9968cf.c +6 -52
104 lines not on this page · raw message
include/linux/vmalloc.h +2 -0
@@ -32,9 +32,11 @@ struct vm_struct {* Highlevel APIs for driver use */ extern void *vmalloc (unsigned long size); +extern void *vmalloc_user (unsigned long size);extern void *vmalloc_node (unsigned long size,int node);extern void *vmalloc_exec (unsigned long size);extern void *vmalloc_32 (unsigned long size); +extern void *vmalloc_32_user (unsigned long size);extern void *__vmalloc (unsigned long size,gfp_t gfp_mask,pgprot_t prot);extern void *__vmalloc_area (struct vm_struct *area,gfp_t gfp_mask,pgprot_t prot);
kernel/power/snapshot.c +3 -4
@@ -89,10 +89,9 @@ static int save_highmem_zone(struct zonecontinue ; page =pfn_to_page (pfn);/* -* This condition results from rvmalloc() sans vmalloc_32() -* and architectural memory reservations. This should be -* corrected eventually when the cases giving rise to this -* are better understood. +* This condition results from architectural memory +* reservations. This should be corrected eventually when the +* cases giving rise to this are better understood. */ if (PageReserved (page))continue ;
mm/vmalloc.c +28 -2
@@ -512,11 +512,24 @@ EXPORT_SYMBOL(__vmalloc);*/ void *vmalloc (unsigned long size) { -return __vmalloc (size,GFP_KERNEL | __GFP_HIGHMEM,PAGE_KERNEL ); +return __vmalloc (size,GFP_KERNEL | __GFP_HIGHMEM,PAGE_KERNEL ); }EXPORT_SYMBOL (vmalloc);/** +* vmalloc_user - allocate virtually contiguous memory which has +* been zeroed so it can be mapped to userspace without +* leaking data. +* +* @size: allocation size +*/ +void *vmalloc_user (unsigned long size) +{ +return __vmalloc (size,GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,PAGE_KERNEL ); +} +EXPORT_SYMBOL (vmalloc_user); + +/** * vmalloc_node - allocate memory on a specific node * * @size: allocation size
@@ -530,7 +543,7 @@ EXPORT_SYMBOL(vmalloc);*/ void *vmalloc_node (unsigned long size,int node) { -return __vmalloc_node (size,GFP_KERNEL | __GFP_HIGHMEM,PAGE_KERNEL , node); +return __vmalloc_node (size,GFP_KERNEL | __GFP_HIGHMEM,PAGE_KERNEL , node); }EXPORT_SYMBOL (vmalloc_node);
@@ -570,6 +583,19 @@ void *vmalloc_32(unsigned long size) }EXPORT_SYMBOL (vmalloc_32); +/** +* vmalloc_32_user - allocate virtually contiguous memory (32bit +* addressable) which is zeroed so it can be +* mapped to userspace without leaking data. +* +* @size: allocation size +*/ +void *vmalloc_32_user (unsigned long size) +{ +return __vmalloc (size,GFP_KERNEL | __GFP_ZERO,PAGE_KERNEL ); +} +EXPORT_SYMBOL (vmalloc_32_user); +long vread (char *buf,char *addr,unsigned long count) {struct vm_struct *tmp;
arch/ia64/kernel/perfmon.c +8 -56
105 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 4/5 mm: extra remap_vmalloc_range check
In reply to Nick PigginAdd a flag to ensure all remap_vmalloc_range memory has been allocated with the vmalloc _user variants, so data does not get leaked.
include/linux/vmalloc.h +1 -0
@@ -8,6 +8,7 @@#define VM_IOREMAP 0x00000001/* ioremap() and friends */ #define VM_ALLOC 0x00000002/* vmalloc() */ #define VM_MAP 0x00000004/* vmap()ed pages */ +#define VM_USERMAP 0x00000008/* suitable for remap_vmalloc_range */ /* bits [20..32] reserved for arch specific ioremap internals */ /*
drivers/media/video/et61x251/et61x251_core.c +2 -1
@@ -133,7 +133,8 @@ et61x251_request_buffers(struct et61x251 cam->nbuffers = count;while (cam->nbuffers >0 ) { -if ((buff =vmalloc_32 (cam->nbuffers *PAGE_ALIGN (imagesize)))) +if ((buff =vmalloc_32_user (cam->nbuffers * +PAGE_ALIGN (imagesize))))break ; cam->nbuffers--; }
drivers/media/video/sn9c102/sn9c102_core.c +1 -1
@@ -149,7 +149,7 @@ sn9c102_request_buffers(struct sn9c102_d cam->nbuffers = count;while (cam->nbuffers >0 ) { -if ((buff =vmalloc_32 (cam->nbuffers *PAGE_ALIGN (imagesize)))) +if ((buff =vmalloc_32_user (cam->nbuffers *PAGE_ALIGN (imagesize))))break ; cam->nbuffers--; }
drivers/media/video/zc0301/zc0301_core.c +1 -1
@@ -136,7 +136,7 @@ zc0301_request_buffers(struct zc0301_dev cam->nbuffers = count;while (cam->nbuffers >0 ) { -if ((buff =vmalloc_32 (cam->nbuffers *PAGE_ALIGN (imagesize)))) +if ((buff =vmalloc_32_user (cam->nbuffers *PAGE_ALIGN (imagesize))))break ; cam->nbuffers--; }
mm/vmalloc.c +21 -2
@@ -525,7 +525,15 @@ EXPORT_SYMBOL(vmalloc);*/ void *vmalloc_user (unsigned long size) { -return __vmalloc (size,GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,PAGE_KERNEL ); +struct vm_struct *area; +void *ret; + + ret =__vmalloc (size,GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,PAGE_KERNEL ); + area =find_vm_area (ret); +BUG_ON (!area); + area->flags |=VM_USERMAP ; + +return ret; }EXPORT_SYMBOL (vmalloc_user);
@@ -592,7 +600,15 @@ EXPORT_SYMBOL(vmalloc_32);*/ void *vmalloc_32_user (unsigned long size) { -return __vmalloc (size,GFP_KERNEL | __GFP_ZERO,PAGE_KERNEL ); +struct vm_struct *area; +void *ret; + + ret =__vmalloc (size,GFP_KERNEL | __GFP_ZERO,PAGE_KERNEL ); + area =find_vm_area (ret); +BUG_ON (!area); + area->flags |=VM_USERMAP ; + +return ret; }EXPORT_SYMBOL (vmalloc_32_user);
@@ -700,6 +716,9 @@ int remap_vmalloc_range(struct vm_area_sif (!area)return -EINVAL ; +if (!(area->flags &VM_USERMAP )) +return -EINVAL ; +if (usize + (pgoff <<PAGE_SHIFT ) > area->size -PAGE_SIZE )return -EINVAL ;
drivers/media/video/em28xx/em28xx-core.c +1 -3
@@ -79,10 +79,8 @@ u32 em28xx_request_buffers(struct em28xx dev->num_frames = count;while (dev->num_frames >0 ) { -if ((buff =vmalloc_32 (dev->num_frames * imagesize))) { -memset (buff,0 , dev->num_frames * imagesize); +if ((buff =vmalloc_32_user (dev->num_frames * imagesize)))break ; - } dev->num_frames--; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 5/5 drivers: leave vm_flags alone
In reply to Nick PigginGet rid of some vm_flags twiddling from driver code. The net result of this + the last 4 patches is that all converted remap_vmalloc_range memory can support get_user_pages - do we want that? Can't hurt, can it?
drivers/media/video/em28xx/em28xx-video.c +0 -4
@@ -620,10 +620,6 @@ static int em28xx_v4l2_mmap(struct filereturn -EINVAL ; } -/* VM_IO is eventually going to replace PageReserved altogether */ - vma->vm_flags |=VM_IO ; - vma->vm_flags |=VM_RESERVED ;/* avoid to swap out this VMA */ -if (remap_vmalloc_range (vma, dev->frame[i].bufmem,0 )) {em28xx_videodbg ("mmap: remap_vmalloc_range failed\n" );mutex_unlock (&dev->fileop_lock);
drivers/media/video/et61x251/et61x251_core.c +0 -3
@@ -1499,9 +1499,6 @@ static int et61x251_mmap(struct file* fireturn -EINVAL ; } - vma->vm_flags |=VM_IO ; - vma->vm_flags |=VM_RESERVED ; -if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) {mutex_unlock (&cam->fileop_mutex);return -EAGAIN ;
drivers/media/video/meye.c +0 -2
@@ -1689,8 +1689,6 @@ static int meye_mmap(struct file *file, } vma->vm_ops = &meye_vm_ops; - vma->vm_flags &= ~VM_IO ;/* not I/O memory */ - vma->vm_flags |=VM_RESERVED ;/* avoid to swap out this VMA */ vma->vm_private_data = (void *) (offset / gbufsize);meye_vm_open (vma);
drivers/media/video/pwc/pwc-if.c +0 -2
@@ -1567,8 +1567,6 @@ static int pwc_video_mmap(struct file *f vma->vm_start, vma->vm_end - vma->vm_start); pdev = vdev->priv; - vma->vm_flags |=VM_IO ; -if (remap_vmalloc_range (vma, pdev->image_data,0 ))return -EAGAIN ;
drivers/media/video/sn9c102/sn9c102_core.c +0 -3
@@ -1762,9 +1762,6 @@ static int sn9c102_mmap(struct file* filreturn -EINVAL ; } - vma->vm_flags |=VM_IO ; - vma->vm_flags |=VM_RESERVED ; -if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) {mutex_unlock (&cam->fileop_mutex);return -EAGAIN ;
drivers/media/video/zc0301/zc0301_core.c +0 -3
@@ -963,9 +963,6 @@ static int zc0301_mmap(struct file* filpreturn -EINVAL ; } - vma->vm_flags |=VM_IO ; - vma->vm_flags |=VM_RESERVED ; -if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) {mutex_unlock (&cam->fileop_mutex);return -EAGAIN ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
[patch 6/5] mm: find_vm_area locking fixes
In reply to Nick PigginBite the bullet and try to get the locking correct the first^Wsecond time.
(subtle bugs like area->flagas modification not having the right memory consistency could be a nightmare to track down)
mm/vmalloc.c +18 -11
@@ -256,16 +256,15 @@ struct vm_struct *get_vm_area_node(unsigreturn __get_vm_area_node (size, flags,VMALLOC_START ,VMALLOC_END , node); } -static struct vm_struct *find_vm_area (void *addr) +/* Caller must hold vmlist_lock */ +static struct vm_struct *__find_vm_area (void *addr) {struct vm_struct *tmp; -write_lock (&vmlist_lock);for (tmp = vmlist; tmp !=NULL ; tmp = tmp->next) {if (tmp->addr == addr)break ; } -write_unlock (&vmlist_lock);return tmp; }
@@ -529,9 +528,10 @@ void *vmalloc_user(unsigned long size)void *ret; ret =__vmalloc (size,GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,PAGE_KERNEL ); - area =find_vm_area (ret); -BUG_ON (!area); +write_lock (&vmlist_lock); + area =__find_vm_area (ret); area->flags |=VM_USERMAP ; +write_unlock (&vmlist_lock);return ret; }
@@ -604,9 +604,10 @@ void *vmalloc_32_user(unsigned long sizevoid *ret; ret =__vmalloc (size,GFP_KERNEL | __GFP_ZERO,PAGE_KERNEL ); - area =find_vm_area (ret); -BUG_ON (!area); +write_lock (&vmlist_lock); + area =__find_vm_area (ret); area->flags |=VM_USERMAP ; +write_unlock (&vmlist_lock);return ret; }
@@ -712,15 +713,17 @@ int remap_vmalloc_range(struct vm_area_sif ((PAGE_SIZE -1 ) & (unsigned long )addr)return -EINVAL ; - area =find_vm_area (addr); +read_lock (&vmlist_lock); + area =__find_vm_area (addr);if (!area) -return -EINVAL ; + goto out_einval_locked;if (!(area->flags &VM_USERMAP )) -return -EINVAL ; + goto out_einval_locked;if (usize + (pgoff <<PAGE_SHIFT ) > area->size -PAGE_SIZE ) -return -EINVAL ; + goto out_einval_locked; +read_unlock (&vmlist_lock); addr = (void *)((unsigned long )addr + (pgoff <<PAGE_SHIFT )); do {
@@ -738,6 +741,10 @@ int remap_vmalloc_range(struct vm_area_s vma->vm_flags |=VM_RESERVED ;return ret; + +out_einval_locked: +read_unlock (&vmlist_lock); +return -EINVAL ; }EXPORT_SYMBOL (remap_vmalloc_range);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 1/1 improve remap_vmalloc_range callers' return values
In reply to Nick PigginNot directly related to the current patchset... but does anyone see a reason why we shouldn't try to return saner values from remap_vmalloc_range callers?
(This patch is slightly more involved for perfmon, so Stephane CCed. It catches insert_vm_struct errors, and moves remap_vmalloc_range below it so we needn't have to clean up by unmapping stuff).
--
arch/ia64/kernel/perfmon.c +18 -14
@@ -2199,6 +2199,7 @@ pfm_smpl_buffer_alloc(struct task_structstruct vm_area_struct *vma =NULL ;unsigned long size;void *smpl_buf; +int ret = -ENOMEM ;/*
@@ -2217,7 +2218,7 @@ pfm_smpl_buffer_alloc(struct task_struct* return -ENOMEM; */ if (size > task->signal->rlim[RLIMIT_MEMLOCK ].rlim_cur) -return -ENOMEM ; + goto out;/* * We do the easy to undo allocations first.
@@ -2227,7 +2228,7 @@ pfm_smpl_buffer_alloc(struct task_struct smpl_buf =vmalloc_user (size);if (smpl_buf ==NULL ) {DPRINT (("Can't allocate sampling buffer\n" )); -return -ENOMEM ; + goto out; }DPRINT (("smpl_buf @%p\n" , smpl_buf));
@@ -2267,7 +2268,6 @@ pfm_smpl_buffer_alloc(struct task_struct vma->vm_start =pfm_get_unmapped_area (NULL ,0 , size,0 ,MAP_PRIVATE |MAP_ANONYMOUS ,0 );if (vma->vm_start ==0UL ) {DPRINT (("Cannot find unmapped area for size %ld\n" , size)); -up_write (&task->mm->mmap_sem); goto error; } vma->vm_end = vma->vm_start + size;
@@ -2275,23 +2275,24 @@ pfm_smpl_buffer_alloc(struct task_structDPRINT (("aligned size=%ld, hdr=%p mapped @0x%lx\n" , size, ctx->ctx_smpl_hdr, vma->vm_start)); -/* can only be applied to current task, need to have the mm semaphore held when called */ -if (remap_vmalloc_range (vma, smpl_buf,0 )) { -DPRINT (("Can't remap buffer\n" )); -up_write (&task->mm->mmap_sem); - goto error; - } -/* * now insert the vma in the vm list for the process, must be * done with mmap lock held */ -insert_vm_struct (mm, vma); + if ((ret = insert_vm_struct(mm, vma)) { +DPRINT (("Can't insert vma\n" )); + goto error; + } + +/* can only be applied to current task, need to have the mm semaphore held when called */ +if ((ret =remap_vmalloc_range (vma, smpl_buf,0 ))) { +DPRINT (("Can't remap buffer\n" )); + goto error; + } mm->total_vm += size >>PAGE_SHIFT ;vm_stat_account (vma->vm_mm, vma->vm_flags, vma->vm_file,vma_pages (vma)); -up_write (&task->mm->mmap_sem);/* * keep track of user level virtual address
@@ -2299,14 +2300,17 @@ pfm_smpl_buffer_alloc(struct task_struct ctx->ctx_smpl_vaddr = (void *)vma->vm_start; *(unsigned long *)user_vaddr = vma->vm_start; +up_write (&task->mm->mmap_sem); +return 0 ; error: +up_write (&task->mm->mmap_sem);kmem_cache_free (vm_area_cachep, vma); error_kmem:vfree (smpl_buf); - -return -ENOMEM ; +out: +return ret; }/*
drivers/media/video/cpia.c +2 -2
@@ -3734,9 +3734,9 @@ static int cpia_mmap(struct file *file, } } -if (remap_vmalloc_range (vma, cam->frame_buf,0 )) { +if ((retval =remap_vmalloc_range (vma, cam->frame_buf,0 ))) {mutex_unlock (&cam->busy_lock); -return -EAGAIN ; +return retval; }DBG ("cpia_mmap: %ld\n" , size);
drivers/media/video/em28xx/em28xx-video.c +14 -12
@@ -585,6 +585,7 @@ static int em28xx_v4l2_mmap(struct file {unsigned long size = vma->vm_end - vma->vm_start;u32 i; +int ret;struct em28xx *dev = filp->private_data;
@@ -593,21 +594,21 @@ static int em28xx_v4l2_mmap(struct fileif (dev->state &DEV_DISCONNECTED ) {em28xx_videodbg ("mmap: device not present\n" ); -mutex_unlock (&dev->fileop_lock); -return -ENODEV ; + ret = -ENODEV ; + goto out; }if (dev->state &DEV_MISCONFIGURED ) {em28xx_videodbg ("mmap: Device is misconfigured; close and " "open it again\n" ); -mutex_unlock (&dev->fileop_lock); -return -EIO ; + ret = -EIO ; + goto out; }if (dev->io !=IO_MMAP || !(vma->vm_flags &VM_WRITE ) || size !=PAGE_ALIGN (dev->frame[0 ].buf.length)) { -mutex_unlock (&dev->fileop_lock); -return -EINVAL ; + ret = -EINVAL ; + goto out; }for (i =0 ; i < dev->num_frames; i++) {
@@ -616,22 +617,23 @@ static int em28xx_v4l2_mmap(struct file }if (i == dev->num_frames) {em28xx_videodbg ("mmap: user supplied mapping address is out of range\n" ); -mutex_unlock (&dev->fileop_lock); -return -EINVAL ; + ret = -EINVAL ; + goto out; } -if (remap_vmalloc_range (vma, dev->frame[i].bufmem,0 )) { +if ((ret =remap_vmalloc_range (vma, dev->frame[i].bufmem,0 ))) {em28xx_videodbg ("mmap: remap_vmalloc_range failed\n" ); -mutex_unlock (&dev->fileop_lock); -return -EAGAIN ; + goto out; } vma->vm_ops = &em28xx_vm_ops; vma->vm_private_data = &dev->frame[i];em28xx_vm_open (vma); + +out:mutex_unlock (&dev->fileop_lock); -return 0 ; +return ret; }/*
drivers/media/video/meye.c +9 -9
@@ -1663,11 +1663,12 @@ static struct vm_operations_struct meye_static int meye_mmap (struct file *file,struct vm_area_struct *vma) {unsigned long size = vma->vm_end - vma->vm_start; +int ret;mutex_lock (&meye.lock);if (size > gbuffers * gbufsize) {/* XXX: should be size + vm_pgoff? */ -mutex_unlock (&meye.lock); -return -EINVAL ; + ret = -EINVAL ; + goto out; }if (!meye.grab_fbuffer) {int i;
@@ -1676,24 +1677,23 @@ static int meye_mmap(struct file *file, meye.grab_fbuffer =vmalloc_32_user (gbuffers*gbufsize);if (!meye.grab_fbuffer) {printk (KERN_ERR "meye: v4l framebuffer allocation failed\n" ); -mutex_unlock (&meye.lock); -return -ENOMEM ; + ret = -ENOMEM ; + goto out; }for (i =0 ; i < gbuffers; i++) meye.vma_use_count[i] =0 ; } -if (remap_vmalloc_range (vma, meye.grab_fbuffer, vma->vm_pgoff)) { -mutex_unlock (&meye.lock); -return -EAGAIN ; - } +if ((ret =remap_vmalloc_range (vma, meye.grab_fbuffer, vma->vm_pgoff))) + goto out; vma->vm_ops = &meye_vm_ops; vma->vm_private_data = (void *) (offset / gbufsize);meye_vm_open (vma); +out:mutex_unlock (&meye.lock); -return 0 ; +return ret; }static struct file_operations meye_fops = {
drivers/media/video/ov511.c +3 -5
@@ -4574,6 +4574,7 @@ ov51x_v4l1_mmap(struct file *file, strucstruct video_device *vdev = file->private_data;unsigned long size = vma->vm_end - vma->vm_start;struct usb_ov511 *ov =video_get_drvdata (vdev); +int ret;if (ov->dev ==NULL )return -EIO ;
@@ -4588,13 +4589,10 @@ ov51x_v4l1_mmap(struct file *file, strucif (mutex_lock_interruptible (&ov->lock))return -EINTR ; -if (remap_vmalloc_range (vma, ov->fbuf,0 )) { -mutex_unlock (&ov->lock); -return -EAGAIN ; - } + ret =remap_vmalloc_range (vma, ov->fbuf,0 );mutex_unlock (&ov->lock); -return 0 ; +return ret; }static struct file_operations ov511_fops = {
drivers/media/video/pwc/pwc-if.c +1 -4
@@ -1567,10 +1567,7 @@ static int pwc_video_mmap(struct file *f vma->vm_start, vma->vm_end - vma->vm_start); pdev = vdev->priv; -if (remap_vmalloc_range (vma, pdev->image_data,0 )) -return -EAGAIN ; - -return 0 ; +return remap_vmalloc_range (vma, pdev->image_data,0 ); }/***************************************************************************/
drivers/media/video/se401.c +10 -10
@@ -1110,24 +1110,24 @@ static int se401_mmap(struct file *file,struct video_device *dev = file->private_data;struct usb_se401 *se401 = (struct usb_se401 *)dev;unsigned long size = vma->vm_end-vma->vm_start; +int ret;mutex_lock (&se401->lock);if (se401->dev ==NULL ) { -mutex_unlock (&se401->lock); -return -EIO ; + ret = -EIO ; + goto out; }if (size > (((SE401_NUMFRAMES * se401->maxframesize) +PAGE_SIZE -1 ) & ~(PAGE_SIZE -1 ))) { -mutex_unlock (&se401->lock); -return -EINVAL ; - } -if (remap_vmalloc_range (vma, se401->fbuf,0 )) { -mutex_unlock (&se401->lock); -return -EAGAIN ; + ret = -EINVAL ; + goto out; } -mutex_unlock (&se401->lock); -return 0 ; + ret =remap_vmalloc_range (vma, se401->fbuf,0 ); + +out: +mutex_unlock (&se401->lock); +return ret; }static struct file_operations se401_fops = {
drivers/media/video/sn9c102/sn9c102_core.c +13 -14
@@ -1730,27 +1730,28 @@ static int sn9c102_mmap(struct file* filstruct sn9c102_device * cam =video_get_drvdata (video_devdata (filp));unsigned long size = vma->vm_end - vma->vm_start;u32 i; +int ret;if (mutex_lock_interruptible (&cam->fileop_mutex))return -ERESTARTSYS ;if (cam->state &DEV_DISCONNECTED ) {DBG (1 ,"Device not present" ); -mutex_unlock (&cam->fileop_mutex); -return -ENODEV ; + ret = -ENODEV ; + goto out; }if (cam->state &DEV_MISCONFIGURED ) {DBG (1 ,"The camera is misconfigured. Close and open it " "again." ); -mutex_unlock (&cam->fileop_mutex); -return -EIO ; + ret = -EIO ; + goto out; }if (cam->io !=IO_MMAP || !(vma->vm_flags &VM_WRITE ) || size !=PAGE_ALIGN (cam->frame[0 ].buf.length)) { -mutex_unlock (&cam->fileop_mutex); -return -EINVAL ; + ret = -EINVAL ; + goto out; }for (i =0 ; i < cam->nbuffers; i++) {
@@ -1758,23 +1759,21 @@ static int sn9c102_mmap(struct file* filbreak ; }if (i == cam->nbuffers) { -mutex_unlock (&cam->fileop_mutex); -return -EINVAL ; + ret = -EINVAL ; + goto out; } -if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) { -mutex_unlock (&cam->fileop_mutex); -return -EAGAIN ; - } +if ((ret =remap_vmalloc_range (vma, cam->frame[i].bufmem,0 ))) + goto out; vma->vm_ops = &sn9c102_vm_ops; vma->vm_private_data = &cam->frame[i];sn9c102_vm_open (vma); +out:mutex_unlock (&cam->fileop_mutex); - -return 0 ; +return ret; }/*****************************************************************************/
drivers/media/video/stv680.c +10 -10
@@ -1200,25 +1200,25 @@ static int stv680_mmap (struct file *filstruct video_device *dev = file->private_data;struct usb_stv *stv680 =video_get_drvdata (dev);unsigned long size = vma->vm_end-vma->vm_start; +int ret;mutex_lock (&stv680->lock);if (stv680->udev ==NULL ) { -mutex_unlock (&stv680->lock); -return -EIO ; + ret = -EIO ; + goto out; }if (size > (((STV680_NUMFRAMES * stv680->maxframesize) +PAGE_SIZE -1 ) & ~(PAGE_SIZE -1 ))) { -mutex_unlock (&stv680->lock); -return -EINVAL ; - } -if (remap_vmalloc_range (vma, stv680->fbuf,0 )) { -mutex_unlock (&stv680->lock); -return -EAGAIN ; + ret = -EINVAL ; + goto out; } -mutex_unlock (&stv680->lock); -return 0 ; + ret =remap_vmalloc_range (vma, stv680->fbuf,0 ); + +out: +mutex_unlock (&stv680->lock); +return ret; } static ssize_t stv680_read (struct file *file, char __user *buf,
drivers/media/video/usbvideo/usbvideo.c +1 -4
@@ -1036,10 +1036,7 @@ static int usbvideo_v4l_mmap(struct fileif (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) +PAGE_SIZE -1 ) & ~(PAGE_SIZE -1 )))return -EINVAL ; -if (remap_vmalloc_range (vma, uvd->fbuf,0 )) -return -EAGAIN ; - -return 0 ; +return remap_vmalloc_range (vma, uvd->fbuf,0 ); }/*
drivers/media/video/usbvideo/vicam.c +1 -4
@@ -1002,10 +1002,7 @@ vicam_mmap(struct file *file, struct vm_if (size >VICAM_FRAMES *VICAM_MAX_FRAME_SIZE )return -EINVAL ; -if (remap_vmalloc_range (vma, cam->framebuf,0 )) -return -EAGAIN ; - -return 0 ; +return remap_vmalloc_range (vma, cam->framebuf,0 ); }#if defined(CONFIG_VIDEO_PROC_FS )
drivers/media/video/w9968cf.c +3 -3
@@ -2816,6 +2816,7 @@ static int w9968cf_mmap(struct file* filvideo_get_drvdata (video_devdata (filp));unsigned long vsize = vma->vm_end - vma->vm_start, psize = cam->nbuffers * cam->frame[0 ].size; +int ret;if (cam->disconnected) {DBG (2 ,"Device not present" )
@@ -2832,11 +2833,10 @@ static int w9968cf_mmap(struct file* filif (vsize > psize - (vma->vm_pgoff <<PAGE_SHIFT ))return -EINVAL ; -if (remap_vmalloc_range (vma, cam->frame[0 ].buffer, vma->vm_pgoff)) -return -EAGAIN ; + ret =remap_vmalloc_range (vma, cam->frame[0 ].buffer, vma->vm_pgoff); DBG(5, "mmap method successfully called") -return 0 ; +return ret; }
drivers/media/video/zc0301/zc0301_core.c +13 -14
@@ -931,27 +931,28 @@ static int zc0301_mmap(struct file* filpstruct zc0301_device * cam =video_get_drvdata (video_devdata (filp));unsigned long size = vma->vm_end - vma->vm_start;u32 i; +int ret;if (mutex_lock_interruptible (&cam->fileop_mutex))return -ERESTARTSYS ;if (cam->state &DEV_DISCONNECTED ) {DBG (1 ,"Device not present" ); -mutex_unlock (&cam->fileop_mutex); -return -ENODEV ; + ret = -ENODEV ; + goto out; }if (cam->state &DEV_MISCONFIGURED ) {DBG (1 ,"The camera is misconfigured. Close and open it " "again." ); -mutex_unlock (&cam->fileop_mutex); -return -EIO ; + ret = -EIO ; + goto out; }if (cam->io !=IO_MMAP || !(vma->vm_flags &VM_WRITE ) || size !=PAGE_ALIGN (cam->frame[0 ].buf.length)) { -mutex_unlock (&cam->fileop_mutex); -return -EINVAL ; + ret = -EINVAL ; + goto out; }for (i =0 ; i < cam->nbuffers; i++) {
@@ -959,23 +960,21 @@ static int zc0301_mmap(struct file* filpbreak ; }if (i == cam->nbuffers) { -mutex_unlock (&cam->fileop_mutex); -return -EINVAL ; + ret = -EINVAL ; + goto out; } -if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) { -mutex_unlock (&cam->fileop_mutex); -return -EAGAIN ; - } +if ((ret =remap_vmalloc_range (vma, cam->frame[i].bufmem,0 ))) + goto out; vma->vm_ops = &zc0301_vm_ops; vma->vm_private_data = &cam->frame[i];zc0301_vm_open (vma); +out:mutex_unlock (&cam->fileop_mutex); - -return 0 ; +return ret; }/*****************************************************************************/
drivers/media/video/et61x251/et61x251_core.c +13 -14
@@ -1467,27 +1467,28 @@ static int et61x251_mmap(struct file* fistruct et61x251_device * cam =video_get_drvdata (video_devdata (filp));unsigned long size = vma->vm_end - vma->vm_start;u32 i; +int ret;if (mutex_lock_interruptible (&cam->fileop_mutex))return -ERESTARTSYS ;if (cam->state &DEV_DISCONNECTED ) {DBG (1 ,"Device not present" ); -mutex_unlock (&cam->fileop_mutex); -return -ENODEV ; + ret = -ENODEV ; + goto out; }if (cam->state &DEV_MISCONFIGURED ) {DBG (1 ,"The camera is misconfigured. Close and open it " "again." ); -mutex_unlock (&cam->fileop_mutex); -return -EIO ; + ret = -EIO ; + goto out; }if (cam->io !=IO_MMAP || !(vma->vm_flags &VM_WRITE ) || size !=PAGE_ALIGN (cam->frame[0 ].buf.length)) { -mutex_unlock (&cam->fileop_mutex); -return -EINVAL ; + ret = -EINVAL ; + goto out; }for (i =0 ; i < cam->nbuffers; i++) {
@@ -1495,23 +1496,21 @@ static int et61x251_mmap(struct file* fibreak ; }if (i == cam->nbuffers) { -mutex_unlock (&cam->fileop_mutex); -return -EINVAL ; + ret = -EINVAL ; + goto out; } -if (remap_vmalloc_range (vma, cam->frame[i].bufmem,0 )) { -mutex_unlock (&cam->fileop_mutex); -return -EAGAIN ; - } +if ((ret =remap_vmalloc_range (vma, cam->frame[i].bufmem,0 ))) + goto out; vma->vm_ops = &et61x251_vm_ops; vma->vm_private_data = &cam->frame[i];et61x251_vm_open (vma); +out:mutex_unlock (&cam->fileop_mutex); - -return 0 ; +return ret; }/*****************************************************************************/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 2 lines · Nick Piggin
Not tested, because I don't have any of the hardware, but it seems compiles OK.
I have a CPIA webcam, so I have taken 2.6.17-rc3 and added your patchset on top.
The patch is working fine, using "motion" as the video4linux application accessing the parallel port CPIA webcam.
Signature · 2 lines
`O O' | [email protected] // ^ \\ | http://www.pyrites.org.uk/