diff options
-rw-r--r-- | mm/page_alloc.c | 22 |
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 | ||
1066 | static 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 | ||