From 42f43903e997e4db9137e2d560cedc3642dc5dfe Mon Sep 17 00:00:00 2001 From: Namhoon Kim Date: Mon, 19 Mar 2018 17:56:04 -0400 Subject: Added recolor syscall --- arch/arm/include/asm/unistd.h | 2 +- arch/arm/kernel/calls.S | 1 + arch/x86/syscalls/syscall_32.tbl | 1 + arch/x86/syscalls/syscall_64.tbl | 1 + include/litmus/unistd_32.h | 3 +- include/litmus/unistd_64.h | 7 +-- 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 @@ * This may need to be greater than __NR_last_syscall+1 in order to * account for the padding in the syscall table */ -#define __NR_syscalls (388 + NR_litmus_syscalls + 0) +#define __NR_syscalls (388 + NR_litmus_syscalls + 3) /* 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 @@ /* 405 */ CALL(sys_test_call) CALL(sys_run_test) CALL(sys_lock_buffer) + CALL(sys_recolor_mem) #ifndef syscalls_counted .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 @@ 376 i386 test_call sys_test_call 377 i386 run_test sys_run_test 378 i386 lock_buffer sys_lock_buffer +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 @@ 368 common test_call sys_test_call 369 common run_test sys_run_test 370 common lock_buffer sys_lock_buffer +371 common recolor_mem sys_recolor_mem # # 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 @@ #define __NR_test_call __LSC(17) #define __NR_run_test __LSC(18) #define __NR_lock_buffer __LSC(19) +#define __NR_recolor_mem __LSC(20) -#define NR_litmus_syscalls 20 +#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) #define __NR_run_test __LSC(18) __SYSCALL(__NR_run_test, sys_run_test) #define __NR_lock_buffer __LSC(19) -__SYACALL(__NR_lock_buffer, sys_lock_buffer) +__SYSCALL(__NR_lock_buffer, sys_lock_buffer) +#define __NR_recolor_mem __LSC(20) +__SYSCALL(__NR_recolor_mem, sys_recolor_mem) - -#define NR_litmus_syscalls 20 +#define NR_litmus_syscalls 21 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) return ret; } +asmlinkage long sys_recolor_mem(void* mem, int n_pages, int cpu) +{ + long ret = 0; + struct vm_area_struct *vma_itr = NULL; + int nr_pages = 0, nr_failed = 0, nr_not_migrated = 0; + unsigned long node; + enum crit_level lv; + struct mm_struct *mm; + + LIST_HEAD(pagelist); + + printk(KERN_INFO "mem addr = %d\n", (unsigned long)mem); + return 0; + + migrate_prep(); + + /* Find the current mm_struct */ + rcu_read_lock(); + get_task_struct(current); + rcu_read_unlock(); + mm = get_task_mm(current); + put_task_struct(current); + + down_read(&mm->mmap_sem); + + vma_itr = mm->mmap; + /* Iterate all vm_area_struct */ + while (vma_itr != NULL) { + unsigned int num_pages = 0, i; + struct page *old_page = NULL; + int pages_in_vma = 0; + + num_pages = (vma_itr->vm_end - vma_itr->vm_start) / PAGE_SIZE; + if (num_pages != n_pages) + continue; + + /* Traverse all pages in vm_area_struct */ + for (i = 0; i < num_pages; i++) { + old_page = follow_page(vma_itr, vma_itr->vm_start + PAGE_SIZE*i, FOLL_GET|FOLL_SPLIT); + + if (IS_ERR(old_page)) + continue; + if (!old_page) + continue; + + if (PageReserved(old_page)) { + TRACE("Reserved Page!\n"); + put_page(old_page); + continue; + } + /* + if (PageDirty(old_page)) { + TRACE("Dirty Page!\n"); + put_page(old_page); + continue; + } + */ + 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":"-"); + pages_in_vma++; + + /* Conditions for replicable pages */ + if (page_count(old_page) == 1) { + ret = isolate_lru_page(old_page); + if (!ret) { + list_add_tail(&old_page->lru, &pagelist); + inc_zone_page_state(old_page, NR_ISOLATED_ANON + !PageSwapBacked(old_page)); + nr_pages++; + } else if (!is_in_correct_bank(old_page, cpu)) { + TRACE_TASK(current, "isolate_lru_page for a private page failed\n"); + nr_failed++; + } else { + TRACE_TASK(current, "page is already in the correct bank\n"); + } + put_page(old_page); + } + } + TRACE_TASK(current, "PAGES_IN_VMA = %d size = %d KB\n", pages_in_vma, pages_in_vma*4); + vma_itr = vma_itr->vm_next; + } + + ret = 0; + lv = tsk_rt(current)->mc2_data->crit; + if (cpu == -1) + node = 8; + else + node = cpu*2 + lv; + + /* Migrate private pages */ + if (!list_empty(&pagelist)) { + ret = migrate_pages(&pagelist, alloc_colored_page, NULL, node, MIGRATE_SYNC, MR_SYSCALL); + TRACE_TASK(current, "%ld pages not migrated.\n", ret); + nr_not_migrated = ret; + if (ret) { + putback_movable_pages(&pagelist); + } + } + + up_read(&mm->mmap_sem); + + TRACE_TASK(current, "nr_pages = %d nr_failed = %d nr_not_migrated = %d\n", nr_pages, nr_failed, nr_not_migrated); + 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); + + return nr_not_migrated; +} + /* p is a real-time task. Re-init its state as a best-effort task. */ static void reinit_litmus_state(struct task_struct* p, int restore) { -- cgit v1.2.2