|
@@ -818,6 +818,13 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
|
|
page_count(page) > page_mapcount(page))
|
|
page_count(page) > page_mapcount(page))
|
|
goto isolate_fail;
|
|
goto isolate_fail;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Only allow to migrate anonymous pages in GFP_NOFS context
|
|
|
|
+ * because those do not depend on fs locks.
|
|
|
|
+ */
|
|
|
|
+ if (!(cc->gfp_mask & __GFP_FS) && page_mapping(page))
|
|
|
|
+ goto isolate_fail;
|
|
|
|
+
|
|
/* If we already hold the lock, we can skip some rechecking */
|
|
/* If we already hold the lock, we can skip some rechecking */
|
|
if (!locked) {
|
|
if (!locked) {
|
|
locked = compact_trylock_irqsave(zone_lru_lock(zone),
|
|
locked = compact_trylock_irqsave(zone_lru_lock(zone),
|
|
@@ -1677,14 +1684,16 @@ enum compact_result try_to_compact_pages(gfp_t gfp_mask, unsigned int order,
|
|
unsigned int alloc_flags, const struct alloc_context *ac,
|
|
unsigned int alloc_flags, const struct alloc_context *ac,
|
|
enum compact_priority prio)
|
|
enum compact_priority prio)
|
|
{
|
|
{
|
|
- int may_enter_fs = gfp_mask & __GFP_FS;
|
|
|
|
int may_perform_io = gfp_mask & __GFP_IO;
|
|
int may_perform_io = gfp_mask & __GFP_IO;
|
|
struct zoneref *z;
|
|
struct zoneref *z;
|
|
struct zone *zone;
|
|
struct zone *zone;
|
|
enum compact_result rc = COMPACT_SKIPPED;
|
|
enum compact_result rc = COMPACT_SKIPPED;
|
|
|
|
|
|
- /* Check if the GFP flags allow compaction */
|
|
|
|
- if (!may_enter_fs || !may_perform_io)
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Check if the GFP flags allow compaction - GFP_NOIO is really
|
|
|
|
+ * tricky context because the migration might require IO
|
|
|
|
+ */
|
|
|
|
+ if (!may_perform_io)
|
|
return COMPACT_SKIPPED;
|
|
return COMPACT_SKIPPED;
|
|
|
|
|
|
trace_mm_compaction_try_to_compact_pages(order, gfp_mask, prio);
|
|
trace_mm_compaction_try_to_compact_pages(order, gfp_mask, prio);
|
|
@@ -1751,6 +1760,7 @@ static void compact_node(int nid)
|
|
.mode = MIGRATE_SYNC,
|
|
.mode = MIGRATE_SYNC,
|
|
.ignore_skip_hint = true,
|
|
.ignore_skip_hint = true,
|
|
.whole_zone = true,
|
|
.whole_zone = true,
|
|
|
|
+ .gfp_mask = GFP_KERNEL,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -1876,6 +1886,7 @@ static void kcompactd_do_work(pg_data_t *pgdat)
|
|
.classzone_idx = pgdat->kcompactd_classzone_idx,
|
|
.classzone_idx = pgdat->kcompactd_classzone_idx,
|
|
.mode = MIGRATE_SYNC_LIGHT,
|
|
.mode = MIGRATE_SYNC_LIGHT,
|
|
.ignore_skip_hint = true,
|
|
.ignore_skip_hint = true,
|
|
|
|
+ .gfp_mask = GFP_KERNEL,
|
|
|
|
|
|
};
|
|
};
|
|
trace_mm_compaction_kcompactd_wake(pgdat->node_id, cc.order,
|
|
trace_mm_compaction_kcompactd_wake(pgdat->node_id, cc.order,
|