mm: make swapin readahead skip over holes
[linux-2.6.git] / mm / ksm.c
index d708b3e..a6d3fb7 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -672,9 +672,9 @@ error:
 static u32 calc_checksum(struct page *page)
 {
        u32 checksum;
-       void *addr = kmap_atomic(page, KM_USER0);
+       void *addr = kmap_atomic(page);
        checksum = jhash2(addr, PAGE_SIZE / 4, 17);
-       kunmap_atomic(addr, KM_USER0);
+       kunmap_atomic(addr);
        return checksum;
 }
 
@@ -683,11 +683,11 @@ static int memcmp_pages(struct page *page1, struct page *page2)
        char *addr1, *addr2;
        int ret;
 
-       addr1 = kmap_atomic(page1, KM_USER0);
-       addr2 = kmap_atomic(page2, KM_USER1);
+       addr1 = kmap_atomic(page1);
+       addr2 = kmap_atomic(page2);
        ret = memcmp(addr1, addr2, PAGE_SIZE);
-       kunmap_atomic(addr2, KM_USER1);
-       kunmap_atomic(addr1, KM_USER0);
+       kunmap_atomic(addr2);
+       kunmap_atomic(addr1);
        return ret;
 }
 
@@ -1302,6 +1302,12 @@ static struct rmap_item *scan_get_next_rmap_item(struct page **page)
                slot = list_entry(slot->mm_list.next, struct mm_slot, mm_list);
                ksm_scan.mm_slot = slot;
                spin_unlock(&ksm_mmlist_lock);
+               /*
+                * Although we tested list_empty() above, a racing __ksm_exit
+                * of the last mm on the list may have removed it since then.
+                */
+               if (slot == &ksm_mm_head)
+                       return NULL;
 next_mm:
                ksm_scan.address = 0;
                ksm_scan.rmap_list = &slot->rmap_list;
@@ -1899,7 +1905,8 @@ static ssize_t run_store(struct kobject *kobj, struct kobj_attribute *attr,
 
                        oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX);
                        err = unmerge_and_remove_all_rmap_items();
-                       test_set_oom_score_adj(oom_score_adj);
+                       compare_swap_oom_score_adj(OOM_SCORE_ADJ_MAX,
+                                                               oom_score_adj);
                        if (err) {
                                ksm_run = KSM_RUN_STOP;
                                count = err;