History

Merge branch 'vm-cleanups' (unmap_vma() interface cleanup)

This series sanitizes the interface to unmap_vma(). The crazy interface annoyed me no end when I was looking at unmap_single_vma(), which we can spend quite a lot of time in (especially with loads that have a lot of small fork/exec's: shell scripts etc). Moving the nr_accounted calculations to where they belong at least clarifies things a little. I hope to come back to look at the performance of this later, but if/when I get back to it I at least don't have to see the crazy interfaces any more. * vm-cleanups: vm: remove 'nr_accounted' calculations from the unmap_vmas() interfaces vm: simplify unmap_vmas() calling convention

Linus Torvalds committed 14 years ago

Commit dddbd542 parents 76e10d1 4f74d2c3 files · +25 −27Browse files

Unified · Split

3 files
  1. include/linux/mm.h +2 −4
  2. mm/memory.c +11 −17
  3. mm/mmap.c +12 −6
include/linux/mm.h+2−4
@@ -896,10 +896,8 @@ int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, · 895 unmodified lines
896896 unsigned long size);
897897 void zap_page_range(struct vm_area_struct *vma, unsigned long address,
898898 unsigned long size, struct zap_details *);
899−void unmap_vmas(struct mmu_gather *tlb,
900− struct vm_area_struct *start_vma, unsigned long start_addr,
901− unsigned long end_addr, unsigned long *nr_accounted,
902− struct zap_details *);
899+void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
900+ unsigned long start, unsigned long end);
903901
904902 /**
905903 * mm_walk - callbacks for walk_page_range
mm/memory.c+11−17
@@ -1295,7 +1295,7 @@ static void unmap_page_range(struct mmu_gather *tlb, · 1294 unmodified lines
12951295
12961296 static void unmap_single_vma(struct mmu_gather *tlb,
12971297 struct vm_area_struct *vma, unsigned long start_addr,
1298− unsigned long end_addr, unsigned long *nr_accounted,
1298+ unsigned long end_addr,
12991299 struct zap_details *details)
13001300 {
13011301 unsigned long start = max(vma->vm_start, start_addr);
@@ -1307,9 +1307,6 @@ static void unmap_single_vma(struct mmu_gather *tlb, · 5 unmodified lines
13071307 if (end <= vma->vm_start)
13081308 return;
13091309
1310− if (vma->vm_flags & VM_ACCOUNT)
1311− *nr_accounted += (end - start) >> PAGE_SHIFT;
1312−
13131310 if (unlikely(is_pfn_mapping(vma)))
13141311 untrack_pfn_vma(vma, 0, 0);
13151312
@@ -1339,8 +1336,6 @@ static void unmap_single_vma(struct mmu_gather *tlb, · 23 unmodified lines
13391336 * @vma: the starting vma
13401337 * @start_addr: virtual address at which to start unmapping
13411338 * @end_addr: virtual address at which to end unmapping
1342− * @nr_accounted: Place number of unmapped pages in vm-accountable vma's here
1343− * @details: details of nonlinear truncation or shared cache invalidation
13441339 *
13451340 * Unmap all pages in the vma list.
13461341 *
@@ -1355,15 +1350,13 @@ static void unmap_single_vma(struct mmu_gather *tlb, · 8 unmodified lines
13551350 */
13561351 void unmap_vmas(struct mmu_gather *tlb,
13571352 struct vm_area_struct *vma, unsigned long start_addr,
1358− unsigned long end_addr, unsigned long *nr_accounted,
1359− struct zap_details *details)
1353+ unsigned long end_addr)
13601354 {
13611355 struct mm_struct *mm = vma->vm_mm;
13621356
13631357 mmu_notifier_invalidate_range_start(mm, start_addr, end_addr);
13641358 for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next)
1365− unmap_single_vma(tlb, vma, start_addr, end_addr, nr_accounted,
1366− details);
1359+ unmap_single_vma(tlb, vma, start_addr, end_addr, NULL);
13671360 mmu_notifier_invalidate_range_end(mm, start_addr, end_addr);
13681361 }
13691362
@@ -1376,19 +1369,21 @@ void unmap_vmas(struct mmu_gather *tlb, · 6 unmodified lines
13761369 *
13771370 * Caller must protect the VMA list
13781371 */
1379−void zap_page_range(struct vm_area_struct *vma, unsigned long address,
1372+void zap_page_range(struct vm_area_struct *vma, unsigned long start,
13801373 unsigned long size, struct zap_details *details)
13811374 {
13821375 struct mm_struct *mm = vma->vm_mm;
13831376 struct mmu_gather tlb;
1384− unsigned long end = address + size;
1385− unsigned long nr_accounted = 0;
1377+ unsigned long end = start + size;
13861378
13871379 lru_add_drain();
13881380 tlb_gather_mmu(&tlb, mm, 0);
13891381 update_hiwater_rss(mm);
1390− unmap_vmas(&tlb, vma, address, end, &nr_accounted, details);
1391− tlb_finish_mmu(&tlb, address, end);
1382+ mmu_notifier_invalidate_range_start(mm, start, end);
1383+ for ( ; vma && vma->vm_start < end; vma = vma->vm_next)
1384+ unmap_single_vma(&tlb, vma, start, end, details);
1385+ mmu_notifier_invalidate_range_end(mm, start, end);
1386+ tlb_finish_mmu(&tlb, start, end);
13921387 }
13931388
13941389 /**
@@ -1406,13 +1401,12 @@ static void zap_page_range_single(struct vm_area_struct *vma, unsigned long addr · 11 unmodified lines
14061401 struct mm_struct *mm = vma->vm_mm;
14071402 struct mmu_gather tlb;
14081403 unsigned long end = address + size;
1409− unsigned long nr_accounted = 0;
14101404
14111405 lru_add_drain();
14121406 tlb_gather_mmu(&tlb, mm, 0);
14131407 update_hiwater_rss(mm);
14141408 mmu_notifier_invalidate_range_start(mm, address, end);
1415− unmap_single_vma(&tlb, vma, address, end, &nr_accounted, details);
1409+ unmap_single_vma(&tlb, vma, address, end, details);
14161410 mmu_notifier_invalidate_range_end(mm, address, end);
14171411 tlb_finish_mmu(&tlb, address, end);
14181412 }
mm/mmap.c+12−6
@@ -1889,15 +1889,20 @@ find_extend_vma(struct mm_struct * mm, unsigned long addr) · 1888 unmodified lines
18891889 */
18901890 static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
18911891 {
1892+ unsigned long nr_accounted = 0;
1893+
18921894 /* Update high watermark before we lower total_vm */
18931895 update_hiwater_vm(mm);
18941896 do {
18951897 long nrpages = vma_pages(vma);
18961898
1899+ if (vma->vm_flags & VM_ACCOUNT)
1900+ nr_accounted += nrpages;
18971901 mm->total_vm -= nrpages;
18981902 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
18991903 vma = remove_vma(vma);
19001904 } while (vma);
1905+ vm_unacct_memory(nr_accounted);
19011906 validate_mm(mm);
19021907 }
19031908
@@ -1912,13 +1917,11 @@ static void unmap_region(struct mm_struct *mm, · 8 unmodified lines
19121917 {
19131918 struct vm_area_struct *next = prev? prev->vm_next: mm->mmap;
19141919 struct mmu_gather tlb;
1915− unsigned long nr_accounted = 0;
19161920
19171921 lru_add_drain();
19181922 tlb_gather_mmu(&tlb, mm, 0);
19191923 update_hiwater_rss(mm);
1920− unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL);
1921− vm_unacct_memory(nr_accounted);
1924+ unmap_vmas(&tlb, vma, start, end);
19221925 free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS,
19231926 next ? next->vm_start : 0);
19241927 tlb_finish_mmu(&tlb, start, end);
@@ -2305,8 +2308,7 @@ void exit_mmap(struct mm_struct *mm) · 380 unmodified lines
23052308 tlb_gather_mmu(&tlb, mm, 1);
23062309 /* update_hiwater_rss(mm) here? but nobody should be looking */
23072310 /* Use -1 here to ensure all VMAs in the mm are unmapped */
2308− unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL);
2309− vm_unacct_memory(nr_accounted);
2311+ unmap_vmas(&tlb, vma, 0, -1);
23102312
23112313 free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
23122314 tlb_finish_mmu(&tlb, 0, -1);
@@ -2315,8 +2317,12 @@ void exit_mmap(struct mm_struct *mm) · 2 unmodified lines
23152317 * Walk the list again, actually closing and freeing it,
23162318 * with preemption enabled, without holding any MM locks.
23172319 */
2318− while (vma)
2320+ while (vma) {
2321+ if (vma->vm_flags & VM_ACCOUNT)
2322+ nr_accounted += vma_pages(vma);
23192323 vma = remove_vma(vma);
2324+ }
2325+ vm_unacct_memory(nr_accounted);
23202326
23212327 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
23222328 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t