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 2/3 v2] swap: refactor pagevec flushing
Date: Mon, 27 Oct 2008 13:18:38 +0100 [thread overview]
Message-ID: <873aiii63l.fsf_-_@saeurebad.de> (raw)
In-Reply-To: <877i7uihns.fsf@saeurebad.de> (Johannes Weiner's message of "Mon, 27 Oct 2008 09:08:55 +0100")
Johannes Weiner <hannes@saeurebad.de> writes:
> Andrew Morton <akpm@linux-foundation.org> writes:
>
>> On Thu, 23 Oct 2008 00:50:08 +0200 Johannes Weiner <hannes@saeurebad.de> wrote:
>>
>>> Having all pagevecs in one array allows for easier flushing. Use a
>>> single flush function that decides what to do based on the target LRU.
>>>
>>> Signed-off-by: Johannes Weiner <hannes@saeurebad.de>
>>> ---
>>> include/linux/pagevec.h | 13 +++--
>>> mm/swap.c | 121 +++++++++++++++++++++++-------------------------
>>> 2 files changed, 66 insertions(+), 68 deletions(-)
>>>
>>> --- a/include/linux/pagevec.h
>>> +++ b/include/linux/pagevec.h
>>> @@ -27,10 +27,13 @@ enum lru_pagevec {
>>> NR_LRU_PAGEVECS
>>> };
>>>
>>> +#define for_each_lru_pagevec(pv) \
>>> + for (pv = 0; pv < NR_LRU_PAGEVECS; pv++)
>>
>> This only gets used once. I don't think it's existence is justified?
>
> I don't see any other use-case for it now. So, yes, let's drop it.
>
>> (`pv' is usally parenthesised in macros like this, but it's unlikely to
>> matter).
>
> Hmm, wondering which valid lvalue construction could break it...?
> Probably something involving stars...
>
> Okay, get doubly rid of it. Replacement patch coming soon.
---
Having all pagevecs in one array allows for easier flushing. Use a
single flush function that decides what to do based on the target LRU.
Signed-off-by: Johannes Weiner <hannes@saeurebad.de>
---
v2: Drop for_each_lru_pagevec()
include/linux/pagevec.h | 10 +--
mm/swap.c | 121 +++++++++++++++++++++++-------------------------
2 files changed, 63 insertions(+), 68 deletions(-)
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -30,7 +30,7 @@ enum lru_pagevec {
void __pagevec_release(struct pagevec *pvec);
void __pagevec_release_nonlru(struct pagevec *pvec);
void __pagevec_free(struct pagevec *pvec);
-void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru);
+void __pagevec_flush(struct pagevec *pvec, enum lru_pagevec target);
void pagevec_strip(struct pagevec *pvec);
void pagevec_swap_free(struct pagevec *pvec);
unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
@@ -90,22 +90,22 @@ static inline void pagevec_free(struct p
static inline void __pagevec_lru_add_anon(struct pagevec *pvec)
{
- ____pagevec_lru_add(pvec, LRU_INACTIVE_ANON);
+ __pagevec_flush(pvec, LRU_INACTIVE_ANON);
}
static inline void __pagevec_lru_add_active_anon(struct pagevec *pvec)
{
- ____pagevec_lru_add(pvec, LRU_ACTIVE_ANON);
+ __pagevec_flush(pvec, LRU_ACTIVE_ANON);
}
static inline void __pagevec_lru_add_file(struct pagevec *pvec)
{
- ____pagevec_lru_add(pvec, LRU_INACTIVE_FILE);
+ __pagevec_flush(pvec, LRU_INACTIVE_FILE);
}
static inline void __pagevec_lru_add_active_file(struct pagevec *pvec)
{
- ____pagevec_lru_add(pvec, LRU_ACTIVE_FILE);
+ __pagevec_flush(pvec, LRU_ACTIVE_FILE);
}
static inline void pagevec_lru_add_file(struct pagevec *pvec)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -96,17 +96,44 @@ void put_pages_list(struct list_head *pa
}
EXPORT_SYMBOL(put_pages_list);
-/*
- * pagevec_move_tail() must be called with IRQ disabled.
- * Otherwise this may cause nasty races.
- */
-static void pagevec_move_tail(struct pagevec *pvec)
+static void pagevec_flush_add(struct zone *zone, struct page *page,
+ enum lru_list lru)
+{
+ VM_BUG_ON(is_unevictable_lru(lru));
+ VM_BUG_ON(PageActive(page));
+ VM_BUG_ON(PageUnevictable(page));
+ VM_BUG_ON(PageLRU(page));
+ SetPageLRU(page);
+ if (is_active_lru(lru))
+ SetPageActive(page);
+ add_page_to_lru_list(zone, page, lru);
+}
+
+static void pagevec_flush_rotate(struct zone *zone, struct page *page)
+{
+ int lru;
+
+ if (!PageLRU(page) || PageActive(page) || PageUnevictable(page))
+ return;
+ lru = page_is_file_cache(page);
+ list_move_tail(&page->lru, &zone->lru[lru].list);
+ __count_vm_event(PGROTATED);
+}
+
+static enum lru_pagevec target_mode(enum lru_pagevec target)
+{
+ if (target > PAGEVEC_ADD && target < PAGEVEC_ROTATE)
+ return PAGEVEC_ADD;
+ return target;
+}
+
+static void ____pagevec_flush(struct pagevec *pvec, enum lru_pagevec target)
{
int i;
- int pgmoved = 0;
struct zone *zone = NULL;
for (i = 0; i < pagevec_count(pvec); i++) {
+ enum lru_pagevec mode;
struct page *page = pvec->pages[i];
struct zone *pagezone = page_zone(page);
@@ -116,19 +143,33 @@ static void pagevec_move_tail(struct pag
zone = pagezone;
spin_lock(&zone->lru_lock);
}
- if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
- int lru = page_is_file_cache(page);
- list_move_tail(&page->lru, &zone->lru[lru].list);
- pgmoved++;
+
+ mode = target_mode(target);
+ switch (mode) {
+ case PAGEVEC_ADD:
+ pagevec_flush_add(zone, page, target);
+ break;
+ case PAGEVEC_ROTATE:
+ pagevec_flush_rotate(zone, page);
+ break;
+ default:
+ BUG();
}
}
if (zone)
spin_unlock(&zone->lru_lock);
- __count_vm_events(PGROTATED, pgmoved);
release_pages(pvec->pages, pvec->nr, pvec->cold);
pagevec_reinit(pvec);
}
+void __pagevec_flush(struct pagevec *pvec, enum lru_pagevec target)
+{
+ local_irq_disable();
+ ____pagevec_flush(pvec, target);
+ local_irq_enable();
+}
+EXPORT_SYMBOL(__pagevec_flush);
+
/*
* 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
@@ -145,7 +186,7 @@ void rotate_reclaimable_page(struct pag
local_irq_save(flags);
pvec = &__get_cpu_var(lru_pvecs)[PAGEVEC_ROTATE];
if (!pagevec_add(pvec, page))
- pagevec_move_tail(pvec);
+ ____pagevec_flush(pvec, PAGEVEC_ROTATE);
local_irq_restore(flags);
}
}
@@ -201,7 +242,7 @@ void __lru_cache_add(struct page *page,
page_cache_get(page);
if (!pagevec_add(pvec, page))
- ____pagevec_lru_add(pvec, lru);
+ __pagevec_flush(pvec, lru);
put_cpu_var(lru_pvecs);
}
@@ -273,22 +314,12 @@ static void drain_cpu_pagevecs(int cpu)
{
struct pagevec *pvecs = per_cpu(lru_pvecs, cpu);
struct pagevec *pvec;
- int lru;
+ int pv;
- for_each_lru(lru) {
- pvec = &pvecs[PAGEVEC_ADD + lru];
+ for (pv = 0; pv < NR_LRU_PAGEVECS; pv++) {
+ pvec = &pvecs[pv];
if (pagevec_count(pvec))
- ____pagevec_lru_add(pvec, lru);
- }
-
- pvec = &pvecs[PAGEVEC_ROTATE];
- if (pagevec_count(pvec)) {
- unsigned long flags;
-
- /* No harm done if a racing interrupt already did this */
- local_irq_save(flags);
- pagevec_move_tail(pvec);
- local_irq_restore(flags);
+ __pagevec_flush(pvec, pv);
}
}
@@ -432,42 +463,6 @@ void __pagevec_release_nonlru(struct pag
}
/*
- * Add the passed pages to the LRU, then drop the caller's refcount
- * on them. Reinitialises the caller's pagevec.
- */
-void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru)
-{
- int i;
- struct zone *zone = NULL;
- VM_BUG_ON(is_unevictable_lru(lru));
-
- 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(PageActive(page));
- VM_BUG_ON(PageUnevictable(page));
- VM_BUG_ON(PageLRU(page));
- SetPageLRU(page);
- if (is_active_lru(lru))
- SetPageActive(page);
- add_page_to_lru_list(zone, page, lru);
- }
- 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
*/
void pagevec_strip(struct pagevec *pvec)
--
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>
next prev parent reply other threads:[~2008-10-27 12:18 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 ` Johannes Weiner [this message]
2008-10-22 22:50 ` [patch 3/3] swap: cache page activation Johannes Weiner
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=873aiii63l.fsf_-_@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