diff options
author | Matthew Wilcox <willy@linux.intel.com> | 2016-03-17 17:22:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-17 18:09:34 -0400 |
commit | 2cf938aae17203426a89b5955bd1c9668657bfa8 (patch) | |
tree | df3afed25409565778e49995541fabf6f083672d | |
parent | c28f2420635b7000f7b9cde6cdbe6e7a0f8beed1 (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.c | 53 | ||||
-rw-r--r-- | mm/shmem.c | 23 |
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(); |
1258 | restart: | ||
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; |
1261 | repeat: | 1260 | repeat: |
@@ -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(); |
1320 | restart: | ||
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; |
1323 | repeat: | 1323 | repeat: |
@@ -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(); |
1387 | restart: | ||
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; |
1390 | repeat: | 1384 | repeat: |
@@ -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(); |
1463 | restart: | ||
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(); |
1542 | restart: | ||
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 | } |