* [PATCH] shrink_mmap with fewer list modifications
@ 2000-05-29 21:35 Roger Larsson
0 siblings, 0 replies; only message in thread
From: Roger Larsson @ 2000-05-29 21:35 UTC (permalink / raw)
To: linux-mm@kvack.org, Juan J. Quintela
[-- Attachment #1: Type: text/plain, Size: 386 bytes --]
Hi,
This patch improves Riels patch by using fewer list modifications.
It could be applied to most shrink_mmaps but Riels version will
gain the most.
Function:
- Do not delete + insert all pages while scanning.
- Scan until a suitable page is found, then move the head.
/RogerL
This time with diff -Naur ... and Riels patch removed...
--
Home page:
http://www.norran.net/nra02596/
[-- Attachment #2: patch-2.4.0-test1-deferred_swap-speedup.2 --]
[-- Type: text/plain, Size: 2998 bytes --]
--- /usr/src/linux/mm/filemap.c.riel Sat May 27 01:22:47 2000
+++ /usr/src/linux/mm/filemap.c Mon May 29 16:58:56 2000
@@ -258,23 +258,27 @@
count = nr_lru_pages / (priority + 1);
nr_dirty = priority;
- /* we need pagemap_lru_lock for list_del() ... subtle code below */
+ /* we need pagemap_lru_lock for lru_cache head movement... 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;
+ if (page_lru == &lru_cache)
+ break; /* one whole run */
+
page = list_entry(page_lru, struct page, lru);
- list_del(page_lru);
if (PageTestandClearReferenced(page)) {
page->age += 3;
if (page->age > 10)
- page->age = 0;
- goto dispose_continue;
+ page->age = 10;
+ continue;
}
if (page->age)
page->age--;
if (page->age)
- goto dispose_continue;
+ continue;
count--;
/*
@@ -282,10 +286,20 @@
* immediate tell are untouchable..
*/
if (!page->buffers && page_count(page) > 1)
- goto dispose_continue;
+ continue;
if (TryLockPage(page))
- goto dispose_continue;
+ continue;
+
+ /* move header before unlock...
+ * NOTE: the page to scan might move on while having
+ * pagemap_lru unlocked. Avoid rescanning same pages
+ * by moving head and set page_lru to NULL to avoid
+ * misuses!
+ */
+ list_del(&lru_cache);
+ list_add_tail(&lru_cache, page_lru);
+ page_lru = NULL;
/* Release the pagemap_lru lock even if the page is not yet
queued in any lru queue since we have just locked down
@@ -322,6 +336,9 @@
* We can't free pages unless there's just one user
* (count == 2 because we added one ourselves above).
*/
+ if (page_count(page) < 2)
+ BUG();
+
if (page_count(page) != 2)
goto cache_unlock_continue;
@@ -345,7 +362,7 @@
}
/* PageDeferswap -> we swap out the page now. */
if (gfp_mask & __GFP_IO)
- goto async_swap;
+ goto async_swap_continue;
goto cache_unlock_continue;
}
@@ -368,27 +385,29 @@
UnlockPage(page);
page_cache_release(page);
goto dispose_continue;
-async_swap:
+async_swap_continue:
spin_unlock(&pagecache_lock);
/* Do NOT unlock the page ... that is done after IO. */
ClearPageDirty(page);
rw_swap_page(WRITE, page, 0);
+ /* no lock held here? SMP? is page_cache_get enough? */
spin_lock(&pagemap_lru_lock);
page_cache_release(page);
dispose_continue:
- list_add(page_lru, &lru_cache);
+ page_lru = &lru_cache;
}
goto out;
made_inode_progress:
page_cache_release(page);
made_buffer_progress:
- UnlockPage(page);
- page_cache_release(page);
- ret = 1;
spin_lock(&pagemap_lru_lock);
+ list_del(&page->lru); /* page_lru is NULL... */
/* nr_lru_pages needs the spinlock */
nr_lru_pages--;
+ UnlockPage(page);
+ page_cache_release(page);
+ ret = 1;
out:
spin_unlock(&pagemap_lru_lock);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2000-05-29 21:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-05-29 21:35 [PATCH] shrink_mmap with fewer list modifications Roger Larsson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.