perf evlist: Add a method to return the list of evsels as a string
[linux-2.6-microblaze.git] / mm / truncate.c
index 8aa4907..4559442 100644 (file)
@@ -57,11 +57,10 @@ static void clear_shadow_entry(struct address_space *mapping, pgoff_t index,
  * exceptional entries similar to what pagevec_remove_exceptionals does.
  */
 static void truncate_exceptional_pvec_entries(struct address_space *mapping,
-                               struct pagevec *pvec, pgoff_t *indices,
-                               pgoff_t end)
+                               struct pagevec *pvec, pgoff_t *indices)
 {
        int i, j;
-       bool dax, lock;
+       bool dax;
 
        /* Handled by shmem itself */
        if (shmem_mapping(mapping))
@@ -75,8 +74,7 @@ static void truncate_exceptional_pvec_entries(struct address_space *mapping,
                return;
 
        dax = dax_mapping(mapping);
-       lock = !dax && indices[j] < end;
-       if (lock)
+       if (!dax)
                xa_lock_irq(&mapping->i_pages);
 
        for (i = j; i < pagevec_count(pvec); i++) {
@@ -88,9 +86,6 @@ static void truncate_exceptional_pvec_entries(struct address_space *mapping,
                        continue;
                }
 
-               if (index >= end)
-                       continue;
-
                if (unlikely(dax)) {
                        dax_delete_mapping_entry(mapping, index);
                        continue;
@@ -99,7 +94,7 @@ static void truncate_exceptional_pvec_entries(struct address_space *mapping,
                __clear_shadow_entry(mapping, index, page);
        }
 
-       if (lock)
+       if (!dax)
                xa_unlock_irq(&mapping->i_pages);
        pvec->nr = j;
 }
@@ -326,51 +321,19 @@ void truncate_inode_pages_range(struct address_space *mapping,
 
        pagevec_init(&pvec);
        index = start;
-       while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE),
-                       indices)) {
-               /*
-                * Pagevec array has exceptional entries and we may also fail
-                * to lock some pages. So we store pages that can be deleted
-                * in a new pagevec.
-                */
-               struct pagevec locked_pvec;
-
-               pagevec_init(&locked_pvec);
-               for (i = 0; i < pagevec_count(&pvec); i++) {
-                       struct page *page = pvec.pages[i];
-
-                       /* We rely upon deletion not changing page->index */
-                       index = indices[i];
-                       if (index >= end)
-                               break;
-
-                       if (xa_is_value(page))
-                               continue;
-
-                       if (!trylock_page(page))
-                               continue;
-                       WARN_ON(page_to_index(page) != index);
-                       if (PageWriteback(page)) {
-                               unlock_page(page);
-                               continue;
-                       }
-                       if (page->mapping != mapping) {
-                               unlock_page(page);
-                               continue;
-                       }
-                       pagevec_add(&locked_pvec, page);
-               }
-               for (i = 0; i < pagevec_count(&locked_pvec); i++)
-                       truncate_cleanup_page(mapping, locked_pvec.pages[i]);
-               delete_from_page_cache_batch(mapping, &locked_pvec);
-               for (i = 0; i < pagevec_count(&locked_pvec); i++)
-                       unlock_page(locked_pvec.pages[i]);
-               truncate_exceptional_pvec_entries(mapping, &pvec, indices, end);
+       while (index < end && find_lock_entries(mapping, index, end - 1,
+                       &pvec, indices)) {
+               index = indices[pagevec_count(&pvec) - 1] + 1;
+               truncate_exceptional_pvec_entries(mapping, &pvec, indices);
+               for (i = 0; i < pagevec_count(&pvec); i++)
+                       truncate_cleanup_page(mapping, pvec.pages[i]);
+               delete_from_page_cache_batch(mapping, &pvec);
+               for (i = 0; i < pagevec_count(&pvec); i++)
+                       unlock_page(pvec.pages[i]);
                pagevec_release(&pvec);
                cond_resched();
-               index++;
        }
+
        if (partial_start) {
                struct page *page = find_lock_page(mapping, start - 1);
                if (page) {
@@ -413,8 +376,8 @@ void truncate_inode_pages_range(struct address_space *mapping,
        index = start;
        for ( ; ; ) {
                cond_resched();
-               if (!pagevec_lookup_entries(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE), indices)) {
+               if (!find_get_entries(mapping, index, end - 1, &pvec,
+                               indices)) {
                        /* If all gone from start onwards, we're done */
                        if (index == start)
                                break;
@@ -422,23 +385,12 @@ void truncate_inode_pages_range(struct address_space *mapping,
                        index = start;
                        continue;
                }
-               if (index == start && indices[0] >= end) {
-                       /* All gone out of hole to be punched, we're done */
-                       pagevec_remove_exceptionals(&pvec);
-                       pagevec_release(&pvec);
-                       break;
-               }
 
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
 
                        /* We rely upon deletion not changing page->index */
                        index = indices[i];
-                       if (index >= end) {
-                               /* Restart punch to make sure all gone */
-                               index = start - 1;
-                               break;
-                       }
 
                        if (xa_is_value(page))
                                continue;
@@ -449,7 +401,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
                        truncate_inode_page(mapping, page);
                        unlock_page(page);
                }
-               truncate_exceptional_pvec_entries(mapping, &pvec, indices, end);
+               truncate_exceptional_pvec_entries(mapping, &pvec, indices);
                pagevec_release(&pvec);
                index++;
        }
@@ -539,55 +491,19 @@ static unsigned long __invalidate_mapping_pages(struct address_space *mapping,
        int i;
 
        pagevec_init(&pvec);
-       while (index <= end && pagevec_lookup_entries(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
-                       indices)) {
+       while (find_lock_entries(mapping, index, end, &pvec, indices)) {
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
 
                        /* We rely upon deletion not changing page->index */
                        index = indices[i];
-                       if (index > end)
-                               break;
 
                        if (xa_is_value(page)) {
                                invalidate_exceptional_entry(mapping, index,
                                                             page);
                                continue;
                        }
-
-                       if (!trylock_page(page))
-                               continue;
-
-                       WARN_ON(page_to_index(page) != index);
-
-                       /* Middle of THP: skip */
-                       if (PageTransTail(page)) {
-                               unlock_page(page);
-                               continue;
-                       } else if (PageTransHuge(page)) {
-                               index += HPAGE_PMD_NR - 1;
-                               i += HPAGE_PMD_NR - 1;
-                               /*
-                                * 'end' is in the middle of THP. Don't
-                                * invalidate the page as the part outside of
-                                * 'end' could be still useful.
-                                */
-                               if (index > end) {
-                                       unlock_page(page);
-                                       continue;
-                               }
-
-                               /* Take a pin outside pagevec */
-                               get_page(page);
-
-                               /*
-                                * Drop extra pins before trying to invalidate
-                                * the huge page.
-                                */
-                               pagevec_remove_exceptionals(&pvec);
-                               pagevec_release(&pvec);
-                       }
+                       index += thp_nr_pages(page) - 1;
 
                        ret = invalidate_inode_page(page);
                        unlock_page(page);
@@ -601,9 +517,6 @@ static unsigned long __invalidate_mapping_pages(struct address_space *mapping,
                                if (nr_pagevec)
                                        (*nr_pagevec)++;
                        }
-
-                       if (PageTransHuge(page))
-                               put_page(page);
                        count += ret;
                }
                pagevec_remove_exceptionals(&pvec);
@@ -725,16 +638,12 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 
        pagevec_init(&pvec);
        index = start;
-       while (index <= end && pagevec_lookup_entries(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
-                       indices)) {
+       while (find_get_entries(mapping, index, end, &pvec, indices)) {
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
 
                        /* We rely upon deletion not changing page->index */
                        index = indices[i];
-                       if (index > end)
-                               break;
 
                        if (xa_is_value(page)) {
                                if (!invalidate_exceptional_entry2(mapping,