]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - mm/compaction.c
sched/headers: Prepare to move signal wakeup & sigpending methods from <linux/sched...
[mirror_ubuntu-artful-kernel.git] / mm / compaction.c
index 949198d012602002ca75fd47a03845e571eca53e..81e1eaa2a2cf1bea89767185e9cb9549f2139ca2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/migrate.h>
 #include <linux/compaction.h>
 #include <linux/mm_inline.h>
+#include <linux/sched/signal.h>
 #include <linux/backing-dev.h>
 #include <linux/sysctl.h>
 #include <linux/sysfs.h>
@@ -548,7 +549,7 @@ isolate_fail:
        if (blockpfn == end_pfn)
                update_pageblock_skip(cc, valid_page, total_isolated, false);
 
-       count_compact_events(COMPACTFREE_SCANNED, nr_scanned);
+       cc->total_free_scanned += nr_scanned;
        if (total_isolated)
                count_compact_events(COMPACTISOLATED, total_isolated);
        return total_isolated;
@@ -802,7 +803,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
                                        locked = false;
                                }
 
-                               if (isolate_movable_page(page, isolate_mode))
+                               if (!isolate_movable_page(page, isolate_mode))
                                        goto isolate_success;
                        }
 
@@ -931,7 +932,7 @@ isolate_fail:
        trace_mm_compaction_isolate_migratepages(start_pfn, low_pfn,
                                                nr_scanned, nr_isolated);
 
-       count_compact_events(COMPACTMIGRATE_SCANNED, nr_scanned);
+       cc->total_migrate_scanned += nr_scanned;
        if (nr_isolated)
                count_compact_events(COMPACTISOLATED, nr_isolated);
 
@@ -1631,6 +1632,9 @@ out:
                        zone->compact_cached_free_pfn = free_pfn;
        }
 
+       count_compact_events(COMPACTMIGRATE_SCANNED, cc->total_migrate_scanned);
+       count_compact_events(COMPACTFREE_SCANNED, cc->total_free_scanned);
+
        trace_mm_compaction_end(start_pfn, cc->migrate_pfn,
                                cc->free_pfn, end_pfn, sync, ret);
 
@@ -1645,6 +1649,8 @@ static enum compact_result compact_zone_order(struct zone *zone, int order,
        struct compact_control cc = {
                .nr_freepages = 0,
                .nr_migratepages = 0,
+               .total_migrate_scanned = 0,
+               .total_free_scanned = 0,
                .order = order,
                .gfp_mask = gfp_mask,
                .zone = zone,
@@ -1757,6 +1763,8 @@ static void compact_node(int nid)
        struct zone *zone;
        struct compact_control cc = {
                .order = -1,
+               .total_migrate_scanned = 0,
+               .total_free_scanned = 0,
                .mode = MIGRATE_SYNC,
                .ignore_skip_hint = true,
                .whole_zone = true,
@@ -1883,6 +1891,8 @@ static void kcompactd_do_work(pg_data_t *pgdat)
        struct zone *zone;
        struct compact_control cc = {
                .order = pgdat->kcompactd_max_order,
+               .total_migrate_scanned = 0,
+               .total_free_scanned = 0,
                .classzone_idx = pgdat->kcompactd_classzone_idx,
                .mode = MIGRATE_SYNC_LIGHT,
                .ignore_skip_hint = true,
@@ -1891,7 +1901,7 @@ static void kcompactd_do_work(pg_data_t *pgdat)
        };
        trace_mm_compaction_kcompactd_wake(pgdat->node_id, cc.order,
                                                        cc.classzone_idx);
-       count_vm_event(KCOMPACTD_WAKE);
+       count_compact_event(KCOMPACTD_WAKE);
 
        for (zoneid = 0; zoneid <= cc.classzone_idx; zoneid++) {
                int status;
@@ -1909,6 +1919,8 @@ static void kcompactd_do_work(pg_data_t *pgdat)
 
                cc.nr_freepages = 0;
                cc.nr_migratepages = 0;
+               cc.total_migrate_scanned = 0;
+               cc.total_free_scanned = 0;
                cc.zone = zone;
                INIT_LIST_HEAD(&cc.freepages);
                INIT_LIST_HEAD(&cc.migratepages);
@@ -1927,6 +1939,11 @@ static void kcompactd_do_work(pg_data_t *pgdat)
                        defer_compaction(zone, cc.order);
                }
 
+               count_compact_events(KCOMPACTD_MIGRATE_SCANNED,
+                                    cc.total_migrate_scanned);
+               count_compact_events(KCOMPACTD_FREE_SCANNED,
+                                    cc.total_free_scanned);
+
                VM_BUG_ON(!list_empty(&cc.freepages));
                VM_BUG_ON(!list_empty(&cc.migratepages));
        }
@@ -1950,6 +1967,13 @@ void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx)
        if (pgdat->kcompactd_max_order < order)
                pgdat->kcompactd_max_order = order;
 
+       /*
+        * Pairs with implicit barrier in wait_event_freezable()
+        * such that wakeups are not missed in the lockless
+        * waitqueue_active() call.
+        */
+       smp_acquire__after_ctrl_dep();
+
        if (pgdat->kcompactd_classzone_idx > classzone_idx)
                pgdat->kcompactd_classzone_idx = classzone_idx;