diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-09-22 14:49:49 -0400 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-09-22 14:49:49 -0400 |
commit | d7352bf3c9392104c34b56e2c0756a14db81b68a (patch) | |
tree | 34a42a02bb6ce3a10b00ce5fa9302ab182d3aae0 | |
parent | 2b1bccf411c97a933796526b0427785a2dafde1d (diff) |
9/22/2016
-rw-r--r-- | include/linux/fs.h | 1 | ||||
-rw-r--r-- | include/linux/mm.h | 2 | ||||
-rw-r--r-- | include/linux/mm_types.h | 7 | ||||
-rw-r--r-- | include/linux/mmzone.h | 1 | ||||
-rw-r--r-- | init/main.c | 1 | ||||
-rw-r--r-- | litmus/litmus.c | 5 | ||||
-rw-r--r-- | litmus/sched_mc2.c | 15 | ||||
-rw-r--r-- | mm/Makefile | 2 | ||||
-rw-r--r-- | mm/filemap.c | 129 | ||||
-rw-r--r-- | mm/internal.h | 28 | ||||
-rw-r--r-- | mm/memory.c | 2 | ||||
-rw-r--r-- | mm/page-writeback.c | 3 |
12 files changed, 175 insertions, 21 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index 1ea979d984c2..9bddbf91dcbf 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -489,6 +489,7 @@ struct block_device { | |||
489 | #define PAGECACHE_TAG_DIRTY 0 | 489 | #define PAGECACHE_TAG_DIRTY 0 |
490 | #define PAGECACHE_TAG_WRITEBACK 1 | 490 | #define PAGECACHE_TAG_WRITEBACK 1 |
491 | #define PAGECACHE_TAG_TOWRITE 2 | 491 | #define PAGECACHE_TAG_TOWRITE 2 |
492 | #define PAGECACHE_TAG_REPLICATED 3 | ||
492 | 493 | ||
493 | int mapping_tagged(struct address_space *mapping, int tag); | 494 | int mapping_tagged(struct address_space *mapping, int tag); |
494 | 495 | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index 0755b9fd03a7..55df1f8bf4cb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -2200,5 +2200,7 @@ void __init setup_nr_node_ids(void); | |||
2200 | static inline void setup_nr_node_ids(void) {} | 2200 | static inline void setup_nr_node_ids(void) {} |
2201 | #endif | 2201 | #endif |
2202 | 2202 | ||
2203 | extern void replication_init(void); | ||
2204 | |||
2203 | #endif /* __KERNEL__ */ | 2205 | #endif /* __KERNEL__ */ |
2204 | #endif /* _LINUX_MM_H */ | 2206 | #endif /* _LINUX_MM_H */ |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 8d37e26a1007..76603d077455 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/page-flags-layout.h> | 14 | #include <linux/page-flags-layout.h> |
15 | #include <asm/page.h> | 15 | #include <asm/page.h> |
16 | #include <asm/mmu.h> | 16 | #include <asm/mmu.h> |
17 | #include <linux/radix-tree.h> | ||
17 | 18 | ||
18 | #ifndef AT_VECTOR_SIZE_ARCH | 19 | #ifndef AT_VECTOR_SIZE_ARCH |
19 | #define AT_VECTOR_SIZE_ARCH 0 | 20 | #define AT_VECTOR_SIZE_ARCH 0 |
@@ -545,4 +546,10 @@ typedef struct { | |||
545 | unsigned long val; | 546 | unsigned long val; |
546 | } swp_entry_t; | 547 | } swp_entry_t; |
547 | 548 | ||
549 | struct pcache_desc { | ||
550 | struct page *master; | ||
551 | cpumask_t cpus_present; | ||
552 | struct radix_tree_root page_tree; | ||
553 | }; | ||
554 | |||
548 | #endif /* _LINUX_MM_TYPES_H */ | 555 | #endif /* _LINUX_MM_TYPES_H */ |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 54d74f6eb233..d3762dec9dea 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -128,6 +128,7 @@ enum zone_stat_item { | |||
128 | NR_FILE_PAGES, | 128 | NR_FILE_PAGES, |
129 | NR_FILE_DIRTY, | 129 | NR_FILE_DIRTY, |
130 | NR_WRITEBACK, | 130 | NR_WRITEBACK, |
131 | NR_REPL_PAGES, | ||
131 | NR_SLAB_RECLAIMABLE, | 132 | NR_SLAB_RECLAIMABLE, |
132 | NR_SLAB_UNRECLAIMABLE, | 133 | NR_SLAB_UNRECLAIMABLE, |
133 | NR_PAGETABLE, /* used for pagetables */ | 134 | NR_PAGETABLE, /* used for pagetables */ |
diff --git a/init/main.c b/init/main.c index 2a89545e0a5d..88917d93fbe4 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -628,6 +628,7 @@ asmlinkage __visible void __init start_kernel(void) | |||
628 | kmemleak_init(); | 628 | kmemleak_init(); |
629 | setup_per_cpu_pageset(); | 629 | setup_per_cpu_pageset(); |
630 | numa_policy_init(); | 630 | numa_policy_init(); |
631 | replication_init(); | ||
631 | if (late_time_init) | 632 | if (late_time_init) |
632 | late_time_init(); | 633 | late_time_init(); |
633 | sched_clock_init(); | 634 | sched_clock_init(); |
diff --git a/litmus/litmus.c b/litmus/litmus.c index ad3d50c78bb1..cad0e5adb5a3 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -444,6 +444,7 @@ asmlinkage long sys_set_page_color(int cpu) | |||
444 | 444 | ||
445 | nr_shared_pages++; | 445 | nr_shared_pages++; |
446 | TRACE_TASK(current, "SHARED\n"); | 446 | TRACE_TASK(current, "SHARED\n"); |
447 | put_page(old_page); | ||
447 | } | 448 | } |
448 | else { | 449 | else { |
449 | ret = isolate_lru_page(old_page); | 450 | ret = isolate_lru_page(old_page); |
@@ -504,7 +505,7 @@ asmlinkage long sys_set_page_color(int cpu) | |||
504 | } | 505 | } |
505 | } | 506 | } |
506 | } | 507 | } |
507 | 508 | /* | |
508 | if (!list_empty(&task_shared_pagelist)) { | 509 | if (!list_empty(&task_shared_pagelist)) { |
509 | ret = replicate_pages(&task_shared_pagelist, new_alloc_page, NULL, node, MIGRATE_SYNC, MR_SYSCALL); | 510 | ret = replicate_pages(&task_shared_pagelist, new_alloc_page, NULL, node, MIGRATE_SYNC, MR_SYSCALL); |
510 | TRACE_TASK(current, "%ld shared pages not migrated.\n", ret); | 511 | TRACE_TASK(current, "%ld shared pages not migrated.\n", ret); |
@@ -513,7 +514,7 @@ asmlinkage long sys_set_page_color(int cpu) | |||
513 | putback_movable_pages(&task_shared_pagelist); | 514 | putback_movable_pages(&task_shared_pagelist); |
514 | } | 515 | } |
515 | } | 516 | } |
516 | 517 | */ | |
517 | /* handle sigpage and litmus ctrl_page */ | 518 | /* handle sigpage and litmus ctrl_page */ |
518 | /* vma_itr = current->mm->mmap; | 519 | /* vma_itr = current->mm->mmap; |
519 | while (vma_itr != NULL) { | 520 | while (vma_itr != NULL) { |
diff --git a/litmus/sched_mc2.c b/litmus/sched_mc2.c index 5c88a36aacec..d0a39ff96b13 100644 --- a/litmus/sched_mc2.c +++ b/litmus/sched_mc2.c | |||
@@ -341,7 +341,7 @@ static void mc2_update_timer_and_unlock(struct mc2_cpu_state *state) | |||
341 | local = local_cpu_state() == state; | 341 | local = local_cpu_state() == state; |
342 | 342 | ||
343 | raw_spin_lock(&_global_env.lock); | 343 | raw_spin_lock(&_global_env.lock); |
344 | 344 | // TRACE("P%d acquired GE lock L344\n"); | |
345 | list_for_each_entry_safe(event, next, &_global_env.next_events, list) { | 345 | list_for_each_entry_safe(event, next, &_global_env.next_events, list) { |
346 | /* If the event time is already passed, we call schedule() on | 346 | /* If the event time is already passed, we call schedule() on |
347 | the lowest priority cpu */ | 347 | the lowest priority cpu */ |
@@ -376,6 +376,7 @@ static void mc2_update_timer_and_unlock(struct mc2_cpu_state *state) | |||
376 | /* Must drop state lock before calling into hrtimer_start(), which | 376 | /* Must drop state lock before calling into hrtimer_start(), which |
377 | * may raise a softirq, which in turn may wake ksoftirqd. */ | 377 | * may raise a softirq, which in turn may wake ksoftirqd. */ |
378 | raw_spin_unlock(&_global_env.lock); | 378 | raw_spin_unlock(&_global_env.lock); |
379 | // TRACE("P%d releases GE lock L379\n"); | ||
379 | raw_spin_unlock(&state->lock); | 380 | raw_spin_unlock(&state->lock); |
380 | 381 | ||
381 | if (update <= now || reschedule[state->cpu]) { | 382 | if (update <= now || reschedule[state->cpu]) { |
@@ -600,6 +601,7 @@ static enum hrtimer_restart on_scheduling_timer(struct hrtimer *timer) | |||
600 | } | 601 | } |
601 | 602 | ||
602 | raw_spin_lock(&_global_env.lock); | 603 | raw_spin_lock(&_global_env.lock); |
604 | // TRACE("P%d acquired GE lock L604\n"); | ||
603 | global_schedule_now = gmp_update_time(&_global_env, now); | 605 | global_schedule_now = gmp_update_time(&_global_env, now); |
604 | 606 | ||
605 | BUG_ON(global_schedule_now < 0 || global_schedule_now > 4); | 607 | BUG_ON(global_schedule_now < 0 || global_schedule_now > 4); |
@@ -619,7 +621,7 @@ static enum hrtimer_restart on_scheduling_timer(struct hrtimer *timer) | |||
619 | } | 621 | } |
620 | } | 622 | } |
621 | raw_spin_unlock(&_global_env.lock); | 623 | raw_spin_unlock(&_global_env.lock); |
622 | 624 | // TRACE("P%d releases GE lock L624\n"); | |
623 | raw_spin_unlock_irqrestore(&state->lock, flags); | 625 | raw_spin_unlock_irqrestore(&state->lock, flags); |
624 | //raw_spin_unlock_irqrestore(&_global_env.lock, flags); | 626 | //raw_spin_unlock_irqrestore(&_global_env.lock, flags); |
625 | 627 | ||
@@ -679,6 +681,7 @@ static long mc2_complete_job(void) | |||
679 | state = local_cpu_state(); | 681 | state = local_cpu_state(); |
680 | raw_spin_lock(&state->lock); | 682 | raw_spin_lock(&state->lock); |
681 | raw_spin_lock(&_global_env.lock); | 683 | raw_spin_lock(&_global_env.lock); |
684 | // TRACE("P%d acquired GE lock L684\n"); | ||
682 | res = gmp_find_by_id(&_global_env, tinfo->mc2_param.res_id); | 685 | res = gmp_find_by_id(&_global_env, tinfo->mc2_param.res_id); |
683 | _global_env.env.time_zero = tsk_rt(current)->sporadic_release_time; | 686 | _global_env.env.time_zero = tsk_rt(current)->sporadic_release_time; |
684 | } | 687 | } |
@@ -705,8 +708,10 @@ static long mc2_complete_job(void) | |||
705 | //if (lv < CRIT_LEVEL_C) | 708 | //if (lv < CRIT_LEVEL_C) |
706 | // raw_spin_unlock(&state->lock); | 709 | // raw_spin_unlock(&state->lock); |
707 | //else | 710 | //else |
708 | if (lv == CRIT_LEVEL_C) | 711 | if (lv == CRIT_LEVEL_C) { |
709 | raw_spin_unlock(&_global_env.lock); | 712 | raw_spin_unlock(&_global_env.lock); |
713 | // TRACE("P%d releases GE lock L713\n"); | ||
714 | } | ||
710 | 715 | ||
711 | raw_spin_unlock(&state->lock); | 716 | raw_spin_unlock(&state->lock); |
712 | local_irq_restore(flags); | 717 | local_irq_restore(flags); |
@@ -991,7 +996,7 @@ static struct task_struct* mc2_schedule(struct task_struct * prev) | |||
991 | } | 996 | } |
992 | } | 997 | } |
993 | 998 | ||
994 | if (to_schedule != 0) { | 999 | if (to_schedule > 0) { |
995 | raw_spin_lock(&_global_env.lock); | 1000 | raw_spin_lock(&_global_env.lock); |
996 | while (to_schedule--) { | 1001 | while (to_schedule--) { |
997 | int cpu = get_lowest_prio_cpu(0); | 1002 | int cpu = get_lowest_prio_cpu(0); |
@@ -1078,9 +1083,11 @@ static void mc2_task_resume(struct task_struct *tsk) | |||
1078 | task_arrives(state, tsk); | 1083 | task_arrives(state, tsk); |
1079 | } else { | 1084 | } else { |
1080 | raw_spin_lock(&_global_env.lock); | 1085 | raw_spin_lock(&_global_env.lock); |
1086 | // TRACE("P%d acquired GE lock L1086\n"); | ||
1081 | gmp_update_time(&_global_env, litmus_clock()); | 1087 | gmp_update_time(&_global_env, litmus_clock()); |
1082 | task_arrives(state, tsk); | 1088 | task_arrives(state, tsk); |
1083 | raw_spin_unlock(&_global_env.lock); | 1089 | raw_spin_unlock(&_global_env.lock); |
1090 | // TRACE("P%d releases GE lock L1090\n"); | ||
1084 | } | 1091 | } |
1085 | 1092 | ||
1086 | /* 9/20/2015 fix | 1093 | /* 9/20/2015 fix |
diff --git a/mm/Makefile b/mm/Makefile index 98c4eaeabdcb..98d28edd36a5 100644 --- a/mm/Makefile +++ b/mm/Makefile | |||
@@ -56,7 +56,7 @@ obj-$(CONFIG_KASAN) += kasan/ | |||
56 | obj-$(CONFIG_FAILSLAB) += failslab.o | 56 | obj-$(CONFIG_FAILSLAB) += failslab.o |
57 | obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o | 57 | obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o |
58 | obj-$(CONFIG_MEMTEST) += memtest.o | 58 | obj-$(CONFIG_MEMTEST) += memtest.o |
59 | obj-$(CONFIG_MIGRATION) += migrate.o | 59 | obj-$(CONFIG_MIGRATION) += migrate.o replication.o |
60 | obj-$(CONFIG_QUICKLIST) += quicklist.o | 60 | obj-$(CONFIG_QUICKLIST) += quicklist.o |
61 | obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o | 61 | obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o |
62 | obj-$(CONFIG_PAGE_COUNTER) += page_counter.o | 62 | obj-$(CONFIG_PAGE_COUNTER) += page_counter.o |
diff --git a/mm/filemap.c b/mm/filemap.c index 8f378ac675d7..60d7e38cf73d 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -36,6 +36,9 @@ | |||
36 | #include <linux/rmap.h> | 36 | #include <linux/rmap.h> |
37 | #include "internal.h" | 37 | #include "internal.h" |
38 | 38 | ||
39 | #include <litmus/litmus.h> | ||
40 | #include <litmus/mc2_common.h> | ||
41 | |||
39 | #define CREATE_TRACE_POINTS | 42 | #define CREATE_TRACE_POINTS |
40 | #include <trace/events/filemap.h> | 43 | #include <trace/events/filemap.h> |
41 | 44 | ||
@@ -970,13 +973,23 @@ repeat: | |||
970 | page = NULL; | 973 | page = NULL; |
971 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); | 974 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); |
972 | if (pagep) { | 975 | if (pagep) { |
973 | void *pdesc; | 976 | page = radix_tree_deref_slot(pagep); |
974 | pdesc = radix_tree_deref_slot(pagep); | ||
975 | if (pdesc) | ||
976 | page = (struct page*)pdesc; | ||
977 | //page = radix_tree_deref_slot(pagep); | ||
978 | if (unlikely(!page)) | 977 | if (unlikely(!page)) |
979 | goto out; | 978 | goto out; |
979 | if (is_pcache_desc(page)) { | ||
980 | struct pcache_desc *pcd; | ||
981 | |||
982 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
983 | |||
984 | pcd = ptr_to_pcache_desc(page); | ||
985 | page = pcd->master; | ||
986 | page_cache_get_speculative(page); | ||
987 | |||
988 | unreplicate_pcache(mapping, page->index); | ||
989 | |||
990 | goto out; | ||
991 | } | ||
992 | |||
980 | if (radix_tree_exception(page)) { | 993 | if (radix_tree_exception(page)) { |
981 | if (radix_tree_deref_retry(page)) | 994 | if (radix_tree_deref_retry(page)) |
982 | goto repeat; | 995 | goto repeat; |
@@ -1175,6 +1188,21 @@ repeat: | |||
1175 | page = radix_tree_deref_slot(slot); | 1188 | page = radix_tree_deref_slot(slot); |
1176 | if (unlikely(!page)) | 1189 | if (unlikely(!page)) |
1177 | continue; | 1190 | continue; |
1191 | |||
1192 | if (is_pcache_desc(page)) { | ||
1193 | struct pcache_desc *pcd; | ||
1194 | |||
1195 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
1196 | |||
1197 | pcd = ptr_to_pcache_desc(page); | ||
1198 | page = pcd->master; | ||
1199 | page_cache_get_speculative(page); | ||
1200 | |||
1201 | unreplicate_pcache(mapping, page->index); | ||
1202 | |||
1203 | goto export; | ||
1204 | } | ||
1205 | |||
1178 | if (radix_tree_exception(page)) { | 1206 | if (radix_tree_exception(page)) { |
1179 | if (radix_tree_deref_retry(page)) | 1207 | if (radix_tree_deref_retry(page)) |
1180 | goto restart; | 1208 | goto restart; |
@@ -1238,6 +1266,20 @@ repeat: | |||
1238 | if (unlikely(!page)) | 1266 | if (unlikely(!page)) |
1239 | continue; | 1267 | continue; |
1240 | 1268 | ||
1269 | if (is_pcache_desc(page)) { | ||
1270 | struct pcache_desc *pcd; | ||
1271 | |||
1272 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
1273 | |||
1274 | pcd = ptr_to_pcache_desc(page); | ||
1275 | page = pcd->master; | ||
1276 | page_cache_get_speculative(page); | ||
1277 | |||
1278 | unreplicate_pcache(mapping, page->index); | ||
1279 | |||
1280 | goto export; | ||
1281 | } | ||
1282 | |||
1241 | if (radix_tree_exception(page)) { | 1283 | if (radix_tree_exception(page)) { |
1242 | if (radix_tree_deref_retry(page)) { | 1284 | if (radix_tree_deref_retry(page)) { |
1243 | /* | 1285 | /* |
@@ -1264,7 +1306,7 @@ repeat: | |||
1264 | page_cache_release(page); | 1306 | page_cache_release(page); |
1265 | goto repeat; | 1307 | goto repeat; |
1266 | } | 1308 | } |
1267 | 1309 | export: | |
1268 | pages[ret] = page; | 1310 | pages[ret] = page; |
1269 | if (++ret == nr_pages) | 1311 | if (++ret == nr_pages) |
1270 | break; | 1312 | break; |
@@ -1306,6 +1348,21 @@ repeat: | |||
1306 | if (unlikely(!page)) | 1348 | if (unlikely(!page)) |
1307 | break; | 1349 | break; |
1308 | 1350 | ||
1351 | if (is_pcache_desc(page)) { | ||
1352 | struct pcache_desc *pcd; | ||
1353 | |||
1354 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
1355 | |||
1356 | pcd = ptr_to_pcache_desc(page); | ||
1357 | page = pcd->master; | ||
1358 | if (!page_cache_get_speculative(page)) | ||
1359 | goto repeat; | ||
1360 | |||
1361 | unreplicate_pcache(mapping, page->index); | ||
1362 | |||
1363 | goto export; | ||
1364 | } | ||
1365 | |||
1309 | if (radix_tree_exception(page)) { | 1366 | if (radix_tree_exception(page)) { |
1310 | if (radix_tree_deref_retry(page)) { | 1367 | if (radix_tree_deref_retry(page)) { |
1311 | /* | 1368 | /* |
@@ -1331,7 +1388,7 @@ repeat: | |||
1331 | page_cache_release(page); | 1388 | page_cache_release(page); |
1332 | goto repeat; | 1389 | goto repeat; |
1333 | } | 1390 | } |
1334 | 1391 | export: | |
1335 | /* | 1392 | /* |
1336 | * must check mapping and index after taking the ref. | 1393 | * must check mapping and index after taking the ref. |
1337 | * otherwise we can get both false positives and false | 1394 | * otherwise we can get both false positives and false |
@@ -1382,6 +1439,10 @@ repeat: | |||
1382 | if (unlikely(!page)) | 1439 | if (unlikely(!page)) |
1383 | continue; | 1440 | continue; |
1384 | 1441 | ||
1442 | if (is_pcache_desc(page)) { | ||
1443 | BUG(); | ||
1444 | } | ||
1445 | |||
1385 | if (radix_tree_exception(page)) { | 1446 | if (radix_tree_exception(page)) { |
1386 | if (radix_tree_deref_retry(page)) { | 1447 | if (radix_tree_deref_retry(page)) { |
1387 | /* | 1448 | /* |
@@ -1489,7 +1550,13 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, | |||
1489 | 1550 | ||
1490 | cond_resched(); | 1551 | cond_resched(); |
1491 | find_page: | 1552 | find_page: |
1492 | page = find_get_page(mapping, index); | 1553 | if (tsk_mc2_data(current)) { |
1554 | printk(KERN_INFO "RT Task file_read1\n"); | ||
1555 | page = find_get_page_readonly(mapping, index); | ||
1556 | } | ||
1557 | else | ||
1558 | page = find_get_page(mapping, index); | ||
1559 | |||
1493 | if (!page) { | 1560 | if (!page) { |
1494 | page_cache_sync_readahead(mapping, | 1561 | page_cache_sync_readahead(mapping, |
1495 | ra, filp, | 1562 | ra, filp, |
@@ -1526,7 +1593,6 @@ page_ok: | |||
1526 | * part of the page is not copied back to userspace (unless | 1593 | * part of the page is not copied back to userspace (unless |
1527 | * another truncate extends the file - this is desired though). | 1594 | * another truncate extends the file - this is desired though). |
1528 | */ | 1595 | */ |
1529 | |||
1530 | isize = i_size_read(inode); | 1596 | isize = i_size_read(inode); |
1531 | end_index = (isize - 1) >> PAGE_CACHE_SHIFT; | 1597 | end_index = (isize - 1) >> PAGE_CACHE_SHIFT; |
1532 | if (unlikely(!isize || index > end_index)) { | 1598 | if (unlikely(!isize || index > end_index)) { |
@@ -1544,7 +1610,16 @@ page_ok: | |||
1544 | } | 1610 | } |
1545 | } | 1611 | } |
1546 | nr = nr - offset; | 1612 | nr = nr - offset; |
1547 | 1613 | ||
1614 | if (tsk_mc2_data(current)) { | ||
1615 | printk(KERN_INFO "RT Task file_read2\n"); | ||
1616 | page_cache_release(page); | ||
1617 | page = find_get_page_readonly(mapping, index); | ||
1618 | if (!page) { | ||
1619 | BUG(); | ||
1620 | } | ||
1621 | } | ||
1622 | |||
1548 | /* If users can be writing to this page using arbitrary | 1623 | /* If users can be writing to this page using arbitrary |
1549 | * virtual addresses, take care about potential aliasing | 1624 | * virtual addresses, take care about potential aliasing |
1550 | * before reading the page on the kernel side. | 1625 | * before reading the page on the kernel side. |
@@ -1885,7 +1960,13 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1885 | /* | 1960 | /* |
1886 | * Do we have something in the page cache already? | 1961 | * Do we have something in the page cache already? |
1887 | */ | 1962 | */ |
1888 | page = find_get_page(mapping, offset); | 1963 | if (tsk_mc2_data(current)) { |
1964 | printk(KERN_INFO "RT Task filemap_fault1\n"); | ||
1965 | page = find_get_page_readonly(mapping, offset); | ||
1966 | } | ||
1967 | else | ||
1968 | page = find_get_page(mapping, offset); | ||
1969 | |||
1889 | if (likely(page) && !(vmf->flags & FAULT_FLAG_TRIED)) { | 1970 | if (likely(page) && !(vmf->flags & FAULT_FLAG_TRIED)) { |
1890 | /* | 1971 | /* |
1891 | * We found the page, so try async readahead before | 1972 | * We found the page, so try async readahead before |
@@ -1899,7 +1980,13 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1899 | mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); | 1980 | mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); |
1900 | ret = VM_FAULT_MAJOR; | 1981 | ret = VM_FAULT_MAJOR; |
1901 | retry_find: | 1982 | retry_find: |
1902 | page = find_get_page(mapping, offset); | 1983 | if (tsk_mc2_data(current)) { |
1984 | printk(KERN_INFO "RT Task filemap_fault2\n"); | ||
1985 | page = find_get_page_readonly(mapping, offset); | ||
1986 | } | ||
1987 | else | ||
1988 | page = find_get_page(mapping, offset); | ||
1989 | |||
1903 | if (!page) | 1990 | if (!page) |
1904 | goto no_cached_page; | 1991 | goto no_cached_page; |
1905 | } | 1992 | } |
@@ -2007,6 +2094,22 @@ repeat: | |||
2007 | page = radix_tree_deref_slot(slot); | 2094 | page = radix_tree_deref_slot(slot); |
2008 | if (unlikely(!page)) | 2095 | if (unlikely(!page)) |
2009 | goto next; | 2096 | goto next; |
2097 | |||
2098 | if (is_pcache_desc(page)) { | ||
2099 | struct pcache_desc *pcd; | ||
2100 | |||
2101 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
2102 | |||
2103 | pcd = ptr_to_pcache_desc(page); | ||
2104 | page = pcd->master; | ||
2105 | if (!page_cache_get_speculative(page)) | ||
2106 | goto repeat; | ||
2107 | |||
2108 | unreplicate_pcache(mapping, page->index); | ||
2109 | |||
2110 | goto export; | ||
2111 | } | ||
2112 | |||
2010 | if (radix_tree_exception(page)) { | 2113 | if (radix_tree_exception(page)) { |
2011 | if (radix_tree_deref_retry(page)) | 2114 | if (radix_tree_deref_retry(page)) |
2012 | break; | 2115 | break; |
@@ -2022,7 +2125,7 @@ repeat: | |||
2022 | page_cache_release(page); | 2125 | page_cache_release(page); |
2023 | goto repeat; | 2126 | goto repeat; |
2024 | } | 2127 | } |
2025 | 2128 | export: | |
2026 | if (!PageUptodate(page) || | 2129 | if (!PageUptodate(page) || |
2027 | PageReadahead(page) || | 2130 | PageReadahead(page) || |
2028 | PageHWPoison(page)) | 2131 | PageHWPoison(page)) |
diff --git a/mm/internal.h b/mm/internal.h index a25e359a4039..8bdf34edb5c2 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -13,6 +13,34 @@ | |||
13 | 13 | ||
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/pagemap.h> | ||
17 | |||
18 | /* | ||
19 | * Pagecache replication | ||
20 | */ | ||
21 | static inline int pcache_replicated(struct address_space *mapping, unsigned long offset) | ||
22 | { | ||
23 | return radix_tree_tag_get(&mapping->page_tree, offset, | ||
24 | PAGECACHE_TAG_REPLICATED); | ||
25 | } | ||
26 | |||
27 | extern int reclaim_replicated_page(struct address_space *mapping, | ||
28 | struct page *page); | ||
29 | extern struct page *get_unreplicated_page(struct address_space *mapping, | ||
30 | unsigned long offset, struct page *page); | ||
31 | extern void get_unreplicated_pages(struct address_space *mapping, | ||
32 | struct page **pages, int nr); | ||
33 | extern struct page *find_get_page_readonly(struct address_space *mapping, | ||
34 | unsigned long offset); | ||
35 | extern int is_pcache_desc(void *ptr); | ||
36 | extern struct pcache_desc *ptr_to_pcache_desc(void *ptr); | ||
37 | extern void *pcache_desc_to_ptr(struct pcache_desc *pcd); | ||
38 | extern void unreplicate_pcache(struct address_space *mapping, unsigned long offset); | ||
39 | |||
40 | struct page *get_unreplicated_page_fault(struct page *page); | ||
41 | |||
42 | /* End Pagecache replication */ | ||
43 | |||
16 | 44 | ||
17 | void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, | 45 | void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, |
18 | unsigned long floor, unsigned long ceiling); | 46 | unsigned long floor, unsigned long ceiling); |
diff --git a/mm/memory.c b/mm/memory.c index 22e037e3364e..c9fa78dfccb9 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2235,6 +2235,8 @@ static int wp_page_shared(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2235 | int tmp; | 2235 | int tmp; |
2236 | 2236 | ||
2237 | pte_unmap_unlock(page_table, ptl); | 2237 | pte_unmap_unlock(page_table, ptl); |
2238 | old_page = get_unreplicated_page_fault(old_page); | ||
2239 | |||
2238 | tmp = do_page_mkwrite(vma, old_page, address); | 2240 | tmp = do_page_mkwrite(vma, old_page, address); |
2239 | if (unlikely(!tmp || (tmp & | 2241 | if (unlikely(!tmp || (tmp & |
2240 | (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) { | 2242 | (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))) { |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 7e39ffceb566..161af608b7e2 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -2287,7 +2287,8 @@ int clear_page_dirty_for_io(struct page *page) | |||
2287 | 2287 | ||
2288 | BUG_ON(!PageLocked(page)); | 2288 | BUG_ON(!PageLocked(page)); |
2289 | 2289 | ||
2290 | if (mapping && mapping_cap_account_dirty(mapping)) { | 2290 | //if (mapping && mapping_cap_account_dirty(mapping)) { |
2291 | if (mapping) { | ||
2291 | /* | 2292 | /* |
2292 | * Yes, Virginia, this is indeed insane. | 2293 | * Yes, Virginia, this is indeed insane. |
2293 | * | 2294 | * |