aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/compaction.c53
-rw-r--r--mm/vmscan.c10
2 files changed, 45 insertions, 18 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index d9ebebe1a2aa..36f0f61f4a24 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -675,44 +675,61 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist,
675 675
676 676
677/* Compact all zones within a node */ 677/* Compact all zones within a node */
678static int compact_node(int nid) 678static int __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc)
679{ 679{
680 int zoneid; 680 int zoneid;
681 pg_data_t *pgdat;
682 struct zone *zone; 681 struct zone *zone;
683 682
684 if (nid < 0 || nid >= nr_node_ids || !node_online(nid))
685 return -EINVAL;
686 pgdat = NODE_DATA(nid);
687
688 /* Flush pending updates to the LRU lists */ 683 /* Flush pending updates to the LRU lists */
689 lru_add_drain_all(); 684 lru_add_drain_all();
690 685
691 for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) { 686 for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) {
692 struct compact_control cc = {
693 .nr_freepages = 0,
694 .nr_migratepages = 0,
695 .order = -1,
696 .sync = true,
697 };
698 687
699 zone = &pgdat->node_zones[zoneid]; 688 zone = &pgdat->node_zones[zoneid];
700 if (!populated_zone(zone)) 689 if (!populated_zone(zone))
701 continue; 690 continue;
702 691
703 cc.zone = zone; 692 cc->nr_freepages = 0;
704 INIT_LIST_HEAD(&cc.freepages); 693 cc->nr_migratepages = 0;
705 INIT_LIST_HEAD(&cc.migratepages); 694 cc->zone = zone;
695 INIT_LIST_HEAD(&cc->freepages);
696 INIT_LIST_HEAD(&cc->migratepages);
706 697
707 compact_zone(zone, &cc); 698 if (cc->order < 0 || !compaction_deferred(zone))
699 compact_zone(zone, cc);
708 700
709 VM_BUG_ON(!list_empty(&cc.freepages)); 701 VM_BUG_ON(!list_empty(&cc->freepages));
710 VM_BUG_ON(!list_empty(&cc.migratepages)); 702 VM_BUG_ON(!list_empty(&cc->migratepages));
711 } 703 }
712 704
713 return 0; 705 return 0;
714} 706}
715 707
708int compact_pgdat(pg_data_t *pgdat, int order)
709{
710 struct compact_control cc = {
711 .order = order,
712 .sync = false,
713 };
714
715 return __compact_pgdat(pgdat, &cc);
716}
717
718static int compact_node(int nid)
719{
720 pg_data_t *pgdat;
721 struct compact_control cc = {
722 .order = -1,
723 .sync = true,
724 };
725
726 if (nid < 0 || nid >= nr_node_ids || !node_online(nid))
727 return -EINVAL;
728 pgdat = NODE_DATA(nid);
729
730 return __compact_pgdat(pgdat, &cc);
731}
732
716/* Compact all nodes in the system */ 733/* Compact all nodes in the system */
717static int compact_nodes(void) 734static int compact_nodes(void)
718{ 735{
diff --git a/mm/vmscan.c b/mm/vmscan.c
index d7dad2a4e69c..b2b4c4a0ada2 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2919,6 +2919,8 @@ out:
2919 * and it is potentially going to sleep here. 2919 * and it is potentially going to sleep here.
2920 */ 2920 */
2921 if (order) { 2921 if (order) {
2922 int zones_need_compaction = 1;
2923
2922 for (i = 0; i <= end_zone; i++) { 2924 for (i = 0; i <= end_zone; i++) {
2923 struct zone *zone = pgdat->node_zones + i; 2925 struct zone *zone = pgdat->node_zones + i;
2924 2926
@@ -2939,9 +2941,17 @@ out:
2939 goto loop_again; 2941 goto loop_again;
2940 } 2942 }
2941 2943
2944 /* Check if the memory needs to be defragmented. */
2945 if (zone_watermark_ok(zone, order,
2946 low_wmark_pages(zone), *classzone_idx, 0))
2947 zones_need_compaction = 0;
2948
2942 /* If balanced, clear the congested flag */ 2949 /* If balanced, clear the congested flag */
2943 zone_clear_flag(zone, ZONE_CONGESTED); 2950 zone_clear_flag(zone, ZONE_CONGESTED);
2944 } 2951 }
2952
2953 if (zones_need_compaction)
2954 compact_pgdat(pgdat, order);
2945 } 2955 }
2946 2956
2947 /* 2957 /*