diff options
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 1ff1a58e7c10..1fd4912a596c 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -844,6 +844,51 @@ static unsigned long clear_active_flags(struct list_head *page_list) | |||
844 | return nr_active; | 844 | return nr_active; |
845 | } | 845 | } |
846 | 846 | ||
847 | /** | ||
848 | * isolate_lru_page - tries to isolate a page from its LRU list | ||
849 | * @page: page to isolate from its LRU list | ||
850 | * | ||
851 | * Isolates a @page from an LRU list, clears PageLRU and adjusts the | ||
852 | * vmstat statistic corresponding to whatever LRU list the page was on. | ||
853 | * | ||
854 | * Returns 0 if the page was removed from an LRU list. | ||
855 | * Returns -EBUSY if the page was not on an LRU list. | ||
856 | * | ||
857 | * The returned page will have PageLRU() cleared. If it was found on | ||
858 | * the active list, it will have PageActive set. That flag may need | ||
859 | * to be cleared by the caller before letting the page go. | ||
860 | * | ||
861 | * The vmstat statistic corresponding to the list on which the page was | ||
862 | * found will be decremented. | ||
863 | * | ||
864 | * Restrictions: | ||
865 | * (1) Must be called with an elevated refcount on the page. This is a | ||
866 | * fundamentnal difference from isolate_lru_pages (which is called | ||
867 | * without a stable reference). | ||
868 | * (2) the lru_lock must not be held. | ||
869 | * (3) interrupts must be enabled. | ||
870 | */ | ||
871 | int isolate_lru_page(struct page *page) | ||
872 | { | ||
873 | int ret = -EBUSY; | ||
874 | |||
875 | if (PageLRU(page)) { | ||
876 | struct zone *zone = page_zone(page); | ||
877 | |||
878 | spin_lock_irq(&zone->lru_lock); | ||
879 | if (PageLRU(page) && get_page_unless_zero(page)) { | ||
880 | ret = 0; | ||
881 | ClearPageLRU(page); | ||
882 | if (PageActive(page)) | ||
883 | del_page_from_active_list(zone, page); | ||
884 | else | ||
885 | del_page_from_inactive_list(zone, page); | ||
886 | } | ||
887 | spin_unlock_irq(&zone->lru_lock); | ||
888 | } | ||
889 | return ret; | ||
890 | } | ||
891 | |||
847 | /* | 892 | /* |
848 | * shrink_inactive_list() is a helper for shrink_zone(). It returns the number | 893 | * shrink_inactive_list() is a helper for shrink_zone(). It returns the number |
849 | * of reclaimed pages | 894 | * of reclaimed pages |