Commit 83b41646 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] s390: rmap optimization.

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

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.
parent f8e8784a
...@@ -135,12 +135,10 @@ int page_referenced(struct page * page) ...@@ -135,12 +135,10 @@ int page_referenced(struct page * page)
for (pc = page->pte.chain; pc; pc = pte_chain_next(pc)) { for (pc = page->pte.chain; pc; pc = pte_chain_next(pc)) {
int i; 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_addr_t pte_paddr = pc->ptes[i];
pte_t *p; pte_t *p;
if (!pte_paddr)
break;
p = rmap_ptep_map(pte_paddr); p = rmap_ptep_map(pte_paddr);
if (ptep_test_and_clear_young(p)) if (ptep_test_and_clear_young(p))
referenced++; referenced++;
...@@ -245,7 +243,7 @@ void page_remove_rmap(struct page *page, pte_t *ptep) ...@@ -245,7 +243,7 @@ void page_remove_rmap(struct page *page, pte_t *ptep)
} else { } else {
struct pte_chain *start = page->pte.chain; struct pte_chain *start = page->pte.chain;
struct pte_chain *next; struct pte_chain *next;
int victim_i = -1; int victim_i = pte_chain_idx(start);
for (pc = start; pc; pc = next) { for (pc = start; pc; pc = next) {
int i; int i;
...@@ -256,8 +254,6 @@ void page_remove_rmap(struct page *page, pte_t *ptep) ...@@ -256,8 +254,6 @@ void page_remove_rmap(struct page *page, pte_t *ptep)
for (i = pte_chain_idx(pc); i < NRPTE; i++) { for (i = pte_chain_idx(pc); i < NRPTE; i++) {
pte_addr_t pa = pc->ptes[i]; pte_addr_t pa = pc->ptes[i];
if (victim_i == -1)
victim_i = i;
if (pa != pte_paddr) if (pa != pte_paddr)
continue; continue;
pc->ptes[i] = start->ptes[victim_i]; pc->ptes[i] = start->ptes[victim_i];
...@@ -389,7 +385,7 @@ int try_to_unmap(struct page * page) ...@@ -389,7 +385,7 @@ int try_to_unmap(struct page * page)
{ {
struct pte_chain *pc, *next_pc, *start; struct pte_chain *pc, *next_pc, *start;
int ret = SWAP_SUCCESS; int ret = SWAP_SUCCESS;
int victim_i = -1; int victim_i;
/* This page should not be on the pageout lists. */ /* This page should not be on the pageout lists. */
if (PageReserved(page)) if (PageReserved(page))
...@@ -413,6 +409,7 @@ int try_to_unmap(struct page * page) ...@@ -413,6 +409,7 @@ int try_to_unmap(struct page * page)
} }
start = page->pte.chain; start = page->pte.chain;
victim_i = pte_chain_idx(start);
for (pc = start; pc; pc = next_pc) { for (pc = start; pc; pc = next_pc) {
int i; int i;
...@@ -422,11 +419,6 @@ int try_to_unmap(struct page * page) ...@@ -422,11 +419,6 @@ int try_to_unmap(struct page * page)
for (i = pte_chain_idx(pc); i < NRPTE; i++) { for (i = pte_chain_idx(pc); i < NRPTE; i++) {
pte_addr_t pte_paddr = pc->ptes[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)) { switch (try_to_unmap_one(page, pte_paddr)) {
case SWAP_SUCCESS: case SWAP_SUCCESS:
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment