|
@@ -70,8 +70,7 @@ static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags,
|
|
|
|
|
|
/* async aborts if taking too long or contended */
|
|
|
if (!cc->sync) {
|
|
|
- if (cc->contended)
|
|
|
- *cc->contended = true;
|
|
|
+ cc->contended = true;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -688,7 +687,7 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
|
|
|
|
|
|
/* Perform the isolation */
|
|
|
low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn);
|
|
|
- if (!low_pfn)
|
|
|
+ if (!low_pfn || cc->contended)
|
|
|
return ISOLATE_ABORT;
|
|
|
|
|
|
cc->migrate_pfn = low_pfn;
|
|
@@ -848,6 +847,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
|
|
|
switch (isolate_migratepages(zone, cc)) {
|
|
|
case ISOLATE_ABORT:
|
|
|
ret = COMPACT_PARTIAL;
|
|
|
+ putback_lru_pages(&cc->migratepages);
|
|
|
+ cc->nr_migratepages = 0;
|
|
|
goto out;
|
|
|
case ISOLATE_NONE:
|
|
|
continue;
|
|
@@ -896,6 +897,7 @@ static unsigned long compact_zone_order(struct zone *zone,
|
|
|
bool sync, bool *contended,
|
|
|
struct page **page)
|
|
|
{
|
|
|
+ unsigned long ret;
|
|
|
struct compact_control cc = {
|
|
|
.nr_freepages = 0,
|
|
|
.nr_migratepages = 0,
|
|
@@ -903,13 +905,18 @@ static unsigned long compact_zone_order(struct zone *zone,
|
|
|
.migratetype = allocflags_to_migratetype(gfp_mask),
|
|
|
.zone = zone,
|
|
|
.sync = sync,
|
|
|
- .contended = contended,
|
|
|
.page = page,
|
|
|
};
|
|
|
INIT_LIST_HEAD(&cc.freepages);
|
|
|
INIT_LIST_HEAD(&cc.migratepages);
|
|
|
|
|
|
- return compact_zone(zone, &cc);
|
|
|
+ ret = compact_zone(zone, &cc);
|
|
|
+
|
|
|
+ VM_BUG_ON(!list_empty(&cc.freepages));
|
|
|
+ VM_BUG_ON(!list_empty(&cc.migratepages));
|
|
|
+
|
|
|
+ *contended = cc.contended;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
int sysctl_extfrag_threshold = 500;
|