From: Roger Larsson <roger.larsson@norran.net>
To: Linus Torvalds <torvalds@transmeta.com>,
Ingo Molnar <mingo@chiara.elte.hu>
Cc: Rik van Riel <riel@conectiva.com.br>,
"linux-mm@kvack.org" <linux-mm@kvack.org>
Subject: [PATCH] more efficient shrink_mmap
Date: Sat, 13 May 2000 19:37:34 +0200 [thread overview]
Message-ID: <391D92DE.1AA3F6EA@norran.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 817 bytes --]
This patch is against pre7-9 (almost)
I will prepare a patch against pre8 but it might take
until Monday.
Tested on PPro 180 UP system with 96MB RAM.
(Bennos latency tests)
This shrink_mmap checks all pages at the priority level
and frees the one it can. And then it is not retried
with the same level.
It does not move pages around unnecessarily thus keeping
the list LRU (unscanned but referenced pages are not
moved up... bad)
I think the locking is SMP safe [Ingo].
pagemap_lru_lock or page_locked
It uses the >> priority trick since that will result
in scanning double amount of pages next time.
(pages already scanned + the same no of prev. unscanned)
vmscan.c is modified to call only once per priority level.
(it has the goto sleep patch too)
/RogerL
--
Home page:
http://www.norran.net/nra02596/
[-- Attachment #2: patch-2.3.99-pre7-9-shrink_mmap.2 --]
[-- Type: text/plain, Size: 3906 bytes --]
--- linux-2.3-pre9--/mm/filemap.c Fri May 12 02:42:19 2000
+++ linux-2.3/mm/filemap.c Sat May 13 18:01:25 2000
@@ -236,34 +236,36 @@
int shrink_mmap(int priority, int gfp_mask)
{
int ret = 0, count;
- LIST_HEAD(old);
struct list_head * page_lru, * dispose;
struct page * page = NULL;
- count = nr_lru_pages / (priority + 1);
+ count = nr_lru_pages >> priority;
/* we need pagemap_lru_lock for list_del() ... subtle code below */
spin_lock(&pagemap_lru_lock);
- while (count > 0 && (page_lru = lru_cache.prev) != &lru_cache) {
+ page_lru = &lru_cache;
+ while (count > 0 && (page_lru = page_lru->prev) != &lru_cache) {
page = list_entry(page_lru, struct page, lru);
- list_del(page_lru);
dispose = &lru_cache;
if (PageTestandClearReferenced(page))
goto dispose_continue;
count--;
- dispose = &old;
+
+ dispose = NULL;
/*
* Avoid unscalable SMP locking for pages we can
* immediate tell are untouchable..
*/
if (!page->buffers && page_count(page) > 1)
- goto dispose_continue;
+ continue;
+ /* Lock this lru page, reentrant
+ * will be disposed correctly when unlocked */
if (TryLockPage(page))
- goto dispose_continue;
+ continue;
/* Release the pagemap_lru lock even if the page is not yet
queued in any lru queue since we have just locked down
@@ -281,7 +283,7 @@
*/
if (page->buffers) {
if (!try_to_free_buffers(page))
- goto unlock_continue;
+ goto page_unlock_continue;
/* page was locked, inode can't go away under us */
if (!page->mapping) {
atomic_dec(&buffermem_pages);
@@ -336,27 +338,43 @@
cache_unlock_continue:
spin_unlock(&pagecache_lock);
-unlock_continue:
+page_unlock_continue:
spin_lock(&pagemap_lru_lock);
UnlockPage(page);
put_page(page);
+ continue;
+
dispose_continue:
- list_add(page_lru, dispose);
- }
- goto out;
+ /* have the pagemap_lru_lock, lru cannot change */
+ {
+ struct list_head * page_lru_to_move = page_lru;
+ page_lru = page_lru->next; /* continues with page_lru.prev */
+ list_del(page_lru_to_move);
+ list_add(page_lru_to_move, dispose);
+ }
+ continue;
made_inode_progress:
- page_cache_release(page);
+ page_cache_release(page);
made_buffer_progress:
- UnlockPage(page);
- put_page(page);
- ret = 1;
- spin_lock(&pagemap_lru_lock);
- /* nr_lru_pages needs the spinlock */
- nr_lru_pages--;
+ /* like to have the lru lock before UnlockPage */
+ spin_lock(&pagemap_lru_lock);
-out:
- list_splice(&old, lru_cache.prev);
+ UnlockPage(page);
+ put_page(page);
+ ret++;
+
+ /* lru manipulation needs the spin lock */
+ {
+ struct list_head * page_lru_to_free = page_lru;
+ page_lru = page_lru->next; /* continues with page_lru.prev */
+ list_del(page_lru_to_free);
+ }
+
+ /* nr_lru_pages needs the spinlock */
+ nr_lru_pages--;
+
+ }
spin_unlock(&pagemap_lru_lock);
--- linux-2.3-pre9--/mm/vmscan.c Fri May 12 02:42:19 2000
+++ linux-2.3/mm/vmscan.c Sat May 13 19:01:51 2000
@@ -443,10 +443,9 @@
priority = 6;
do {
- while (shrink_mmap(priority, gfp_mask)) {
- if (!--count)
- goto done;
- }
+ count -= shrink_mmap(priority, gfp_mask);
+ if (count <= 0)
+ goto done;
/* Try to get rid of some shared memory pages.. */
if (gfp_mask & __GFP_IO) {
@@ -481,10 +480,9 @@
} while (--priority >= 0);
/* Always end on a shrink_mmap.. */
- while (shrink_mmap(0, gfp_mask)) {
- if (!--count)
- goto done;
- }
+ count -= shrink_mmap(0, gfp_mask);
+ if (count <= 0)
+ goto done;
return 0;
@@ -544,13 +542,14 @@
something_to_do = 1;
do_try_to_free_pages(GFP_KSWAPD);
if (tsk->need_resched)
- schedule();
+ goto sleep;
}
run_task_queue(&tq_disk);
pgdat = pgdat->node_next;
} while (pgdat);
if (!something_to_do) {
+sleep:
tsk->state = TASK_INTERRUPTIBLE;
interruptible_sleep_on(&kswapd_wait);
}
reply other threads:[~2000-05-13 17:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=391D92DE.1AA3F6EA@norran.net \
--to=roger.larsson@norran.net \
--cc=linux-mm@kvack.org \
--cc=mingo@chiara.elte.hu \
--cc=riel@conectiva.com.br \
--cc=torvalds@transmeta.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