aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@linux.intel.com>2016-03-17 17:22:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 18:09:34 -0400
commit2cf938aae17203426a89b5955bd1c9668657bfa8 (patch)
treedf3afed25409565778e49995541fabf6f083672d
parentc28f2420635b7000f7b9cde6cdbe6e7a0f8beed1 (diff)
mm: use radix_tree_iter_retry()
Instead of a 'goto restart', we can now use radix_tree_iter_retry() to restart from our current position. This will make a difference when there are more ways to happen across an indirect pointer. And it eliminates some confusing gotos. [vbabka@suse.cz: remove now-obsolete-and-misleading comment] Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Cc: Hugh Dickins <hughd@google.com> Cc: Konstantin Khlebnikov <khlebnikov@openvz.org> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/filemap.c53
-rw-r--r--mm/shmem.c23
2 files changed, 29 insertions, 47 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 084ad0fe73c7..7c00f105845e 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1255,7 +1255,6 @@ unsigned find_get_entries(struct address_space *mapping,
1255 return 0; 1255 return 0;
1256 1256
1257 rcu_read_lock(); 1257 rcu_read_lock();
1258restart:
1259 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) { 1258 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
1260 struct page *page; 1259 struct page *page;
1261repeat: 1260repeat:
@@ -1263,8 +1262,10 @@ repeat:
1263 if (unlikely(!page)) 1262 if (unlikely(!page))
1264 continue; 1263 continue;
1265 if (radix_tree_exception(page)) { 1264 if (radix_tree_exception(page)) {
1266 if (radix_tree_deref_retry(page)) 1265 if (radix_tree_deref_retry(page)) {
1267 goto restart; 1266 slot = radix_tree_iter_retry(&iter);
1267 continue;
1268 }
1268 /* 1269 /*
1269 * A shadow entry of a recently evicted page, a swap 1270 * A shadow entry of a recently evicted page, a swap
1270 * entry from shmem/tmpfs or a DAX entry. Return it 1271 * entry from shmem/tmpfs or a DAX entry. Return it
@@ -1317,7 +1318,6 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
1317 return 0; 1318 return 0;
1318 1319
1319 rcu_read_lock(); 1320 rcu_read_lock();
1320restart:
1321 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) { 1321 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
1322 struct page *page; 1322 struct page *page;
1323repeat: 1323repeat:
@@ -1327,13 +1327,8 @@ repeat:
1327 1327
1328 if (radix_tree_exception(page)) { 1328 if (radix_tree_exception(page)) {
1329 if (radix_tree_deref_retry(page)) { 1329 if (radix_tree_deref_retry(page)) {
1330 /* 1330 slot = radix_tree_iter_retry(&iter);
1331 * Transient condition which can only trigger 1331 continue;
1332 * when entry at index 0 moves out of or back
1333 * to root: none yet gotten, safe to restart.
1334 */
1335 WARN_ON(iter.index);
1336 goto restart;
1337 } 1332 }
1338 /* 1333 /*
1339 * A shadow entry of a recently evicted page, 1334 * A shadow entry of a recently evicted page,
@@ -1384,7 +1379,6 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index,
1384 return 0; 1379 return 0;
1385 1380
1386 rcu_read_lock(); 1381 rcu_read_lock();
1387restart:
1388 radix_tree_for_each_contig(slot, &mapping->page_tree, &iter, index) { 1382 radix_tree_for_each_contig(slot, &mapping->page_tree, &iter, index) {
1389 struct page *page; 1383 struct page *page;
1390repeat: 1384repeat:
@@ -1395,12 +1389,8 @@ repeat:
1395 1389
1396 if (radix_tree_exception(page)) { 1390 if (radix_tree_exception(page)) {
1397 if (radix_tree_deref_retry(page)) { 1391 if (radix_tree_deref_retry(page)) {
1398 /* 1392 slot = radix_tree_iter_retry(&iter);
1399 * Transient condition which can only trigger 1393 continue;
1400 * when entry at index 0 moves out of or back
1401 * to root: none yet gotten, safe to restart.
1402 */
1403 goto restart;
1404 } 1394 }
1405 /* 1395 /*
1406 * A shadow entry of a recently evicted page, 1396 * A shadow entry of a recently evicted page,
@@ -1460,7 +1450,6 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
1460 return 0; 1450 return 0;
1461 1451
1462 rcu_read_lock(); 1452 rcu_read_lock();
1463restart:
1464 radix_tree_for_each_tagged(slot, &mapping->page_tree, 1453 radix_tree_for_each_tagged(slot, &mapping->page_tree,
1465 &iter, *index, tag) { 1454 &iter, *index, tag) {
1466 struct page *page; 1455 struct page *page;
@@ -1471,12 +1460,8 @@ repeat:
1471 1460
1472 if (radix_tree_exception(page)) { 1461 if (radix_tree_exception(page)) {
1473 if (radix_tree_deref_retry(page)) { 1462 if (radix_tree_deref_retry(page)) {
1474 /* 1463 slot = radix_tree_iter_retry(&iter);
1475 * Transient condition which can only trigger 1464 continue;
1476 * when entry at index 0 moves out of or back
1477 * to root: none yet gotten, safe to restart.
1478 */
1479 goto restart;
1480 } 1465 }
1481 /* 1466 /*
1482 * A shadow entry of a recently evicted page. 1467 * A shadow entry of a recently evicted page.
@@ -1539,7 +1524,6 @@ unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
1539 return 0; 1524 return 0;
1540 1525
1541 rcu_read_lock(); 1526 rcu_read_lock();
1542restart:
1543 radix_tree_for_each_tagged(slot, &mapping->page_tree, 1527 radix_tree_for_each_tagged(slot, &mapping->page_tree,
1544 &iter, start, tag) { 1528 &iter, start, tag) {
1545 struct page *page; 1529 struct page *page;
@@ -1549,12 +1533,8 @@ repeat:
1549 continue; 1533 continue;
1550 if (radix_tree_exception(page)) { 1534 if (radix_tree_exception(page)) {
1551 if (radix_tree_deref_retry(page)) { 1535 if (radix_tree_deref_retry(page)) {
1552 /* 1536 slot = radix_tree_iter_retry(&iter);
1553 * Transient condition which can only trigger 1537 continue;
1554 * when entry at index 0 moves out of or back
1555 * to root: none yet gotten, safe to restart.
1556 */
1557 goto restart;
1558 } 1538 }
1559 1539
1560 /* 1540 /*
@@ -2171,10 +2151,11 @@ repeat:
2171 if (unlikely(!page)) 2151 if (unlikely(!page))
2172 goto next; 2152 goto next;
2173 if (radix_tree_exception(page)) { 2153 if (radix_tree_exception(page)) {
2174 if (radix_tree_deref_retry(page)) 2154 if (radix_tree_deref_retry(page)) {
2175 break; 2155 slot = radix_tree_iter_retry(&iter);
2176 else 2156 continue;
2177 goto next; 2157 }
2158 goto next;
2178 } 2159 }
2179 2160
2180 if (!page_cache_get_speculative(page)) 2161 if (!page_cache_get_speculative(page))
diff --git a/mm/shmem.c b/mm/shmem.c
index c484f6888d5e..91c0dadf48d3 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -383,13 +383,10 @@ restart:
383 383
384 page = radix_tree_deref_slot(slot); 384 page = radix_tree_deref_slot(slot);
385 385
386 /* 386 if (radix_tree_deref_retry(page)) {
387 * This should only be possible to happen at index 0, so we 387 slot = radix_tree_iter_retry(&iter);
388 * don't need to reset the counter, nor do we risk infinite 388 continue;
389 * restarts. 389 }
390 */
391 if (radix_tree_deref_retry(page))
392 goto restart;
393 390
394 if (radix_tree_exceptional_entry(page)) 391 if (radix_tree_exceptional_entry(page))
395 swapped++; 392 swapped++;
@@ -1951,8 +1948,10 @@ restart:
1951 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) { 1948 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
1952 page = radix_tree_deref_slot(slot); 1949 page = radix_tree_deref_slot(slot);
1953 if (!page || radix_tree_exception(page)) { 1950 if (!page || radix_tree_exception(page)) {
1954 if (radix_tree_deref_retry(page)) 1951 if (radix_tree_deref_retry(page)) {
1955 goto restart; 1952 slot = radix_tree_iter_retry(&iter);
1953 continue;
1954 }
1956 } else if (page_count(page) - page_mapcount(page) > 1) { 1955 } else if (page_count(page) - page_mapcount(page) > 1) {
1957 spin_lock_irq(&mapping->tree_lock); 1956 spin_lock_irq(&mapping->tree_lock);
1958 radix_tree_tag_set(&mapping->page_tree, iter.index, 1957 radix_tree_tag_set(&mapping->page_tree, iter.index,
@@ -2006,8 +2005,10 @@ restart:
2006 2005
2007 page = radix_tree_deref_slot(slot); 2006 page = radix_tree_deref_slot(slot);
2008 if (radix_tree_exception(page)) { 2007 if (radix_tree_exception(page)) {
2009 if (radix_tree_deref_retry(page)) 2008 if (radix_tree_deref_retry(page)) {
2010 goto restart; 2009 slot = radix_tree_iter_retry(&iter);
2010 continue;
2011 }
2011 2012
2012 page = NULL; 2013 page = NULL;
2013 } 2014 }