From: Dave McCracken <dmccr@us.ibm.com>
To: Linux Memory Management <linux-mm@kvack.org>
Subject: [PATCH] Optimize out pte_chain take two
Date: Tue, 09 Jul 2002 14:04:14 -0500 [thread overview]
Message-ID: <59590000.1026241454@baldur.austin.ibm.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 403 bytes --]
Here's a version of my pte_chain removal patch that does not use anonymous
unions, so it'll compile with gcc 2.95. Once again, it's based on Rik's
rmap-2.5.25-akpmtested.
Dave McCracken
======================================================================
Dave McCracken IBM Linux Base Kernel Team 1-512-838-3059
dmccr@us.ibm.com T/L 678-3059
[-- Attachment #2: rmap-opt-2.5.25.diff --]
[-- Type: text/plain, Size: 8763 bytes --]
--- linux-2.5.25-rmap/./include/linux/mm.h Mon Jul 8 15:37:35 2002
+++ linux-2.5.25-rmap-opt/./include/linux/mm.h Tue Jul 9 13:41:11 2002
@@ -157,8 +157,11 @@
updated asynchronously */
struct list_head lru; /* Pageout list, eg. active_list;
protected by pagemap_lru_lock !! */
- struct pte_chain * pte_chain; /* Reverse pte mapping pointer.
+ union {
+ struct pte_chain * _pte_chain; /* Reverse pte mapping pointer.
* protected by PG_chainlock */
+ pte_t * _pte_direct;
+ } _pte_union;
unsigned long private; /* mapping-private opaque data */
/*
@@ -176,6 +179,9 @@
not kmapped, ie. highmem) */
#endif /* CONFIG_HIGMEM || WANT_PAGE_VIRTUAL */
};
+
+#define pte__chain _pte_union._pte_chain
+#define pte_direct _pte_union._pte_direct
/*
* Methods to modify the page usage count.
--- linux-2.5.25-rmap/./include/linux/page-flags.h Mon Jul 8 15:37:35 2002
+++ linux-2.5.25-rmap-opt/./include/linux/page-flags.h Tue Jul 9 10:31:28 2002
@@ -66,6 +66,7 @@
#define PG_writeback 13 /* Page is under writeback */
#define PG_nosave 15 /* Used for system suspend/resume */
#define PG_chainlock 16 /* lock bit for ->pte_chain */
+#define PG_direct 17 /* ->pte_chain points directly at pte */
/*
* Global page accounting. One instance per CPU.
@@ -216,6 +217,12 @@
#define TestSetPageNosave(page) test_and_set_bit(PG_nosave, &(page)->flags)
#define ClearPageNosave(page) clear_bit(PG_nosave, &(page)->flags)
#define TestClearPageNosave(page) test_and_clear_bit(PG_nosave, &(page)->flags)
+
+#define PageDirect(page) test_bit(PG_direct, &(page)->flags)
+#define SetPageDirect(page) set_bit(PG_direct, &(page)->flags)
+#define TestSetPageDirect(page) test_and_set_bit(PG_direct, &(page)->flags)
+#define ClearPageDirect(page) clear_bit(PG_direct, &(page)->flags)
+#define TestClearPageDirect(page) test_and_clear_bit(PG_direct, &(page)->flags)
/*
* inlines for acquisition and release of PG_chainlock
--- linux-2.5.25-rmap/./mm/page_alloc.c Mon Jul 8 15:37:35 2002
+++ linux-2.5.25-rmap-opt/./mm/page_alloc.c Tue Jul 9 13:43:46 2002
@@ -92,7 +92,7 @@
BUG_ON(PageLRU(page));
BUG_ON(PageActive(page));
BUG_ON(PageWriteback(page));
- BUG_ON(page->pte_chain != NULL);
+ BUG_ON(page->pte__chain != NULL);
if (PageDirty(page))
ClearPageDirty(page);
BUG_ON(page_count(page) != 0);
--- linux-2.5.25-rmap/./mm/vmscan.c Mon Jul 8 15:37:35 2002
+++ linux-2.5.25-rmap-opt/./mm/vmscan.c Tue Jul 9 13:42:38 2002
@@ -48,7 +48,7 @@
struct address_space *mapping = page->mapping;
/* Page is in somebody's page tables. */
- if (page->pte_chain)
+ if (page->pte__chain)
return 1;
/* XXX: does this happen ? */
@@ -151,7 +151,7 @@
*
* XXX: implement swap clustering ?
*/
- if (page->pte_chain && !page->mapping && !PagePrivate(page)) {
+ if (page->pte__chain && !page->mapping && !PagePrivate(page)) {
page_cache_get(page);
pte_chain_unlock(page);
spin_unlock(&pagemap_lru_lock);
@@ -171,7 +171,7 @@
* The page is mapped into the page tables of one or more
* processes. Try to unmap it here.
*/
- if (page->pte_chain) {
+ if (page->pte__chain) {
switch (try_to_unmap(page)) {
case SWAP_ERROR:
case SWAP_FAIL:
@@ -348,7 +348,7 @@
entry = entry->prev;
pte_chain_lock(page);
- if (page->pte_chain && page_referenced(page)) {
+ if (page->pte__chain && page_referenced(page)) {
list_del(&page->lru);
list_add(&page->lru, &active_list);
pte_chain_unlock(page);
--- linux-2.5.25-rmap/./mm/rmap.c Mon Jul 8 15:37:35 2002
+++ linux-2.5.25-rmap-opt/./mm/rmap.c Tue Jul 9 13:41:47 2002
@@ -13,7 +13,7 @@
/*
* Locking:
- * - the page->pte_chain is protected by the PG_chainlock bit,
+ * - the page->pte__chain is protected by the PG_chainlock bit,
* which nests within the pagemap_lru_lock, then the
* mm->page_table_lock, and then the page lock.
* - because swapout locking is opposite to the locking order
@@ -71,10 +71,15 @@
if (TestClearPageReferenced(page))
referenced++;
- /* Check all the page tables mapping this page. */
- for (pc = page->pte_chain; pc; pc = pc->next) {
- if (ptep_test_and_clear_young(pc->ptep))
+ if (PageDirect(page)) {
+ if (ptep_test_and_clear_young(page->pte_direct))
referenced++;
+ } else {
+ /* Check all the page tables mapping this page. */
+ for (pc = page->pte__chain; pc; pc = pc->next) {
+ if (ptep_test_and_clear_young(pc->ptep))
+ referenced++;
+ }
}
return referenced;
}
@@ -108,22 +113,39 @@
pte_chain_lock(page);
{
struct pte_chain * pc;
- for (pc = page->pte_chain; pc; pc = pc->next) {
- if (pc->ptep == ptep)
+ if (PageDirect(page)) {
+ if (page->pte_direct == ptep)
BUG();
+ } else {
+ for (pc = page->pte__chain; pc; pc = pc->next) {
+ if (pc->ptep == ptep)
+ BUG();
+ }
}
}
pte_chain_unlock(page);
#endif
- pte_chain = pte_chain_alloc();
-
pte_chain_lock(page);
- /* Hook up the pte_chain to the page. */
- pte_chain->ptep = ptep;
- pte_chain->next = page->pte_chain;
- page->pte_chain = pte_chain;
+ if (PageDirect(page)) {
+ /* Convert a direct pointer into a pte_chain */
+ pte_chain = pte_chain_alloc();
+ pte_chain->ptep = page->pte_direct;
+ pte_chain->next = NULL;
+ page->pte__chain = pte_chain;
+ ClearPageDirect(page);
+ }
+ if (page->pte__chain) {
+ /* Hook up the pte_chain to the page. */
+ pte_chain = pte_chain_alloc();
+ pte_chain->ptep = ptep;
+ pte_chain->next = page->pte__chain;
+ page->pte__chain = pte_chain;
+ } else {
+ page->pte_direct = ptep;
+ SetPageDirect(page);
+ }
pte_chain_unlock(page);
}
@@ -149,18 +171,38 @@
return;
pte_chain_lock(page);
- for (pc = page->pte_chain; pc; prev_pc = pc, pc = pc->next) {
- if (pc->ptep == ptep) {
- pte_chain_free(pc, prev_pc, page);
+
+ if (PageDirect(page)) {
+ if (page->pte_direct == ptep) {
+ page->pte_direct = NULL;
+ ClearPageDirect(page);
goto out;
}
+ } else {
+ for (pc = page->pte__chain; pc; prev_pc = pc, pc = pc->next) {
+ if (pc->ptep == ptep) {
+ pte_chain_free(pc, prev_pc, page);
+ /* Check whether we can convert to direct */
+ pc = page->pte__chain;
+ if (!pc->next) {
+ page->pte_direct = pc->ptep;
+ SetPageDirect(page);
+ pte_chain_free(pc, NULL, NULL);
+ }
+ goto out;
+ }
+ }
}
#ifdef DEBUG_RMAP
/* Not found. This should NEVER happen! */
printk(KERN_ERR "page_remove_rmap: pte_chain %p not present.\n", ptep);
printk(KERN_ERR "page_remove_rmap: only found: ");
- for (pc = page->pte_chain; pc; pc = pc->next)
- printk("%p ", pc->ptep);
+ if (PageDirect(page)) {
+ printk("%p ", page->pte_direct);
+ } else {
+ for (pc = page->pte__chain; pc; pc = pc->next)
+ printk("%p ", pc->ptep);
+ }
printk("\n");
printk(KERN_ERR "page_remove_rmap: driver cleared PG_reserved ?\n");
#endif
@@ -270,22 +312,42 @@
if (!page->mapping)
BUG();
- for (pc = page->pte_chain; pc; pc = next_pc) {
- next_pc = pc->next;
- switch (try_to_unmap_one(page, pc->ptep)) {
+ if (PageDirect(page)) {
+ switch (ret = try_to_unmap_one(page, page->pte_direct)) {
case SWAP_SUCCESS:
- /* Free the pte_chain struct. */
- pte_chain_free(pc, prev_pc, page);
- break;
+ page->pte_direct = NULL;
+ ClearPageDirect(page);
+ return ret;
case SWAP_AGAIN:
- /* Skip this pte, remembering status. */
- prev_pc = pc;
- ret = SWAP_AGAIN;
- continue;
case SWAP_FAIL:
- return SWAP_FAIL;
case SWAP_ERROR:
- return SWAP_ERROR;
+ return ret;
+ }
+ } else {
+ for (pc = page->pte__chain; pc; pc = next_pc) {
+ next_pc = pc->next;
+ switch (try_to_unmap_one(page, pc->ptep)) {
+ case SWAP_SUCCESS:
+ /* Free the pte_chain struct. */
+ pte_chain_free(pc, prev_pc, page);
+ break;
+ case SWAP_AGAIN:
+ /* Skip this pte, remembering status. */
+ prev_pc = pc;
+ ret = SWAP_AGAIN;
+ continue;
+ case SWAP_FAIL:
+ return SWAP_FAIL;
+ case SWAP_ERROR:
+ return SWAP_ERROR;
+ }
+ }
+ /* Check whether we can convert to direct pte pointer */
+ pc = page->pte__chain;
+ if (pc && !pc->next) {
+ page->pte_direct = pc->ptep;
+ SetPageDirect(page);
+ pte_chain_free(pc, NULL, NULL);
}
}
@@ -336,7 +398,7 @@
if (prev_pte_chain)
prev_pte_chain->next = pte_chain->next;
else if (page)
- page->pte_chain = pte_chain->next;
+ page->pte__chain = pte_chain->next;
spin_lock(&pte_chain_freelist_lock);
pte_chain_push(pte_chain);
next reply other threads:[~2002-07-09 19:04 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-07-09 19:04 Dave McCracken [this message]
2002-07-10 0:21 ` Andrew Morton
2002-07-10 14:33 ` [PATCH] Optimize out pte_chain take three Dave McCracken
2002-07-10 15:18 ` Rik van Riel
2002-07-10 17:32 ` William Lee Irwin III
2002-07-10 20:01 ` Andrew Morton
2002-07-10 20:14 ` Rik van Riel
2002-07-10 20:28 ` Andrew Morton
2002-07-10 20:38 ` Rik van Riel
2002-07-13 13:42 ` Daniel Phillips
2002-07-10 20:33 ` Martin J. Bligh
2002-07-10 22:22 ` William Lee Irwin III
2002-07-11 0:39 ` Andrew Morton
2002-07-11 0:47 ` Rik van Riel
2002-07-11 1:27 ` Andrew Morton
2002-07-13 14:10 ` Daniel Phillips
2002-07-11 1:51 ` William Lee Irwin III
2002-07-11 2:28 ` William Lee Irwin III
2002-07-11 19:54 ` Andrew Morton
2002-07-11 20:05 ` Rik van Riel
2002-07-11 20:42 ` Andrew Morton
2002-07-11 20:54 ` Rik van Riel
2002-07-11 21:16 ` Andrew Morton
2002-07-11 21:41 ` Rik van Riel
2002-07-11 22:38 ` Andrew Morton
2002-07-11 23:18 ` Rik van Riel
2002-07-12 18:27 ` Paul Larson
2002-07-12 19:06 ` Andrew Morton
2002-07-12 19:28 ` Andrew Morton
2002-07-13 15:08 ` Daniel Phillips
2002-07-11 22:54 ` William Lee Irwin III
2002-07-13 14:52 ` Daniel Phillips
2002-07-13 14:08 ` Daniel Phillips
2002-07-13 14:20 ` Daniel Phillips
2002-07-13 14:45 ` Daniel Phillips
2002-07-13 13:22 ` Daniel Phillips
2002-07-13 13:30 ` William Lee Irwin III
2002-07-13 13:55 ` Daniel Phillips
2002-07-13 13:41 ` Daniel Phillips
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=59590000.1026241454@baldur.austin.ibm.com \
--to=dmccr@us.ibm.com \
--cc=linux-mm@kvack.org \
/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