Merge tag 'acpi-5.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6-microblaze.git] / mm / util.c
index bacabe4..7e43369 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -549,13 +549,10 @@ EXPORT_SYMBOL(vm_mmap);
  * Uses kmalloc to get the memory but if the allocation fails then falls back
  * to the vmalloc allocator. Use kvfree for freeing the memory.
  *
- * Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported.
+ * GFP_NOWAIT and GFP_ATOMIC are not supported, neither is the __GFP_NORETRY modifier.
  * __GFP_RETRY_MAYFAIL is supported, and it should be used only if kmalloc is
  * preferable to the vmalloc fallback, due to visible performance drawbacks.
  *
- * Please note that any use of gfp flags outside of GFP_KERNEL is careful to not
- * fall back to vmalloc.
- *
  * Return: pointer to the allocated memory of %NULL in case of failure
  */
 void *kvmalloc_node(size_t size, gfp_t flags, int node)
@@ -563,13 +560,6 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
        gfp_t kmalloc_flags = flags;
        void *ret;
 
-       /*
-        * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables)
-        * so the given set of flags has to be compatible.
-        */
-       if ((flags & GFP_KERNEL) != GFP_KERNEL)
-               return kmalloc_node(size, flags, node);
-
        /*
         * We want to attempt a large physically contiguous block first because
         * it is less likely to fragment multiple larger blocks and therefore
@@ -582,6 +572,9 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
 
                if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL))
                        kmalloc_flags |= __GFP_NORETRY;
+
+               /* nofail semantic is implemented by the vmalloc fallback */
+               kmalloc_flags &= ~__GFP_NOFAIL;
        }
 
        ret = kmalloc_node(size, kmalloc_flags, node);
@@ -654,81 +647,78 @@ void *kvrealloc(const void *p, size_t oldsize, size_t newsize, gfp_t flags)
 }
 EXPORT_SYMBOL(kvrealloc);
 
-static inline void *__page_rmapping(struct page *page)
-{
-       unsigned long mapping;
-
-       mapping = (unsigned long)page->mapping;
-       mapping &= ~PAGE_MAPPING_FLAGS;
-
-       return (void *)mapping;
-}
-
 /* Neutral page->mapping pointer to address_space or anon_vma or other */
 void *page_rmapping(struct page *page)
 {
-       page = compound_head(page);
-       return __page_rmapping(page);
+       return folio_raw_mapping(page_folio(page));
 }
 
-/*
- * Return true if this page is mapped into pagetables.
- * For compound page it returns true if any subpage of compound page is mapped.
+/**
+ * folio_mapped - Is this folio mapped into userspace?
+ * @folio: The folio.
+ *
+ * Return: True if any page in this folio is referenced by user page tables.
  */
-bool page_mapped(struct page *page)
+bool folio_mapped(struct folio *folio)
 {
-       int i;
+       long i, nr;
 
-       if (likely(!PageCompound(page)))
-               return atomic_read(&page->_mapcount) >= 0;
-       page = compound_head(page);
-       if (atomic_read(compound_mapcount_ptr(page)) >= 0)
+       if (!folio_test_large(folio))
+               return atomic_read(&folio->_mapcount) >= 0;
+       if (atomic_read(folio_mapcount_ptr(folio)) >= 0)
                return true;
-       if (PageHuge(page))
+       if (folio_test_hugetlb(folio))
                return false;
-       for (i = 0; i < compound_nr(page); i++) {
-               if (atomic_read(&page[i]._mapcount) >= 0)
+
+       nr = folio_nr_pages(folio);
+       for (i = 0; i < nr; i++) {
+               if (atomic_read(&folio_page(folio, i)->_mapcount) >= 0)
                        return true;
        }
        return false;
 }
-EXPORT_SYMBOL(page_mapped);
+EXPORT_SYMBOL(folio_mapped);
 
 struct anon_vma *page_anon_vma(struct page *page)
 {
-       unsigned long mapping;
+       struct folio *folio = page_folio(page);
+       unsigned long mapping = (unsigned long)folio->mapping;
 
-       page = compound_head(page);
-       mapping = (unsigned long)page->mapping;
        if ((mapping & PAGE_MAPPING_FLAGS) != PAGE_MAPPING_ANON)
                return NULL;
-       return __page_rmapping(page);
+       return (void *)(mapping - PAGE_MAPPING_ANON);
 }
 
-struct address_space *page_mapping(struct page *page)
+/**
+ * folio_mapping - Find the mapping where this folio is stored.
+ * @folio: The folio.
+ *
+ * For folios which are in the page cache, return the mapping that this
+ * page belongs to.  Folios in the swap cache return the swap mapping
+ * this page is stored in (which is different from the mapping for the
+ * swap file or swap device where the data is stored).
+ *
+ * You can call this for folios which aren't in the swap cache or page
+ * cache and it will return NULL.
+ */
+struct address_space *folio_mapping(struct folio *folio)
 {
        struct address_space *mapping;
 
-       page = compound_head(page);
-
        /* This happens if someone calls flush_dcache_page on slab page */
-       if (unlikely(PageSlab(page)))
+       if (unlikely(folio_test_slab(folio)))
                return NULL;
 
-       if (unlikely(PageSwapCache(page))) {
-               swp_entry_t entry;
-
-               entry.val = page_private(page);
-               return swap_address_space(entry);
-       }
+       if (unlikely(folio_test_swapcache(folio)))
+               return swap_address_space(folio_swap_entry(folio));
 
-       mapping = page->mapping;
+       mapping = folio->mapping;
        if ((unsigned long)mapping & PAGE_MAPPING_ANON)
                return NULL;
 
        return (void *)((unsigned long)mapping & ~PAGE_MAPPING_FLAGS);
 }
-EXPORT_SYMBOL(page_mapping);
+EXPORT_SYMBOL(folio_mapping);
 
 /* Slow path of page_mapcount() for compound pages */
 int __page_mapcount(struct page *page)
@@ -750,13 +740,26 @@ int __page_mapcount(struct page *page)
 }
 EXPORT_SYMBOL_GPL(__page_mapcount);
 
-void copy_huge_page(struct page *dst, struct page *src)
+/**
+ * folio_copy - Copy the contents of one folio to another.
+ * @dst: Folio to copy to.
+ * @src: Folio to copy from.
+ *
+ * The bytes in the folio represented by @src are copied to @dst.
+ * Assumes the caller has validated that @dst is at least as large as @src.
+ * Can be called in atomic context for order-0 folios, but if the folio is
+ * larger, it may sleep.
+ */
+void folio_copy(struct folio *dst, struct folio *src)
 {
-       unsigned i, nr = compound_nr(src);
+       long i = 0;
+       long nr = folio_nr_pages(src);
 
-       for (i = 0; i < nr; i++) {
+       for (;;) {
+               copy_highpage(folio_page(dst, i), folio_page(src, i));
+               if (++i == nr)
+                       break;
                cond_resched();
-               copy_highpage(nth_page(dst, i), nth_page(src, i));
        }
 }
 
@@ -1079,3 +1082,14 @@ void page_offline_end(void)
        up_write(&page_offline_rwsem);
 }
 EXPORT_SYMBOL(page_offline_end);
+
+#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO
+void flush_dcache_folio(struct folio *folio)
+{
+       long i, nr = folio_nr_pages(folio);
+
+       for (i = 0; i < nr; i++)
+               flush_dcache_page(folio_page(folio, i));
+}
+EXPORT_SYMBOL(flush_dcache_folio);
+#endif