|
@@ -367,22 +367,30 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
|
|
|
goto isolate_fail;
|
|
|
|
|
|
/*
|
|
|
- * The zone lock must be held to isolate freepages.
|
|
|
- * Unfortunately this is a very coarse lock and can be
|
|
|
- * heavily contended if there are parallel allocations
|
|
|
- * or parallel compactions. For async compaction do not
|
|
|
- * spin on the lock and we acquire the lock as late as
|
|
|
- * possible.
|
|
|
+ * If we already hold the lock, we can skip some rechecking.
|
|
|
+ * Note that if we hold the lock now, checked_pageblock was
|
|
|
+ * already set in some previous iteration (or strict is true),
|
|
|
+ * so it is correct to skip the suitable migration target
|
|
|
+ * recheck as well.
|
|
|
*/
|
|
|
- if (!locked)
|
|
|
+ if (!locked) {
|
|
|
+ /*
|
|
|
+ * The zone lock must be held to isolate freepages.
|
|
|
+ * Unfortunately this is a very coarse lock and can be
|
|
|
+ * heavily contended if there are parallel allocations
|
|
|
+ * or parallel compactions. For async compaction do not
|
|
|
+ * spin on the lock and we acquire the lock as late as
|
|
|
+ * possible.
|
|
|
+ */
|
|
|
locked = compact_trylock_irqsave(&cc->zone->lock,
|
|
|
&flags, cc);
|
|
|
- if (!locked)
|
|
|
- break;
|
|
|
+ if (!locked)
|
|
|
+ break;
|
|
|
|
|
|
- /* Recheck this is a buddy page under lock */
|
|
|
- if (!PageBuddy(page))
|
|
|
- goto isolate_fail;
|
|
|
+ /* Recheck this is a buddy page under lock */
|
|
|
+ if (!PageBuddy(page))
|
|
|
+ goto isolate_fail;
|
|
|
+ }
|
|
|
|
|
|
/* Found a free page, break it into order-0 pages */
|
|
|
isolated = split_free_page(page);
|
|
@@ -644,19 +652,20 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
|
|
|
page_count(page) > page_mapcount(page))
|
|
|
continue;
|
|
|
|
|
|
- /* If the lock is not held, try to take it */
|
|
|
- if (!locked)
|
|
|
+ /* If we already hold the lock, we can skip some rechecking */
|
|
|
+ if (!locked) {
|
|
|
locked = compact_trylock_irqsave(&zone->lru_lock,
|
|
|
&flags, cc);
|
|
|
- if (!locked)
|
|
|
- break;
|
|
|
+ if (!locked)
|
|
|
+ break;
|
|
|
|
|
|
- /* Recheck PageLRU and PageTransHuge under lock */
|
|
|
- if (!PageLRU(page))
|
|
|
- continue;
|
|
|
- if (PageTransHuge(page)) {
|
|
|
- low_pfn += (1 << compound_order(page)) - 1;
|
|
|
- continue;
|
|
|
+ /* Recheck PageLRU and PageTransHuge under lock */
|
|
|
+ if (!PageLRU(page))
|
|
|
+ continue;
|
|
|
+ if (PageTransHuge(page)) {
|
|
|
+ low_pfn += (1 << compound_order(page)) - 1;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
lruvec = mem_cgroup_page_lruvec(page, zone);
|