diff options
| author | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-09-09 03:07:58 -0400 |
|---|---|---|
| committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-09-09 03:07:58 -0400 |
| commit | 418e60bb6948a4cf6eb7c737bea21c2314619c73 (patch) | |
| tree | 4dc9a4f1ee2b04ff92a331beef7944c9e5126bea | |
| parent | d57b8f5a8e2d08fa972dad6b646a02a5dd931be4 (diff) | |
Shared library identification
| -rw-r--r-- | include/litmus/replicate_lib.h | 14 | ||||
| -rw-r--r-- | litmus/Makefile | 1 | ||||
| -rw-r--r-- | litmus/cache_proc.c | 10 | ||||
| -rw-r--r-- | litmus/litmus.c | 81 | ||||
| -rw-r--r-- | litmus/replicate_lib.c | 48 | ||||
| -rw-r--r-- | litmus/sched_mc2.c | 4 | ||||
| -rw-r--r-- | litmus/sched_psn_edf.c | 60 |
7 files changed, 191 insertions, 27 deletions
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 @@ | |||
| 1 | #ifndef LITMUS_REPLICATE_LIB_H | ||
| 2 | #define LITMUS_REPLICATE_LIB_H | ||
| 3 | |||
| 4 | #include <linux/list.h> | ||
| 5 | #include <linux/mm_types.h> | ||
| 6 | #include <linux/mm_inline.h> | ||
| 7 | |||
| 8 | struct shared_lib_page { | ||
| 9 | struct page *p_page; | ||
| 10 | unsigned long pfn; | ||
| 11 | struct list_head list; | ||
| 12 | }; | ||
| 13 | |||
| 14 | #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 \ | |||
| 28 | sched_mc2.o \ | 28 | sched_mc2.o \ |
| 29 | bank_proc.o \ | 29 | bank_proc.o \ |
| 30 | color_shm.o \ | 30 | color_shm.o \ |
| 31 | replicate_lib.o \ | ||
| 31 | cache_proc.o | 32 | cache_proc.o |
| 32 | 33 | ||
| 33 | obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o | 34 | 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) | |||
| 1133 | } | 1133 | } |
| 1134 | 1134 | ||
| 1135 | /* src = shared, dst = local */ | 1135 | /* src = shared, dst = local */ |
| 1136 | #if 0 // random | 1136 | #if 1 // random |
| 1137 | asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t *dst, lt_t __user *ts) | 1137 | asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t *dst, lt_t __user *ts) |
| 1138 | { | 1138 | { |
| 1139 | /* size is in KB */ | 1139 | /* size is in KB */ |
| @@ -1157,8 +1157,8 @@ asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t * | |||
| 1157 | for (i = 0; i < numlines; i++) { | 1157 | for (i = 0; i < numlines; i++) { |
| 1158 | next = src[next].line[0]; | 1158 | next = src[next].line[0]; |
| 1159 | for (j = 1; j < INTS_IN_CACHELINE; j++) { | 1159 | for (j = 1; j < INTS_IN_CACHELINE; j++) { |
| 1160 | dst[next].line[j] = src[next].line[j]; // read | 1160 | //dst[next].line[j] = src[next].line[j]; // read |
| 1161 | //src[next].line[j] = dst[next].line[j]; // write | 1161 | src[next].line[j] = dst[next].line[j]; // write |
| 1162 | } | 1162 | } |
| 1163 | } | 1163 | } |
| 1164 | t2 = litmus_clock(); | 1164 | t2 = litmus_clock(); |
| @@ -1175,8 +1175,8 @@ asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t * | |||
| 1175 | for (i = 0; i < numlines; i++) { | 1175 | for (i = 0; i < numlines; i++) { |
| 1176 | next = src[next].line[0]; | 1176 | next = src[next].line[0]; |
| 1177 | for (j = 1; j < INTS_IN_CACHELINE; j++) { | 1177 | for (j = 1; j < INTS_IN_CACHELINE; j++) { |
| 1178 | dst[next].line[j] = src[next].line[j]; //read | 1178 | //dst[next].line[j] = src[next].line[j]; //read |
| 1179 | //src[next].line[j] = dst[next].line[j]; //write | 1179 | src[next].line[j] = dst[next].line[j]; //write |
| 1180 | } | 1180 | } |
| 1181 | } | 1181 | } |
| 1182 | t2 = litmus_clock(); | 1182 | 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 @@ | |||
| 27 | #include <litmus/sched_trace.h> | 27 | #include <litmus/sched_trace.h> |
| 28 | #include <litmus/cache_proc.h> | 28 | #include <litmus/cache_proc.h> |
| 29 | #include <litmus/mc2_common.h> | 29 | #include <litmus/mc2_common.h> |
| 30 | #include <litmus/replicate_lib.h> | ||
| 30 | 31 | ||
| 31 | #ifdef CONFIG_SCHED_CPU_AFFINITY | 32 | #ifdef CONFIG_SCHED_CPU_AFFINITY |
| 32 | #include <litmus/affinity.h> | 33 | #include <litmus/affinity.h> |
| @@ -351,6 +352,8 @@ extern int isolate_lru_page(struct page *page); | |||
| 351 | extern void putback_movable_page(struct page *page); | 352 | extern void putback_movable_page(struct page *page); |
| 352 | extern struct page *new_alloc_page(struct page *page, unsigned long node, int **x); | 353 | extern struct page *new_alloc_page(struct page *page, unsigned long node, int **x); |
| 353 | 354 | ||
| 355 | DECLARE_PER_CPU(struct list_head, shared_lib_page_list); | ||
| 356 | |||
| 354 | asmlinkage long sys_set_page_color(int cpu) | 357 | asmlinkage long sys_set_page_color(int cpu) |
| 355 | { | 358 | { |
| 356 | long ret = 0; | 359 | long ret = 0; |
| @@ -360,6 +363,7 @@ asmlinkage long sys_set_page_color(int cpu) | |||
| 360 | unsigned long node; | 363 | unsigned long node; |
| 361 | enum crit_level lv; | 364 | enum crit_level lv; |
| 362 | struct mm_struct *mm; | 365 | struct mm_struct *mm; |
| 366 | //struct list_head *shared_pagelist = this_cpu_ptr(&shared_lib_page_list); | ||
| 363 | 367 | ||
| 364 | LIST_HEAD(pagelist); | 368 | LIST_HEAD(pagelist); |
| 365 | LIST_HEAD(shared_pagelist); | 369 | LIST_HEAD(shared_pagelist); |
| @@ -372,13 +376,13 @@ asmlinkage long sys_set_page_color(int cpu) | |||
| 372 | mm = get_task_mm(current); | 376 | mm = get_task_mm(current); |
| 373 | put_task_struct(current); | 377 | put_task_struct(current); |
| 374 | 378 | ||
| 375 | //down_read(¤t->mm->mmap_sem); | ||
| 376 | down_read(&mm->mmap_sem); | 379 | down_read(&mm->mmap_sem); |
| 377 | TRACE_TASK(current, "SYSCALL set_page_color\n"); | 380 | TRACE_TASK(current, "SYSCALL set_page_color\n"); |
| 378 | vma_itr = mm->mmap; | 381 | vma_itr = mm->mmap; |
| 379 | while (vma_itr != NULL) { | 382 | while (vma_itr != NULL) { |
| 380 | unsigned int num_pages = 0, i; | 383 | unsigned int num_pages = 0, i; |
| 381 | struct page *old_page = NULL; | 384 | struct page *old_page = NULL; |
| 385 | int pages_in_vma = 0; | ||
| 382 | 386 | ||
| 383 | num_pages = (vma_itr->vm_end - vma_itr->vm_start) / PAGE_SIZE; | 387 | num_pages = (vma_itr->vm_end - vma_itr->vm_start) / PAGE_SIZE; |
| 384 | // print vma flags | 388 | // print vma flags |
| @@ -399,9 +403,19 @@ asmlinkage long sys_set_page_color(int cpu) | |||
| 399 | continue; | 403 | continue; |
| 400 | } | 404 | } |
| 401 | 405 | ||
| 402 | 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)); | 406 | 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":"-"); |
| 407 | pages_in_vma++; | ||
| 403 | 408 | ||
| 404 | //if (page_mapcount(old_page) == 1) { | 409 | if (page_count(old_page) > 2 && vma_itr->vm_file != NULL && !(vma_itr->vm_flags&VM_WRITE)) { |
| 410 | struct shared_lib_page *lib_page; | ||
| 411 | lib_page = kmalloc(sizeof(struct shared_lib_page), GFP_KERNEL); | ||
| 412 | lib_page->p_page = old_page; | ||
| 413 | lib_page->pfn = page_to_pfn(old_page); | ||
| 414 | list_add_tail(&lib_page->list, &shared_pagelist); | ||
| 415 | nr_shared_pages++; | ||
| 416 | TRACE_TASK(current, "SHARED\n"); | ||
| 417 | } | ||
| 418 | else { | ||
| 405 | ret = isolate_lru_page(old_page); | 419 | ret = isolate_lru_page(old_page); |
| 406 | if (!ret) { | 420 | if (!ret) { |
| 407 | list_add_tail(&old_page->lru, &pagelist); | 421 | list_add_tail(&old_page->lru, &pagelist); |
| @@ -414,16 +428,10 @@ asmlinkage long sys_set_page_color(int cpu) | |||
| 414 | } | 428 | } |
| 415 | //printk(KERN_INFO "PRIVATE _mapcount = %d, _count = %d\n", page_mapcount(old_page), page_count(old_page)); | 429 | //printk(KERN_INFO "PRIVATE _mapcount = %d, _count = %d\n", page_mapcount(old_page), page_count(old_page)); |
| 416 | put_page(old_page); | 430 | put_page(old_page); |
| 417 | //} | 431 | TRACE_TASK(current, "PRIVATE\n"); |
| 418 | /* | ||
| 419 | else { | ||
| 420 | nr_shared_pages++; | ||
| 421 | //printk(KERN_INFO "SHARED _mapcount = %d, _count = %d\n", page_mapcount(old_page), page_count(old_page)); | ||
| 422 | put_page(old_page); | ||
| 423 | } | 432 | } |
| 424 | */ | ||
| 425 | } | 433 | } |
| 426 | 434 | TRACE_TASK(current, "PAGES_IN_VMA = %d size = %d KB\n", pages_in_vma, pages_in_vma*4); | |
| 427 | vma_itr = vma_itr->vm_next; | 435 | vma_itr = vma_itr->vm_next; |
| 428 | } | 436 | } |
| 429 | 437 | ||
| @@ -466,15 +474,52 @@ asmlinkage long sys_set_page_color(int cpu) | |||
| 466 | */ | 474 | */ |
| 467 | up_read(&mm->mmap_sem); | 475 | up_read(&mm->mmap_sem); |
| 468 | 476 | ||
| 469 | /* | 477 | |
| 470 | list_for_each_entry(page_itr, &shared_pagelist, lru) { | ||
| 471 | 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)); | ||
| 472 | } | ||
| 473 | */ | ||
| 474 | TRACE_TASK(current, "nr_pages = %d nr_failed = %d\n", nr_pages, nr_failed); | 478 | TRACE_TASK(current, "nr_pages = %d nr_failed = %d\n", nr_pages, nr_failed); |
| 475 | 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); | 479 | 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); |
| 476 | //printk(KERN_INFO "node = %d\n", cpu_to_node(smp_processor_id())); | 480 | |
| 477 | flush_cache(1); | 481 | flush_cache(1); |
| 482 | /* for debug START */ | ||
| 483 | TRACE_TASK(current, "SHARED PAGES\n"); | ||
| 484 | { | ||
| 485 | struct shared_lib_page *lpage; | ||
| 486 | |||
| 487 | rcu_read_lock(); | ||
| 488 | list_for_each_entry(lpage, &shared_pagelist, list) | ||
| 489 | { | ||
| 490 | TRACE_TASK(current, "PFN = %ld\n", lpage->pfn); | ||
| 491 | } | ||
| 492 | rcu_read_unlock(); | ||
| 493 | } | ||
| 494 | |||
| 495 | TRACE_TASK(current, "AFTER migration\n"); | ||
| 496 | down_read(&mm->mmap_sem); | ||
| 497 | vma_itr = mm->mmap; | ||
| 498 | while (vma_itr != NULL) { | ||
| 499 | unsigned int num_pages = 0, i; | ||
| 500 | struct page *old_page = NULL; | ||
| 501 | |||
| 502 | num_pages = (vma_itr->vm_end - vma_itr->vm_start) / PAGE_SIZE; | ||
| 503 | for (i = 0; i < num_pages; i++) { | ||
| 504 | old_page = follow_page(vma_itr, vma_itr->vm_start + PAGE_SIZE*i, FOLL_GET|FOLL_SPLIT); | ||
| 505 | if (IS_ERR(old_page)) | ||
| 506 | continue; | ||
| 507 | if (!old_page) | ||
| 508 | continue; | ||
| 509 | |||
| 510 | if (PageReserved(old_page)) { | ||
| 511 | TRACE("Reserved Page!\n"); | ||
| 512 | put_page(old_page); | ||
| 513 | continue; | ||
| 514 | } | ||
| 515 | 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)); | ||
| 516 | put_page(old_page); | ||
| 517 | } | ||
| 518 | |||
| 519 | vma_itr = vma_itr->vm_next; | ||
| 520 | } | ||
| 521 | up_read(&mm->mmap_sem); | ||
| 522 | /* for debug FIN. */ | ||
| 478 | 523 | ||
| 479 | return ret; | 524 | return ret; |
| 480 | } | 525 | } |
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 @@ | |||
| 1 | #include <asm/uaccess.h> | ||
| 2 | #include <linux/uaccess.h> | ||
| 3 | #include <linux/init.h> | ||
| 4 | #include <linux/types.h> | ||
| 5 | #include <linux/kernel.h> | ||
| 6 | #include <linux/module.h> | ||
| 7 | #include <linux/sysctl.h> | ||
| 8 | #include <linux/slab.h> | ||
| 9 | #include <linux/io.h> | ||
| 10 | #include <linux/mutex.h> | ||
| 11 | #include <linux/time.h> | ||
| 12 | #include <linux/migrate.h> | ||
| 13 | #include <linux/mm.h> | ||
| 14 | #include <linux/memcontrol.h> | ||
| 15 | #include <linux/mm_inline.h> | ||
| 16 | |||
| 17 | #include <litmus/litmus_proc.h> | ||
| 18 | #include <litmus/sched_trace.h> | ||
| 19 | #include <litmus/cache_proc.h> | ||
| 20 | #include <litmus/mc2_common.h> | ||
| 21 | #include <litmus/replicate_lib.h> | ||
| 22 | |||
| 23 | DEFINE_PER_CPU(struct list_head, shared_lib_page_list); | ||
| 24 | |||
| 25 | #define shared_lib_pages_for(cpu_id) (&per_cpu(shared_lib_page_list, cpu_id)) | ||
| 26 | #define local_shared_lib_pages() (this_cpu_ptr(&shared_lib_page_list)) | ||
| 27 | |||
| 28 | static int __init litmus_replicate_lib_init(void) | ||
| 29 | { | ||
| 30 | int cpu, ret = 0; | ||
| 31 | |||
| 32 | printk(KERN_INFO "Registering LITMUS^RT Per-core Shared Library module.\n"); | ||
| 33 | |||
| 34 | for_each_online_cpu(cpu) { | ||
| 35 | INIT_LIST_HEAD(shared_lib_pages_for(cpu)); | ||
| 36 | printk(KERN_INFO "CPU%d PSL-list initialized.\n", cpu); | ||
| 37 | } | ||
| 38 | |||
| 39 | return ret; | ||
| 40 | } | ||
| 41 | |||
| 42 | static void litmus_replicate_lib_exit(void) | ||
| 43 | { | ||
| 44 | return; | ||
| 45 | } | ||
| 46 | |||
| 47 | module_init(litmus_replicate_lib_init); | ||
| 48 | 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 @@ | |||
| 27 | #include <litmus/reservation.h> | 27 | #include <litmus/reservation.h> |
| 28 | #include <litmus/polling_reservations.h> | 28 | #include <litmus/polling_reservations.h> |
| 29 | 29 | ||
| 30 | #ifdef CONFIG_PGMRT_SUPPORT | ||
| 31 | #include <litmus/pgm.h> | ||
| 32 | #endif | ||
| 33 | |||
| 34 | //#define TRACE(fmt, args...) do {} while (false) | 30 | //#define TRACE(fmt, args...) do {} while (false) |
| 35 | //#define TRACE_TASK(fmt, args...) do {} while (false) | 31 | //#define TRACE_TASK(fmt, args...) do {} while (false) |
| 36 | 32 | ||
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 @@ | |||
| 23 | #include <litmus/sched_trace.h> | 23 | #include <litmus/sched_trace.h> |
| 24 | #include <litmus/trace.h> | 24 | #include <litmus/trace.h> |
| 25 | 25 | ||
| 26 | #ifdef CONFIG_PGMRT_SUPPORT | ||
| 27 | #include <litmus/pgm.h> | ||
| 28 | #endif | ||
| 29 | |||
| 26 | /* to set up domain/cpu mappings */ | 30 | /* to set up domain/cpu mappings */ |
| 27 | #include <litmus/litmus_proc.h> | 31 | #include <litmus/litmus_proc.h> |
| 28 | 32 | ||
| @@ -199,6 +203,62 @@ static struct task_struct* psnedf_schedule(struct task_struct * prev) | |||
| 199 | */ | 203 | */ |
| 200 | resched = preempt; | 204 | resched = preempt; |
| 201 | 205 | ||
| 206 | #ifdef CONFIG_PGMRT_SUPPORT | ||
| 207 | if (exists) { | ||
| 208 | if (is_pgm_sending(pedf->scheduled)) { | ||
| 209 | if (!is_pgm_satisfied(pedf->scheduled)) { | ||
| 210 | if (!is_priority_boosted(pedf->scheduled)) { | ||
| 211 | TRACE_TASK(pedf->scheduled, "is sending PGM tokens and needs boosting.\n"); | ||
| 212 | BUG_ON(is_pgm_satisfied(pedf->scheduled)); | ||
| 213 | |||
| 214 | /* We are either sending tokens or waiting for tokes. | ||
| 215 | If waiting: Boost priority so we'll be scheduled | ||
| 216 | immediately when needed tokens arrive. | ||
| 217 | If sending: Boost priority so no one (specifically, our | ||
| 218 | consumers) will preempt us while signalling the token | ||
| 219 | transmission. | ||
| 220 | */ | ||
| 221 | tsk_rt(pedf->scheduled)->priority_boosted = 1; | ||
| 222 | tsk_rt(pedf->scheduled)->boost_start_time = litmus_clock(); | ||
| 223 | |||
| 224 | if (likely(!blocks)) { | ||
| 225 | requeue(pedf->scheduled, edf); | ||
| 226 | /* we may regain the processor */ | ||
| 227 | if (preempt) { | ||
| 228 | preempt = edf_preemption_needed(edf, prev); | ||
| 229 | if (!preempt) { | ||
| 230 | TRACE_TASK(pedf->scheduled, "blocked preemption by lazy boosting.\n"); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | } | ||
| 234 | } | ||
| 235 | } | ||
| 236 | else { /* sending is satisfied */ | ||
| 237 | tsk_rt(pedf->scheduled)->ctrl_page->pgm_sending = 0; | ||
| 238 | tsk_rt(pedf->scheduled)->ctrl_page->pgm_satisfied = 0; | ||
| 239 | |||
| 240 | if (is_priority_boosted(pedf->scheduled)) { | ||
| 241 | TRACE_TASK(pedf->scheduled, | ||
| 242 | "is done sending PGM tokens must relinquish boosting.\n"); | ||
| 243 | /* clear boosting */ | ||
| 244 | tsk_rt(pedf->scheduled)->priority_boosted = 0; | ||
| 245 | if(likely(!blocks)) { | ||
| 246 | /* recheck priority */ | ||
| 247 | requeue(pedf->scheduled, edf); | ||
| 248 | /* we may lose the processor */ | ||
| 249 | if (!preempt) { | ||
| 250 | preempt = edf_preemption_needed(edf, prev); | ||
| 251 | if (preempt) { | ||
| 252 | TRACE_TASK(pedf->scheduled, "preempted by lazy unboosting.\n"); | ||
| 253 | } | ||
| 254 | } | ||
| 255 | } | ||
| 256 | } | ||
| 257 | } | ||
| 258 | } | ||
| 259 | } | ||
| 260 | #endif | ||
| 261 | |||
| 202 | /* If a task blocks we have no choice but to reschedule. | 262 | /* If a task blocks we have no choice but to reschedule. |
| 203 | */ | 263 | */ |
| 204 | if (blocks) | 264 | if (blocks) |
