aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2016-09-22 14:49:49 -0400
committerNamhoon Kim <namhoonk@cs.unc.edu>2016-09-22 14:49:49 -0400
commitd7352bf3c9392104c34b56e2c0756a14db81b68a (patch)
tree34a42a02bb6ce3a10b00ce5fa9302ab182d3aae0
parent2b1bccf411c97a933796526b0427785a2dafde1d (diff)
9/22/2016
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/mm.h2
-rw-r--r--include/linux/mm_types.h7
-rw-r--r--include/linux/mmzone.h1
-rw-r--r--init/main.c1
-rw-r--r--litmus/litmus.c5
-rw-r--r--litmus/sched_mc2.c15
-rw-r--r--mm/Makefile2
-rw-r--r--mm/filemap.c129
-rw-r--r--mm/internal.h28
-rw-r--r--mm/memory.c2
-rw-r--r--mm/page-writeback.c3
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
493int mapping_tagged(struct address_space *mapping, int tag); 494int 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);
2200static inline void setup_nr_node_ids(void) {} 2200static inline void setup_nr_node_ids(void) {}
2201#endif 2201#endif
2202 2202
2203extern 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
549struct 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/
56obj-$(CONFIG_FAILSLAB) += failslab.o 56obj-$(CONFIG_FAILSLAB) += failslab.o
57obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o 57obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
58obj-$(CONFIG_MEMTEST) += memtest.o 58obj-$(CONFIG_MEMTEST) += memtest.o
59obj-$(CONFIG_MIGRATION) += migrate.o 59obj-$(CONFIG_MIGRATION) += migrate.o replication.o
60obj-$(CONFIG_QUICKLIST) += quicklist.o 60obj-$(CONFIG_QUICKLIST) += quicklist.o
61obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o 61obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o
62obj-$(CONFIG_PAGE_COUNTER) += page_counter.o 62obj-$(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
982printk(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
1195printk(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
1272printk(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 1309export:
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
1354printk(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 1391export:
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();
1491find_page: 1552find_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;
1901retry_find: 1982retry_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
2101printk(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 2128export:
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 */
21static 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
27extern int reclaim_replicated_page(struct address_space *mapping,
28 struct page *page);
29extern struct page *get_unreplicated_page(struct address_space *mapping,
30 unsigned long offset, struct page *page);
31extern void get_unreplicated_pages(struct address_space *mapping,
32 struct page **pages, int nr);
33extern struct page *find_get_page_readonly(struct address_space *mapping,
34 unsigned long offset);
35extern int is_pcache_desc(void *ptr);
36extern struct pcache_desc *ptr_to_pcache_desc(void *ptr);
37extern void *pcache_desc_to_ptr(struct pcache_desc *pcd);
38extern void unreplicate_pcache(struct address_space *mapping, unsigned long offset);
39
40struct page *get_unreplicated_page_fault(struct page *page);
41
42/* End Pagecache replication */
43
16 44
17void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, 45void 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 *