nommu: struct vm_region's vm_usage count need not be atomic

The vm_usage count field in struct vm_region does not need to be atomic as
it's only even modified whilst nommu_region_sem is write locked.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: Greg Ungerer <gerg@snapgear.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
David Howells 2010-01-15 17:01:33 -08:00 committed by Linus Torvalds
parent ed5e5894b2
commit 1e2ae599d3
2 changed files with 8 additions and 8 deletions

View file

@ -122,7 +122,7 @@ struct vm_region {
unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
struct file *vm_file; /* the backing file or NULL */ struct file *vm_file; /* the backing file or NULL */
atomic_t vm_usage; /* region usage count */ int vm_usage; /* region usage count (access under nommu_region_sem) */
bool vm_icache_flushed : 1; /* true if the icache has been flushed for bool vm_icache_flushed : 1; /* true if the icache has been flushed for
* this region */ * this region */
}; };

View file

@ -552,11 +552,11 @@ static void free_page_series(unsigned long from, unsigned long to)
static void __put_nommu_region(struct vm_region *region) static void __put_nommu_region(struct vm_region *region)
__releases(nommu_region_sem) __releases(nommu_region_sem)
{ {
kenter("%p{%d}", region, atomic_read(&region->vm_usage)); kenter("%p{%d}", region, region->vm_usage);
BUG_ON(!nommu_region_tree.rb_node); BUG_ON(!nommu_region_tree.rb_node);
if (atomic_dec_and_test(&region->vm_usage)) { if (--region->vm_usage == 0) {
if (region->vm_top > region->vm_start) if (region->vm_top > region->vm_start)
delete_nommu_region(region); delete_nommu_region(region);
up_write(&nommu_region_sem); up_write(&nommu_region_sem);
@ -1205,7 +1205,7 @@ unsigned long do_mmap_pgoff(struct file *file,
if (!vma) if (!vma)
goto error_getting_vma; goto error_getting_vma;
atomic_set(&region->vm_usage, 1); region->vm_usage = 1;
region->vm_flags = vm_flags; region->vm_flags = vm_flags;
region->vm_pgoff = pgoff; region->vm_pgoff = pgoff;
@ -1272,7 +1272,7 @@ unsigned long do_mmap_pgoff(struct file *file,
} }
/* we've found a region we can share */ /* we've found a region we can share */
atomic_inc(&pregion->vm_usage); pregion->vm_usage++;
vma->vm_region = pregion; vma->vm_region = pregion;
start = pregion->vm_start; start = pregion->vm_start;
start += (pgoff - pregion->vm_pgoff) << PAGE_SHIFT; start += (pgoff - pregion->vm_pgoff) << PAGE_SHIFT;
@ -1289,7 +1289,7 @@ unsigned long do_mmap_pgoff(struct file *file,
vma->vm_region = NULL; vma->vm_region = NULL;
vma->vm_start = 0; vma->vm_start = 0;
vma->vm_end = 0; vma->vm_end = 0;
atomic_dec(&pregion->vm_usage); pregion->vm_usage--;
pregion = NULL; pregion = NULL;
goto error_just_free; goto error_just_free;
} }
@ -1444,7 +1444,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
/* we're only permitted to split anonymous regions that have a single /* we're only permitted to split anonymous regions that have a single
* owner */ * owner */
if (vma->vm_file || if (vma->vm_file ||
atomic_read(&vma->vm_region->vm_usage) != 1) vma->vm_region->vm_usage != 1)
return -ENOMEM; return -ENOMEM;
if (mm->map_count >= sysctl_max_map_count) if (mm->map_count >= sysctl_max_map_count)
@ -1518,7 +1518,7 @@ static int shrink_vma(struct mm_struct *mm,
/* cut the backing region down to size */ /* cut the backing region down to size */
region = vma->vm_region; region = vma->vm_region;
BUG_ON(atomic_read(&region->vm_usage) != 1); BUG_ON(region->vm_usage != 1);
down_write(&nommu_region_sem); down_write(&nommu_region_sem);
delete_nommu_region(region); delete_nommu_region(region);