mm, compaction: add vmstats for kcompactd work
authorDavid Rientjes <rientjes@google.com>
Wed, 22 Feb 2017 23:44:50 +0000 (15:44 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Feb 2017 00:41:29 +0000 (16:41 -0800)
A "compact_daemon_wake" vmstat exists that represents the number of
times kcompactd has woken up.  This doesn't represent how much work it
actually did, though.

It's useful to understand how much compaction work is being done by
kcompactd versus other methods such as direct compaction and explicitly
triggered per-node (or system) compaction.

This adds two new vmstats: "compact_daemon_migrate_scanned" and
"compact_daemon_free_scanned" to represent the number of pages kcompactd
has scanned as part of its migration scanner and freeing scanner,
respectively.

These values are still accounted for in the general
"compact_migrate_scanned" and "compact_free_scanned" for compatibility.

It could be argued that explicitly triggered compaction could also be
tracked separately, and that could be added if others find it useful.

Link: http://lkml.kernel.org/r/alpine.DEB.2.10.1612071749390.69852@chino.kir.corp.google.com
Signed-off-by: David Rientjes <rientjes@google.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/vm_event_item.h
mm/compaction.c
mm/internal.h
mm/vmstat.c

index 4d6ec58a8d45b04aa6bae51585e49d44319dd155..6aa1b6cb58285d92ccd4a53d8de660669f518a6b 100644 (file)
@@ -56,6 +56,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
                COMPACTISOLATED,
                COMPACTSTALL, COMPACTFAIL, COMPACTSUCCESS,
                KCOMPACTD_WAKE,
+               KCOMPACTD_MIGRATE_SCANNED, KCOMPACTD_FREE_SCANNED,
 #endif
 #ifdef CONFIG_HUGETLB_PAGE
                HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL,
index 949198d012602002ca75fd47a03845e571eca53e..c6178bbd3e044ed08476cf52cb83626c836bbfc2 100644 (file)
@@ -548,7 +548,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;
@@ -931,7 +931,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 +1631,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 +1648,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 +1762,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 +1890,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 +1900,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 +1918,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 +1938,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));
        }
index bfad3b5d266541315dd31eb1655141b91b9890d7..9ad04fc6eefebf15838da349830305ca58caaeb8 100644 (file)
@@ -175,6 +175,8 @@ struct compact_control {
        struct list_head migratepages;  /* List of pages being migrated */
        unsigned long nr_freepages;     /* Number of isolated free pages */
        unsigned long nr_migratepages;  /* Number of pages to migrate */
+       unsigned long total_migrate_scanned;
+       unsigned long total_free_scanned;
        unsigned long free_pfn;         /* isolate_freepages search base */
        unsigned long migrate_pfn;      /* isolate_migratepages search base */
        unsigned long last_migrated_pfn;/* Not yet flushed page being freed */
index 7c28df36f50ff009963ff1f04cf0be848dd0fa13..69f9aff39a2eaf608d4f7cfaed8904bd3c3312c8 100644 (file)
@@ -1038,6 +1038,8 @@ const char * const vmstat_text[] = {
        "compact_fail",
        "compact_success",
        "compact_daemon_wake",
+       "compact_daemon_migrate_scanned",
+       "compact_daemon_free_scanned",
 #endif
 
 #ifdef CONFIG_HUGETLB_PAGE