History

mm: account skipped entries to avoid looping in find_get_pages

The found entries by find_get_pages() could be all swap entries. In this case we skip the entries, but make sure the skipped entries are accounted, so we don't keep looping. Using nr_found > nr_skip to simplify code as suggested by Eric.

Shaohua Li committed 15 years ago

Commit cc39c6a1 parent 4f5b0481 file · +4 −2Browse files

Unified · Split

mm/filemap.c+4−2
@@ -827,13 +827,14 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, · 826 unmodified lines
827827 {
828828 unsigned int i;
829829 unsigned int ret;
830− unsigned int nr_found;
830+ unsigned int nr_found, nr_skip;
831831
832832 rcu_read_lock();
833833 restart:
834834 nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree,
835835 (void ***)pages, NULL, start, nr_pages);
836836 ret = 0;
837+ nr_skip = 0;
837838 for (i = 0; i < nr_found; i++) {
838839 struct page *page;
839840 repeat:
@@ -856,6 +857,7 @@ repeat: · 16 unmodified lines
856857 * here as an exceptional entry: so skip over it -
857858 * we only reach this from invalidate_mapping_pages().
858859 */
860+ nr_skip++;
859861 continue;
860862 }
861863
@@ -876,7 +878,7 @@ repeat: · 14 unmodified lines
876878 * If all entries were removed before we could secure them,
877879 * try again, because callers stop trying once 0 is returned.
878880 */
879− if (unlikely(!ret && nr_found))
881+ if (unlikely(!ret && nr_found > nr_skip))
880882 goto restart;
881883 rcu_read_unlock();
882884 return ret;