All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ryan Harper <ryanh@us.ibm.com>
To: Keir Fraser <keir@xensource.com>
Cc: xen-devel@lists.xensource.com, ryanh@us.ibm.com
Subject: Re: [RFC][PATCH 2/2] Add hcall to probe Xen heap
Date: Tue, 10 Jul 2007 15:34:19 -0500	[thread overview]
Message-ID: <20070710203419.GA23852@us.ibm.com> (raw)
In-Reply-To: <C2B41B1E.1201D%keir@xensource.com>

[-- Attachment #1: Type: text/plain, Size: 834 bytes --]

* Keir Fraser <keir@xensource.com> [2007-07-06 10:17]:
> First, it should be a sysctl, not a domctl. Second, please add the zone
> range checks into the function you added to page_alloc.c. This will avoid
> making use of allocator-private defines outside of page_alloc.c (so you can
> avoid moving NR_ZONES into mm.h.

We need access to NR_ZONES so we can calculate zone_hi limit as the user
might not have put in a value for zone_hi, and NR_ZONES would truncate
that.  I've moved the calculation into avail_heap_pages(), but had to
change the signature to take a pointer to the nr_zone value that will be
calculated.  I don't really like it that much so I'm open to suggestions
on a different approach.

-- 
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253   T/L: 678-9253
ryanh@us.ibm.com

[-- Attachment #2: add_availheap_hcall.patch --]
[-- Type: text/plain, Size: 8408 bytes --]

Add new domctl hypercall to expose current heap values.  This functionality is
needed for probing how much memory is available in a given node prior to VM
creation.

Signed-off-by: Ryan Harper <ryanh@us.ibm.com>

diff -r 27e993c80ceb tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c	Mon Jul 09 09:47:20 2007 +0100
+++ b/tools/libxc/xc_domain.c	Tue Jul 10 14:02:53 2007 -0500
@@ -586,6 +586,34 @@ int xc_domain_ioport_permission(int xc_h
     domctl.u.ioport_permission.allow_access = allow_access;
 
     return do_domctl(xc_handle, &domctl);
+}
+
+int xc_availheap(int xc_handle,
+                 int zone_lo,
+                 int zone_hi,
+                 int node,
+                 uint32_t *nr_zones,
+                 uint32_t *nr_nodes,
+                 uint64_t *pages)
+{
+    DECLARE_SYSCTL;
+    int rc = 0;
+
+    sysctl.cmd = XEN_SYSCTL_availheap;
+    sysctl.u.availheap.zone_lo = zone_lo;
+    sysctl.u.availheap.zone_hi = zone_hi;
+    sysctl.u.availheap.node = node;
+
+    rc = xc_sysctl(xc_handle, &sysctl);
+    if ( rc >= 0 ) {
+        if (nr_zones)
+            *nr_zones = sysctl.u.availheap.nr_zones;
+        if (nr_nodes)
+            *nr_nodes = sysctl.u.availheap.nr_nodes;
+        *pages = sysctl.u.availheap.pages;
+    }
+
+    return rc;
 }
 
 int xc_vcpu_setcontext(int xc_handle,
diff -r 27e993c80ceb tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Mon Jul 09 09:47:20 2007 +0100
+++ b/tools/libxc/xenctrl.h	Tue Jul 10 14:02:53 2007 -0500
@@ -616,6 +616,22 @@ int xc_get_pfn_type_batch(int xc_handle,
 /* Get current total pages allocated to a domain. */
 long xc_get_tot_pages(int xc_handle, uint32_t domid);
 
+/**
+ * This function retrieves the the number of pages available
+ * in the heap in a specific range of zones and nodes.
+ * 
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain to query
+ * @parm zone_lo the starting zone to query
+ * @parm zone_lo the last zone to query
+ * @parm node the node to query
+ * @parm *nr_zones caller variable to put number of zones queried
+ * @parm *nr_nodes caller variable to put number of nodes queried
+ * @parm *pages caller variable to put total pages counted
+ * @return 0 on success, <0 on failure.
+ */
+int xc_availheap(int xc_handle, int zone_lo, int zone_hi, int node,
+                 uint32_t *nr_zones, uint32_t *nr_nodes, uint64_t *pages);
 
 /*
  * Trace Buffer Operations
diff -r 27e993c80ceb xen/common/page_alloc.c
--- a/xen/common/page_alloc.c	Mon Jul 09 09:47:20 2007 +0100
+++ b/xen/common/page_alloc.c	Tue Jul 10 14:09:28 2007 -0500
@@ -569,8 +569,9 @@ void init_heap_pages(
     }
 }
 
-static unsigned long avail_heap_pages(
-    unsigned int zone_lo, unsigned int zone_hi, unsigned int node)
+unsigned long avail_heap_pages(
+    unsigned int zone_lo, unsigned int zone_hi, unsigned int node,
+    unsigned int *nr_zones)
 {
     unsigned int i, zone, num_nodes = num_online_nodes();
     unsigned long free_pages = 0;
@@ -586,6 +587,9 @@ static unsigned long avail_heap_pages(
             if ( (node == -1) || (node == i) )
                 free_pages += avail[i][zone];
     }
+
+    if (nr_zones)
+       *nr_zones = zone_hi - zone_lo + 1;
 
     return free_pages;
 }
@@ -834,7 +838,7 @@ struct page_info *__alloc_domheap_pages(
              ((order > MAX_ORDER) ||
               (avail_heap_pages(MEMZONE_XEN + 1,
                                 dma_bitsize - PAGE_SHIFT - 1,
-                                -1) <
+                                -1, NULL) <
                (dma_emergency_pool_pages + (1UL << order)))) )
             return NULL;
     }
@@ -934,11 +938,11 @@ unsigned long avail_domheap_pages(void)
     
     avail_nrm = avail_heap_pages(dma_bitsize - PAGE_SHIFT,
                                  NR_ZONES - 1,
-                                 -1);
+                                 -1, NULL);
 
     avail_dma = avail_heap_pages(MEMZONE_XEN + 1,
                                  dma_bitsize - PAGE_SHIFT - 1,
-                                 -1);
+                                 -1, NULL);
 
     if ( avail_dma > dma_emergency_pool_pages )
         avail_dma -= dma_emergency_pool_pages;
@@ -950,7 +954,7 @@ unsigned long avail_domheap_pages(void)
 
 unsigned long avail_nodeheap_pages(int node)
 {
-    return avail_heap_pages(0, NR_ZONES - 1, node);
+    return avail_heap_pages(0, NR_ZONES - 1, node, NULL);
 }
 
 static void pagealloc_keyhandler(unsigned char key)
@@ -960,7 +964,7 @@ static void pagealloc_keyhandler(unsigne
 
     printk("Physical memory information:\n");
     printk("    Xen heap: %lukB free\n",
-           avail_heap_pages(zone, zone, -1) << (PAGE_SHIFT-10));
+           avail_heap_pages(zone, zone, -1, NULL) << (PAGE_SHIFT-10));
 
     while ( ++zone < NR_ZONES )
     {
@@ -972,7 +976,7 @@ static void pagealloc_keyhandler(unsigne
             total = 0;
         }
 
-        if ( (n = avail_heap_pages(zone, zone, -1)) != 0 )
+        if ( (n = avail_heap_pages(zone, zone, -1, NULL)) != 0 )
         {
             total += n;
             printk("    heap[%02u]: %lukB free\n", zone, n << (PAGE_SHIFT-10));
diff -r 27e993c80ceb xen/common/sysctl.c
--- a/xen/common/sysctl.c	Mon Jul 09 09:47:20 2007 +0100
+++ b/xen/common/sysctl.c	Tue Jul 10 14:09:59 2007 -0500
@@ -21,6 +21,8 @@
 #include <xen/keyhandler.h>
 #include <asm/current.h>
 #include <public/sysctl.h>
+#include <asm/numa.h>
+#include <xen/nodemask.h>
 
 extern long arch_do_sysctl(
     struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
@@ -166,6 +168,31 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
 
         if ( copy_to_guest(u_sysctl, op, 1) )
             ret = -EFAULT;
+    }
+    break;
+
+    case XEN_SYSCTL_availheap:
+    { 
+        ret = -EINVAL;
+
+        if ( op->u.availheap.node >= num_online_nodes() )
+            break;
+        if ( op->u.availheap.zone_lo > op->u.availheap.zone_hi )
+            break;
+
+        ( op->u.availheap.node < 0 ) ?
+            (op->u.availheap.nr_nodes=num_online_nodes()) :
+            (op->u.availheap.nr_nodes=1);
+
+        op->u.availheap.pages = avail_heap_pages(op->u.availheap.zone_lo,
+                                                 op->u.availheap.zone_hi,
+                                                 op->u.availheap.node,
+                                                 &(op->u.availheap.nr_zones));
+
+        if ( copy_to_guest(u_sysctl, op, 1) )
+            ret = -EFAULT;
+        else
+            ret = 0;
     }
     break;
 
diff -r 27e993c80ceb xen/include/public/sysctl.h
--- a/xen/include/public/sysctl.h	Mon Jul 09 09:47:20 2007 +0100
+++ b/xen/include/public/sysctl.h	Tue Jul 10 14:02:53 2007 -0500
@@ -185,6 +185,20 @@ typedef struct xen_sysctl_getcpuinfo xen
 typedef struct xen_sysctl_getcpuinfo xen_sysctl_getcpuinfo_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getcpuinfo_t); 
 
+#define XEN_SYSCTL_availheap        9
+struct xen_sysctl_availheap {
+    /* in  */
+    int zone_lo;             /* starting zone */
+    int zone_hi;             /* ending zone, -1 for zone_lo to NR_ZONES */
+    int node;                /* query available pages in node, -1 for all */
+    /* out */
+    uint32_t nr_zones;    /* number of zones queried */
+    uint32_t nr_nodes;    /* number of nodes queried */
+    uint64_t pages;
+};
+typedef struct xen_sysctl_availheap xen_sysctl_availheap_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_availheap_t);
+ 
 struct xen_sysctl {
     uint32_t cmd;
     uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
@@ -197,6 +211,7 @@ struct xen_sysctl {
         struct xen_sysctl_getdomaininfolist getdomaininfolist;
         struct xen_sysctl_debug_keys        debug_keys;
         struct xen_sysctl_getcpuinfo        getcpuinfo;
+        struct xen_sysctl_availheap         availheap;
         uint8_t                             pad[128];
     } u;
 };
diff -r 27e993c80ceb xen/include/xen/mm.h
--- a/xen/include/xen/mm.h	Mon Jul 09 09:47:20 2007 +0100
+++ b/xen/include/xen/mm.h	Tue Jul 10 14:08:03 2007 -0500
@@ -65,6 +65,10 @@ unsigned long avail_domheap_pages(void);
 #define alloc_domheap_page(d) (alloc_domheap_pages(d,0,0))
 #define free_domheap_page(p)  (free_domheap_pages(p,0))
 
+unsigned long avail_heap_pages(
+    unsigned int zone_lo, unsigned int zone_hi, unsigned int node,
+    unsigned int *nr_zones);
+
 void scrub_heap_pages(void);
 
 int assign_pages(

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

      reply	other threads:[~2007-07-10 20:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-10  1:09 [RFC][PATCH 2/2] Add hcall to probe Xen heap Ryan Harper
2007-06-06 16:07 ` Ryan Harper
2007-06-17 16:44   ` Subrahmanian, Raj
2007-06-17 17:00     ` Keir Fraser
2007-06-18 13:27       ` Subrahmanian, Raj
2007-06-18 15:51     ` Ryan Harper
2007-06-19 22:30       ` Subrahmanian, Raj
2007-06-19 22:39         ` Ryan Harper
2007-07-06 15:15   ` Keir Fraser
2007-07-10 20:34     ` Ryan Harper [this message]

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=20070710203419.GA23852@us.ibm.com \
    --to=ryanh@us.ibm.com \
    --cc=keir@xensource.com \
    --cc=xen-devel@lists.xensource.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.