All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alejandro Vallejo <alejandro.vallejo@cloud.com>
To: xen-devel@lists.xenproject.org
Cc: Alejandro Vallejo <alejandro.vallejo@cloud.com>,
	Bernhard Kaindl <bernhard.kaindl@cloud.com>,
	Nick Rosbrook <rosbrookn@gmail.com>,
	George Dunlap <gwd@xenproject.org>,
	Anthony PERARD <anthony.perard@vates.tech>,
	Juergen Gross <jgross@suse.com>
Subject: [PATCH 10/11] tools/xl: Expose a "claim_on_node" setting in xl.cfg
Date: Fri, 14 Mar 2025 17:25:01 +0000	[thread overview]
Message-ID: <20250314172502.53498-11-alejandro.vallejo@cloud.com> (raw)
In-Reply-To: <20250314172502.53498-1-alejandro.vallejo@cloud.com>

Expose a setting to explicitly select a NUMA node for created domains

If the hypervisor can't reserve enough memory in the relevant NUMA node
it fails the claim early. Also, disable automatic NUMA placement when
this new option is enabled.

Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com>
---
 tools/golang/xenlight/helpers.gen.go |  2 ++
 tools/golang/xenlight/types.gen.go   |  1 +
 tools/include/xenguest.h             |  7 +++++++
 tools/libs/guest/xg_dom_core.c       |  1 +
 tools/libs/guest/xg_dom_x86.c        | 18 +++++++++---------
 tools/libs/light/libxl_dom.c         |  2 ++
 tools/libs/light/libxl_types.idl     |  3 ++-
 tools/xl/xl_parse.c                  | 11 +++++++++++
 8 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index 90846ea8e882..9204020224d5 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -1108,6 +1108,7 @@ x.LlcColors[i] = uint32(v)
 if err := x.ClaimMode.fromC(&xc.claim_mode);err != nil {
 return fmt.Errorf("converting field ClaimMode: %v", err)
 }
+x.ClaimOnNode = uint32(xc.claim_on_node)
 x.EventChannels = uint32(xc.event_channels)
 x.Kernel = C.GoString(xc.kernel)
 x.Cmdline = C.GoString(xc.cmdline)
@@ -1472,6 +1473,7 @@ cLlcColors[i] = C.uint32_t(v)
 if err := x.ClaimMode.toC(&xc.claim_mode); err != nil {
 return fmt.Errorf("converting field ClaimMode: %v", err)
 }
+xc.claim_on_node = C.uint32_t(x.ClaimOnNode)
 xc.event_channels = C.uint32_t(x.EventChannels)
 if x.Kernel != "" {
 xc.kernel = C.CString(x.Kernel)}
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
index e7667f1ce3a3..1c6319200411 100644
--- a/tools/golang/xenlight/types.gen.go
+++ b/tools/golang/xenlight/types.gen.go
@@ -577,6 +577,7 @@ Irqs []uint32
 Iomem []IomemRange
 LlcColors []uint32
 ClaimMode Defbool
+ClaimOnNode uint32
 EventChannels uint32
 Kernel string
 Cmdline string
diff --git a/tools/include/xenguest.h b/tools/include/xenguest.h
index e01f494b772a..08aae1e24e4c 100644
--- a/tools/include/xenguest.h
+++ b/tools/include/xenguest.h
@@ -185,6 +185,13 @@ struct xc_dom_image {
     uint32_t guest_domid;
     int claim_enabled; /* 0 by default, 1 enables it */
 
+    /*
+     * Exact NUMA node on which to allocate memory from.
+     *
+     * XC_NUMA_NO_NODE by default.
+     */
+    unsigned int claim_on_node;
+
     int xen_version;
     xen_capabilities_info_t xen_caps;
 
diff --git a/tools/libs/guest/xg_dom_core.c b/tools/libs/guest/xg_dom_core.c
index 595b0a667c03..152ec8ea6591 100644
--- a/tools/libs/guest/xg_dom_core.c
+++ b/tools/libs/guest/xg_dom_core.c
@@ -775,6 +775,7 @@ struct xc_dom_image *xc_dom_allocate(xc_interface *xch,
     dom->parms->p2m_base = UNSET_ADDR;
 
     dom->flags = SIF_VIRT_P2M_4TOOLS;
+    dom->claim_on_node = XC_NUMA_NO_NODE;
 
     dom->alloc_malloc += sizeof(*dom);
     return dom;
diff --git a/tools/libs/guest/xg_dom_x86.c b/tools/libs/guest/xg_dom_x86.c
index ac05106a8c1c..4fe816b9bcb4 100644
--- a/tools/libs/guest/xg_dom_x86.c
+++ b/tools/libs/guest/xg_dom_x86.c
@@ -1199,7 +1199,7 @@ static int meminit_pv(struct xc_dom_image *dom)
     if ( dom->claim_enabled )
     {
         rc = xc_domain_claim_pages(dom->xch, dom->guest_domid,
-                                   XC_NUMA_NO_NODE,
+                                   dom->claim_on_node,
                                    dom->total_pages);
         if ( rc )
             return rc;
@@ -1209,9 +1209,10 @@ static int meminit_pv(struct xc_dom_image *dom)
      * that this is a valid state if libxl doesn't provide any
      * vNUMA information.
      *
-     * The dummy values make libxc allocate all pages from
-     * arbitrary physical nodes. This is the expected behaviour if
-     * no vNUMA configuration is provided to libxc.
+     * If there's an outstanding claim on a node, memory is allocated from that
+     * node. Otherwise the dummy values make libxc allocate all pages from
+     * arbitrary physical nodes. This is the expected behaviour if no vNUMA
+     * configuration is provided to libxc and.
      *
      * Note that the following hunk is just for the convenience of
      * allocation code. No defaulting happens in libxc.
@@ -1227,7 +1228,7 @@ static int meminit_pv(struct xc_dom_image *dom)
 
         nr_vnodes = 1;
         vnode_to_pnode = dummy_vnode_to_pnode;
-        vnode_to_pnode[0] = XC_NUMA_NO_NODE;
+        vnode_to_pnode[0] = dom->claim_on_node;
     }
     else
     {
@@ -1357,7 +1358,6 @@ static int meminit_hvm(struct xc_dom_image *dom)
     unsigned long stat_normal_pages = 0, stat_2mb_pages = 0,
         stat_1gb_pages = 0;
     unsigned int memflags = 0;
-    int claim_enabled = dom->claim_enabled;
     uint64_t total_pages;
     xen_vmemrange_t dummy_vmemrange[2];
     unsigned int dummy_vnode_to_pnode[1];
@@ -1397,7 +1397,7 @@ static int meminit_hvm(struct xc_dom_image *dom)
             nr_vmemranges++;
         }
 
-        dummy_vnode_to_pnode[0] = XC_NUMA_NO_NODE;
+        dummy_vnode_to_pnode[0] = dom->claim_on_node;
         nr_vnodes = 1;
         vmemranges = dummy_vmemrange;
         vnode_to_pnode = dummy_vnode_to_pnode;
@@ -1443,8 +1443,8 @@ static int meminit_hvm(struct xc_dom_image *dom)
      * actually allocates memory for the guest. Claiming after memory has been
      * allocated is pointless.
      */
-    if ( claim_enabled ) {
-        rc = xc_domain_claim_pages(xch, domid, XC_NUMA_NO_NODE,
+    if ( dom->claim_enabled ) {
+        rc = xc_domain_claim_pages(xch, domid, dom->claim_on_node,
                                    target_pages - dom->vga_hole_size);
         if ( rc != 0 )
         {
diff --git a/tools/libs/light/libxl_dom.c b/tools/libs/light/libxl_dom.c
index 94fef374014e..1a5500702239 100644
--- a/tools/libs/light/libxl_dom.c
+++ b/tools/libs/light/libxl_dom.c
@@ -663,6 +663,7 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
     dom->xenstore_evtchn = state->store_port;
     dom->xenstore_domid = state->store_domid;
     dom->claim_enabled = libxl_defbool_val(info->claim_mode);
+    dom->claim_on_node = info->claim_on_node;
     dom->max_vcpus = info->max_vcpus;
 
     if (info->num_vnuma_nodes != 0) {
@@ -1090,6 +1091,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
     mem_size = (uint64_t)(info->max_memkb - info->video_memkb) << 10;
     dom->target_pages = (uint64_t)(info->target_memkb - info->video_memkb) >> 2;
     dom->claim_enabled = libxl_defbool_val(info->claim_mode);
+    dom->claim_on_node = info->claim_on_node;
     if (info->u.hvm.mmio_hole_memkb) {
         uint64_t max_ram_below_4g = (1ULL << 32) -
             (info->u.hvm.mmio_hole_memkb << 10);
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index bd4b8721ff19..a252b36c2b5d 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -617,7 +617,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
     ("irqs",             Array(uint32, "num_irqs")),
     ("iomem",            Array(libxl_iomem_range, "num_iomem")),
     ("llc_colors",       Array(uint32, "num_llc_colors")),
-    ("claim_mode",	     libxl_defbool),
+    ("claim_mode",       libxl_defbool),
+    ("claim_on_node",    uint32),
     ("event_channels",   uint32),
     ("kernel",           string),
     ("cmdline",          string),
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 089a88935aff..5880a032e6d6 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1558,6 +1558,17 @@ void parse_config_data(const char *config_source,
         exit(1);
 
     libxl_defbool_set(&b_info->claim_mode, claim_mode);
+    e = xlu_cfg_get_bounded_long (config, "claim_on_node", 0,
+                                  254, &l, 1);
+    if (e == ESRCH) /* not specified */
+        b_info->claim_on_node = ~0U;
+    else if (!e) {
+        libxl_defbool_set(&b_info->numa_placement, false);
+        libxl_defbool_set(&b_info->claim_mode, true);
+        b_info->claim_on_node = l;
+    }
+    else
+        exit(1);
 
     if (xlu_cfg_get_string (config, "on_poweroff", &buf, 0))
         buf = "destroy";
-- 
2.48.1



  parent reply	other threads:[~2025-03-14 17:31 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-14 17:24 [PATCH 00/11] Add support for exact-node memory claims Alejandro Vallejo
2025-03-14 17:24 ` [PATCH 01/11] xen/memory: Mask XENMEMF_node() to 8 bits Alejandro Vallejo
2025-03-17 16:33   ` Jan Beulich
2025-03-18 16:10     ` Alejandro Vallejo
2025-03-14 17:24 ` [PATCH 02/11] xen/page_alloc: Remove `claim` from domain_set_outstanding_pages() Alejandro Vallejo
2025-06-05 16:42   ` Roger Pau Monné
2025-06-10 12:23     ` Jan Beulich
2025-06-10 12:52       ` Roger Pau Monné
2025-06-10 17:51       ` Alejandro Vallejo
2025-06-10 12:37   ` Jan Beulich
2025-03-14 17:24 ` [PATCH 03/11] xen/page_alloc: Add static per-node counts of free pages Alejandro Vallejo
2025-06-05 16:46   ` Roger Pau Monné
2025-06-11 13:35   ` Jan Beulich
2025-03-14 17:24 ` [PATCH 04/11] xen: Add node argument to domain_{adjust_tot_pages,set_outstanding_pages}() Alejandro Vallejo
2025-06-06  7:57   ` Roger Pau Monné
2025-06-11 13:43   ` Jan Beulich
2025-03-14 17:24 ` [PATCH 05/11] xen: Create per-node outstanding claims Alejandro Vallejo
2025-06-06  8:14   ` Roger Pau Monné
2025-06-06  8:36   ` Roger Pau Monné
2025-03-14 17:24 ` [PATCH 06/11] xen/page_alloc: Hook per-node claims to alloc_heap_pages() Alejandro Vallejo
2025-06-06  8:22   ` Roger Pau Monné
2025-03-14 17:24 ` [PATCH 07/11] xen/page_alloc: Set node affinity when claiming pages from an exact node Alejandro Vallejo
2025-06-06  8:34   ` Roger Pau Monné
2025-06-11 13:51   ` Jan Beulich
2025-03-14 17:24 ` [PATCH 08/11] xen/memory: Enable parsing NUMA node argument in XENMEM_claim_pages Alejandro Vallejo
2025-06-06  8:51   ` Roger Pau Monné
2025-03-14 17:25 ` [PATCH 09/11] tools/xc: Add `node` argument to xc_domain_claim_pages() Alejandro Vallejo
2025-06-06  9:02   ` Roger Pau Monné
2025-03-14 17:25 ` Alejandro Vallejo [this message]
2025-06-06  9:00   ` [PATCH 10/11] tools/xl: Expose a "claim_on_node" setting in xl.cfg Roger Pau Monné
2025-03-14 17:25 ` [PATCH 11/11] docs/man: Document the new claim_on_node option Alejandro Vallejo
2025-06-06  9:03   ` Roger Pau Monné

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=20250314172502.53498-11-alejandro.vallejo@cloud.com \
    --to=alejandro.vallejo@cloud.com \
    --cc=anthony.perard@vates.tech \
    --cc=bernhard.kaindl@cloud.com \
    --cc=gwd@xenproject.org \
    --cc=jgross@suse.com \
    --cc=rosbrookn@gmail.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 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.