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. --- 25-akpm/mm/rmap.c | 16 ++++------------ 1 files changed, 4 insertions(+), 12 deletions(-) diff -puN mm/rmap.c~s390-14-rmap-optimisation mm/rmap.c --- 25/mm/rmap.c~s390-14-rmap-optimisation Thu Jan 8 14:11:43 2004 +++ 25-akpm/mm/rmap.c Thu Jan 8 14:11:43 2004 @@ -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, } 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, 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: /* _