aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2016-09-09 03:07:58 -0400
committerNamhoon Kim <namhoonk@cs.unc.edu>2016-09-09 03:07:58 -0400
commit418e60bb6948a4cf6eb7c737bea21c2314619c73 (patch)
tree4dc9a4f1ee2b04ff92a331beef7944c9e5126bea
parentd57b8f5a8e2d08fa972dad6b646a02a5dd931be4 (diff)
Shared library identification
-rw-r--r--include/litmus/replicate_lib.h14
-rw-r--r--litmus/Makefile1
-rw-r--r--litmus/cache_proc.c10
-rw-r--r--litmus/litmus.c81
-rw-r--r--litmus/replicate_lib.c48
-rw-r--r--litmus/sched_mc2.c4
-rw-r--r--litmus/sched_psn_edf.c60
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
8struct 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
33obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o 34obj-$(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
1137asmlinkage long sys_run_test(int type, int size, cacheline_t *src, cacheline_t *dst, lt_t __user *ts) 1137asmlinkage 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);
351extern void putback_movable_page(struct page *page); 352extern void putback_movable_page(struct page *page);
352extern struct page *new_alloc_page(struct page *page, unsigned long node, int **x); 353extern struct page *new_alloc_page(struct page *page, unsigned long node, int **x);
353 354
355DECLARE_PER_CPU(struct list_head, shared_lib_page_list);
356
354asmlinkage long sys_set_page_color(int cpu) 357asmlinkage 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(&current->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
23DEFINE_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
28static 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
42static void litmus_replicate_lib_exit(void)
43{
44 return;
45}
46
47module_init(litmus_replicate_lib_init);
48module_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)