Merge tag 'v3.10.68' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / mm / page-writeback.c
index 4514ad7415c327bfbbe9837f3a7955291f3a172d..5f7725bb2a08624afba17d21f2a93cda81820eac 100644 (file)
@@ -108,6 +108,7 @@ unsigned int dirty_expire_interval = 30 * 100; /* centiseconds */
  * Flag that makes the machine dump writes/reads and block dirtyings.
  */
 int block_dump;
+EXPORT_SYMBOL_GPL(block_dump);
 
 /*
  * Flag that puts the machine in "laptop mode". Doubles as a timeout in jiffies:
@@ -188,6 +189,26 @@ static unsigned long writeout_period_time = 0;
  * global dirtyable memory first.
  */
 
+/**
+ * zone_dirtyable_memory - number of dirtyable pages in a zone
+ * @zone: the zone
+ *
+ * Returns the zone's number of pages potentially available for dirty
+ * page cache.  This is the base value for the per-zone dirty limits.
+ */
+static unsigned long zone_dirtyable_memory(struct zone *zone)
+{
+       unsigned long nr_pages;
+
+       nr_pages = zone_page_state(zone, NR_FREE_PAGES);
+       nr_pages -= min(nr_pages, zone->dirty_balance_reserve);
+
+       nr_pages += zone_page_state(zone, NR_INACTIVE_FILE);
+       nr_pages += zone_page_state(zone, NR_ACTIVE_FILE);
+
+       return nr_pages;
+}
+
 static unsigned long highmem_dirtyable_memory(unsigned long total)
 {
 #ifdef CONFIG_HIGHMEM
@@ -195,11 +216,9 @@ static unsigned long highmem_dirtyable_memory(unsigned long total)
        unsigned long x = 0;
 
        for_each_node_state(node, N_HIGH_MEMORY) {
-               struct zone *z =
-                       &NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
+               struct zone *z = &NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
 
-               x += zone_page_state(z, NR_FREE_PAGES) +
-                    zone_reclaimable_pages(z) - z->dirty_balance_reserve;
+               x += zone_dirtyable_memory(z);
        }
        /*
         * Unreclaimable memory (kernel memory or anonymous memory
@@ -235,9 +254,12 @@ static unsigned long global_dirtyable_memory(void)
 {
        unsigned long x;
 
-       x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages();
+       x = global_page_state(NR_FREE_PAGES);
        x -= min(x, dirty_balance_reserve);
 
+       x += global_page_state(NR_INACTIVE_FILE);
+       x += global_page_state(NR_ACTIVE_FILE);
+
        if (!vm_highmem_is_dirtyable)
                x -= highmem_dirtyable_memory(x);
 
@@ -288,32 +310,6 @@ void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty)
        trace_global_dirty_state(background, dirty);
 }
 
-/**
- * zone_dirtyable_memory - number of dirtyable pages in a zone
- * @zone: the zone
- *
- * Returns the zone's number of pages potentially available for dirty
- * page cache.  This is the base value for the per-zone dirty limits.
- */
-static unsigned long zone_dirtyable_memory(struct zone *zone)
-{
-       /*
-        * The effective global number of dirtyable pages may exclude
-        * highmem as a big-picture measure to keep the ratio between
-        * dirty memory and lowmem reasonable.
-        *
-        * But this function is purely about the individual zone and a
-        * highmem zone can hold its share of dirty pages, so we don't
-        * care about vm_highmem_is_dirtyable here.
-        */
-       unsigned long nr_pages = zone_page_state(zone, NR_FREE_PAGES) +
-               zone_reclaimable_pages(zone);
-
-       /* don't allow this to underflow */
-       nr_pages -= min(nr_pages, zone->dirty_balance_reserve);
-       return nr_pages;
-}
-
 /**
  * zone_dirty_limit - maximum number of dirty pages allowed in a zone
  * @zone: the zone
@@ -1104,11 +1100,11 @@ static unsigned long dirty_poll_interval(unsigned long dirty,
        return 1;
 }
 
-static long bdi_max_pause(struct backing_dev_info *bdi,
-                         unsigned long bdi_dirty)
+static unsigned long bdi_max_pause(struct backing_dev_info *bdi,
+                                  unsigned long bdi_dirty)
 {
-       long bw = bdi->avg_write_bandwidth;
-       long t;
+       unsigned long bw = bdi->avg_write_bandwidth;
+       unsigned long t;
 
        /*
         * Limit pause time for small memory systems. If sleeping for too long
@@ -1120,7 +1116,7 @@ static long bdi_max_pause(struct backing_dev_info *bdi,
        t = bdi_dirty / (1 + bw / roundup_pow_of_two(1 + HZ / 8));
        t++;
 
-       return min_t(long, t, MAX_PAUSE);
+       return min_t(unsigned long, t, MAX_PAUSE);
 }
 
 static long bdi_min_pause(struct backing_dev_info *bdi,
@@ -2031,11 +2027,12 @@ int __set_page_dirty_nobuffers(struct page *page)
        if (!TestSetPageDirty(page)) {
                struct address_space *mapping = page_mapping(page);
                struct address_space *mapping2;
+               unsigned long flags;
 
                if (!mapping)
                        return 1;
 
-               spin_lock_irq(&mapping->tree_lock);
+               spin_lock_irqsave(&mapping->tree_lock, flags);
                mapping2 = page_mapping(page);
                if (mapping2) { /* Race with truncate? */
                        BUG_ON(mapping2 != mapping);
@@ -2044,7 +2041,7 @@ int __set_page_dirty_nobuffers(struct page *page)
                        radix_tree_tag_set(&mapping->page_tree,
                                page_index(page), PAGECACHE_TAG_DIRTY);
                }
-               spin_unlock_irq(&mapping->tree_lock);
+               spin_unlock_irqrestore(&mapping->tree_lock, flags);
                if (mapping->host) {
                        /* !PageAnon && !swapper_space */
                        __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);