diff options
Diffstat (limited to 'litmus/litmus.c')
-rw-r--r-- | litmus/litmus.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/litmus/litmus.c b/litmus/litmus.c index 144e3bfdcfc1..cf599d1a6b3a 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -631,6 +631,111 @@ asmlinkage long sys_test_call(unsigned int param) | |||
631 | return ret; | 631 | return ret; |
632 | } | 632 | } |
633 | 633 | ||
634 | asmlinkage long sys_recolor_mem(void* mem, int n_pages, int cpu) | ||
635 | { | ||
636 | long ret = 0; | ||
637 | struct vm_area_struct *vma_itr = NULL; | ||
638 | int nr_pages = 0, nr_failed = 0, nr_not_migrated = 0; | ||
639 | unsigned long node; | ||
640 | enum crit_level lv; | ||
641 | struct mm_struct *mm; | ||
642 | |||
643 | LIST_HEAD(pagelist); | ||
644 | |||
645 | printk(KERN_INFO "mem addr = %d\n", (unsigned long)mem); | ||
646 | return 0; | ||
647 | |||
648 | migrate_prep(); | ||
649 | |||
650 | /* Find the current mm_struct */ | ||
651 | rcu_read_lock(); | ||
652 | get_task_struct(current); | ||
653 | rcu_read_unlock(); | ||
654 | mm = get_task_mm(current); | ||
655 | put_task_struct(current); | ||
656 | |||
657 | down_read(&mm->mmap_sem); | ||
658 | |||
659 | vma_itr = mm->mmap; | ||
660 | /* Iterate all vm_area_struct */ | ||
661 | while (vma_itr != NULL) { | ||
662 | unsigned int num_pages = 0, i; | ||
663 | struct page *old_page = NULL; | ||
664 | int pages_in_vma = 0; | ||
665 | |||
666 | num_pages = (vma_itr->vm_end - vma_itr->vm_start) / PAGE_SIZE; | ||
667 | if (num_pages != n_pages) | ||
668 | continue; | ||
669 | |||
670 | /* Traverse all pages in vm_area_struct */ | ||
671 | for (i = 0; i < num_pages; i++) { | ||
672 | old_page = follow_page(vma_itr, vma_itr->vm_start + PAGE_SIZE*i, FOLL_GET|FOLL_SPLIT); | ||
673 | |||
674 | if (IS_ERR(old_page)) | ||
675 | continue; | ||
676 | if (!old_page) | ||
677 | continue; | ||
678 | |||
679 | if (PageReserved(old_page)) { | ||
680 | TRACE("Reserved Page!\n"); | ||
681 | put_page(old_page); | ||
682 | continue; | ||
683 | } | ||
684 | /* | ||
685 | if (PageDirty(old_page)) { | ||
686 | TRACE("Dirty Page!\n"); | ||
687 | put_page(old_page); | ||
688 | continue; | ||
689 | } | ||
690 | */ | ||
691 | TRACE_TASK(current, "addr: %08x, pfn: %05lx, _mapcount: %d, _count: %d flags: %s%s%s\n", vma_itr->vm_start + PAGE_SIZE*i, page_to_pfn(old_page), page_mapcount(old_page), page_count(old_page), vma_itr->vm_flags&VM_READ?"r":"-", vma_itr->vm_flags&VM_WRITE?"w":"-", vma_itr->vm_flags&VM_EXEC?"x":"-"); | ||
692 | pages_in_vma++; | ||
693 | |||
694 | /* Conditions for replicable pages */ | ||
695 | if (page_count(old_page) == 1) { | ||
696 | ret = isolate_lru_page(old_page); | ||
697 | if (!ret) { | ||
698 | list_add_tail(&old_page->lru, &pagelist); | ||
699 | inc_zone_page_state(old_page, NR_ISOLATED_ANON + !PageSwapBacked(old_page)); | ||
700 | nr_pages++; | ||
701 | } else if (!is_in_correct_bank(old_page, cpu)) { | ||
702 | TRACE_TASK(current, "isolate_lru_page for a private page failed\n"); | ||
703 | nr_failed++; | ||
704 | } else { | ||
705 | TRACE_TASK(current, "page is already in the correct bank\n"); | ||
706 | } | ||
707 | put_page(old_page); | ||
708 | } | ||
709 | } | ||
710 | TRACE_TASK(current, "PAGES_IN_VMA = %d size = %d KB\n", pages_in_vma, pages_in_vma*4); | ||
711 | vma_itr = vma_itr->vm_next; | ||
712 | } | ||
713 | |||
714 | ret = 0; | ||
715 | lv = tsk_rt(current)->mc2_data->crit; | ||
716 | if (cpu == -1) | ||
717 | node = 8; | ||
718 | else | ||
719 | node = cpu*2 + lv; | ||
720 | |||
721 | /* Migrate private pages */ | ||
722 | if (!list_empty(&pagelist)) { | ||
723 | ret = migrate_pages(&pagelist, alloc_colored_page, NULL, node, MIGRATE_SYNC, MR_SYSCALL); | ||
724 | TRACE_TASK(current, "%ld pages not migrated.\n", ret); | ||
725 | nr_not_migrated = ret; | ||
726 | if (ret) { | ||
727 | putback_movable_pages(&pagelist); | ||
728 | } | ||
729 | } | ||
730 | |||
731 | up_read(&mm->mmap_sem); | ||
732 | |||
733 | TRACE_TASK(current, "nr_pages = %d nr_failed = %d nr_not_migrated = %d\n", nr_pages, nr_failed, nr_not_migrated); | ||
734 | printk(KERN_INFO "node = %ld, nr_private_pages = %d, nr_failed_to_isolate_lru = %d, nr_not_migrated = %d\n", node, nr_pages, nr_failed, nr_not_migrated); | ||
735 | |||
736 | return nr_not_migrated; | ||
737 | } | ||
738 | |||
634 | /* p is a real-time task. Re-init its state as a best-effort task. */ | 739 | /* p is a real-time task. Re-init its state as a best-effort task. */ |
635 | static void reinit_litmus_state(struct task_struct* p, int restore) | 740 | static void reinit_litmus_state(struct task_struct* p, int restore) |
636 | { | 741 | { |