aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/page_alloc.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e29a6ba050c8..f6005b7c3446 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1063,6 +1063,15 @@ static bool bulkfree_pcp_prepare(struct page *page)
1063} 1063}
1064#endif /* CONFIG_DEBUG_VM */ 1064#endif /* CONFIG_DEBUG_VM */
1065 1065
1066static inline void prefetch_buddy(struct page *page)
1067{
1068 unsigned long pfn = page_to_pfn(page);
1069 unsigned long buddy_pfn = __find_buddy_pfn(pfn, 0);
1070 struct page *buddy = page + (buddy_pfn - pfn);
1071
1072 prefetch(buddy);
1073}
1074
1066/* 1075/*
1067 * Frees a number of pages from the PCP lists 1076 * Frees a number of pages from the PCP lists
1068 * Assumes all pages on list are in same zone, and of same order. 1077 * Assumes all pages on list are in same zone, and of same order.
@@ -1079,6 +1088,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
1079{ 1088{
1080 int migratetype = 0; 1089 int migratetype = 0;
1081 int batch_free = 0; 1090 int batch_free = 0;
1091 int prefetch_nr = 0;
1082 bool isolated_pageblocks; 1092 bool isolated_pageblocks;
1083 struct page *page, *tmp; 1093 struct page *page, *tmp;
1084 LIST_HEAD(head); 1094 LIST_HEAD(head);
@@ -1114,6 +1124,18 @@ static void free_pcppages_bulk(struct zone *zone, int count,
1114 continue; 1124 continue;
1115 1125
1116 list_add_tail(&page->lru, &head); 1126 list_add_tail(&page->lru, &head);
1127
1128 /*
1129 * We are going to put the page back to the global
1130 * pool, prefetch its buddy to speed up later access
1131 * under zone->lock. It is believed the overhead of
1132 * an additional test and calculating buddy_pfn here
1133 * can be offset by reduced memory latency later. To
1134 * avoid excessive prefetching due to large count, only
1135 * prefetch buddy for the first pcp->batch nr of pages.
1136 */
1137 if (prefetch_nr++ < pcp->batch)
1138 prefetch_buddy(page);
1117 } while (--count && --batch_free && !list_empty(list)); 1139 } while (--count && --batch_free && !list_empty(list));
1118 } 1140 }
1119 1141