aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/page-writeback.c59
-rw-r--r--mm/thrash.c5
-rw-r--r--mm/vmstat.c2
3 files changed, 43 insertions, 23 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 63cd88840eb2..eec1481ba44f 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -588,31 +588,27 @@ void __init page_writeback_init(void)
588} 588}
589 589
590/** 590/**
591 * generic_writepages - walk the list of dirty pages of the given address space and writepage() all of them. 591 * write_cache_pages - walk the list of dirty pages of the given address space and write all of them.
592 * @mapping: address space structure to write 592 * @mapping: address space structure to write
593 * @wbc: subtract the number of written pages from *@wbc->nr_to_write 593 * @wbc: subtract the number of written pages from *@wbc->nr_to_write
594 * @writepage: function called for each page
595 * @data: data passed to writepage function
594 * 596 *
595 * This is a library function, which implements the writepages() 597 * If a page is already under I/O, write_cache_pages() skips it, even
596 * address_space_operation.
597 *
598 * If a page is already under I/O, generic_writepages() skips it, even
599 * if it's dirty. This is desirable behaviour for memory-cleaning writeback, 598 * if it's dirty. This is desirable behaviour for memory-cleaning writeback,
600 * but it is INCORRECT for data-integrity system calls such as fsync(). fsync() 599 * but it is INCORRECT for data-integrity system calls such as fsync(). fsync()
601 * and msync() need to guarantee that all the data which was dirty at the time 600 * and msync() need to guarantee that all the data which was dirty at the time
602 * the call was made get new I/O started against them. If wbc->sync_mode is 601 * the call was made get new I/O started against them. If wbc->sync_mode is
603 * WB_SYNC_ALL then we were called for data integrity and we must wait for 602 * WB_SYNC_ALL then we were called for data integrity and we must wait for
604 * existing IO to complete. 603 * existing IO to complete.
605 *
606 * Derived from mpage_writepages() - if you fix this you should check that
607 * also!
608 */ 604 */
609int generic_writepages(struct address_space *mapping, 605int write_cache_pages(struct address_space *mapping,
610 struct writeback_control *wbc) 606 struct writeback_control *wbc, writepage_t writepage,
607 void *data)
611{ 608{
612 struct backing_dev_info *bdi = mapping->backing_dev_info; 609 struct backing_dev_info *bdi = mapping->backing_dev_info;
613 int ret = 0; 610 int ret = 0;
614 int done = 0; 611 int done = 0;
615 int (*writepage)(struct page *page, struct writeback_control *wbc);
616 struct pagevec pvec; 612 struct pagevec pvec;
617 int nr_pages; 613 int nr_pages;
618 pgoff_t index; 614 pgoff_t index;
@@ -625,12 +621,6 @@ int generic_writepages(struct address_space *mapping,
625 return 0; 621 return 0;
626 } 622 }
627 623
628 writepage = mapping->a_ops->writepage;
629
630 /* deal with chardevs and other special file */
631 if (!writepage)
632 return 0;
633
634 pagevec_init(&pvec, 0); 624 pagevec_init(&pvec, 0);
635 if (wbc->range_cyclic) { 625 if (wbc->range_cyclic) {
636 index = mapping->writeback_index; /* Start from prev offset */ 626 index = mapping->writeback_index; /* Start from prev offset */
@@ -682,8 +672,7 @@ retry:
682 continue; 672 continue;
683 } 673 }
684 674
685 ret = (*writepage)(page, wbc); 675 ret = (*writepage)(page, wbc, data);
686 mapping_set_error(mapping, ret);
687 676
688 if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) 677 if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
689 unlock_page(page); 678 unlock_page(page);
@@ -710,6 +699,38 @@ retry:
710 mapping->writeback_index = index; 699 mapping->writeback_index = index;
711 return ret; 700 return ret;
712} 701}
702EXPORT_SYMBOL(write_cache_pages);
703
704/*
705 * Function used by generic_writepages to call the real writepage
706 * function and set the mapping flags on error
707 */
708static int __writepage(struct page *page, struct writeback_control *wbc,
709 void *data)
710{
711 struct address_space *mapping = data;
712 int ret = mapping->a_ops->writepage(page, wbc);
713 mapping_set_error(mapping, ret);
714 return ret;
715}
716
717/**
718 * generic_writepages - walk the list of dirty pages of the given address space and writepage() all of them.
719 * @mapping: address space structure to write
720 * @wbc: subtract the number of written pages from *@wbc->nr_to_write
721 *
722 * This is a library function, which implements the writepages()
723 * address_space_operation.
724 */
725int generic_writepages(struct address_space *mapping,
726 struct writeback_control *wbc)
727{
728 /* deal with chardevs and other special file */
729 if (!mapping->a_ops->writepage)
730 return 0;
731
732 return write_cache_pages(mapping, wbc, __writepage, mapping);
733}
713 734
714EXPORT_SYMBOL(generic_writepages); 735EXPORT_SYMBOL(generic_writepages);
715 736
diff --git a/mm/thrash.c b/mm/thrash.c
index 9ef9071f99bc..c4c5205a9c35 100644
--- a/mm/thrash.c
+++ b/mm/thrash.c
@@ -48,9 +48,8 @@ void grab_swap_token(void)
48 if (current_interval < current->mm->last_interval) 48 if (current_interval < current->mm->last_interval)
49 current->mm->token_priority++; 49 current->mm->token_priority++;
50 else { 50 else {
51 current->mm->token_priority--; 51 if (likely(current->mm->token_priority > 0))
52 if (unlikely(current->mm->token_priority < 0)) 52 current->mm->token_priority--;
53 current->mm->token_priority = 0;
54 } 53 }
55 /* Check if we deserve the token */ 54 /* Check if we deserve the token */
56 if (current->mm->token_priority > 55 if (current->mm->token_priority >
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 9832d9a41d8c..8faf27e5aa98 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -698,7 +698,7 @@ static void __devinit start_cpu_timer(int cpu)
698{ 698{
699 struct delayed_work *vmstat_work = &per_cpu(vmstat_work, cpu); 699 struct delayed_work *vmstat_work = &per_cpu(vmstat_work, cpu);
700 700
701 INIT_DELAYED_WORK(vmstat_work, vmstat_update); 701 INIT_DELAYED_WORK_DEFERRABLE(vmstat_work, vmstat_update);
702 schedule_delayed_work_on(cpu, vmstat_work, HZ + cpu); 702 schedule_delayed_work_on(cpu, vmstat_work, HZ + cpu);
703} 703}
704 704