From 418e60bb6948a4cf6eb7c737bea21c2314619c73 Mon Sep 17 00:00:00 2001 From: Namhoon Kim Date: Fri, 9 Sep 2016 03:07:58 -0400 Subject: Shared library identification --- include/litmus/replicate_lib.h | 14 ++++++++ litmus/Makefile | 1 + litmus/cache_proc.c | 10 +++--- litmus/litmus.c | 81 ++++++++++++++++++++++++++++++++---------- litmus/replicate_lib.c | 48 +++++++++++++++++++++++++ litmus/sched_mc2.c | 4 --- litmus/sched_psn_edf.c | 60 +++++++++++++++++++++++++++++++ 7 files changed, 191 insertions(+), 27 deletions(-) create mode 100644 include/litmus/replicate_lib.h create mode 100644 litmus/replicate_lib.c diff --git a/include/litmus/replicate_lib.h b/include/litmus/replicate_lib.h new file mode 100644 index 000000000000..af2af36b6b79 --- /dev/null +++ b/include/litmus/replicate_lib.h @@ -0,0 +1,14 @@ +#ifndef LITMUS_REPLICATE_LIB_H +#define LITMUS_REPLICATE_LIB_H + +#include +#include +#include + +struct shared_lib_page { + struct page *p_page; + unsigned long pfn; + struct list_head list; +}; + +#endif diff --git a/litmus/Makefile b/litmus/Makefile index e27440917ca1..7e4711cf25b4 100644 --- a/litmus/Makefile +++ b/litmus/Makefile @@ -28,6 +28,7 @@ obj-y = sched_plugin.o litmus.o \ sched_mc2.o \ bank_proc.o \ color_shm.o \ + replicate_lib.o \ cache_proc.o obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o diff --git a/litmus/cache_proc.c b/litmus/cache_proc.c index 397214f2b8cc..49e98f6ed86a 100644 --- a/litmus/cache_proc.c +++ b/litmus/cache_proc.c @@ -1133,7 +1133,7 @@ void flush_cache(int all) } /* src = shared, dst = local */ -#if 0 // random +#if 1 // random asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t *dst, lt_t __user *ts) { /* size is in KB */ @@ -1157,8 +1157,8 @@ asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t * for (i = 0; i < numlines; i++) { next = src[next].line[0]; for (j = 1; j < INTS_IN_CACHELINE; j++) { - dst[next].line[j] = src[next].line[j]; // read - //src[next].line[j] = dst[next].line[j]; // write + //dst[next].line[j] = src[next].line[j]; // read + src[next].line[j] = dst[next].line[j]; // write } } t2 = litmus_clock(); @@ -1175,8 +1175,8 @@ asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t * for (i = 0; i < numlines; i++) { next = src[next].line[0]; for (j = 1; j < INTS_IN_CACHELINE; j++) { - dst[next].line[j] = src[next].line[j]; //read - //src[next].line[j] = dst[next].line[j]; //write + //dst[next].line[j] = src[next].line[j]; //read + src[next].line[j] = dst[next].line[j]; //write } } t2 = litmus_clock(); diff --git a/litmus/litmus.c b/litmus/litmus.c index ddb80e1aae12..402c495f62c6 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef CONFIG_SCHED_CPU_AFFINITY #include @@ -351,6 +352,8 @@ extern int isolate_lru_page(struct page *page); extern void putback_movable_page(struct page *page); extern struct page *new_alloc_page(struct page *page, unsigned long node, int **x); +DECLARE_PER_CPU(struct list_head, shared_lib_page_list); + asmlinkage long sys_set_page_color(int cpu) { long ret = 0; @@ -360,6 +363,7 @@ asmlinkage long sys_set_page_color(int cpu) unsigned long node; enum crit_level lv; struct mm_struct *mm; + //struct list_head *shared_pagelist = this_cpu_ptr(&shared_lib_page_list); LIST_HEAD(pagelist); LIST_HEAD(shared_pagelist); @@ -372,13 +376,13 @@ asmlinkage long sys_set_page_color(int cpu) mm = get_task_mm(current); put_task_struct(current); - //down_read(¤t->mm->mmap_sem); down_read(&mm->mmap_sem); TRACE_TASK(current, "SYSCALL set_page_color\n"); vma_itr = mm->mmap; 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; // print vma flags @@ -399,9 +403,19 @@ asmlinkage long sys_set_page_color(int cpu) continue; } - TRACE_TASK(current, "addr: %08x, pfn: %x, _mapcount: %d, _count: %d\n", vma_itr->vm_start + PAGE_SIZE*i, __page_to_pfn(old_page), page_mapcount(old_page), page_count(old_page)); + TRACE_TASK(current, "addr: %08x, pfn: %ld, _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++; - //if (page_mapcount(old_page) == 1) { + if (page_count(old_page) > 2 && vma_itr->vm_file != NULL && !(vma_itr->vm_flags&VM_WRITE)) { + struct shared_lib_page *lib_page; + lib_page = kmalloc(sizeof(struct shared_lib_page), GFP_KERNEL); + lib_page->p_page = old_page; + lib_page->pfn = page_to_pfn(old_page); + list_add_tail(&lib_page->list, &shared_pagelist); + nr_shared_pages++; + TRACE_TASK(current, "SHARED\n"); + } + else { ret = isolate_lru_page(old_page); if (!ret) { list_add_tail(&old_page->lru, &pagelist); @@ -414,16 +428,10 @@ asmlinkage long sys_set_page_color(int cpu) } //printk(KERN_INFO "PRIVATE _mapcount = %d, _count = %d\n", page_mapcount(old_page), page_count(old_page)); put_page(old_page); - //} - /* - else { - nr_shared_pages++; - //printk(KERN_INFO "SHARED _mapcount = %d, _count = %d\n", page_mapcount(old_page), page_count(old_page)); - put_page(old_page); + TRACE_TASK(current, "PRIVATE\n"); } - */ } - + TRACE_TASK(current, "PAGES_IN_VMA = %d size = %d KB\n", pages_in_vma, pages_in_vma*4); vma_itr = vma_itr->vm_next; } @@ -466,15 +474,52 @@ asmlinkage long sys_set_page_color(int cpu) */ up_read(&mm->mmap_sem); -/* - list_for_each_entry(page_itr, &shared_pagelist, lru) { - TRACE("S Anon=%d, pfn = %lu, _mapcount = %d, _count = %d\n", PageAnon(page_itr), __page_to_pfn(page_itr), page_mapcount(page_itr), page_count(page_itr)); - } -*/ + TRACE_TASK(current, "nr_pages = %d nr_failed = %d\n", nr_pages, nr_failed); - printk(KERN_INFO "node = %ld, nr_migrated_pages = %d, nr_shared_pages = %d, nr_failed = %d\n", node, nr_pages-nr_not_migrated, nr_failed-2, nr_failed); - //printk(KERN_INFO "node = %d\n", cpu_to_node(smp_processor_id())); + printk(KERN_INFO "node = %ld, nr_migrated_pages = %d, nr_shared_pages = %d, nr_failed = %d\n", node, nr_pages-nr_not_migrated, nr_shared_pages, nr_failed); + flush_cache(1); +/* for debug START */ + TRACE_TASK(current, "SHARED PAGES\n"); + { + struct shared_lib_page *lpage; + + rcu_read_lock(); + list_for_each_entry(lpage, &shared_pagelist, list) + { + TRACE_TASK(current, "PFN = %ld\n", lpage->pfn); + } + rcu_read_unlock(); + } + + TRACE_TASK(current, "AFTER migration\n"); + down_read(&mm->mmap_sem); + vma_itr = mm->mmap; + while (vma_itr != NULL) { + unsigned int num_pages = 0, i; + struct page *old_page = NULL; + + num_pages = (vma_itr->vm_end - vma_itr->vm_start) / PAGE_SIZE; + 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; + } + TRACE_TASK(current, "addr: %08x, pfn: %ld, _mapcount: %d, _count: %d\n", vma_itr->vm_start + PAGE_SIZE*i, __page_to_pfn(old_page), page_mapcount(old_page), page_count(old_page)); + put_page(old_page); + } + + vma_itr = vma_itr->vm_next; + } + up_read(&mm->mmap_sem); +/* for debug FIN. */ return ret; } diff --git a/litmus/replicate_lib.c b/litmus/replicate_lib.c new file mode 100644 index 000000000000..7aa240058ef5 --- /dev/null +++ b/litmus/replicate_lib.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +DEFINE_PER_CPU(struct list_head, shared_lib_page_list); + +#define shared_lib_pages_for(cpu_id) (&per_cpu(shared_lib_page_list, cpu_id)) +#define local_shared_lib_pages() (this_cpu_ptr(&shared_lib_page_list)) + +static int __init litmus_replicate_lib_init(void) +{ + int cpu, ret = 0; + + printk(KERN_INFO "Registering LITMUS^RT Per-core Shared Library module.\n"); + + for_each_online_cpu(cpu) { + INIT_LIST_HEAD(shared_lib_pages_for(cpu)); + printk(KERN_INFO "CPU%d PSL-list initialized.\n", cpu); + } + + return ret; +} + +static void litmus_replicate_lib_exit(void) +{ + return; +} + +module_init(litmus_replicate_lib_init); +module_exit(litmus_replicate_lib_exit); \ No newline at end of file diff --git a/litmus/sched_mc2.c b/litmus/sched_mc2.c index a2abda848cbf..5c88a36aacec 100644 --- a/litmus/sched_mc2.c +++ b/litmus/sched_mc2.c @@ -27,10 +27,6 @@ #include #include -#ifdef CONFIG_PGMRT_SUPPORT -#include -#endif - //#define TRACE(fmt, args...) do {} while (false) //#define TRACE_TASK(fmt, args...) do {} while (false) diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index 76a57af9ae95..216b9f3b8c50 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c @@ -23,6 +23,10 @@ #include #include +#ifdef CONFIG_PGMRT_SUPPORT +#include +#endif + /* to set up domain/cpu mappings */ #include @@ -199,6 +203,62 @@ static struct task_struct* psnedf_schedule(struct task_struct * prev) */ resched = preempt; +#ifdef CONFIG_PGMRT_SUPPORT + if (exists) { + if (is_pgm_sending(pedf->scheduled)) { + if (!is_pgm_satisfied(pedf->scheduled)) { + if (!is_priority_boosted(pedf->scheduled)) { + TRACE_TASK(pedf->scheduled, "is sending PGM tokens and needs boosting.\n"); + BUG_ON(is_pgm_satisfied(pedf->scheduled)); + + /* We are either sending tokens or waiting for tokes. + If waiting: Boost priority so we'll be scheduled + immediately when needed tokens arrive. + If sending: Boost priority so no one (specifically, our + consumers) will preempt us while signalling the token + transmission. + */ + tsk_rt(pedf->scheduled)->priority_boosted = 1; + tsk_rt(pedf->scheduled)->boost_start_time = litmus_clock(); + + if (likely(!blocks)) { + requeue(pedf->scheduled, edf); + /* we may regain the processor */ + if (preempt) { + preempt = edf_preemption_needed(edf, prev); + if (!preempt) { + TRACE_TASK(pedf->scheduled, "blocked preemption by lazy boosting.\n"); + } + } + } + } + } + else { /* sending is satisfied */ + tsk_rt(pedf->scheduled)->ctrl_page->pgm_sending = 0; + tsk_rt(pedf->scheduled)->ctrl_page->pgm_satisfied = 0; + + if (is_priority_boosted(pedf->scheduled)) { + TRACE_TASK(pedf->scheduled, + "is done sending PGM tokens must relinquish boosting.\n"); + /* clear boosting */ + tsk_rt(pedf->scheduled)->priority_boosted = 0; + if(likely(!blocks)) { + /* recheck priority */ + requeue(pedf->scheduled, edf); + /* we may lose the processor */ + if (!preempt) { + preempt = edf_preemption_needed(edf, prev); + if (preempt) { + TRACE_TASK(pedf->scheduled, "preempted by lazy unboosting.\n"); + } + } + } + } + } + } + } +#endif + /* If a task blocks we have no choice but to reschedule. */ if (blocks) -- cgit v1.2.2