diff options
-rw-r--r-- | arch/arm/include/asm/unistd.h | 2 | ||||
-rw-r--r-- | arch/arm/kernel/calls.S | 1 | ||||
-rw-r--r-- | arch/x86/syscalls/syscall_32.tbl | 1 | ||||
-rw-r--r-- | arch/x86/syscalls/syscall_64.tbl | 1 | ||||
-rw-r--r-- | include/litmus/unistd_32.h | 3 | ||||
-rw-r--r-- | include/litmus/unistd_64.h | 7 | ||||
-rw-r--r-- | litmus/litmus.c | 105 |
7 files changed, 115 insertions, 5 deletions
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 5291b703ed3f..7197bbe4dda1 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
@@ -19,7 +19,7 @@ | |||
19 | * This may need to be greater than __NR_last_syscall+1 in order to | 19 | * This may need to be greater than __NR_last_syscall+1 in order to |
20 | * account for the padding in the syscall table | 20 | * account for the padding in the syscall table |
21 | */ | 21 | */ |
22 | #define __NR_syscalls (388 + NR_litmus_syscalls + 0) | 22 | #define __NR_syscalls (388 + NR_litmus_syscalls + 3) |
23 | 23 | ||
24 | 24 | ||
25 | /* | 25 | /* |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 55dc86323c86..04cc83b7d35a 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -417,6 +417,7 @@ | |||
417 | /* 405 */ CALL(sys_test_call) | 417 | /* 405 */ CALL(sys_test_call) |
418 | CALL(sys_run_test) | 418 | CALL(sys_run_test) |
419 | CALL(sys_lock_buffer) | 419 | CALL(sys_lock_buffer) |
420 | CALL(sys_recolor_mem) | ||
420 | 421 | ||
421 | #ifndef syscalls_counted | 422 | #ifndef syscalls_counted |
422 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls | 423 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl index b303a9b2183a..6b80d9885da4 100644 --- a/arch/x86/syscalls/syscall_32.tbl +++ b/arch/x86/syscalls/syscall_32.tbl | |||
@@ -385,3 +385,4 @@ | |||
385 | 376 i386 test_call sys_test_call | 385 | 376 i386 test_call sys_test_call |
386 | 377 i386 run_test sys_run_test | 386 | 377 i386 run_test sys_run_test |
387 | 378 i386 lock_buffer sys_lock_buffer | 387 | 378 i386 lock_buffer sys_lock_buffer |
388 | 379 i386 recolor_mem sys_recolor_mem | ||
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl index 5f24a80930cc..05aa913bfbdf 100644 --- a/arch/x86/syscalls/syscall_64.tbl +++ b/arch/x86/syscalls/syscall_64.tbl | |||
@@ -350,6 +350,7 @@ | |||
350 | 368 common test_call sys_test_call | 350 | 368 common test_call sys_test_call |
351 | 369 common run_test sys_run_test | 351 | 369 common run_test sys_run_test |
352 | 370 common lock_buffer sys_lock_buffer | 352 | 370 common lock_buffer sys_lock_buffer |
353 | 371 common recolor_mem sys_recolor_mem | ||
353 | 354 | ||
354 | # | 355 | # |
355 | # x32-specific system call numbers start at 512 to avoid cache impact | 356 | # x32-specific system call numbers start at 512 to avoid cache impact |
diff --git a/include/litmus/unistd_32.h b/include/litmus/unistd_32.h index 86bbbb8d33ea..664f73f862cb 100644 --- a/include/litmus/unistd_32.h +++ b/include/litmus/unistd_32.h | |||
@@ -25,5 +25,6 @@ | |||
25 | #define __NR_test_call __LSC(17) | 25 | #define __NR_test_call __LSC(17) |
26 | #define __NR_run_test __LSC(18) | 26 | #define __NR_run_test __LSC(18) |
27 | #define __NR_lock_buffer __LSC(19) | 27 | #define __NR_lock_buffer __LSC(19) |
28 | #define __NR_recolor_mem __LSC(20) | ||
28 | 29 | ||
29 | #define NR_litmus_syscalls 20 | 30 | #define NR_litmus_syscalls 21 |
diff --git a/include/litmus/unistd_64.h b/include/litmus/unistd_64.h index 4b96e7c259d1..994e8a5e57a2 100644 --- a/include/litmus/unistd_64.h +++ b/include/litmus/unistd_64.h | |||
@@ -44,7 +44,8 @@ __SYSCALL(__NR_test_call, sys_test_call) | |||
44 | #define __NR_run_test __LSC(18) | 44 | #define __NR_run_test __LSC(18) |
45 | __SYSCALL(__NR_run_test, sys_run_test) | 45 | __SYSCALL(__NR_run_test, sys_run_test) |
46 | #define __NR_lock_buffer __LSC(19) | 46 | #define __NR_lock_buffer __LSC(19) |
47 | __SYACALL(__NR_lock_buffer, sys_lock_buffer) | 47 | __SYSCALL(__NR_lock_buffer, sys_lock_buffer) |
48 | #define __NR_recolor_mem __LSC(20) | ||
49 | __SYSCALL(__NR_recolor_mem, sys_recolor_mem) | ||
48 | 50 | ||
49 | 51 | #define NR_litmus_syscalls 21 | |
50 | #define NR_litmus_syscalls 20 | ||
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 | { |