]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] rmap bugfix, try_to_unmap
authorRik van Riel <riel@conectiva.com.br>
Mon, 12 Aug 2002 10:07:07 +0000 (03:07 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Mon, 12 Aug 2002 10:07:07 +0000 (03:07 -0700)
The following patch corrects a bug where rmap would continue trying to
swap out a page even after it failed on one pte, which could result in
leaked pte chains and a bug when exiting applications which use mlock().

The bug was tracked down by Christian Ehrhardt, the reason it wasn't
found earlier was a subtlety in the code, so I've taken the liberty of
changing Christian's patch into something more explicit, we shouldn't
let this one happen again ;)

mm/rmap.c

index 891583e3438fc90a61089729f0cba9de8f3e2664..714395e1287892c6f3b3009732de8edcdae593ff 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -328,7 +328,7 @@ int try_to_unmap(struct page * page)
                                case SWAP_SUCCESS:
                                        /* Free the pte_chain struct. */
                                        pte_chain_free(pc, prev_pc, page);
-                                       break;
+                                       continue;
                                case SWAP_AGAIN:
                                        /* Skip this pte, remembering status. */
                                        prev_pc = pc;
@@ -336,12 +336,13 @@ int try_to_unmap(struct page * page)
                                        continue;
                                case SWAP_FAIL:
                                        ret = SWAP_FAIL;
-                                       break;
+                                       goto give_up;
                                case SWAP_ERROR:
                                        ret = SWAP_ERROR;
-                                       break;
+                                       goto give_up;
                        }
                }
+give_up:
                /* Check whether we can convert to direct pte pointer */
                pc = page->pte.chain;
                if (pc && !pc->next) {