diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 119 |
1 files changed, 105 insertions, 14 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 8ea609718839..93853e337f07 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -973,13 +973,21 @@ repeat: | |||
973 | page = NULL; | 973 | page = NULL; |
974 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); | 974 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); |
975 | if (pagep) { | 975 | if (pagep) { |
976 | void *pdesc; | 976 | page = radix_tree_deref_slot(pagep); |
977 | pdesc = radix_tree_deref_slot(pagep); | ||
978 | if (pdesc) | ||
979 | page = (struct page*)pdesc; | ||
980 | //page = radix_tree_deref_slot(pagep); | ||
981 | if (unlikely(!page)) | 977 | if (unlikely(!page)) |
982 | goto out; | 978 | goto out; |
979 | if (is_pcache_desc(page)) { | ||
980 | struct pcache_desc *pcd; | ||
981 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
982 | pcd = ptr_to_pcache_desc(page); | ||
983 | page = pcd->master; | ||
984 | page_cache_get_speculative(page); | ||
985 | |||
986 | unreplicate_pcache(mapping, page->index, 0); | ||
987 | |||
988 | goto out; | ||
989 | } | ||
990 | |||
983 | if (radix_tree_exception(page)) { | 991 | if (radix_tree_exception(page)) { |
984 | if (radix_tree_deref_retry(page)) | 992 | if (radix_tree_deref_retry(page)) |
985 | goto repeat; | 993 | goto repeat; |
@@ -1178,6 +1186,20 @@ repeat: | |||
1178 | page = radix_tree_deref_slot(slot); | 1186 | page = radix_tree_deref_slot(slot); |
1179 | if (unlikely(!page)) | 1187 | if (unlikely(!page)) |
1180 | continue; | 1188 | continue; |
1189 | |||
1190 | if (is_pcache_desc(page)) { | ||
1191 | struct pcache_desc *pcd; | ||
1192 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
1193 | |||
1194 | pcd = ptr_to_pcache_desc(page); | ||
1195 | page = pcd->master; | ||
1196 | page_cache_get_speculative(page); | ||
1197 | |||
1198 | unreplicate_pcache(mapping, page->index, 0); | ||
1199 | |||
1200 | goto export; | ||
1201 | } | ||
1202 | |||
1181 | if (radix_tree_exception(page)) { | 1203 | if (radix_tree_exception(page)) { |
1182 | if (radix_tree_deref_retry(page)) | 1204 | if (radix_tree_deref_retry(page)) |
1183 | goto restart; | 1205 | goto restart; |
@@ -1241,6 +1263,20 @@ repeat: | |||
1241 | if (unlikely(!page)) | 1263 | if (unlikely(!page)) |
1242 | continue; | 1264 | continue; |
1243 | 1265 | ||
1266 | if (is_pcache_desc(page)) { | ||
1267 | struct pcache_desc *pcd; | ||
1268 | |||
1269 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
1270 | |||
1271 | pcd = ptr_to_pcache_desc(page); | ||
1272 | page = pcd->master; | ||
1273 | page_cache_get_speculative(page); | ||
1274 | |||
1275 | unreplicate_pcache(mapping, page->index, 0); | ||
1276 | |||
1277 | goto export; | ||
1278 | } | ||
1279 | |||
1244 | if (radix_tree_exception(page)) { | 1280 | if (radix_tree_exception(page)) { |
1245 | if (radix_tree_deref_retry(page)) { | 1281 | if (radix_tree_deref_retry(page)) { |
1246 | /* | 1282 | /* |
@@ -1268,6 +1304,7 @@ repeat: | |||
1268 | goto repeat; | 1304 | goto repeat; |
1269 | } | 1305 | } |
1270 | 1306 | ||
1307 | export: | ||
1271 | pages[ret] = page; | 1308 | pages[ret] = page; |
1272 | if (++ret == nr_pages) | 1309 | if (++ret == nr_pages) |
1273 | break; | 1310 | break; |
@@ -1309,6 +1346,20 @@ repeat: | |||
1309 | if (unlikely(!page)) | 1346 | if (unlikely(!page)) |
1310 | break; | 1347 | break; |
1311 | 1348 | ||
1349 | if (is_pcache_desc(page)) { | ||
1350 | struct pcache_desc *pcd; | ||
1351 | |||
1352 | printk(KERN_INFO "PCACHE_DESC\n"); | ||
1353 | |||
1354 | pcd = ptr_to_pcache_desc(page); | ||
1355 | page = pcd->master; | ||
1356 | page_cache_get_speculative(page); | ||
1357 | |||
1358 | unreplicate_pcache(mapping, page->index, 0); | ||
1359 | |||
1360 | goto export; | ||
1361 | } | ||
1362 | |||
1312 | if (radix_tree_exception(page)) { | 1363 | if (radix_tree_exception(page)) { |
1313 | if (radix_tree_deref_retry(page)) { | 1364 | if (radix_tree_deref_retry(page)) { |
1314 | /* | 1365 | /* |
@@ -1334,7 +1385,7 @@ repeat: | |||
1334 | page_cache_release(page); | 1385 | page_cache_release(page); |
1335 | goto repeat; | 1386 | goto repeat; |
1336 | } | 1387 | } |
1337 | 1388 | export: | |
1338 | /* | 1389 | /* |
1339 | * must check mapping and index after taking the ref. | 1390 | * must check mapping and index after taking the ref. |
1340 | * otherwise we can get both false positives and false | 1391 | * otherwise we can get both false positives and false |
@@ -1385,6 +1436,20 @@ repeat: | |||
1385 | if (unlikely(!page)) | 1436 | if (unlikely(!page)) |
1386 | continue; | 1437 | continue; |
1387 | 1438 | ||
1439 | if (is_pcache_desc(page)) { | ||
1440 | struct pcache_desc *pcd; | ||
1441 | |||
1442 | printk(KERN_INFO "PCACHE_DESC BUG!!!!!!!!!!\n"); | ||
1443 | |||
1444 | pcd = ptr_to_pcache_desc(page); | ||
1445 | page = pcd->master; | ||
1446 | page_cache_get_speculative(page); | ||
1447 | |||
1448 | unreplicate_pcache(mapping, page->index, 0); | ||
1449 | |||
1450 | goto export; | ||
1451 | } | ||
1452 | |||
1388 | if (radix_tree_exception(page)) { | 1453 | if (radix_tree_exception(page)) { |
1389 | if (radix_tree_deref_retry(page)) { | 1454 | if (radix_tree_deref_retry(page)) { |
1390 | /* | 1455 | /* |
@@ -1416,7 +1481,7 @@ repeat: | |||
1416 | page_cache_release(page); | 1481 | page_cache_release(page); |
1417 | goto repeat; | 1482 | goto repeat; |
1418 | } | 1483 | } |
1419 | 1484 | export: | |
1420 | pages[ret] = page; | 1485 | pages[ret] = page; |
1421 | if (++ret == nr_pages) | 1486 | if (++ret == nr_pages) |
1422 | break; | 1487 | break; |
@@ -1492,7 +1557,11 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, | |||
1492 | 1557 | ||
1493 | cond_resched(); | 1558 | cond_resched(); |
1494 | find_page: | 1559 | find_page: |
1495 | page = find_get_page(mapping, index); | 1560 | if (is_realtime(current)) |
1561 | page = find_get_page_readonly(mapping, index); | ||
1562 | else | ||
1563 | page = find_get_page(mapping, index); | ||
1564 | |||
1496 | if (!page) { | 1565 | if (!page) { |
1497 | page_cache_sync_readahead(mapping, | 1566 | page_cache_sync_readahead(mapping, |
1498 | ra, filp, | 1567 | ra, filp, |
@@ -1644,7 +1713,8 @@ readpage: | |||
1644 | unlock_page(page); | 1713 | unlock_page(page); |
1645 | } | 1714 | } |
1646 | 1715 | ||
1647 | goto page_ok; | 1716 | page_cache_release(page); |
1717 | goto find_page; | ||
1648 | 1718 | ||
1649 | readpage_error: | 1719 | readpage_error: |
1650 | /* UHHUH! A synchronous read error occurred. Report it */ | 1720 | /* UHHUH! A synchronous read error occurred. Report it */ |
@@ -1888,9 +1958,11 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1888 | /* | 1958 | /* |
1889 | * Do we have something in the page cache already? | 1959 | * Do we have something in the page cache already? |
1890 | */ | 1960 | */ |
1891 | if (is_realtime(current)) | 1961 | if ((vmf->flags & FAULT_FLAG_WRITE) || !is_realtime(current)) |
1892 | printk("FILEMAP_FAULT %ld\n", vma->vm_start); | 1962 | page = find_get_page(mapping, offset); |
1893 | page = find_get_page(mapping, offset); | 1963 | else |
1964 | page = find_get_page_readonly(mapping, offset); | ||
1965 | |||
1894 | if (likely(page) && !(vmf->flags & FAULT_FLAG_TRIED)) { | 1966 | if (likely(page) && !(vmf->flags & FAULT_FLAG_TRIED)) { |
1895 | /* | 1967 | /* |
1896 | * We found the page, so try async readahead before | 1968 | * We found the page, so try async readahead before |
@@ -1904,7 +1976,10 @@ if (is_realtime(current)) | |||
1904 | mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); | 1976 | mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); |
1905 | ret = VM_FAULT_MAJOR; | 1977 | ret = VM_FAULT_MAJOR; |
1906 | retry_find: | 1978 | retry_find: |
1907 | page = find_get_page(mapping, offset); | 1979 | if ((vmf->flags & FAULT_FLAG_WRITE) || !is_realtime(current)) |
1980 | page = find_get_page(mapping, offset); | ||
1981 | else | ||
1982 | page = find_get_page_readonly(mapping, offset); | ||
1908 | if (!page) | 1983 | if (!page) |
1909 | goto no_cached_page; | 1984 | goto no_cached_page; |
1910 | } | 1985 | } |
@@ -2012,6 +2087,22 @@ repeat: | |||
2012 | page = radix_tree_deref_slot(slot); | 2087 | page = radix_tree_deref_slot(slot); |
2013 | if (unlikely(!page)) | 2088 | if (unlikely(!page)) |
2014 | goto next; | 2089 | goto next; |
2090 | |||
2091 | if (is_pcache_desc(page)) { | ||
2092 | struct pcache_desc *pcd; | ||
2093 | |||
2094 | printk(KERN_INFO "PCACHE_DESC FILE_MAP_PAGES\n"); | ||
2095 | |||
2096 | pcd = ptr_to_pcache_desc(page); | ||
2097 | page = pcd->master; | ||
2098 | if (!page_cache_get_speculative(page)) | ||
2099 | goto repeat; | ||
2100 | |||
2101 | //unreplicate_pcache(mapping, page->index, 0); | ||
2102 | |||
2103 | goto export; | ||
2104 | } | ||
2105 | |||
2015 | if (radix_tree_exception(page)) { | 2106 | if (radix_tree_exception(page)) { |
2016 | if (radix_tree_deref_retry(page)) | 2107 | if (radix_tree_deref_retry(page)) |
2017 | break; | 2108 | break; |
@@ -2027,7 +2118,7 @@ repeat: | |||
2027 | page_cache_release(page); | 2118 | page_cache_release(page); |
2028 | goto repeat; | 2119 | goto repeat; |
2029 | } | 2120 | } |
2030 | 2121 | export: | |
2031 | if (!PageUptodate(page) || | 2122 | if (!PageUptodate(page) || |
2032 | PageReadahead(page) || | 2123 | PageReadahead(page) || |
2033 | PageHWPoison(page)) | 2124 | PageHWPoison(page)) |