|
@@ -34,8 +34,7 @@
|
|
/* How many pages do we try to swap or page in/out together? */
|
|
/* How many pages do we try to swap or page in/out together? */
|
|
int page_cluster;
|
|
int page_cluster;
|
|
|
|
|
|
-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs);
|
|
|
|
-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs);
|
|
|
|
|
|
+static DEFINE_PER_CPU(struct pagevec[NR_LRU_LISTS], lru_add_pvecs);
|
|
static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
|
|
static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -186,28 +185,29 @@ void mark_page_accessed(struct page *page)
|
|
|
|
|
|
EXPORT_SYMBOL(mark_page_accessed);
|
|
EXPORT_SYMBOL(mark_page_accessed);
|
|
|
|
|
|
-/**
|
|
|
|
- * lru_cache_add: add a page to the page lists
|
|
|
|
- * @page: the page to add
|
|
|
|
- */
|
|
|
|
-void lru_cache_add(struct page *page)
|
|
|
|
|
|
+void __lru_cache_add(struct page *page, enum lru_list lru)
|
|
{
|
|
{
|
|
- struct pagevec *pvec = &get_cpu_var(lru_add_pvecs);
|
|
|
|
|
|
+ struct pagevec *pvec = &get_cpu_var(lru_add_pvecs)[lru];
|
|
|
|
|
|
page_cache_get(page);
|
|
page_cache_get(page);
|
|
if (!pagevec_add(pvec, page))
|
|
if (!pagevec_add(pvec, page))
|
|
- __pagevec_lru_add(pvec);
|
|
|
|
|
|
+ ____pagevec_lru_add(pvec, lru);
|
|
put_cpu_var(lru_add_pvecs);
|
|
put_cpu_var(lru_add_pvecs);
|
|
}
|
|
}
|
|
|
|
|
|
-void lru_cache_add_active(struct page *page)
|
|
|
|
|
|
+/**
|
|
|
|
+ * lru_cache_add_lru - add a page to a page list
|
|
|
|
+ * @page: the page to be added to the LRU.
|
|
|
|
+ * @lru: the LRU list to which the page is added.
|
|
|
|
+ */
|
|
|
|
+void lru_cache_add_lru(struct page *page, enum lru_list lru)
|
|
{
|
|
{
|
|
- struct pagevec *pvec = &get_cpu_var(lru_add_active_pvecs);
|
|
|
|
|
|
+ if (PageActive(page)) {
|
|
|
|
+ ClearPageActive(page);
|
|
|
|
+ }
|
|
|
|
|
|
- page_cache_get(page);
|
|
|
|
- if (!pagevec_add(pvec, page))
|
|
|
|
- __pagevec_lru_add_active(pvec);
|
|
|
|
- put_cpu_var(lru_add_active_pvecs);
|
|
|
|
|
|
+ VM_BUG_ON(PageLRU(page) || PageActive(page));
|
|
|
|
+ __lru_cache_add(page, lru);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -217,15 +217,15 @@ void lru_cache_add_active(struct page *page)
|
|
*/
|
|
*/
|
|
static void drain_cpu_pagevecs(int cpu)
|
|
static void drain_cpu_pagevecs(int cpu)
|
|
{
|
|
{
|
|
|
|
+ struct pagevec *pvecs = per_cpu(lru_add_pvecs, cpu);
|
|
struct pagevec *pvec;
|
|
struct pagevec *pvec;
|
|
|
|
+ int lru;
|
|
|
|
|
|
- pvec = &per_cpu(lru_add_pvecs, cpu);
|
|
|
|
- if (pagevec_count(pvec))
|
|
|
|
- __pagevec_lru_add(pvec);
|
|
|
|
-
|
|
|
|
- pvec = &per_cpu(lru_add_active_pvecs, cpu);
|
|
|
|
- if (pagevec_count(pvec))
|
|
|
|
- __pagevec_lru_add_active(pvec);
|
|
|
|
|
|
+ for_each_lru(lru) {
|
|
|
|
+ pvec = &pvecs[lru - LRU_BASE];
|
|
|
|
+ if (pagevec_count(pvec))
|
|
|
|
+ ____pagevec_lru_add(pvec, lru);
|
|
|
|
+ }
|
|
|
|
|
|
pvec = &per_cpu(lru_rotate_pvecs, cpu);
|
|
pvec = &per_cpu(lru_rotate_pvecs, cpu);
|
|
if (pagevec_count(pvec)) {
|
|
if (pagevec_count(pvec)) {
|
|
@@ -380,7 +380,7 @@ void __pagevec_release_nonlru(struct pagevec *pvec)
|
|
* Add the passed pages to the LRU, then drop the caller's refcount
|
|
* Add the passed pages to the LRU, then drop the caller's refcount
|
|
* on them. Reinitialises the caller's pagevec.
|
|
* on them. Reinitialises the caller's pagevec.
|
|
*/
|
|
*/
|
|
-void __pagevec_lru_add(struct pagevec *pvec)
|
|
|
|
|
|
+void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
struct zone *zone = NULL;
|
|
struct zone *zone = NULL;
|
|
@@ -397,7 +397,9 @@ void __pagevec_lru_add(struct pagevec *pvec)
|
|
}
|
|
}
|
|
VM_BUG_ON(PageLRU(page));
|
|
VM_BUG_ON(PageLRU(page));
|
|
SetPageLRU(page);
|
|
SetPageLRU(page);
|
|
- add_page_to_inactive_list(zone, page);
|
|
|
|
|
|
+ if (is_active_lru(lru))
|
|
|
|
+ SetPageActive(page);
|
|
|
|
+ add_page_to_lru_list(zone, page, lru);
|
|
}
|
|
}
|
|
if (zone)
|
|
if (zone)
|
|
spin_unlock_irq(&zone->lru_lock);
|
|
spin_unlock_irq(&zone->lru_lock);
|
|
@@ -405,34 +407,7 @@ void __pagevec_lru_add(struct pagevec *pvec)
|
|
pagevec_reinit(pvec);
|
|
pagevec_reinit(pvec);
|
|
}
|
|
}
|
|
|
|
|
|
-EXPORT_SYMBOL(__pagevec_lru_add);
|
|
|
|
-
|
|
|
|
-void __pagevec_lru_add_active(struct pagevec *pvec)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
- struct zone *zone = NULL;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < pagevec_count(pvec); i++) {
|
|
|
|
- struct page *page = pvec->pages[i];
|
|
|
|
- struct zone *pagezone = page_zone(page);
|
|
|
|
-
|
|
|
|
- if (pagezone != zone) {
|
|
|
|
- if (zone)
|
|
|
|
- spin_unlock_irq(&zone->lru_lock);
|
|
|
|
- zone = pagezone;
|
|
|
|
- spin_lock_irq(&zone->lru_lock);
|
|
|
|
- }
|
|
|
|
- VM_BUG_ON(PageLRU(page));
|
|
|
|
- SetPageLRU(page);
|
|
|
|
- VM_BUG_ON(PageActive(page));
|
|
|
|
- SetPageActive(page);
|
|
|
|
- add_page_to_active_list(zone, page);
|
|
|
|
- }
|
|
|
|
- if (zone)
|
|
|
|
- spin_unlock_irq(&zone->lru_lock);
|
|
|
|
- release_pages(pvec->pages, pvec->nr, pvec->cold);
|
|
|
|
- pagevec_reinit(pvec);
|
|
|
|
-}
|
|
|
|
|
|
+EXPORT_SYMBOL(____pagevec_lru_add);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Try to drop buffers from the pages in a pagevec
|
|
* Try to drop buffers from the pages in a pagevec
|