Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: set_page_dirty_balance() vs ->page_mkwrite()

All the current page_mkwrite() implementations also set the page dirty. Which
results in the set_page_dirty_balance() call to _not_ call balance, because the
page is already found dirty.

This allows us to dirty a _lot_ of pages without ever hitting
balance_dirty_pages(). Not good (tm).

Force a balance call if ->page_mkwrite() was successful.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Peter Zijlstra and committed by
Linus Torvalds
a200ee18 3eb215de

+10 -5
+1 -1
include/linux/writeback.h
··· 127 127 loff_t pos, loff_t count); 128 128 int sync_page_range_nolock(struct inode *inode, struct address_space *mapping, 129 129 loff_t pos, loff_t count); 130 - void set_page_dirty_balance(struct page *page); 130 + void set_page_dirty_balance(struct page *page, int page_mkwrite); 131 131 void writeback_set_ratelimit(void); 132 132 133 133 /* pdflush.c */
+7 -2
mm/memory.c
··· 1639 1639 struct page *old_page, *new_page; 1640 1640 pte_t entry; 1641 1641 int reuse = 0, ret = 0; 1642 + int page_mkwrite = 0; 1642 1643 struct page *dirty_page = NULL; 1643 1644 1644 1645 old_page = vm_normal_page(vma, address, orig_pte); ··· 1688 1687 page_cache_release(old_page); 1689 1688 if (!pte_same(*page_table, orig_pte)) 1690 1689 goto unlock; 1690 + 1691 + page_mkwrite = 1; 1691 1692 } 1692 1693 dirty_page = old_page; 1693 1694 get_page(dirty_page); ··· 1777 1774 * do_no_page is protected similarly. 1778 1775 */ 1779 1776 wait_on_page_locked(dirty_page); 1780 - set_page_dirty_balance(dirty_page); 1777 + set_page_dirty_balance(dirty_page, page_mkwrite); 1781 1778 put_page(dirty_page); 1782 1779 } 1783 1780 return ret; ··· 2325 2322 struct page *dirty_page = NULL; 2326 2323 struct vm_fault vmf; 2327 2324 int ret; 2325 + int page_mkwrite = 0; 2328 2326 2329 2327 vmf.virtual_address = (void __user *)(address & PAGE_MASK); 2330 2328 vmf.pgoff = pgoff; ··· 2402 2398 anon = 1; /* no anon but release vmf.page */ 2403 2399 goto out; 2404 2400 } 2401 + page_mkwrite = 1; 2405 2402 } 2406 2403 } 2407 2404 ··· 2458 2453 if (anon) 2459 2454 page_cache_release(vmf.page); 2460 2455 else if (dirty_page) { 2461 - set_page_dirty_balance(dirty_page); 2456 + set_page_dirty_balance(dirty_page, page_mkwrite); 2462 2457 put_page(dirty_page); 2463 2458 } 2464 2459
+2 -2
mm/page-writeback.c
··· 274 274 pdflush_operation(background_writeout, 0); 275 275 } 276 276 277 - void set_page_dirty_balance(struct page *page) 277 + void set_page_dirty_balance(struct page *page, int page_mkwrite) 278 278 { 279 - if (set_page_dirty(page)) { 279 + if (set_page_dirty(page) || page_mkwrite) { 280 280 struct address_space *mapping = page_mapping(page); 281 281 282 282 if (mapping)