diff options
Diffstat (limited to 'mm/swap.c')
| -rw-r--r-- | mm/swap.c | 64 |
1 files changed, 33 insertions, 31 deletions
| @@ -209,19 +209,18 @@ int lru_add_drain_all(void) | |||
| 209 | */ | 209 | */ |
| 210 | void fastcall __page_cache_release(struct page *page) | 210 | void fastcall __page_cache_release(struct page *page) |
| 211 | { | 211 | { |
| 212 | unsigned long flags; | 212 | if (PageLRU(page)) { |
| 213 | struct zone *zone = page_zone(page); | 213 | unsigned long flags; |
| 214 | struct zone *zone = page_zone(page); | ||
| 214 | 215 | ||
| 215 | spin_lock_irqsave(&zone->lru_lock, flags); | 216 | spin_lock_irqsave(&zone->lru_lock, flags); |
| 216 | if (TestClearPageLRU(page)) | 217 | BUG_ON(!PageLRU(page)); |
| 218 | __ClearPageLRU(page); | ||
| 217 | del_page_from_lru(zone, page); | 219 | del_page_from_lru(zone, page); |
| 218 | if (page_count(page) != 0) | 220 | spin_unlock_irqrestore(&zone->lru_lock, flags); |
| 219 | page = NULL; | 221 | } |
| 220 | spin_unlock_irqrestore(&zone->lru_lock, flags); | 222 | free_hot_page(page); |
| 221 | if (page) | ||
| 222 | free_hot_page(page); | ||
| 223 | } | 223 | } |
| 224 | |||
| 225 | EXPORT_SYMBOL(__page_cache_release); | 224 | EXPORT_SYMBOL(__page_cache_release); |
| 226 | 225 | ||
| 227 | /* | 226 | /* |
| @@ -245,7 +244,6 @@ void release_pages(struct page **pages, int nr, int cold) | |||
| 245 | pagevec_init(&pages_to_free, cold); | 244 | pagevec_init(&pages_to_free, cold); |
| 246 | for (i = 0; i < nr; i++) { | 245 | for (i = 0; i < nr; i++) { |
| 247 | struct page *page = pages[i]; | 246 | struct page *page = pages[i]; |
| 248 | struct zone *pagezone; | ||
| 249 | 247 | ||
| 250 | if (unlikely(PageCompound(page))) { | 248 | if (unlikely(PageCompound(page))) { |
| 251 | if (zone) { | 249 | if (zone) { |
| @@ -259,23 +257,27 @@ void release_pages(struct page **pages, int nr, int cold) | |||
| 259 | if (!put_page_testzero(page)) | 257 | if (!put_page_testzero(page)) |
| 260 | continue; | 258 | continue; |
| 261 | 259 | ||
| 262 | pagezone = page_zone(page); | 260 | if (PageLRU(page)) { |
| 263 | if (pagezone != zone) { | 261 | struct zone *pagezone = page_zone(page); |
| 264 | if (zone) | 262 | if (pagezone != zone) { |
| 265 | spin_unlock_irq(&zone->lru_lock); | 263 | if (zone) |
| 266 | zone = pagezone; | 264 | spin_unlock_irq(&zone->lru_lock); |
| 267 | spin_lock_irq(&zone->lru_lock); | 265 | zone = pagezone; |
| 268 | } | 266 | spin_lock_irq(&zone->lru_lock); |
| 269 | if (TestClearPageLRU(page)) | 267 | } |
| 268 | BUG_ON(!PageLRU(page)); | ||
| 269 | __ClearPageLRU(page); | ||
| 270 | del_page_from_lru(zone, page); | 270 | del_page_from_lru(zone, page); |
| 271 | if (page_count(page) == 0) { | 271 | } |
| 272 | if (!pagevec_add(&pages_to_free, page)) { | 272 | |
| 273 | if (!pagevec_add(&pages_to_free, page)) { | ||
| 274 | if (zone) { | ||
| 273 | spin_unlock_irq(&zone->lru_lock); | 275 | spin_unlock_irq(&zone->lru_lock); |
| 274 | __pagevec_free(&pages_to_free); | 276 | zone = NULL; |
| 275 | pagevec_reinit(&pages_to_free); | ||
| 276 | zone = NULL; /* No lock is held */ | ||
| 277 | } | 277 | } |
| 278 | } | 278 | __pagevec_free(&pages_to_free); |
| 279 | pagevec_reinit(&pages_to_free); | ||
| 280 | } | ||
| 279 | } | 281 | } |
| 280 | if (zone) | 282 | if (zone) |
| 281 | spin_unlock_irq(&zone->lru_lock); | 283 | spin_unlock_irq(&zone->lru_lock); |
| @@ -343,8 +345,8 @@ void __pagevec_lru_add(struct pagevec *pvec) | |||
| 343 | zone = pagezone; | 345 | zone = pagezone; |
| 344 | spin_lock_irq(&zone->lru_lock); | 346 | spin_lock_irq(&zone->lru_lock); |
| 345 | } | 347 | } |
| 346 | if (TestSetPageLRU(page)) | 348 | BUG_ON(PageLRU(page)); |
| 347 | BUG(); | 349 | SetPageLRU(page); |
| 348 | add_page_to_inactive_list(zone, page); | 350 | add_page_to_inactive_list(zone, page); |
| 349 | } | 351 | } |
| 350 | if (zone) | 352 | if (zone) |
| @@ -370,10 +372,10 @@ void __pagevec_lru_add_active(struct pagevec *pvec) | |||
| 370 | zone = pagezone; | 372 | zone = pagezone; |
| 371 | spin_lock_irq(&zone->lru_lock); | 373 | spin_lock_irq(&zone->lru_lock); |
| 372 | } | 374 | } |
| 373 | if (TestSetPageLRU(page)) | 375 | BUG_ON(PageLRU(page)); |
| 374 | BUG(); | 376 | SetPageLRU(page); |
| 375 | if (TestSetPageActive(page)) | 377 | BUG_ON(PageActive(page)); |
| 376 | BUG(); | 378 | SetPageActive(page); |
| 377 | add_page_to_active_list(zone, page); | 379 | add_page_to_active_list(zone, page); |
| 378 | } | 380 | } |
| 379 | if (zone) | 381 | if (zone) |
