]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - mm/page_alloc.c
tunnels: do not assume mac header is set in skb_tunnel_check_pmtu()
[mirror_ubuntu-jammy-kernel.git] / mm / page_alloc.c
index f95e1d2386a1366f833ee8a7da45dec76c3bcaa6..a0b7afae59e9cbf8a9a55a31c234b1af9baf7952 100644 (file)
@@ -594,8 +594,6 @@ static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
 
 static int page_is_consistent(struct zone *zone, struct page *page)
 {
-       if (!pfn_valid_within(page_to_pfn(page)))
-               return 0;
        if (zone != page_zone(page))
                return 0;
 
@@ -1025,16 +1023,12 @@ buddy_merge_likely(unsigned long pfn, unsigned long buddy_pfn,
        if (order >= MAX_ORDER - 2)
                return false;
 
-       if (!pfn_valid_within(buddy_pfn))
-               return false;
-
        combined_pfn = buddy_pfn & pfn;
        higher_page = page + (combined_pfn - pfn);
        buddy_pfn = __find_buddy_pfn(combined_pfn, order + 1);
        higher_buddy = higher_page + (buddy_pfn - combined_pfn);
 
-       return pfn_valid_within(buddy_pfn) &&
-              page_is_buddy(higher_page, higher_buddy, order + 1);
+       return page_is_buddy(higher_page, higher_buddy, order + 1);
 }
 
 /*
@@ -1095,8 +1089,6 @@ continue_merging:
                buddy_pfn = __find_buddy_pfn(pfn, order);
                buddy = page + (buddy_pfn - pfn);
 
-               if (!pfn_valid_within(buddy_pfn))
-                       goto done_merging;
                if (!page_is_buddy(page, buddy, order))
                        goto done_merging;
                /*
@@ -1320,8 +1312,10 @@ static __always_inline bool free_pages_prepare(struct page *page,
 
                VM_BUG_ON_PAGE(compound && compound_order(page) != order, page);
 
-               if (compound)
+               if (compound) {
                        ClearPageDoubleMap(page);
+                       ClearPageHasHWPoisoned(page);
+               }
                for (i = 1; i < (1 << order); i++) {
                        if (compound)
                                bad += free_tail_pages_check(page, page + i);
@@ -1754,9 +1748,7 @@ void __init memblock_free_pages(struct page *page, unsigned long pfn,
 /*
  * Check that the whole (or subset of) a pageblock given by the interval of
  * [start_pfn, end_pfn) is valid and within the same zone, before scanning it
- * with the migration of free compaction scanner. The scanners then need to
- * use only pfn_valid_within() check for arches that allow holes within
- * pageblocks.
+ * with the migration of free compaction scanner.
  *
  * Return struct page pointer of start_pfn, or NULL if checks were not passed.
  *
@@ -1872,8 +1864,6 @@ static inline void __init pgdat_init_report_one_done(void)
  */
 static inline bool __init deferred_pfn_valid(unsigned long pfn)
 {
-       if (!pfn_valid_within(pfn))
-               return false;
        if (!(pfn & (pageblock_nr_pages - 1)) && !pfn_valid(pfn))
                return false;
        return true;
@@ -2520,11 +2510,6 @@ static int move_freepages(struct zone *zone,
        int pages_moved = 0;
 
        for (pfn = start_pfn; pfn <= end_pfn;) {
-               if (!pfn_valid_within(pfn)) {
-                       pfn++;
-                       continue;
-               }
-
                page = pfn_to_page(pfn);
                if (!PageBuddy(page)) {
                        /*
@@ -3445,8 +3430,10 @@ void free_unref_page_list(struct list_head *list)
        /* Prepare pages for freeing */
        list_for_each_entry_safe(page, next, list, lru) {
                pfn = page_to_pfn(page);
-               if (!free_unref_page_prepare(page, pfn, 0))
+               if (!free_unref_page_prepare(page, pfn, 0)) {
                        list_del(&page->lru);
+                       continue;
+               }
 
                /*
                 * Free isolated pages directly to the allocator, see
@@ -4223,7 +4210,9 @@ void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...)
        va_list args;
        static DEFINE_RATELIMIT_STATE(nopage_rs, 10*HZ, 1);
 
-       if ((gfp_mask & __GFP_NOWARN) || !__ratelimit(&nopage_rs))
+       if ((gfp_mask & __GFP_NOWARN) ||
+            !__ratelimit(&nopage_rs) ||
+            ((gfp_mask & __GFP_DMA) && !has_managed_dma()))
                return;
 
        va_start(args, fmt);
@@ -5238,6 +5227,10 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
        if (unlikely(page_array && nr_pages - nr_populated == 0))
                goto out;
 
+       /* Bulk allocator does not support memcg accounting. */
+       if (memcg_kmem_enabled() && (gfp & __GFP_ACCOUNT))
+               goto failed;
+
        /* Use the single page allocator for one page. */
        if (nr_pages - nr_populated == 1)
                goto failed;
@@ -5306,8 +5299,8 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
                page = __rmqueue_pcplist(zone, 0, ac.migratetype, alloc_flags,
                                                                pcp, pcp_list);
                if (unlikely(!page)) {
-                       /* Try and get at least one page */
-                       if (!nr_populated)
+                       /* Try and allocate at least one page */
+                       if (!nr_account)
                                goto failed_irq;
                        break;
                }
@@ -6099,7 +6092,7 @@ static int build_zonerefs_node(pg_data_t *pgdat, struct zoneref *zonerefs)
        do {
                zone_type--;
                zone = pgdat->node_zones + zone_type;
-               if (managed_zone(zone)) {
+               if (populated_zone(zone)) {
                        zoneref_set_zone(zone, &zonerefs[nr_zones++]);
                        check_highest_zone(zone_type);
                }
@@ -7271,6 +7264,9 @@ static void __init calculate_node_totalpages(struct pglist_data *pgdat,
                        zone->zone_start_pfn = 0;
                zone->spanned_pages = size;
                zone->present_pages = real_size;
+#if defined(CONFIG_MEMORY_HOTPLUG)
+               zone->present_early_pages = real_size;
+#endif
 
                totalpages += size;
                realtotalpages += real_size;
@@ -7903,10 +7899,17 @@ restart:
 
 out2:
        /* Align start of ZONE_MOVABLE on all nids to MAX_ORDER_NR_PAGES */
-       for (nid = 0; nid < MAX_NUMNODES; nid++)
+       for (nid = 0; nid < MAX_NUMNODES; nid++) {
+               unsigned long start_pfn, end_pfn;
+
                zone_movable_pfn[nid] =
                        roundup(zone_movable_pfn[nid], MAX_ORDER_NR_PAGES);
 
+               get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
+               if (zone_movable_pfn[nid] >= end_pfn)
+                       zone_movable_pfn[nid] = 0;
+       }
+
 out:
        /* restore the node_state */
        node_states[N_MEMORY] = saved_node_state;
@@ -8166,7 +8169,7 @@ void __init mem_init_print_info(void)
         */
 #define adj_init_size(start, end, size, pos, adj) \
        do { \
-               if (start <= pos && pos < end && size > adj) \
+               if (&start[0] <= &pos[0] && &pos[0] < &end[0] && size > adj) \
                        size -= adj; \
        } while (0)
 
@@ -8828,9 +8831,6 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
        }
 
        for (; iter < pageblock_nr_pages - offset; iter++) {
-               if (!pfn_valid_within(pfn + iter))
-                       continue;
-
                page = pfn_to_page(pfn + iter);
 
                /*
@@ -9458,3 +9458,18 @@ bool take_page_off_buddy(struct page *page)
        return ret;
 }
 #endif
+
+#ifdef CONFIG_ZONE_DMA
+bool has_managed_dma(void)
+{
+       struct pglist_data *pgdat;
+
+       for_each_online_pgdat(pgdat) {
+               struct zone *zone = &pgdat->node_zones[ZONE_DMA];
+
+               if (managed_zone(zone))
+                       return true;
+       }
+       return false;
+}
+#endif /* CONFIG_ZONE_DMA */