From: Alexander Duyck <alexander.duyck@gmail.com>
To: nitesh@redhat.com, kvm@vger.kernel.org, david@redhat.com,
mst@redhat.com, dave.hansen@intel.com,
linux-kernel@vger.kernel.org, linux-mm@kvack.org
Cc: yang.zhang.wz@gmail.com, pagupta@redhat.com, riel@surriel.com,
konrad.wilk@oracle.com, lcapitulino@redhat.com,
wei.w.wang@intel.com, aarcange@redhat.com, pbonzini@redhat.com,
dan.j.williams@intel.com, alexander.h.duyck@linux.intel.com
Subject: [RFC PATCH 07/11] mm: Add support for acquiring first free "raw" or "untreated" page in zone
Date: Thu, 30 May 2019 14:54:26 -0700 [thread overview]
Message-ID: <20190530215426.13974.82813.stgit@localhost.localdomain> (raw)
In-Reply-To: <20190530215223.13974.22445.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@linux.intel.com>
In order to be able to "treat" memory in an asynchonous fashion we need a
way to acquire a block of memory that isn't already treated, and then flush
that back in a way that we will not pick it back up again.
To achieve that this patch adds a pair of functions. One to fill a list
with pages to be treated, and another that will flush out the list back to
the buddy allocator.
Signed-off-by: Alexander Duyck <alexander.h.duyck@linux.intel.com>
---
include/linux/gfp.h | 6 +++
mm/page_alloc.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 113 insertions(+)
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index fb07b503dc45..407a089d861f 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -559,6 +559,12 @@ extern void *page_frag_alloc(struct page_frag_cache *nc,
void drain_all_pages(struct zone *zone);
void drain_local_pages(struct zone *zone);
+#ifdef CONFIG_AERATION
+struct page *get_raw_pages(struct zone *zone, unsigned int order,
+ int migratetype);
+void free_treated_page(struct page *page);
+#endif
+
void page_alloc_init_late(void);
/*
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f4a629b6af96..e79c65413dc9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2155,6 +2155,113 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
return NULL;
}
+#ifdef CONFIG_AERATION
+static struct page *get_raw_page_from_free_area(struct free_area *area,
+ int migratetype)
+{
+ struct list_head *head = &area->free_list[migratetype];
+ struct page *page;
+
+ /* If we have not worked in this free_list before reset membrane */
+ if (area->treatment_mt != migratetype) {
+ area->treatment_mt = migratetype;
+ area->membrane = head;
+ }
+
+ /* Try to pulling in any untreated pages above the the membrane */
+ page = list_last_entry(area->membrane, struct page, lru);
+ list_for_each_entry_from_reverse(page, head, lru) {
+ /*
+ * If the page in front of the membrane is treated then try
+ * skimming the top to see if we have any untreated pages
+ * up there.
+ */
+ if (PageTreated(page)) {
+ page = list_first_entry(head, struct page, lru);
+ if (PageTreated(page))
+ break;
+ }
+
+ /* update state of treatment */
+ area->treatment_state = TREATMENT_AERATING;
+
+ return page;
+ }
+
+ /*
+ * At this point there are no longer any untreated pages between
+ * the membrane and the first entry of the list. So we can safely
+ * set the membrane to the top of the treated region and will mark
+ * the current migratetype as complete for now.
+ */
+ area->membrane = &page->lru;
+ area->treatment_state = TREATMENT_SETTLING;
+
+ return NULL;
+}
+
+/**
+ * get_raw_pages - Provide a "raw" page for treatment by the aerator
+ * @zone: Zone to draw pages from
+ * @order: Order to draw pages from
+ * @migratetype: Migratetype to draw pages from
+ *
+ * This function will obtain a page that does not have the Treated value
+ * set in the page type field. It will attempt to fetch a "raw" page from
+ * just above the "membrane" and if that is not available it will attempt
+ * to pull a "raw" page from the head of the free list.
+ *
+ * The page will have the migrate type and order stored in the page
+ * metadata.
+ *
+ * Return: page pointer if raw page found, otherwise NULL
+ */
+struct page *get_raw_pages(struct zone *zone, unsigned int order,
+ int migratetype)
+{
+ struct free_area *area = &(zone->free_area[order]);
+ struct page *page;
+
+ /* Find a page of the appropriate size in the preferred list */
+ page = get_raw_page_from_free_area(area, migratetype);
+ if (page) {
+ del_page_from_free_area(page, area);
+
+ /* record migratetype and order within page */
+ set_pcppage_migratetype(page, migratetype);
+ set_page_private(page, order);
+ __mod_zone_freepage_state(zone, -(1 << order), migratetype);
+ }
+
+ return page;
+}
+EXPORT_SYMBOL_GPL(get_raw_pages);
+
+/**
+ * free_treated_page - Return a now-treated "raw" page back where we got it
+ * @page: Previously "raw" page that can now be returned after treatment
+ *
+ * This function will pull the zone, migratetype, and order information out
+ * of the page and attempt to return it where it found it. We default to
+ * using free_one_page to return the page as it is possible that the
+ * pageblock might have been switched to an isolate migratetype during
+ * treatment.
+ */
+void free_treated_page(struct page *page)
+{
+ unsigned int order, mt;
+ struct zone *zone;
+
+ zone = page_zone(page);
+ mt = get_pcppage_migratetype(page);
+ order = page_private(page);
+
+ set_page_private(page, 0);
+
+ free_one_page(zone, page, page_to_pfn(page), order, mt);
+}
+EXPORT_SYMBOL_GPL(free_treated_page);
+#endif /* CONFIG_AERATION */
/*
* This array describes the order lists are fallen back to when
next prev parent reply other threads:[~2019-05-30 21:54 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-30 21:53 [RFC PATCH 00/11] mm / virtio: Provide support for paravirtual waste page treatment Alexander Duyck
2019-05-30 21:53 ` [RFC PATCH 01/11] mm: Move MAX_ORDER definition closer to pageblock_order Alexander Duyck
2019-05-30 21:53 ` [RFC PATCH 02/11] mm: Adjust shuffle code to allow for future coalescing Alexander Duyck
2019-05-30 21:53 ` [RFC PATCH 03/11] mm: Add support for Treated Buddy pages Alexander Duyck
2019-05-30 21:54 ` [RFC PATCH 04/11] mm: Split nr_free into nr_free_raw and nr_free_treated Alexander Duyck
2019-05-30 21:54 ` [RFC PATCH 05/11] mm: Propogate Treated bit when splitting Alexander Duyck
2019-05-30 21:54 ` [RFC PATCH 06/11] mm: Add membrane to free area to use as divider between treated and raw pages Alexander Duyck
2019-05-30 21:54 ` Alexander Duyck [this message]
2019-05-30 21:54 ` [RFC PATCH 08/11] mm: Add support for creating memory aeration Alexander Duyck
2019-05-30 21:54 ` [RFC PATCH 09/11] mm: Count isolated pages as "treated" Alexander Duyck
2019-05-30 21:54 ` [RFC PATCH 10/11] virtio-balloon: Add support for aerating memory via bubble hinting Alexander Duyck
2019-05-30 21:54 ` [RFC PATCH 11/11] mm: Add free page notification hook Alexander Duyck
2019-05-30 21:57 ` [RFC QEMU PATCH] QEMU: Provide a interface for hinting based off of the balloon infrastructure Alexander Duyck
2019-05-30 22:52 ` [RFC PATCH 00/11] mm / virtio: Provide support for paravirtual waste page treatment Michael S. Tsirkin
2019-05-31 11:16 ` Nitesh Narayan Lal
2019-05-31 15:51 ` Alexander Duyck
2019-06-03 9:31 ` David Hildenbrand
2019-06-03 15:33 ` Alexander Duyck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190530215426.13974.82813.stgit@localhost.localdomain \
--to=alexander.duyck@gmail.com \
--cc=aarcange@redhat.com \
--cc=alexander.h.duyck@linux.intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=david@redhat.com \
--cc=konrad.wilk@oracle.com \
--cc=kvm@vger.kernel.org \
--cc=lcapitulino@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mst@redhat.com \
--cc=nitesh@redhat.com \
--cc=pagupta@redhat.com \
--cc=pbonzini@redhat.com \
--cc=riel@surriel.com \
--cc=wei.w.wang@intel.com \
--cc=yang.zhang.wz@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.