~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to mm/ksm.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <linux/ksm.h>
36
36
#include <linux/hash.h>
37
37
#include <linux/freezer.h>
 
38
#include <linux/oom.h>
38
39
 
39
40
#include <asm/tlbflush.h>
40
41
#include "internal.h"
301
302
        return rmap_item->address & STABLE_FLAG;
302
303
}
303
304
 
304
 
static void hold_anon_vma(struct rmap_item *rmap_item,
305
 
                          struct anon_vma *anon_vma)
306
 
{
307
 
        rmap_item->anon_vma = anon_vma;
308
 
        get_anon_vma(anon_vma);
309
 
}
310
 
 
311
 
static void ksm_drop_anon_vma(struct rmap_item *rmap_item)
312
 
{
313
 
        struct anon_vma *anon_vma = rmap_item->anon_vma;
314
 
 
315
 
        drop_anon_vma(anon_vma);
316
 
}
317
 
 
318
305
/*
319
306
 * ksmd, and unmerge_and_remove_all_rmap_items(), must not touch an mm's
320
307
 * page tables after it has passed through ksm_exit() - which, if necessary,
397
384
         * It is not an accident that whenever we want to break COW
398
385
         * to undo, we also need to drop a reference to the anon_vma.
399
386
         */
400
 
        ksm_drop_anon_vma(rmap_item);
 
387
        put_anon_vma(rmap_item->anon_vma);
401
388
 
402
389
        down_read(&mm->mmap_sem);
403
390
        if (ksm_test_exit(mm))
466
453
                        ksm_pages_sharing--;
467
454
                else
468
455
                        ksm_pages_shared--;
469
 
                ksm_drop_anon_vma(rmap_item);
 
456
                put_anon_vma(rmap_item->anon_vma);
470
457
                rmap_item->address &= PAGE_MASK;
471
458
                cond_resched();
472
459
        }
554
541
                else
555
542
                        ksm_pages_shared--;
556
543
 
557
 
                ksm_drop_anon_vma(rmap_item);
 
544
                put_anon_vma(rmap_item->anon_vma);
558
545
                rmap_item->address &= PAGE_MASK;
559
546
 
560
547
        } else if (rmap_item->address & UNSTABLE_FLAG) {
734
721
                swapped = PageSwapCache(page);
735
722
                flush_cache_page(vma, addr, page_to_pfn(page));
736
723
                /*
737
 
                 * Ok this is tricky, when get_user_pages_fast() run it doesnt
 
724
                 * Ok this is tricky, when get_user_pages_fast() run it doesn't
738
725
                 * take any lock, therefore the check that we are going to make
739
726
                 * with the pagecount against the mapcount is racey and
740
727
                 * O_DIRECT can happen right after the check.
949
936
                goto out;
950
937
 
951
938
        /* Must get reference to anon_vma while still holding mmap_sem */
952
 
        hold_anon_vma(rmap_item, vma->anon_vma);
 
939
        rmap_item->anon_vma = vma->anon_vma;
 
940
        get_anon_vma(vma->anon_vma);
953
941
out:
954
942
        up_read(&mm->mmap_sem);
955
943
        return err;
1314
1302
                slot = list_entry(slot->mm_list.next, struct mm_slot, mm_list);
1315
1303
                ksm_scan.mm_slot = slot;
1316
1304
                spin_unlock(&ksm_mmlist_lock);
 
1305
                /*
 
1306
                 * Although we tested list_empty() above, a racing __ksm_exit
 
1307
                 * of the last mm on the list may have removed it since then.
 
1308
                 */
 
1309
                if (slot == &ksm_mm_head)
 
1310
                        return NULL;
1317
1311
next_mm:
1318
1312
                ksm_scan.address = 0;
1319
1313
                ksm_scan.rmap_list = &slot->rmap_list;
1907
1901
        if (ksm_run != flags) {
1908
1902
                ksm_run = flags;
1909
1903
                if (flags & KSM_RUN_UNMERGE) {
1910
 
                        current->flags |= PF_OOM_ORIGIN;
 
1904
                        int oom_score_adj;
 
1905
 
 
1906
                        oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX);
1911
1907
                        err = unmerge_and_remove_all_rmap_items();
1912
 
                        current->flags &= ~PF_OOM_ORIGIN;
 
1908
                        test_set_oom_score_adj(oom_score_adj);
1913
1909
                        if (err) {
1914
1910
                                ksm_run = KSM_RUN_STOP;
1915
1911
                                count = err;