Message ID | 20200211224708.29318.16862.stgit@localhost.localdomain (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm / virtio: Provide support for free page reporting | expand |
On Tue, Feb 11, 2020 at 02:47:08PM -0800, Alexander Duyck wrote: > From: Alexander Duyck <alexander.h.duyck@linux.intel.com> > > Rather than walking over the same pages again and again to get to the pages > that have yet to be reported we can save ourselves a significant amount of > time by simply rotating the list so that when we have a full list of > reported pages the head of the list is pointing to the next non-reported > page. Doing this should save us some significant time when processing each > free list. > > This doesn't gain us much in the standard case as all of the non-reported > pages should be near the top of the list already. However in the case of > page shuffling this results in a noticeable improvement. Below are the > will-it-scale page_fault1 w/ THP numbers for 16 tasks with and without > this patch. > > Without: > tasks processes processes_idle threads threads_idle > 16 8093776.25 0.17 5393242.00 38.20 > > With: > tasks processes processes_idle threads threads_idle > 16 8283274.75 0.17 5594261.00 38.15 > > Signed-off-by: Alexander Duyck <alexander.h.duyck@linux.intel.com> Thanks for pulling this patch out and noting its impact. I think the rotation is ok and if it turns out I missed something, it'll be relatively easy to back out just the optimisation and leave the rest of the feature intact. Acked-by: Mel Gorman <mgorman@techsingularity.net>
diff --git a/mm/page_reporting.c b/mm/page_reporting.c index 1047c6872d4f..6885e74c2367 100644 --- a/mm/page_reporting.c +++ b/mm/page_reporting.c @@ -131,17 +131,27 @@ void __page_reporting_notify(void) if (PageReported(page)) continue; - /* Attempt to pull page from list */ - if (!__isolate_free_page(page, order)) - break; + /* Attempt to pull page from list and place in scatterlist */ + if (*offset) { + if (!__isolate_free_page(page, order)) { + next = page; + break; + } - /* Add page to scatter list */ - --(*offset); - sg_set_page(&sgl[*offset], page, page_len, 0); + /* Add page to scatter list */ + --(*offset); + sg_set_page(&sgl[*offset], page, page_len, 0); - /* If scatterlist isn't full grab more pages */ - if (*offset) continue; + } + + /* + * Make the first non-processed page in the free list + * the new head of the free list before we release the + * zone lock. + */ + if (&page->lru != list && !list_is_first(&page->lru, list)) + list_rotate_to_front(&page->lru, list); /* release lock before waiting on report processing */ spin_unlock_irq(&zone->lock); @@ -169,6 +179,10 @@ void __page_reporting_notify(void) break; } + /* Rotate any leftover pages to the head of the freelist */ + if (&next->lru != list && !list_is_first(&next->lru, list)) + list_rotate_to_front(&next->lru, list); + spin_unlock_irq(&zone->lock); return err;