From 83b416461047903ada908a9bdfa41c958ad78dde Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 18 Jan 2004 18:43:19 -0800 Subject: [PATCH] [PATCH] s390: rmap optimization. From: Martin Schwidefsky while working on my mm patch for s390 I played with rmap a bit, adding BUG statements and the like. While doing so I noticed some room for improvement in rmap. Its minor stuff but anyway... The first observation is that the pte chain array doesn't have holes, meaning that from the pte_chain_idx() of the first array every slot of all following pte chain arrays are full. That is there can't be NULL pointers. The "if (!pte_paddr)" check in try_to_unmap() can be removed and if the loop in page_referenced() is started from pte_chain_idx(pc) then the "if (!pte_paddr)" in page_referenced() can be removed as well. The second observation is that the first pte array of a pte chain has at least one entry. Empty pte chain arrays are always freed immediatly after the last entry was removed. Because of that victim_i can be calculated in a simpler way. Instead of setting victim_i to -1 and then check in each loop iteration against -1 victim_i can just be set to the pte_chain_idx of the first pte chain array. --- mm/rmap.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 7ed83f4845d3d..14fab5522a5a4 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -135,12 +135,10 @@ int page_referenced(struct page * page) for (pc = page->pte.chain; pc; pc = pte_chain_next(pc)) { int i; - for (i = NRPTE-1; i >= 0; i--) { + for (i = pte_chain_idx(pc); i < NRPTE; i++) { pte_addr_t pte_paddr = pc->ptes[i]; pte_t *p; - if (!pte_paddr) - break; p = rmap_ptep_map(pte_paddr); if (ptep_test_and_clear_young(p)) referenced++; @@ -245,7 +243,7 @@ void page_remove_rmap(struct page *page, pte_t *ptep) } else { struct pte_chain *start = page->pte.chain; struct pte_chain *next; - int victim_i = -1; + int victim_i = pte_chain_idx(start); for (pc = start; pc; pc = next) { int i; @@ -256,8 +254,6 @@ void page_remove_rmap(struct page *page, pte_t *ptep) for (i = pte_chain_idx(pc); i < NRPTE; i++) { pte_addr_t pa = pc->ptes[i]; - if (victim_i == -1) - victim_i = i; if (pa != pte_paddr) continue; pc->ptes[i] = start->ptes[victim_i]; @@ -389,7 +385,7 @@ int try_to_unmap(struct page * page) { struct pte_chain *pc, *next_pc, *start; int ret = SWAP_SUCCESS; - int victim_i = -1; + int victim_i; /* This page should not be on the pageout lists. */ if (PageReserved(page)) @@ -413,6 +409,7 @@ int try_to_unmap(struct page * page) } start = page->pte.chain; + victim_i = pte_chain_idx(start); for (pc = start; pc; pc = next_pc) { int i; @@ -422,11 +419,6 @@ int try_to_unmap(struct page * page) for (i = pte_chain_idx(pc); i < NRPTE; i++) { pte_addr_t pte_paddr = pc->ptes[i]; - if (!pte_paddr) - continue; - if (victim_i == -1) - victim_i = i; - switch (try_to_unmap_one(page, pte_paddr)) { case SWAP_SUCCESS: /* -- 2.53.0