All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Campbell <ian.campbell@citrix.com>
To: xen-devel@lists.xen.org
Cc: julien.grall@linaro.org, tim@xen.org,
	Ian Campbell <ian.campbell@citrix.com>,
	stefano.stabellini@eu.citrix.com
Subject: [PATCH 2/6] tools: arm: allocate superpages to guests.
Date: Tue, 10 Jun 2014 10:57:54 +0100	[thread overview]
Message-ID: <1402394278-9850-2-git-send-email-ian.campbell@citrix.com> (raw)
In-Reply-To: <1402394127.29980.52.camel@kazak.uk.xensource.com>

Tries to allocate as many large (1G or 2M) pages as it can to the guest and tries
to align to the next larger size on each attempt so that we can attempt to
allocate even larger pages on the next iteration (this is currently only
exercised via a compile time debug option, which is left in place under a #if
0).

Since ARM page tables are consistent at each level there is a common helper
function which tries to allocate a levels worth of pages. The exception to this
consistency is level 0 which does not support table mappings (0.5TB
superpages!).

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxc/xc_dom_arm.c |  103 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 92 insertions(+), 11 deletions(-)

diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index 75f8363..da68ec3 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -30,6 +30,13 @@
 #define CONSOLE_PFN_OFFSET 0
 #define XENSTORE_PFN_OFFSET 1
 
+#define LPAE_SHIFT 9
+
+#define PFN_4K_SHIFT  (0)
+#define PFN_2M_SHIFT  (PFN_4K_SHIFT+LPAE_SHIFT)
+#define PFN_1G_SHIFT  (PFN_2M_SHIFT+LPAE_SHIFT)
+#define PFN_512G_SHIFT (PFN_1G_SHIFT+LPAE_SHIFT)
+
 /* get guest IO ABI protocol */
 const char *xc_domain_get_native_protocol(xc_interface *xch,
                                           uint32_t domid)
@@ -249,11 +256,57 @@ static int set_mode(xc_interface *xch, domid_t domid, char *guest_type)
     return rc;
 }
 
+#define min_t(type,x,y) \
+        ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+/*  >0: success, *nr_pfns set to number actually populated
+ *   0: didn't try with this pfn shift (e.g. misaligned base etc)
+ *  <0: ERROR
+ */
+static int populate_one_size(struct xc_dom_image *dom, int pfn_shift,
+                             xen_pfn_t base_pfn, xen_pfn_t *nr_pfns)
+{
+    uint64_t mask = ((uint64_t)1<<(pfn_shift))-1;
+    uint64_t next_mask = ((uint64_t)1<<(LPAE_SHIFT))-1;
+    int nr, i, count = min_t(int, 1024*1024, *nr_pfns >> pfn_shift);
+    xen_pfn_t extents[count];
+
+    /* No level zero super pages with current hardware */
+    if ( pfn_shift == PFN_512G_SHIFT )
+        return 0;
+
+    /* Nothing to allocate */
+    if ( !count )
+        return 0;
+
+    /* base is misaligned for this level */
+    if ( mask & base_pfn )
+        return 0;
+
+    /* align to the end of a super page at this level */
+    if ( count & next_mask )
+        count &= next_mask;
+
+    for ( i = 0 ; i < count ; i ++ )
+        extents[i] = base_pfn + (i<<pfn_shift);
+
+    nr = xc_domain_populate_physmap(dom->xch, dom->guest_domid, count,
+                                    pfn_shift, 0, extents);
+    if ( nr <= 0 ) return nr;
+    DOMPRINTF("%s: populated %#x/%#x entries with shift %d",
+              __FUNCTION__, nr, count, pfn_shift);
+
+    *nr_pfns = nr << pfn_shift;
+
+    return 1;
+}
+
 static int populate_guest_memory(struct xc_dom_image *dom,
                                  xen_pfn_t base_pfn, xen_pfn_t nr_pfns)
 {
-    int rc;
+    int rc = 0;
     xen_pfn_t allocsz, pfn;
+    int debug_iters = 0;
 
     DOMPRINTF("%s: populating RAM @ %016"PRIx64"-%016"PRIx64" (%"PRId64"MB)",
               __FUNCTION__,
@@ -261,21 +314,49 @@ static int populate_guest_memory(struct xc_dom_image *dom,
               (uint64_t)(base_pfn + nr_pfns) << XC_PAGE_SHIFT,
               (uint64_t)nr_pfns >> (20-XC_PAGE_SHIFT));
 
-    for ( pfn = 0; pfn < nr_pfns; pfn++ )
-        dom->p2m_host[pfn] = base_pfn + pfn;
-
-    for ( pfn = rc = allocsz = 0; (pfn < nr_pfns) && !rc; pfn += allocsz )
+    for ( pfn = 0; pfn < nr_pfns; pfn += allocsz )
     {
         allocsz = nr_pfns - pfn;
-        if ( allocsz > 1024*1024 )
-            allocsz = 1024*1024;
 
-        rc = xc_domain_populate_physmap_exact(
-            dom->xch, dom->guest_domid, allocsz,
-            0, 0, &dom->p2m_host[pfn]);
+        if ( debug_iters++ > 4 )
+            abort();
+#if 0 /* Enable this to exercise/debug the code which tries to realign
+       * to a superpage boundary, by misaligning at the start. */
+        if ( pfn == 0 )
+        {
+            allocsz = 1;
+            rc = populate_one_size(dom, PFN_4K_SHIFT, base_pfn + pfn, &allocsz);
+            if (rc < 0) break;
+            if (rc > 0) continue;
+            /* Failed to allocate a single page? */
+            break;
+        }
+#endif
+
+        rc = populate_one_size(dom, PFN_512G_SHIFT, base_pfn + pfn, &allocsz);
+        if (rc < 0) break;
+        if (rc > 0) continue;
+
+        rc = populate_one_size(dom, PFN_1G_SHIFT, base_pfn + pfn, &allocsz);
+        if (rc < 0) break;
+        if (rc > 0) continue;
+
+        rc = populate_one_size(dom, PFN_2M_SHIFT, base_pfn + pfn, &allocsz);
+        if (rc < 0) break;
+        if (rc > 0) continue;
+
+        rc = populate_one_size(dom, PFN_4K_SHIFT, base_pfn + pfn, &allocsz);
+        if (rc < 0) break;
+
+        assert(rc > 0); /* Must have tried to allocate some 4k pages! */
     }
 
-    return rc;
+    DOMPRINTF("%s: rc=%d", __FUNCTION__, rc);
+
+    for ( pfn = 0; pfn < nr_pfns; pfn++ )
+        dom->p2m_host[pfn] = base_pfn + pfn;
+
+    return rc < 0 ? rc : 0;
 }
 
 int arch_setup_meminit(struct xc_dom_image *dom)
-- 
1.7.10.4

  parent reply	other threads:[~2014-06-10  9:57 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-10  9:55 [PATCH 0/6] xen: arm: Use super pages in p2m Ian Campbell
2014-06-10  9:57 ` [PATCH 1/6] xen: arm: dump vcpu gic info in arch_dump_vcpu_info Ian Campbell
2014-06-10 11:08   ` Julien Grall
2014-06-10  9:57 ` Ian Campbell [this message]
2014-06-10 11:23   ` [PATCH 2/6] tools: arm: allocate superpages to guests Julien Grall
2014-06-10 15:16     ` Ian Campbell
2014-06-11 11:50       ` Julien Grall
2014-06-11 11:55         ` Ian Campbell
2014-06-11 12:16           ` Julien Grall
2014-06-10  9:57 ` [PATCH 3/6] xen: arm: only put_page for p2m operations which require it Ian Campbell
2014-06-10 11:28   ` Julien Grall
2014-06-10 15:18     ` Ian Campbell
2014-06-10  9:57 ` [PATCH 4/6] xen: arm: handle superpage mappings in p2m_lookup Ian Campbell
2014-06-10 11:35   ` Julien Grall
2014-06-10  9:57 ` [PATCH 5/6] xen: arm: add some helpers for assessing p2m pte Ian Campbell
2014-06-10 11:37   ` Julien Grall
2014-06-10 11:46     ` Ian Campbell
2014-06-10 11:54       ` Julien Grall
2014-06-10 12:29         ` Ian Campbell
2014-06-10 12:52           ` Julien Grall
2014-06-10 15:19             ` Ian Campbell
2014-06-10  9:57 ` [PATCH 6/6] xen: arm: use superpages in p2m when pages are suitably aligned Ian Campbell
2014-06-10 12:10   ` Julien Grall
2014-06-10 15:23     ` Ian Campbell
2014-06-10 19:11       ` Julien Grall
2014-06-11  8:29         ` Ian Campbell

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=1402394278-9850-2-git-send-email-ian.campbell@citrix.com \
    --to=ian.campbell@citrix.com \
    --cc=julien.grall@linaro.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.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 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.