linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Johannes Weiner <hannes@saeurebad.de>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Rik van Riel <riel@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	linux-mm@kvack.org
Subject: [patch 3/3] swap: cache page activation
Date: Thu, 23 Oct 2008 00:50:09 +0200	[thread overview]
Message-ID: <20081022225513.040237161@saeurebad.de> (raw)
In-Reply-To: <20081022225006.010250557@saeurebad.de>

[-- Attachment #1: swap-cache-page-activation.patch --]
[-- Type: text/plain, Size: 3938 bytes --]

Instead of acquiring the highly contented LRU lock on each page
activation, use a pagevec and activate pages batch-wise.

Also factor out the add-to-cache-maybe-flush mechanism that is
shared between page rotation and activation code.

Signed-off-by: Johannes Weiner <hannes@saeurebad.de>
---
 include/linux/pagevec.h |    1 
 mm/swap.c               |   80 +++++++++++++++++++++++++++---------------------
 2 files changed, 47 insertions(+), 34 deletions(-)

--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -24,6 +24,7 @@ enum lru_pagevec {
 	PAGEVEC_BASE,
 	PAGEVEC_ADD = PAGEVEC_BASE,
 	PAGEVEC_ROTATE = NR_LRU_LISTS,
+	PAGEVEC_ACTIVATE,
 	NR_LRU_PAGEVECS
 };
 
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -120,6 +120,24 @@ static void pagevec_flush_rotate(struct 
 	__count_vm_event(PGROTATED);
 }
 
+static void pagevec_flush_activate(struct zone *zone, struct page *page)
+{
+	int file, lru;
+
+	if (!PageLRU(page) || PageActive(page) || PageUnevictable(page))
+		return;
+	file = page_is_file_cache(page);
+	lru = LRU_BASE + file;
+	del_page_from_lru_list(zone, page, lru);
+	SetPageActive(page);
+	lru += LRU_ACTIVE;
+	add_page_to_lru_list(zone, page, lru);
+	mem_cgroup_move_lists(page, lru);
+	__count_vm_event(PGACTIVATE);
+	zone->recent_rotated[!!file]++;
+	zone->recent_scanned[!!file]++;
+}
+
 static enum lru_pagevec target_mode(enum lru_pagevec target)
 {
 	if (target > PAGEVEC_ADD && target < PAGEVEC_ROTATE)
@@ -152,6 +170,9 @@ static void ____pagevec_flush(struct pag
 		case PAGEVEC_ROTATE:
 			pagevec_flush_rotate(zone, page);
 			break;
+		case PAGEVEC_ACTIVATE:
+			pagevec_flush_activate(zone, page);
+			break;
 		default:
 			BUG();
 		}
@@ -170,50 +191,41 @@ void __pagevec_flush(struct pagevec *pve
 }
 EXPORT_SYMBOL(__pagevec_flush);
 
+static void move_page(struct page *page, enum lru_pagevec target)
+{
+	struct pagevec *pvec;
+
+	pvec = &__get_cpu_var(lru_pvecs)[target];
+	if (!pagevec_add(pvec, page))
+		____pagevec_flush(pvec, target);
+}
+
 /*
  * Writeback is about to end against a page which has been marked for immediate
  * reclaim.  If it still appears to be reclaimable, move it to the tail of the
  * inactive list.
  */
-void  rotate_reclaimable_page(struct page *page)
+void rotate_reclaimable_page(struct page *page)
 {
-	if (!PageLocked(page) && !PageDirty(page) && !PageActive(page) &&
-	    !PageUnevictable(page) && PageLRU(page)) {
-		struct pagevec *pvec;
-		unsigned long flags;
-
-		page_cache_get(page);
-		local_irq_save(flags);
-		pvec = &__get_cpu_var(lru_pvecs)[PAGEVEC_ROTATE];
-		if (!pagevec_add(pvec, page))
-			____pagevec_flush(pvec, PAGEVEC_ROTATE);
-		local_irq_restore(flags);
-	}
+	unsigned long flags;
+
+	if (!PageLRU(page) || PageActive(page) || PageUnevictable(page))
+		return;
+	if (PageLocked(page) || PageDirty(page))
+		return;
+	page_cache_get(page);
+	local_irq_save(flags);
+	move_page(page, PAGEVEC_ROTATE);
+	local_irq_restore(flags);
 }
 
-/*
- * FIXME: speed this up?
- */
 void activate_page(struct page *page)
 {
-	struct zone *zone = page_zone(page);
-
-	spin_lock_irq(&zone->lru_lock);
-	if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
-		int file = page_is_file_cache(page);
-		int lru = LRU_BASE + file;
-		del_page_from_lru_list(zone, page, lru);
-
-		SetPageActive(page);
-		lru += LRU_ACTIVE;
-		add_page_to_lru_list(zone, page, lru);
-		__count_vm_event(PGACTIVATE);
-		mem_cgroup_move_lists(page, lru);
-
-		zone->recent_rotated[!!file]++;
-		zone->recent_scanned[!!file]++;
-	}
-	spin_unlock_irq(&zone->lru_lock);
+	if (!PageLRU(page) || PageActive(page) || PageUnevictable(page))
+		return;
+	local_irq_disable();
+	move_page(page, PAGEVEC_ACTIVATE);
+	local_irq_enable();
 }
 
 /*


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2008-10-22 22:50 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-22 22:50 [patch 0/3] activate pages in batch Johannes Weiner
2008-10-22 22:50 ` [patch 1/3] swap: use an array for all pagevecs Johannes Weiner
2008-10-22 22:50 ` [patch 2/3] swap: refactor pagevec flushing Johannes Weiner
2008-10-27  6:50   ` Andrew Morton
2008-10-27  8:08     ` Johannes Weiner
2008-10-27 12:18       ` [patch 2/3 v2] " Johannes Weiner
2008-10-22 22:50 ` Johannes Weiner [this message]
2008-10-23  1:41 ` [patch 0/3] activate pages in batch KOSAKI Motohiro
2008-10-23  2:00   ` Johannes Weiner
2008-10-23  2:10     ` KOSAKI Motohiro
2008-10-23 16:21       ` Johannes Weiner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081022225513.040237161@saeurebad.de \
    --to=hannes@saeurebad.de \
    --cc=akpm@linux-foundation.org \
    --cc=linux-mm@kvack.org \
    --cc=peterz@infradead.org \
    --cc=riel@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox