* [PATCH] 2.4.1 find_page_nolock fixes
@ 2001-01-30 19:48 ` Rik van Riel
0 siblings, 0 replies; 5+ messages in thread
From: Rik van Riel @ 2001-01-30 19:48 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-mm, linux-kernel
Hi Linus,
the patch below contains 3 small changes to mm/filemap.c:
1. replace the aging in __find_page_nolock() with setting
PageReferenced(), otherwise a large number of small
reads from (or writes to) a page can drive up the page
age unfairly
2. remove the wakeup of kswapd from __find_page_nolock(),
the wakeup condition is complex and leaving out the
wakeup has no influence on any workload I tested in
the last few weeks
3. add a __find_page_simple(), which is like __find_page_nolock()
but only needs 2 arguments and doesn't touch the page ... this
can be used by IO clustering and other things that really don't
want to influence page aging, removing the 3rd argument also
keeps things simple
More trivial and tested patches will follow RSN, time to
improve some VM stuff in 2.4.2-pre1 ;)
One more complex patch for page_launder() will also follow,
but not before I get around to testing it a bit on my boxes
here ... that patch should result in more smooth IO behaviour
because it corrects some of the thinkos that are currently
in page_launder()
regards,
Rik
--
Virtual memory is like a game you can't win;
However, without VM there's truly nothing to lose...
http://www.surriel.com/
http://www.conectiva.com/ http://distro.conectiva.com.br/
--- mm/filemap.c.orig Tue Jan 30 17:02:23 2001
+++ mm/filemap.c Tue Jan 30 17:25:29 2001
@@ -286,6 +286,34 @@
spin_unlock(&pagecache_lock);
}
+/*
+ * This function is pretty much like __find_page_nolock(), but it only
+ * requires 2 arguments and doesn't mark the page as touched, making it
+ * ideal for ->writepage() clustering and other places where you don't
+ * want to mark the page referenced.
+ *
+ * The caller needs to hold the pagecache_lock.
+ */
+struct page * __find_page_simple(struct address_space *mapping, unsigned long index)
+{
+ struct page * page = *page_hash(mapping, index);
+ goto inside;
+
+ for (;;) {
+ page = page->next_hash;
+inside:
+ if (!page)
+ goto not_found;
+ if (page->mapping != mapping)
+ continue;
+ if (page->index == index)
+ break;
+ }
+
+not_found:
+ return page;
+}
+
static inline struct page * __find_page_nolock(struct address_space *mapping, unsigned long offset, struct page *page)
{
goto inside;
@@ -301,13 +329,14 @@
break;
}
/*
- * Touching the page may move it to the active list.
- * If we end up with too few inactive pages, we wake
- * up kswapd.
+ * Mark the page referenced, moving inactive pages to the
+ * active list.
*/
- age_page_up(page);
- if (inactive_shortage() > inactive_target / 2 && free_shortage())
- wakeup_kswapd();
+ if (!PageActive(page))
+ activate_page(page);
+ else
+ SetPageReferenced(page);
+
not_found:
return page;
}
@@ -735,7 +764,6 @@
{
struct inode *inode = file->f_dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
- struct page **hash;
struct page *page;
unsigned long start;
@@ -756,8 +784,7 @@
*/
spin_lock(&pagecache_lock);
while (--index >= start) {
- hash = page_hash(mapping, index);
- page = __find_page_nolock(mapping, index, *hash);
+ page = __find_page_simple(mapping, index);
if (!page)
break;
deactivate_page(page);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] 2.4.1 find_page_nolock fixes
@ 2001-01-30 19:48 ` Rik van Riel
0 siblings, 0 replies; 5+ messages in thread
From: Rik van Riel @ 2001-01-30 19:48 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-mm, linux-kernel
Hi Linus,
the patch below contains 3 small changes to mm/filemap.c:
1. replace the aging in __find_page_nolock() with setting
PageReferenced(), otherwise a large number of small
reads from (or writes to) a page can drive up the page
age unfairly
2. remove the wakeup of kswapd from __find_page_nolock(),
the wakeup condition is complex and leaving out the
wakeup has no influence on any workload I tested in
the last few weeks
3. add a __find_page_simple(), which is like __find_page_nolock()
but only needs 2 arguments and doesn't touch the page ... this
can be used by IO clustering and other things that really don't
want to influence page aging, removing the 3rd argument also
keeps things simple
More trivial and tested patches will follow RSN, time to
improve some VM stuff in 2.4.2-pre1 ;)
One more complex patch for page_launder() will also follow,
but not before I get around to testing it a bit on my boxes
here ... that patch should result in more smooth IO behaviour
because it corrects some of the thinkos that are currently
in page_launder()
regards,
Rik
--
Virtual memory is like a game you can't win;
However, without VM there's truly nothing to lose...
http://www.surriel.com/
http://www.conectiva.com/ http://distro.conectiva.com.br/
--- mm/filemap.c.orig Tue Jan 30 17:02:23 2001
+++ mm/filemap.c Tue Jan 30 17:25:29 2001
@@ -286,6 +286,34 @@
spin_unlock(&pagecache_lock);
}
+/*
+ * This function is pretty much like __find_page_nolock(), but it only
+ * requires 2 arguments and doesn't mark the page as touched, making it
+ * ideal for ->writepage() clustering and other places where you don't
+ * want to mark the page referenced.
+ *
+ * The caller needs to hold the pagecache_lock.
+ */
+struct page * __find_page_simple(struct address_space *mapping, unsigned long index)
+{
+ struct page * page = *page_hash(mapping, index);
+ goto inside;
+
+ for (;;) {
+ page = page->next_hash;
+inside:
+ if (!page)
+ goto not_found;
+ if (page->mapping != mapping)
+ continue;
+ if (page->index == index)
+ break;
+ }
+
+not_found:
+ return page;
+}
+
static inline struct page * __find_page_nolock(struct address_space *mapping, unsigned long offset, struct page *page)
{
goto inside;
@@ -301,13 +329,14 @@
break;
}
/*
- * Touching the page may move it to the active list.
- * If we end up with too few inactive pages, we wake
- * up kswapd.
+ * Mark the page referenced, moving inactive pages to the
+ * active list.
*/
- age_page_up(page);
- if (inactive_shortage() > inactive_target / 2 && free_shortage())
- wakeup_kswapd();
+ if (!PageActive(page))
+ activate_page(page);
+ else
+ SetPageReferenced(page);
+
not_found:
return page;
}
@@ -735,7 +764,6 @@
{
struct inode *inode = file->f_dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
- struct page **hash;
struct page *page;
unsigned long start;
@@ -756,8 +784,7 @@
*/
spin_lock(&pagecache_lock);
while (--index >= start) {
- hash = page_hash(mapping, index);
- page = __find_page_nolock(mapping, index, *hash);
+ page = __find_page_simple(mapping, index);
if (!page)
break;
deactivate_page(page);
--
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.eu.org/Linux-MM/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] 2.4.1 find_page_nolock fixes
2001-01-30 19:48 ` Rik van Riel
@ 2001-01-31 2:16 ` Marcelo Tosatti
-1 siblings, 0 replies; 5+ messages in thread
From: Marcelo Tosatti @ 2001-01-31 2:16 UTC (permalink / raw)
To: Rik van Riel; +Cc: Linus Torvalds, linux-mm, linux-kernel
On Tue, 30 Jan 2001, Rik van Riel wrote:
> Hi Linus,
>
> the patch below contains 3 small changes to mm/filemap.c:
>
> 1. replace the aging in __find_page_nolock() with setting
> PageReferenced(), otherwise a large number of small
> reads from (or writes to) a page can drive up the page
> age unfairly
>
> 2. remove the wakeup of kswapd from __find_page_nolock(),
> the wakeup condition is complex and leaving out the
> wakeup has no influence on any workload I tested in
> the last few weeks
>
> 3. add a __find_page_simple(), which is like __find_page_nolock()
> but only needs 2 arguments and doesn't touch the page ... this
> can be used by IO clustering and other things that really don't
> want to influence page aging, removing the 3rd argument also
> keeps things simple
The swapin readahead still makes the page referenced bit set, and it
should not as we discussed previously.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] 2.4.1 find_page_nolock fixes
@ 2001-01-31 2:16 ` Marcelo Tosatti
0 siblings, 0 replies; 5+ messages in thread
From: Marcelo Tosatti @ 2001-01-31 2:16 UTC (permalink / raw)
To: Rik van Riel; +Cc: Linus Torvalds, linux-mm, linux-kernel
On Tue, 30 Jan 2001, Rik van Riel wrote:
> Hi Linus,
>
> the patch below contains 3 small changes to mm/filemap.c:
>
> 1. replace the aging in __find_page_nolock() with setting
> PageReferenced(), otherwise a large number of small
> reads from (or writes to) a page can drive up the page
> age unfairly
>
> 2. remove the wakeup of kswapd from __find_page_nolock(),
> the wakeup condition is complex and leaving out the
> wakeup has no influence on any workload I tested in
> the last few weeks
>
> 3. add a __find_page_simple(), which is like __find_page_nolock()
> but only needs 2 arguments and doesn't touch the page ... this
> can be used by IO clustering and other things that really don't
> want to influence page aging, removing the 3rd argument also
> keeps things simple
The swapin readahead still makes the page referenced bit set, and it
should not as we discussed previously.
--
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.eu.org/Linux-MM/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] 2.4.1 find_page_nolock fixes
@ 2001-02-28 22:57 Rajagopal Ananthanarayanan
0 siblings, 0 replies; 5+ messages in thread
From: Rajagopal Ananthanarayanan @ 2001-02-28 22:57 UTC (permalink / raw)
To: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 591 bytes --]
Rik van Riel wrote:
>
> 3. add a __find_page_simple(), which is like __find_page_nolock()
> but only needs 2 arguments and doesn't touch the page ... this
> can be used by IO clustering and other things that really don't
> want to influence page aging, removing the 3rd argument also
> keeps things simple
>
We've used an exported version of __find_page_simple in XFS to good effect.
Following is a patch against 2.4.2 which is an extension of Rik's patch
to export find_get_page_simple(). Alan, if you want a patch against
the ac series please let me know.
thanks,
ananth.
[-- Attachment #2: page-simple.patch --]
[-- Type: text/plain, Size: 3584 bytes --]
diff -Naur ../../linux-2.4.2/linux/include/linux/pagemap.h ./include/linux/pagemap.h
--- ../../linux-2.4.2/linux/include/linux/pagemap.h Wed Feb 21 16:10:01 2001
+++ ./include/linux/pagemap.h Wed Feb 28 14:10:48 2001
@@ -71,6 +71,8 @@
unsigned long offset, struct page **hash);
extern struct page * __find_lock_page (struct address_space * mapping,
unsigned long index, struct page **hash);
+extern struct page * find_get_page_simple (struct address_space * mapping,
+ unsigned long index);
extern void lock_page(struct page *page);
#define find_lock_page(mapping, index) \
__find_lock_page(mapping, index, page_hash(mapping, index))
diff -Naur ../../linux-2.4.2/linux/kernel/ksyms.c ./kernel/ksyms.c
--- ../../linux-2.4.2/linux/kernel/ksyms.c Fri Feb 9 11:29:44 2001
+++ ./kernel/ksyms.c Wed Feb 28 14:09:51 2001
@@ -241,6 +241,7 @@
EXPORT_SYMBOL(poll_freewait);
EXPORT_SYMBOL(ROOT_DEV);
EXPORT_SYMBOL(__find_lock_page);
+EXPORT_SYMBOL(find_get_page_simple);
EXPORT_SYMBOL(grab_cache_page);
EXPORT_SYMBOL(read_cache_page);
EXPORT_SYMBOL(vfs_readlink);
diff -Naur ../../linux-2.4.2/linux/mm/filemap.c ./mm/filemap.c
--- ../../linux-2.4.2/linux/mm/filemap.c Fri Feb 16 16:06:17 2001
+++ ./mm/filemap.c Wed Feb 28 14:22:09 2001
@@ -285,6 +285,34 @@
spin_unlock(&pagecache_lock);
}
+/*
+ * This function is pretty much like __find_page_nolock(), but it only
+ * requires 2 arguments and doesn't mark the page as touched, making it
+ * ideal for ->writepage() clustering and other places where you don't
+ * want to mark the page referenced.
+ *
+ * The caller needs to hold the pagecache_lock.
+ */
+struct page * __find_page_simple(struct address_space *mapping, unsigned long index)
+{
+ struct page * page = *page_hash(mapping, index);
+ goto inside;
+
+ for (;;) {
+ page = page->next_hash;
+inside:
+ if (!page)
+ goto not_found;
+ if (page->mapping != mapping)
+ continue;
+ if (page->index == index)
+ break;
+ }
+
+not_found:
+ return page;
+}
+
static inline struct page * __find_page_nolock(struct address_space *mapping, unsigned long offset, struct page *page)
{
goto inside;
@@ -300,13 +328,14 @@
break;
}
/*
- * Touching the page may move it to the active list.
- * If we end up with too few inactive pages, we wake
- * up kswapd.
+ * Mark the page referenced, moving inactive pages to the
+ * active list.
*/
- age_page_up(page);
- if (inactive_shortage() > inactive_target / 2 && free_shortage())
- wakeup_kswapd();
+ if (!PageActive(page))
+ activate_page(page);
+ else
+ SetPageReferenced(page);
+
not_found:
return page;
}
@@ -679,6 +708,22 @@
}
/*
+ * Similar to find_get_page but with no VM side-effects such as aging.
+ */
+struct page * find_get_page_simple(struct address_space *mapping,
+ unsigned long index)
+{
+ struct page *page;
+
+ spin_lock(&pagecache_lock);
+ page = __find_page_simple(mapping, index);
+ if (page)
+ page_cache_get(page);
+ spin_unlock(&pagecache_lock);
+ return page;
+}
+
+/*
* Get the lock to a page atomically.
*/
struct page * __find_lock_page (struct address_space *mapping,
@@ -734,7 +779,6 @@
{
struct inode *inode = file->f_dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
- struct page **hash;
struct page *page;
unsigned long start;
@@ -755,8 +799,7 @@
*/
spin_lock(&pagecache_lock);
while (--index >= start) {
- hash = page_hash(mapping, index);
- page = __find_page_nolock(mapping, index, *hash);
+ page = __find_page_simple(mapping, index);
if (!page)
break;
deactivate_page(page);
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2001-02-28 22:58 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-02-28 22:57 [PATCH] 2.4.1 find_page_nolock fixes Rajagopal Ananthanarayanan
-- strict thread matches above, loose matches on Subject: below --
2001-01-30 19:48 Rik van Riel
2001-01-30 19:48 ` Rik van Riel
2001-01-31 2:16 ` Marcelo Tosatti
2001-01-31 2:16 ` Marcelo Tosatti
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.