From 6778948f9de86c3cfaf36725a7c87dcff9ba247f Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 08:20:59 +0000
Subject: [PATCH] kernel_5.10 no rt

---
 kernel/mm/page_alloc.c |  180 ++++++++++++++++++-----------------------------------------
 1 files changed, 55 insertions(+), 125 deletions(-)

diff --git a/kernel/mm/page_alloc.c b/kernel/mm/page_alloc.c
index 4a15674..3868586 100644
--- a/kernel/mm/page_alloc.c
+++ b/kernel/mm/page_alloc.c
@@ -61,7 +61,6 @@
 #include <linux/hugetlb.h>
 #include <linux/sched/rt.h>
 #include <linux/sched/mm.h>
-#include <linux/local_lock.h>
 #include <linux/page_owner.h>
 #include <linux/page_pinner.h>
 #include <linux/kthread.h>
@@ -385,13 +384,6 @@
 EXPORT_SYMBOL(nr_node_ids);
 EXPORT_SYMBOL(nr_online_nodes);
 #endif
-
-struct pa_lock {
-	local_lock_t l;
-};
-static DEFINE_PER_CPU(struct pa_lock, pa_lock) = {
-	.l	= INIT_LOCAL_LOCK(l),
-};
 
 int page_group_by_mobility_disabled __read_mostly;
 
@@ -1430,7 +1422,7 @@
 }
 
 /*
- * Frees a number of pages which have been collected from the pcp lists.
+ * Frees a number of pages from the PCP lists
  * Assumes all pages on list are in same zone, and of same order.
  * count is the number of pages to free.
  *
@@ -1440,56 +1432,15 @@
  * And clear the zone's pages_scanned counter, to hold off the "all pages are
  * pinned" detection logic.
  */
-static void free_pcppages_bulk(struct zone *zone, struct list_head *head,
-			       bool zone_retry)
-{
-	bool isolated_pageblocks;
-	struct page *page, *tmp;
-	unsigned long flags;
-
-	spin_lock_irqsave(&zone->lock, flags);
-	isolated_pageblocks = has_isolate_pageblock(zone);
-
-	/*
-	 * Use safe version since after __free_one_page(),
-	 * page->lru.next will not point to original list.
-	 */
-	list_for_each_entry_safe(page, tmp, head, lru) {
-		int mt = get_pcppage_migratetype(page);
-
-		if (page_zone(page) != zone) {
-			/*
-			 * free_unref_page_list() sorts pages by zone. If we end
-			 * up with pages from a different NUMA nodes belonging
-			 * to the same ZONE index then we need to redo with the
-			 * correct ZONE pointer. Skip the page for now, redo it
-			 * on the next iteration.
-			 */
-			WARN_ON_ONCE(zone_retry == false);
-			if (zone_retry)
-				continue;
-		}
-
-		/* MIGRATE_ISOLATE page should not go to pcplists */
-		VM_BUG_ON_PAGE(is_migrate_isolate(mt), page);
-		/* Pageblock could have been isolated meanwhile */
-		if (unlikely(isolated_pageblocks))
-			mt = get_pageblock_migratetype(page);
-
-		list_del(&page->lru);
-		__free_one_page(page, page_to_pfn(page), zone, 0, mt, FPI_NONE);
-		trace_mm_page_pcpu_drain(page, 0, mt);
-	}
-	spin_unlock_irqrestore(&zone->lock, flags);
-}
-
-static void isolate_pcp_pages(int count, struct per_cpu_pages *pcp,
-			      struct list_head *dst)
+static void free_pcppages_bulk(struct zone *zone, int count,
+					struct per_cpu_pages *pcp)
 {
 	int migratetype = 0;
 	int batch_free = 0;
 	int prefetch_nr = 0;
-	struct page *page;
+	bool isolated_pageblocks;
+	struct page *page, *tmp;
+	LIST_HEAD(head);
 
 	/*
 	 * Ensure proper count is passed which otherwise would stuck in the
@@ -1526,7 +1477,7 @@
 			if (bulkfree_pcp_prepare(page))
 				continue;
 
-			list_add_tail(&page->lru, dst);
+			list_add_tail(&page->lru, &head);
 
 			/*
 			 * We are going to put the page back to the global
@@ -1541,6 +1492,26 @@
 				prefetch_buddy(page);
 		} while (--count && --batch_free && !list_empty(list));
 	}
+
+	spin_lock(&zone->lock);
+	isolated_pageblocks = has_isolate_pageblock(zone);
+
+	/*
+	 * Use safe version since after __free_one_page(),
+	 * page->lru.next will not point to original list.
+	 */
+	list_for_each_entry_safe(page, tmp, &head, lru) {
+		int mt = get_pcppage_migratetype(page);
+		/* MIGRATE_ISOLATE page should not go to pcplists */
+		VM_BUG_ON_PAGE(is_migrate_isolate(mt), page);
+		/* Pageblock could have been isolated meanwhile */
+		if (unlikely(isolated_pageblocks))
+			mt = get_pageblock_migratetype(page);
+
+		__free_one_page(page, page_to_pfn(page), zone, 0, mt, FPI_NONE);
+		trace_mm_page_pcpu_drain(page, 0, mt);
+	}
+	spin_unlock(&zone->lock);
 }
 
 static void free_one_page(struct zone *zone,
@@ -1648,11 +1619,11 @@
 		return;
 
 	migratetype = get_pfnblock_migratetype(page, pfn);
-	local_lock_irqsave(&pa_lock.l, flags);
+	local_irq_save(flags);
 	__count_vm_events(PGFREE, 1 << order);
 	free_one_page(page_zone(page), page, pfn, order, migratetype,
 		      fpi_flags);
-	local_unlock_irqrestore(&pa_lock.l, flags);
+	local_irq_restore(flags);
 }
 
 void __free_pages_core(struct page *page, unsigned int order)
@@ -3105,18 +3076,13 @@
 {
 	unsigned long flags;
 	int to_drain, batch;
-	LIST_HEAD(dst);
 
-	local_lock_irqsave(&pa_lock.l, flags);
+	local_irq_save(flags);
 	batch = READ_ONCE(pcp->batch);
 	to_drain = min(pcp->count, batch);
 	if (to_drain > 0)
-		isolate_pcp_pages(to_drain, pcp, &dst);
-
-	local_unlock_irqrestore(&pa_lock.l, flags);
-
-	if (to_drain > 0)
-		free_pcppages_bulk(zone, &dst, false);
+		free_pcppages_bulk(zone, to_drain, pcp);
+	local_irq_restore(flags);
 }
 #endif
 
@@ -3132,21 +3098,14 @@
 	unsigned long flags;
 	struct per_cpu_pageset *pset;
 	struct per_cpu_pages *pcp;
-	LIST_HEAD(dst);
-	int count;
 
-	local_lock_irqsave(&pa_lock.l, flags);
+	local_irq_save(flags);
 	pset = per_cpu_ptr(zone->pageset, cpu);
 
 	pcp = &pset->pcp;
-	count = pcp->count;
-	if (count)
-		isolate_pcp_pages(count, pcp, &dst);
-
-	local_unlock_irqrestore(&pa_lock.l, flags);
-
-	if (count)
-		free_pcppages_bulk(zone, &dst, false);
+	if (pcp->count)
+		free_pcppages_bulk(zone, pcp->count, pcp);
+	local_irq_restore(flags);
 }
 
 /*
@@ -3194,9 +3153,9 @@
 	 * cpu which is allright but we also have to make sure to not move to
 	 * a different one.
 	 */
-	migrate_disable();
+	preempt_disable();
 	drain_local_pages(drain->zone);
-	migrate_enable();
+	preempt_enable();
 }
 
 /*
@@ -3345,8 +3304,7 @@
 	return true;
 }
 
-static void free_unref_page_commit(struct page *page, unsigned long pfn,
-				   struct list_head *dst)
+static void free_unref_page_commit(struct page *page, unsigned long pfn)
 {
 	struct zone *zone = page_zone(page);
 	struct per_cpu_pages *pcp;
@@ -3380,8 +3338,7 @@
 	pcp->count++;
 	if (pcp->count >= pcp->high) {
 		unsigned long batch = READ_ONCE(pcp->batch);
-
-		isolate_pcp_pages(batch, pcp, dst);
+		free_pcppages_bulk(zone, batch, pcp);
 	}
 }
 
@@ -3392,17 +3349,13 @@
 {
 	unsigned long flags;
 	unsigned long pfn = page_to_pfn(page);
-	struct zone *zone = page_zone(page);
-	LIST_HEAD(dst);
 
 	if (!free_unref_page_prepare(page, pfn))
 		return;
 
-	local_lock_irqsave(&pa_lock.l, flags);
-	free_unref_page_commit(page, pfn, &dst);
-	local_unlock_irqrestore(&pa_lock.l, flags);
-	if (!list_empty(&dst))
-		free_pcppages_bulk(zone, &dst, false);
+	local_irq_save(flags);
+	free_unref_page_commit(page, pfn);
+	local_irq_restore(flags);
 }
 
 /*
@@ -3413,11 +3366,6 @@
 	struct page *page, *next;
 	unsigned long flags, pfn;
 	int batch_count = 0;
-	struct list_head dsts[__MAX_NR_ZONES];
-	int i;
-
-	for (i = 0; i < __MAX_NR_ZONES; i++)
-		INIT_LIST_HEAD(&dsts[i]);
 
 	/* Prepare pages for freeing */
 	list_for_each_entry_safe(page, next, list, lru) {
@@ -3427,42 +3375,25 @@
 		set_page_private(page, pfn);
 	}
 
-	local_lock_irqsave(&pa_lock.l, flags);
+	local_irq_save(flags);
 	list_for_each_entry_safe(page, next, list, lru) {
 		unsigned long pfn = page_private(page);
-		enum zone_type type;
 
 		set_page_private(page, 0);
 		trace_mm_page_free_batched(page);
-		type = page_zonenum(page);
-		free_unref_page_commit(page, pfn, &dsts[type]);
+		free_unref_page_commit(page, pfn);
 
 		/*
 		 * Guard against excessive IRQ disabled times when we get
 		 * a large list of pages to free.
 		 */
 		if (++batch_count == SWAP_CLUSTER_MAX) {
-			local_unlock_irqrestore(&pa_lock.l, flags);
+			local_irq_restore(flags);
 			batch_count = 0;
-			local_lock_irqsave(&pa_lock.l, flags);
+			local_irq_save(flags);
 		}
 	}
-	local_unlock_irqrestore(&pa_lock.l, flags);
-
-	for (i = 0; i < __MAX_NR_ZONES; ) {
-		struct page *page;
-		struct zone *zone;
-
-		if (list_empty(&dsts[i])) {
-			i++;
-			continue;
-		}
-
-		page = list_first_entry(&dsts[i], struct page, lru);
-		zone = page_zone(page);
-
-		free_pcppages_bulk(zone, &dsts[i], true);
-	}
+	local_irq_restore(flags);
 }
 
 /*
@@ -3629,7 +3560,7 @@
 	struct page *page;
 	unsigned long flags;
 
-	local_lock_irqsave(&pa_lock.l, flags);
+	local_irq_save(flags);
 	pcp = &this_cpu_ptr(zone->pageset)->pcp;
 	page = __rmqueue_pcplist(zone,  migratetype, alloc_flags, pcp,
 				 gfp_flags);
@@ -3637,7 +3568,7 @@
 		__count_zid_vm_events(PGALLOC, page_zonenum(page), 1);
 		zone_statistics(preferred_zone, zone);
 	}
-	local_unlock_irqrestore(&pa_lock.l, flags);
+	local_irq_restore(flags);
 	return page;
 }
 
@@ -3664,8 +3595,7 @@
 	 * allocate greater than order-1 page units with __GFP_NOFAIL.
 	 */
 	WARN_ON_ONCE((gfp_flags & __GFP_NOFAIL) && (order > 1));
-	local_lock_irqsave(&pa_lock.l, flags);
-	spin_lock(&zone->lock);
+	spin_lock_irqsave(&zone->lock, flags);
 
 	do {
 		page = NULL;
@@ -3700,7 +3630,7 @@
 	zone_statistics(preferred_zone, zone);
 	trace_android_vh_rmqueue(preferred_zone, zone, order,
 			gfp_flags, alloc_flags, migratetype);
-	local_unlock_irqrestore(&pa_lock.l, flags);
+	local_irq_restore(flags);
 
 out:
 	/* Separate test+clear to avoid unnecessary atomics */
@@ -3713,7 +3643,7 @@
 	return page;
 
 failed:
-	local_unlock_irqrestore(&pa_lock.l, flags);
+	local_irq_restore(flags);
 	return NULL;
 }
 
@@ -9141,7 +9071,7 @@
 	struct per_cpu_pageset *pset;
 
 	/* avoid races with drain_pages()  */
-	local_lock_irqsave(&pa_lock.l, flags);
+	local_irq_save(flags);
 	if (zone->pageset != &boot_pageset) {
 		for_each_online_cpu(cpu) {
 			pset = per_cpu_ptr(zone->pageset, cpu);
@@ -9150,7 +9080,7 @@
 		free_percpu(zone->pageset);
 		zone->pageset = &boot_pageset;
 	}
-	local_unlock_irqrestore(&pa_lock.l, flags);
+	local_irq_restore(flags);
 }
 
 #ifdef CONFIG_MEMORY_HOTREMOVE

--
Gitblit v1.6.2