From: Julien Grall <julien.grall@citrix.com>
To: <xen-devel@lists.xenproject.org>
Cc: <linux-arm-kernel@lists.infradead.org>, <ian.campbell@citrix.com>,
<stefano.stabellini@eu.citrix.com>,
<linux-kernel@vger.kernel.org>, <tim@xen.org>,
Julien Grall <julien.grall@citrix.com>,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
Boris Ostrovsky <boris.ostrovsky@oracle.com>,
"David Vrabel" <david.vrabel@citrix.com>,
Wei Liu <wei.liu2@citrix.com>
Subject: [RFC 15/23] xen/balloon: Don't rely on the page granularity is the same for Xen and Linux
Date: Thu, 14 May 2015 18:00:55 +0100 [thread overview]
Message-ID: <1431622863-28575-16-git-send-email-julien.grall@citrix.com> (raw)
In-Reply-To: <1431622863-28575-1-git-send-email-julien.grall@citrix.com>
For ARM64 guests, Linux is able to support either 64K or 4K page
granularity. Although, the hypercall interface is always based on 4K
page granularity.
With 64K page granuliarty, a single page will be spread over multiple
Xen frame.
When a driver request/free a balloon page, the balloon driver will have
to split the Linux page in 4K chunk before asking Xen to add/remove the
frame from the guest.
Note that this can work on any page granularity assuming it's a multiple
of 4K.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
TODO/LIMITATIONS:
- When CONFIG_XEN_HAVE_PMMU only 4K page granularity is supported
- It may be possible to extend the concept for ballooning 2M/1G
page.
---
drivers/xen/balloon.c | 93 +++++++++++++++++++++++++++++++++------------------
1 file changed, 60 insertions(+), 33 deletions(-)
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index fd93369..f0d8666 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -91,7 +91,7 @@ struct balloon_stats balloon_stats;
EXPORT_SYMBOL_GPL(balloon_stats);
/* We increase/decrease in batches which fit in a page */
-static xen_pfn_t frame_list[PAGE_SIZE / sizeof(unsigned long)];
+static xen_pfn_t frame_list[XEN_PAGE_SIZE / sizeof(unsigned long)];
/* List of ballooned pages, threaded through the mem_map array. */
@@ -326,7 +326,7 @@ static enum bp_state reserve_additional_memory(long credit)
static enum bp_state increase_reservation(unsigned long nr_pages)
{
int rc;
- unsigned long pfn, i;
+ unsigned long pfn, i, nr_frames;
struct page *page;
struct xen_memory_reservation reservation = {
.address_bits = 0,
@@ -343,30 +343,43 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
}
#endif
- if (nr_pages > ARRAY_SIZE(frame_list))
- nr_pages = ARRAY_SIZE(frame_list);
+ if (nr_pages > (ARRAY_SIZE(frame_list) / XEN_PFN_PER_PAGE))
+ nr_pages = ARRAY_SIZE(frame_list) / XEN_PFN_PER_PAGE;
+
+ nr_frames = nr_pages * XEN_PFN_PER_PAGE;
+
+ pfn = 0; /* make gcc happy */
page = list_first_entry_or_null(&ballooned_pages, struct page, lru);
- for (i = 0; i < nr_pages; i++) {
- if (!page) {
- nr_pages = i;
- break;
+ for (i = 0; i < nr_frames; i++) {
+ if (!(i % XEN_PFN_PER_PAGE)) {
+ if (!page) {
+ nr_frames = i;
+ break;
+ }
+ pfn = xen_page_to_pfn(page);
+ page = balloon_next_page(page);
}
- frame_list[i] = page_to_pfn(page);
- page = balloon_next_page(page);
+ frame_list[i] = pfn++;
}
set_xen_guest_handle(reservation.extent_start, frame_list);
- reservation.nr_extents = nr_pages;
+ reservation.nr_extents = nr_frames;
rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
if (rc <= 0)
return BP_EAGAIN;
for (i = 0; i < rc; i++) {
- page = balloon_retrieve(false);
- BUG_ON(page == NULL);
- pfn = page_to_pfn(page);
+ /* TODO: Make this code cleaner to make CONFIG_XEN_HAVE_PVMMU
+ * with 64K Pages
+ */
+ if (!(i % XEN_PFN_PER_PAGE)) {
+ page = balloon_retrieve(false);
+ BUG_ON(page == NULL);
+
+ pfn = page_to_pfn(page);
+ }
#ifdef CONFIG_XEN_HAVE_PVMMU
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -385,7 +398,8 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
#endif
/* Relinquish the page back to the allocator. */
- __free_reserved_page(page);
+ if (!(i % XEN_PFN_PER_PAGE))
+ __free_reserved_page(page);
}
balloon_stats.current_pages += rc;
@@ -396,7 +410,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
{
enum bp_state state = BP_DONE;
- unsigned long pfn, i;
+ unsigned long pfn, i, nr_frames;
struct page *page;
int ret;
struct xen_memory_reservation reservation = {
@@ -414,19 +428,27 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
}
#endif
- if (nr_pages > ARRAY_SIZE(frame_list))
- nr_pages = ARRAY_SIZE(frame_list);
+ if (nr_pages > (ARRAY_SIZE(frame_list) / XEN_PFN_PER_PAGE))
+ nr_pages = ARRAY_SIZE(frame_list) / XEN_PFN_PER_PAGE;
- for (i = 0; i < nr_pages; i++) {
- page = alloc_page(gfp);
- if (page == NULL) {
- nr_pages = i;
- state = BP_EAGAIN;
- break;
+ nr_frames = nr_pages * XEN_PFN_PER_PAGE;
+
+ pfn = 0; /* Make GCC happy */
+
+ for (i = 0; i < nr_frames; i++) {
+
+ if (!(i % XEN_PFN_PER_PAGE)) {
+ page = alloc_page(gfp);
+ if (page == NULL) {
+ nr_frames = i;
+ state = BP_EAGAIN;
+ break;
+ }
+ scrub_page(page);
+ pfn = xen_page_to_pfn(page);
}
- scrub_page(page);
- frame_list[i] = page_to_pfn(page);
+ frame_list[i] = pfn++;
}
/*
@@ -439,16 +461,20 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
kmap_flush_unused();
/* Update direct mapping, invalidate P2M, and add to balloon. */
- for (i = 0; i < nr_pages; i++) {
+ for (i = 0; i < nr_frames; i++) {
pfn = frame_list[i];
frame_list[i] = pfn_to_mfn(pfn);
- page = pfn_to_page(pfn);
+ page = xen_pfn_to_page(pfn);
+
+ /* TODO: Make this code cleaner to make CONFIG_XEN_HAVE_PVMMU
+ * work with 64K pages
+ */
#ifdef CONFIG_XEN_HAVE_PVMMU
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
if (!PageHighMem(page)) {
ret = HYPERVISOR_update_va_mapping(
- (unsigned long)__va(pfn << PAGE_SHIFT),
+ (unsigned long)__va(pfn << XEN_PAGE_SHIFT),
__pte_ma(0), 0);
BUG_ON(ret);
}
@@ -456,17 +482,18 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
}
#endif
- balloon_append(page);
+ if (!(i % XEN_PFN_PER_PAGE))
+ balloon_append(page);
}
flush_tlb_all();
set_xen_guest_handle(reservation.extent_start, frame_list);
- reservation.nr_extents = nr_pages;
+ reservation.nr_extents = nr_frames;
ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
- BUG_ON(ret != nr_pages);
+ BUG_ON(ret != nr_frames);
- balloon_stats.current_pages -= nr_pages;
+ balloon_stats.current_pages -= nr_frames * XEN_PFN_PER_PAGE;
return state;
}
--
2.1.4
next prev parent reply other threads:[~2015-05-14 17:18 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-14 17:00 [RFC 00/23] arm64: Add support for 64KB page granularity in Xen guest Julien Grall
2015-05-14 17:00 ` [RFC 01/23] xen: Include xen/page.h rather than asm/xen/page.h Julien Grall
2015-05-19 13:50 ` [Xen-devel] " David Vrabel
2015-05-14 17:00 ` [RFC 02/23] xen/xenbus: client: Fix call of virt_to_mfn in xenbus_grant_ring Julien Grall
2015-05-19 13:51 ` [Xen-devel] " David Vrabel
2015-05-19 14:12 ` Julien Grall
2015-05-14 17:00 ` [RFC 03/23] xen/grant-table: Remove unused macro SPP Julien Grall
2015-05-19 13:52 ` [Xen-devel] " David Vrabel
2015-05-14 17:00 ` [RFC 04/23] block/xen-blkfront: Remove unused macro MAXIMUM_OUTSTANDING_BLOCK_REQS Julien Grall
2015-05-20 14:36 ` Roger Pau Monné
2015-05-14 17:00 ` [RFC 05/23] block/xen-blkfront: Remove invalid comment Julien Grall
2015-05-20 14:42 ` Roger Pau Monné
2015-05-14 17:00 ` [RFC 06/23] block/xen-blkback: s/nr_pages/nr_segs/ Julien Grall
2015-05-20 14:54 ` Roger Pau Monné
2015-05-14 17:00 ` [RFC 07/23] net/xen-netfront: Correct printf format in xennet_get_responses Julien Grall
2015-05-19 13:53 ` [Xen-devel] " David Vrabel
2015-05-14 17:00 ` [RFC 08/23] net/xen-netback: Remove unused code in xenvif_rx_action Julien Grall
2015-05-15 0:26 ` Wei Liu
2015-05-14 17:00 ` [RFC 09/23] arm/xen: Drop duplicate define mfn_to_virt Julien Grall
2015-06-23 13:25 ` Stefano Stabellini
2015-06-23 13:53 ` [Xen-devel] " Julien Grall
2015-05-14 17:00 ` [RFC 10/23] xen/biomerge: WORKAROUND always says the biovec are not mergeable Julien Grall
2015-05-15 15:54 ` Boris Ostrovsky
2015-05-19 14:16 ` Julien Grall
2015-05-14 17:00 ` [RFC 11/23] xen: Add Xen specific page definition Julien Grall
2015-05-14 17:00 ` [RFC 12/23] xen: Extend page_to_mfn to take an offset in the page Julien Grall
2015-05-19 13:57 ` [Xen-devel] " David Vrabel
2015-05-19 14:18 ` Julien Grall
2015-05-14 17:00 ` [RFC 13/23] xen/xenbus: Use Xen page definition Julien Grall
2015-05-19 13:59 ` [Xen-devel] " David Vrabel
2015-05-19 14:19 ` Julien Grall
2015-05-14 17:00 ` [RFC 14/23] tty/hvc: xen: Use xen " Julien Grall
2015-05-14 17:00 ` Julien Grall [this message]
2015-05-19 15:23 ` [Xen-devel] [RFC 15/23] xen/balloon: Don't rely on the page granularity is the same for Xen and Linux David Vrabel
2015-05-14 17:00 ` [RFC 16/23] xen/events: fifo: Make it running on 64KB granularity Julien Grall
2015-05-19 15:25 ` [Xen-devel] " David Vrabel
2015-05-14 17:00 ` [RFC 17/23] xen/grant-table: " Julien Grall
2015-05-19 15:27 ` [Xen-devel] " David Vrabel
2015-05-14 17:00 ` [RFC 18/23] block/xen-blkfront: Make it running on 64KB page granularity Julien Grall
2015-05-14 17:00 ` [RFC 19/23] block/xen-blkback: " Julien Grall
2015-05-14 17:01 ` [RFC 20/23] net/xen-netfront: " Julien Grall
2015-05-14 17:01 ` [RFC 21/23] net/xen-netback: " Julien Grall
2015-05-15 2:35 ` Wei Liu
2015-05-15 12:35 ` [Xen-devel] " Julien Grall
2015-05-15 15:31 ` Wei Liu
2015-05-15 15:41 ` Ian Campbell
2015-05-18 12:11 ` Julien Grall
2015-05-18 12:54 ` Wei Liu
2015-05-19 22:56 ` Julien Grall
2015-05-20 8:26 ` Wei Liu
2015-05-20 14:26 ` Julien Grall
2015-05-20 14:29 ` Julien Grall
2015-05-14 17:01 ` [RFC 22/23] xen/privcmd: Add support for Linux " Julien Grall
2015-05-19 15:39 ` [Xen-devel] " David Vrabel
2015-06-18 17:05 ` Julien Grall
2015-05-14 17:01 ` [RFC 23/23] arm/xen: Add support for " Julien Grall
2015-06-23 14:19 ` Stefano Stabellini
2015-06-23 14:37 ` Julien Grall
2015-06-23 14:49 ` Stefano Stabellini
2015-06-23 15:02 ` [Xen-devel] " Julien Grall
2015-06-23 16:12 ` Stefano Stabellini
2015-05-15 15:45 ` [Xen-devel] [RFC 00/23] arm64: Add support for 64KB page granularity in Xen guest David Vrabel
2015-05-15 15:51 ` Boris Ostrovsky
2015-05-18 12:23 ` Julien Grall
2015-06-23 13:37 ` Stefano Stabellini
2015-06-23 13:41 ` Stefano Stabellini
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=1431622863-28575-16-git-send-email-julien.grall@citrix.com \
--to=julien.grall@citrix.com \
--cc=boris.ostrovsky@oracle.com \
--cc=david.vrabel@citrix.com \
--cc=ian.campbell@citrix.com \
--cc=konrad.wilk@oracle.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stefano.stabellini@eu.citrix.com \
--cc=tim@xen.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®