]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - mm/vmscan.c
Pull ar-k0-usage into release branch
[karo-tx-linux.git] / mm / vmscan.c
index 0095533cdde963143f7988c048a110519cc50a31..64f9570cff568103c8031706322c0e78b8f93029 100644 (file)
@@ -511,10 +511,11 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc)
                 * PageDirty _after_ making sure that the page is freeable and
                 * not in use by anybody.       (pagecache + us == 2)
                 */
-               if (page_count(page) != 2 || PageDirty(page)) {
-                       write_unlock_irq(&mapping->tree_lock);
-                       goto keep_locked;
-               }
+               if (unlikely(page_count(page) != 2))
+                       goto cannot_free;
+               smp_rmb();
+               if (unlikely(PageDirty(page)))
+                       goto cannot_free;
 
 #ifdef CONFIG_SWAP
                if (PageSwapCache(page)) {
@@ -538,6 +539,10 @@ free_it:
                        __pagevec_release_nonlru(&freed_pvec);
                continue;
 
+cannot_free:
+               write_unlock_irq(&mapping->tree_lock);
+               goto keep_locked;
+
 activate_locked:
                SetPageActive(page);
                pgactivate++;
@@ -894,7 +899,7 @@ shrink_caches(struct zone **zones, struct scan_control *sc)
                if (zone->present_pages == 0)
                        continue;
 
-               if (!cpuset_zone_allowed(zone))
+               if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
                        continue;
 
                zone->temp_priority = sc->priority;
@@ -940,7 +945,7 @@ int try_to_free_pages(struct zone **zones, unsigned int gfp_mask)
        for (i = 0; zones[i] != NULL; i++) {
                struct zone *zone = zones[i];
 
-               if (!cpuset_zone_allowed(zone))
+               if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
                        continue;
 
                zone->temp_priority = DEF_PRIORITY;
@@ -986,7 +991,7 @@ out:
        for (i = 0; zones[i] != 0; i++) {
                struct zone *zone = zones[i];
 
-               if (!cpuset_zone_allowed(zone))
+               if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
                        continue;
 
                zone->prev_priority = zone->temp_priority;
@@ -1256,11 +1261,11 @@ void wakeup_kswapd(struct zone *zone, int order)
                return;
        if (pgdat->kswapd_max_order < order)
                pgdat->kswapd_max_order = order;
-       if (!cpuset_zone_allowed(zone))
+       if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
                return;
-       if (!waitqueue_active(&zone->zone_pgdat->kswapd_wait))
+       if (!waitqueue_active(&pgdat->kswapd_wait))
                return;
-       wake_up_interruptible(&zone->zone_pgdat->kswapd_wait);
+       wake_up_interruptible(&pgdat->kswapd_wait);
 }
 
 #ifdef CONFIG_PM