aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2010-01-15 20:01:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-01-16 15:15:40 -0500
commit1e2ae599d37e60958c03ca5e46b1f657619a30cd (patch)
tree0a0c9ff0370fbefd4eb8fe3a44106880c1aae8cb
parented5e5894b234ce4793d78078c026915b853e0678 (diff)
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>
-rw-r--r--include/linux/mm_types.h2
-rw-r--r--mm/nommu.c14
2 files changed, 8 insertions, 8 deletions
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 84d020bed083..80cfa78a8cf6 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -122,7 +122,7 @@ struct vm_region {
122 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ 122 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
123 struct file *vm_file; /* the backing file or NULL */ 123 struct file *vm_file; /* the backing file or NULL */
124 124
125 atomic_t vm_usage; /* region usage count */ 125 int vm_usage; /* region usage count (access under nommu_region_sem) */
126 bool vm_icache_flushed : 1; /* true if the icache has been flushed for 126 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
127 * this region */ 127 * this region */
128}; 128};
diff --git a/mm/nommu.c b/mm/nommu.c
index 17773862619b..5e39294f8ea8 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -552,11 +552,11 @@ static void free_page_series(unsigned long from, unsigned long to)
552static void __put_nommu_region(struct vm_region *region) 552static void __put_nommu_region(struct vm_region *region)
553 __releases(nommu_region_sem) 553 __releases(nommu_region_sem)
554{ 554{
555 kenter("%p{%d}", region, atomic_read(&region->vm_usage)); 555 kenter("%p{%d}", region, region->vm_usage);
556 556
557 BUG_ON(!nommu_region_tree.rb_node); 557 BUG_ON(!nommu_region_tree.rb_node);
558 558
559 if (atomic_dec_and_test(&region->vm_usage)) { 559 if (--region->vm_usage == 0) {
560 if (region->vm_top > region->vm_start) 560 if (region->vm_top > region->vm_start)
561 delete_nommu_region(region); 561 delete_nommu_region(region);
562 up_write(&nommu_region_sem); 562 up_write(&nommu_region_sem);
@@ -1205,7 +1205,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1205 if (!vma) 1205 if (!vma)
1206 goto error_getting_vma; 1206 goto error_getting_vma;
1207 1207
1208 atomic_set(&region->vm_usage, 1); 1208 region->vm_usage = 1;
1209 region->vm_flags = vm_flags; 1209 region->vm_flags = vm_flags;
1210 region->vm_pgoff = pgoff; 1210 region->vm_pgoff = pgoff;
1211 1211
@@ -1272,7 +1272,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1272 } 1272 }
1273 1273
1274 /* we've found a region we can share */ 1274 /* we've found a region we can share */
1275 atomic_inc(&pregion->vm_usage); 1275 pregion->vm_usage++;
1276 vma->vm_region = pregion; 1276 vma->vm_region = pregion;
1277 start = pregion->vm_start; 1277 start = pregion->vm_start;
1278 start += (pgoff - pregion->vm_pgoff) << PAGE_SHIFT; 1278 start += (pgoff - pregion->vm_pgoff) << PAGE_SHIFT;
@@ -1289,7 +1289,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1289 vma->vm_region = NULL; 1289 vma->vm_region = NULL;
1290 vma->vm_start = 0; 1290 vma->vm_start = 0;
1291 vma->vm_end = 0; 1291 vma->vm_end = 0;
1292 atomic_dec(&pregion->vm_usage); 1292 pregion->vm_usage--;
1293 pregion = NULL; 1293 pregion = NULL;
1294 goto error_just_free; 1294 goto error_just_free;
1295 } 1295 }
@@ -1444,7 +1444,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
1444 /* we're only permitted to split anonymous regions that have a single 1444 /* we're only permitted to split anonymous regions that have a single
1445 * owner */ 1445 * owner */
1446 if (vma->vm_file || 1446 if (vma->vm_file ||
1447 atomic_read(&vma->vm_region->vm_usage) != 1) 1447 vma->vm_region->vm_usage != 1)
1448 return -ENOMEM; 1448 return -ENOMEM;
1449 1449
1450 if (mm->map_count >= sysctl_max_map_count) 1450 if (mm->map_count >= sysctl_max_map_count)
@@ -1518,7 +1518,7 @@ static int shrink_vma(struct mm_struct *mm,
1518 1518
1519 /* cut the backing region down to size */ 1519 /* cut the backing region down to size */
1520 region = vma->vm_region; 1520 region = vma->vm_region;
1521 BUG_ON(atomic_read(&region->vm_usage) != 1); 1521 BUG_ON(region->vm_usage != 1);
1522 1522
1523 down_write(&nommu_region_sem); 1523 down_write(&nommu_region_sem);
1524 delete_nommu_region(region); 1524 delete_nommu_region(region);