Loading include/linux/compaction.h +6 −2 Original line number Diff line number Diff line Loading @@ -33,10 +33,12 @@ extern int fragmentation_index(struct zone *zone, unsigned int order); extern unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *mask, enum migrate_mode mode, int *contended, int alloc_flags, int classzone_idx, struct zone **candidate_zone); extern void compact_pgdat(pg_data_t *pgdat, int order); extern void reset_isolation_suitable(pg_data_t *pgdat); extern unsigned long compaction_suitable(struct zone *zone, int order); extern unsigned long compaction_suitable(struct zone *zone, int order, int alloc_flags, int classzone_idx); /* Do not skip compaction more than 64 times */ #define COMPACT_MAX_DEFER_SHIFT 6 Loading Loading @@ -103,6 +105,7 @@ static inline bool compaction_restarting(struct zone *zone, int order) static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask, enum migrate_mode mode, int *contended, int alloc_flags, int classzone_idx, struct zone **candidate_zone) { return COMPACT_CONTINUE; Loading @@ -116,7 +119,8 @@ static inline void reset_isolation_suitable(pg_data_t *pgdat) { } static inline unsigned long compaction_suitable(struct zone *zone, int order) static inline unsigned long compaction_suitable(struct zone *zone, int order, int alloc_flags, int classzone_idx) { return COMPACT_SKIPPED; } Loading mm/compaction.c +27 −21 Original line number Diff line number Diff line Loading @@ -1115,9 +1115,9 @@ static int compact_finished(struct zone *zone, struct compact_control *cc, /* Compaction run is not finished if the watermark is not met */ watermark = low_wmark_pages(zone); watermark += (1 << cc->order); if (!zone_watermark_ok(zone, cc->order, watermark, 0, 0)) if (!zone_watermark_ok(zone, cc->order, watermark, cc->classzone_idx, cc->alloc_flags)) return COMPACT_CONTINUE; /* Direct compactor: Is a suitable page free? */ Loading @@ -1143,7 +1143,8 @@ static int compact_finished(struct zone *zone, struct compact_control *cc, * COMPACT_PARTIAL - If the allocation would succeed without compaction * COMPACT_CONTINUE - If compaction should run now */ unsigned long compaction_suitable(struct zone *zone, int order) unsigned long compaction_suitable(struct zone *zone, int order, int alloc_flags, int classzone_idx) { int fragindex; unsigned long watermark; Loading @@ -1155,21 +1156,30 @@ unsigned long compaction_suitable(struct zone *zone, int order) if (order == -1) return COMPACT_CONTINUE; watermark = low_wmark_pages(zone); /* * If watermarks for high-order allocation are already met, there * should be no need for compaction at all. */ if (zone_watermark_ok(zone, order, watermark, classzone_idx, alloc_flags)) return COMPACT_PARTIAL; /* * Watermarks for order-0 must be met for compaction. Note the 2UL. * This is because during migration, copies of pages need to be * allocated and for a short time, the footprint is higher */ watermark = low_wmark_pages(zone) + (2UL << order); if (!zone_watermark_ok(zone, 0, watermark, 0, 0)) watermark += (2UL << order); if (!zone_watermark_ok(zone, 0, watermark, classzone_idx, alloc_flags)) return COMPACT_SKIPPED; /* * fragmentation index determines if allocation failures are due to * low memory or external fragmentation * * index of -1000 implies allocations might succeed depending on * watermarks * index of -1000 would imply allocations might succeed depending on * watermarks, but we already failed the high-order watermark check * index towards 0 implies failure is due to lack of memory * index towards 1000 implies failure is due to fragmentation * Loading @@ -1179,10 +1189,6 @@ unsigned long compaction_suitable(struct zone *zone, int order) if (fragindex >= 0 && fragindex <= sysctl_extfrag_threshold) return COMPACT_SKIPPED; if (fragindex == -1000 && zone_watermark_ok(zone, order, watermark, 0, 0)) return COMPACT_PARTIAL; return COMPACT_CONTINUE; } Loading @@ -1194,7 +1200,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) const int migratetype = gfpflags_to_migratetype(cc->gfp_mask); const bool sync = cc->mode != MIGRATE_ASYNC; ret = compaction_suitable(zone, cc->order); ret = compaction_suitable(zone, cc->order, cc->alloc_flags, cc->classzone_idx); switch (ret) { case COMPACT_PARTIAL: case COMPACT_SKIPPED: Loading Loading @@ -1283,7 +1290,8 @@ out: } static unsigned long compact_zone_order(struct zone *zone, int order, gfp_t gfp_mask, enum migrate_mode mode, int *contended) gfp_t gfp_mask, enum migrate_mode mode, int *contended, int alloc_flags, int classzone_idx) { unsigned long ret; struct compact_control cc = { Loading @@ -1293,6 +1301,8 @@ static unsigned long compact_zone_order(struct zone *zone, int order, .gfp_mask = gfp_mask, .zone = zone, .mode = mode, .alloc_flags = alloc_flags, .classzone_idx = classzone_idx, }; INIT_LIST_HEAD(&cc.freepages); INIT_LIST_HEAD(&cc.migratepages); Loading Loading @@ -1324,6 +1334,7 @@ int sysctl_extfrag_threshold = 500; unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask, enum migrate_mode mode, int *contended, int alloc_flags, int classzone_idx, struct zone **candidate_zone) { enum zone_type high_zoneidx = gfp_zone(gfp_mask); Loading @@ -1332,7 +1343,6 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, struct zoneref *z; struct zone *zone; int rc = COMPACT_DEFERRED; int alloc_flags = 0; int all_zones_contended = COMPACT_CONTENDED_LOCK; /* init for &= op */ *contended = COMPACT_CONTENDED_NONE; Loading @@ -1341,10 +1351,6 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, if (!order || !may_enter_fs || !may_perform_io) return COMPACT_SKIPPED; #ifdef CONFIG_CMA if (gfpflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE) alloc_flags |= ALLOC_CMA; #endif /* Compact each zone in the list */ for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx, nodemask) { Loading @@ -1355,7 +1361,7 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, continue; status = compact_zone_order(zone, order, gfp_mask, mode, &zone_contended); &zone_contended, alloc_flags, classzone_idx); rc = max(status, rc); /* * It takes at least one zone that wasn't lock contended Loading @@ -1364,8 +1370,8 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, all_zones_contended &= zone_contended; /* If a normal allocation would succeed, stop compacting */ if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, alloc_flags)) { if (zone_watermark_ok(zone, order, low_wmark_pages(zone), classzone_idx, alloc_flags)) { *candidate_zone = zone; /* * We think the allocation will succeed in this zone, Loading mm/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -168,6 +168,8 @@ struct compact_control { int order; /* order a direct compactor needs */ const gfp_t gfp_mask; /* gfp mask of a direct compactor */ const int alloc_flags; /* alloc flags of a direct compactor */ const int classzone_idx; /* zone index of a direct compactor */ struct zone *zone; int contended; /* Signal need_sched() or lock * contention detected during Loading mm/memory.c +1 −1 Original line number Diff line number Diff line Loading @@ -2766,7 +2766,7 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address, } static unsigned long fault_around_bytes __read_mostly = rounddown_pow_of_two(65536); rounddown_pow_of_two(4096); #ifdef CONFIG_DEBUG_FS static int fault_around_bytes_get(void *data, u64 *val) Loading mm/page_alloc.c +1 −0 Original line number Diff line number Diff line Loading @@ -2399,6 +2399,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, compact_result = try_to_compact_pages(zonelist, order, gfp_mask, nodemask, mode, contended_compaction, alloc_flags, classzone_idx, &last_compact_zone); current->flags &= ~PF_MEMALLOC; Loading Loading
include/linux/compaction.h +6 −2 Original line number Diff line number Diff line Loading @@ -33,10 +33,12 @@ extern int fragmentation_index(struct zone *zone, unsigned int order); extern unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *mask, enum migrate_mode mode, int *contended, int alloc_flags, int classzone_idx, struct zone **candidate_zone); extern void compact_pgdat(pg_data_t *pgdat, int order); extern void reset_isolation_suitable(pg_data_t *pgdat); extern unsigned long compaction_suitable(struct zone *zone, int order); extern unsigned long compaction_suitable(struct zone *zone, int order, int alloc_flags, int classzone_idx); /* Do not skip compaction more than 64 times */ #define COMPACT_MAX_DEFER_SHIFT 6 Loading Loading @@ -103,6 +105,7 @@ static inline bool compaction_restarting(struct zone *zone, int order) static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask, enum migrate_mode mode, int *contended, int alloc_flags, int classzone_idx, struct zone **candidate_zone) { return COMPACT_CONTINUE; Loading @@ -116,7 +119,8 @@ static inline void reset_isolation_suitable(pg_data_t *pgdat) { } static inline unsigned long compaction_suitable(struct zone *zone, int order) static inline unsigned long compaction_suitable(struct zone *zone, int order, int alloc_flags, int classzone_idx) { return COMPACT_SKIPPED; } Loading
mm/compaction.c +27 −21 Original line number Diff line number Diff line Loading @@ -1115,9 +1115,9 @@ static int compact_finished(struct zone *zone, struct compact_control *cc, /* Compaction run is not finished if the watermark is not met */ watermark = low_wmark_pages(zone); watermark += (1 << cc->order); if (!zone_watermark_ok(zone, cc->order, watermark, 0, 0)) if (!zone_watermark_ok(zone, cc->order, watermark, cc->classzone_idx, cc->alloc_flags)) return COMPACT_CONTINUE; /* Direct compactor: Is a suitable page free? */ Loading @@ -1143,7 +1143,8 @@ static int compact_finished(struct zone *zone, struct compact_control *cc, * COMPACT_PARTIAL - If the allocation would succeed without compaction * COMPACT_CONTINUE - If compaction should run now */ unsigned long compaction_suitable(struct zone *zone, int order) unsigned long compaction_suitable(struct zone *zone, int order, int alloc_flags, int classzone_idx) { int fragindex; unsigned long watermark; Loading @@ -1155,21 +1156,30 @@ unsigned long compaction_suitable(struct zone *zone, int order) if (order == -1) return COMPACT_CONTINUE; watermark = low_wmark_pages(zone); /* * If watermarks for high-order allocation are already met, there * should be no need for compaction at all. */ if (zone_watermark_ok(zone, order, watermark, classzone_idx, alloc_flags)) return COMPACT_PARTIAL; /* * Watermarks for order-0 must be met for compaction. Note the 2UL. * This is because during migration, copies of pages need to be * allocated and for a short time, the footprint is higher */ watermark = low_wmark_pages(zone) + (2UL << order); if (!zone_watermark_ok(zone, 0, watermark, 0, 0)) watermark += (2UL << order); if (!zone_watermark_ok(zone, 0, watermark, classzone_idx, alloc_flags)) return COMPACT_SKIPPED; /* * fragmentation index determines if allocation failures are due to * low memory or external fragmentation * * index of -1000 implies allocations might succeed depending on * watermarks * index of -1000 would imply allocations might succeed depending on * watermarks, but we already failed the high-order watermark check * index towards 0 implies failure is due to lack of memory * index towards 1000 implies failure is due to fragmentation * Loading @@ -1179,10 +1189,6 @@ unsigned long compaction_suitable(struct zone *zone, int order) if (fragindex >= 0 && fragindex <= sysctl_extfrag_threshold) return COMPACT_SKIPPED; if (fragindex == -1000 && zone_watermark_ok(zone, order, watermark, 0, 0)) return COMPACT_PARTIAL; return COMPACT_CONTINUE; } Loading @@ -1194,7 +1200,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) const int migratetype = gfpflags_to_migratetype(cc->gfp_mask); const bool sync = cc->mode != MIGRATE_ASYNC; ret = compaction_suitable(zone, cc->order); ret = compaction_suitable(zone, cc->order, cc->alloc_flags, cc->classzone_idx); switch (ret) { case COMPACT_PARTIAL: case COMPACT_SKIPPED: Loading Loading @@ -1283,7 +1290,8 @@ out: } static unsigned long compact_zone_order(struct zone *zone, int order, gfp_t gfp_mask, enum migrate_mode mode, int *contended) gfp_t gfp_mask, enum migrate_mode mode, int *contended, int alloc_flags, int classzone_idx) { unsigned long ret; struct compact_control cc = { Loading @@ -1293,6 +1301,8 @@ static unsigned long compact_zone_order(struct zone *zone, int order, .gfp_mask = gfp_mask, .zone = zone, .mode = mode, .alloc_flags = alloc_flags, .classzone_idx = classzone_idx, }; INIT_LIST_HEAD(&cc.freepages); INIT_LIST_HEAD(&cc.migratepages); Loading Loading @@ -1324,6 +1334,7 @@ int sysctl_extfrag_threshold = 500; unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask, enum migrate_mode mode, int *contended, int alloc_flags, int classzone_idx, struct zone **candidate_zone) { enum zone_type high_zoneidx = gfp_zone(gfp_mask); Loading @@ -1332,7 +1343,6 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, struct zoneref *z; struct zone *zone; int rc = COMPACT_DEFERRED; int alloc_flags = 0; int all_zones_contended = COMPACT_CONTENDED_LOCK; /* init for &= op */ *contended = COMPACT_CONTENDED_NONE; Loading @@ -1341,10 +1351,6 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, if (!order || !may_enter_fs || !may_perform_io) return COMPACT_SKIPPED; #ifdef CONFIG_CMA if (gfpflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE) alloc_flags |= ALLOC_CMA; #endif /* Compact each zone in the list */ for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx, nodemask) { Loading @@ -1355,7 +1361,7 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, continue; status = compact_zone_order(zone, order, gfp_mask, mode, &zone_contended); &zone_contended, alloc_flags, classzone_idx); rc = max(status, rc); /* * It takes at least one zone that wasn't lock contended Loading @@ -1364,8 +1370,8 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, all_zones_contended &= zone_contended; /* If a normal allocation would succeed, stop compacting */ if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, alloc_flags)) { if (zone_watermark_ok(zone, order, low_wmark_pages(zone), classzone_idx, alloc_flags)) { *candidate_zone = zone; /* * We think the allocation will succeed in this zone, Loading
mm/internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -168,6 +168,8 @@ struct compact_control { int order; /* order a direct compactor needs */ const gfp_t gfp_mask; /* gfp mask of a direct compactor */ const int alloc_flags; /* alloc flags of a direct compactor */ const int classzone_idx; /* zone index of a direct compactor */ struct zone *zone; int contended; /* Signal need_sched() or lock * contention detected during Loading
mm/memory.c +1 −1 Original line number Diff line number Diff line Loading @@ -2766,7 +2766,7 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address, } static unsigned long fault_around_bytes __read_mostly = rounddown_pow_of_two(65536); rounddown_pow_of_two(4096); #ifdef CONFIG_DEBUG_FS static int fault_around_bytes_get(void *data, u64 *val) Loading
mm/page_alloc.c +1 −0 Original line number Diff line number Diff line Loading @@ -2399,6 +2399,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, compact_result = try_to_compact_pages(zonelist, order, gfp_mask, nodemask, mode, contended_compaction, alloc_flags, classzone_idx, &last_compact_zone); current->flags &= ~PF_MEMALLOC; Loading