diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 4fe7e3aa02e2..acb7611cd525 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1085,21 +1085,25 @@ static int isolate_lru_pages(int nr_to_scan, struct list_head *src, | |||
1085 | page = lru_to_page(src); | 1085 | page = lru_to_page(src); |
1086 | prefetchw_prev_lru_page(page, src, flags); | 1086 | prefetchw_prev_lru_page(page, src, flags); |
1087 | 1087 | ||
1088 | if (!TestClearPageLRU(page)) | ||
1089 | BUG(); | ||
1090 | list_del(&page->lru); | 1088 | list_del(&page->lru); |
1091 | if (get_page_testone(page)) { | 1089 | if (unlikely(get_page_testone(page))) { |
1092 | /* | 1090 | /* |
1093 | * It is being freed elsewhere | 1091 | * It is being freed elsewhere |
1094 | */ | 1092 | */ |
1095 | __put_page(page); | 1093 | __put_page(page); |
1096 | SetPageLRU(page); | ||
1097 | list_add(&page->lru, src); | 1094 | list_add(&page->lru, src); |
1098 | continue; | 1095 | continue; |
1099 | } else { | ||
1100 | list_add(&page->lru, dst); | ||
1101 | nr_taken++; | ||
1102 | } | 1096 | } |
1097 | |||
1098 | /* | ||
1099 | * Be careful not to clear PageLRU until after we're sure | ||
1100 | * the page is not being freed elsewhere -- the page release | ||
1101 | * code relies on it. | ||
1102 | */ | ||
1103 | if (!TestClearPageLRU(page)) | ||
1104 | BUG(); | ||
1105 | list_add(&page->lru, dst); | ||
1106 | nr_taken++; | ||
1103 | } | 1107 | } |
1104 | 1108 | ||
1105 | *scanned = scan; | 1109 | *scanned = scan; |