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) |