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
827{827{
828 unsigned int i;828 unsigned int i;
829 unsigned int ret;829 unsigned int ret;
830 unsigned int nr_found;830 unsigned int nr_found, nr_skip;
831 831
832 rcu_read_lock();832 rcu_read_lock();
833restart:833restart:
834 nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree,834 nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree,
835 (void ***)pages, NULL, start, nr_pages);835 (void ***)pages, NULL, start, nr_pages);
836 ret = 0;836 ret = 0;
837 nr_skip = 0;
837 for (i = 0; i < nr_found; i++) {838 for (i = 0; i < nr_found; i++) {
838 struct page *page;839 struct page *page;
839repeat:840repeat:
@@ -856,6 +857,7 @@ repeat: · 16 unmodified lines
856 * here as an exceptional entry: so skip over it -857 * here as an exceptional entry: so skip over it -
857 * we only reach this from invalidate_mapping_pages().858 * we only reach this from invalidate_mapping_pages().
858 */859 */
860 nr_skip++;
859 continue;861 continue;
860 }862 }
861 863
@@ -876,7 +878,7 @@ repeat: · 14 unmodified lines
876 * If all entries were removed before we could secure them,878 * If all entries were removed before we could secure them,
877 * try again, because callers stop trying once 0 is returned.879 * try again, because callers stop trying once 0 is returned.
878 */880 */
879 if (unlikely(!ret && nr_found))881 if (unlikely(!ret && nr_found > nr_skip))
880 goto restart;882 goto restart;
881 rcu_read_unlock();883 rcu_read_unlock();
882 return ret;884 return ret;