[PATCH v9 5/6] tools: Allow building xen-hptool without CONFIG_MIGRATE
Mykyta Poturai <[email protected]>
| Newsgroups | org.xenproject.lists.xen-devel |
|---|---|
| Message-ID | <c1f410ccb1469f1c46d2df94cd76546bf3db00b9.1787042017.git.mykyta_poturai@epam.com> |
With CPU hotplug sysctls implemented on Arm it becomes useful to have a tool for calling them. According to the commit history it seems that putting hptool under config MIGRATE was a measure to fix IA64 build. As IA64 is no longer supported it can now be brought back. So build it unconditionally. Operations specific to x86 architecture are moved into a separate file and only built on x86. Signed-off-by: Mykyta Poturai <[email protected]> --- v8->v9: * use CONFIG_X86 instead of CONFIG_MIGRATE * fix style issues * add SPDX headers v7->v8: * move x86 specific function into a separate file v6->v7: * no changes v5->v6: * don't change order in Makefile v4->v5: * make hptool always build v3->v4: * no changes v2->v3: * no changes v1->v2: * switch to configure from legacy config --- tools/misc/Makefile | 9 +- tools/misc/xen-hptool-x86.c | 278 ++++++++++++++++++++++++++++++++++ tools/misc/xen-hptool.c | 293 ++---------------------------------- tools/misc/xen-hptool.h | 15 ++ 4 files changed, 314 insertions(+), 281 deletions(-) create mode 100644 tools/misc/xen-hptool-x86.c create mode 100644 tools/misc/xen-hptool.h diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 6ee783f43e..064ab7c4bd 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -16,7 +16,7 @@ INSTALL_BIN += xencov_split INSTALL_BIN += $(INSTALL_BIN-y) # Everything to be installed in regular sbin/ -INSTALL_SBIN-$(CONFIG_MIGRATE) += xen-hptool +INSTALL_SBIN += xen-hptool INSTALL_SBIN-$(CONFIG_X86) += xen-hvmcrash INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx INSTALL_SBIN-$(CONFIG_X86) += xen-lowmemd @@ -104,8 +104,11 @@ xenhypfs: xenhypfs.o xenlockprof: xenlockprof.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) -xen-hptool: xen-hptool.o - $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS) +hptool-objs-y := xen-hptool.o +hptool-objs-$(CONFIG_X86) += xen-hptool-x86.o + +xen-hptool: $(hptool-objs-y) + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS) xenhypfs.o: CFLAGS += $(CFLAGS_libxenhypfs) diff --git a/tools/misc/xen-hptool-x86.c b/tools/misc/xen-hptool-x86.c new file mode 100644 index 0000000000..95a7e05990 --- /dev/null +++ b/tools/misc/xen-hptool-x86.c @@ -0,0 +1,278 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <xenevtchn.h> +#include <xenctrl.h> +#include <xenguest.h> +#include <xenstore.h> +#include "xen-hptool.h" + +int hp_mem_online_func(int argc, char *argv[], xc_interface *xch) +{ + uint32_t status; + int ret; + unsigned long mfn; + + if (argc != 1) + { + show_help(); + return -1; + } + + sscanf(argv[0], "%lx", &mfn); + printf("Prepare to online MEMORY mfn %lx\n", mfn); + + ret = xc_mark_page_online(xch, mfn, mfn, &status); + + if (ret < 0) + fprintf(stderr, "Onlining page mfn %lx failed, error %x\n", mfn, errno); + else if (status & (PG_ONLINE_FAILED |PG_ONLINE_BROKEN)) { + fprintf(stderr, "Onlining page mfn %lx is broken, " + "Memory online failed\n", mfn); + ret = -1; + } + else if (status & PG_ONLINE_ONLINED) + printf("Memory mfn %lx onlined successfully\n", mfn); + else + printf("Memory is already onlined!\n"); + + return ret; +} + +int hp_mem_query_func(int argc, char *argv[], xc_interface *xch) +{ + uint32_t status; + int ret; + unsigned long mfn; + + if (argc != 1) + { + show_help(); + return -1; + } + + sscanf(argv[0], "%lx", &mfn); + printf("Querying MEMORY mfn %lx status\n", mfn); + ret = xc_query_page_offline_status(xch, mfn, mfn, &status); + + if (ret < 0) + fprintf(stderr, "Querying page mfn %lx failed, error %x\n", mfn, errno); + else + { + printf("Memory Status %x: [", status); + if ( status & PG_OFFLINE_STATUS_OFFLINE_PENDING) + printf(" PAGE_OFFLINE_PENDING "); + if ( status & PG_OFFLINE_STATUS_BROKEN ) + printf(" PAGE_BROKEND "); + if ( status & PG_OFFLINE_STATUS_OFFLINED ) + printf(" PAGE_OFFLINED "); + else + printf(" PAGE_ONLINED "); + printf("]\n"); + } + + return ret; +} + +static int suspend_guest(xc_interface *xch, xenevtchn_handle *xce, int domid, + int *evtchn, int *lockfd) +{ + int port, rc, suspend_evtchn = -1; + + *lockfd = -1; + + if (!evtchn) + return -1; + + port = xs_suspend_evtchn_port(domid); + if (port < 0) + { + fprintf(stderr, "DOM%d: No suspend port, try live migration\n", domid); + goto failed; + } + suspend_evtchn = xc_suspend_evtchn_init_exclusive(xch, xce, domid, + port, lockfd); + if (suspend_evtchn < 0) + { + fprintf(stderr, "Suspend evtchn initialization failed\n"); + goto failed; + } + *evtchn = suspend_evtchn; + + rc = xenevtchn_notify(xce, suspend_evtchn); + if (rc < 0) + { + fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc); + goto failed; + } + if (xc_await_suspend(xch, xce, suspend_evtchn) < 0) + { + fprintf(stderr, "Suspend Failed\n"); + goto failed; + } + return 0; + +failed: + if (suspend_evtchn != -1) + xc_suspend_evtchn_release(xch, xce, domid, + suspend_evtchn, lockfd); + + return -1; +} + +int hp_mem_offline_func(int argc, char *argv[], xc_interface *xch) +{ + uint32_t status, domid; + int ret; + unsigned long mfn; + + if (argc != 1) + { + show_help(); + return -1; + } + + sscanf(argv[0], "%lx", &mfn); + printf("Prepare to offline MEMORY mfn %lx\n", mfn); + ret = xc_mark_page_offline(xch, mfn, mfn, &status); + if (ret < 0) { + fprintf(stderr, "Offlining page mfn %lx failed, error %x\n", mfn, errno); + if (status & (PG_OFFLINE_XENPAGE | PG_OFFLINE_FAILED)) + fprintf(stderr, "XEN_PAGE is not permitted be offlined\n"); + else if (status & (PG_OFFLINE_FAILED | PG_OFFLINE_NOT_CONV_RAM)) + fprintf(stderr, "RESERVED RAM is not permitted to be offlined\n"); + } + else + { + switch(status & PG_OFFLINE_STATUS_MASK) + { + case PG_OFFLINE_OFFLINED: + { + printf("Memory mfn %lx offlined successfully, current state is" + " [PG_OFFLINE_OFFLINED]\n", mfn); + if (status & PG_OFFLINE_BROKEN) + printf("And this offlined PAGE is already marked broken" + " before!\n"); + break; + } + case PG_OFFLINE_FAILED: + { + fprintf(stderr, "Memory mfn %lx offline failed\n", mfn); + if ( status & PG_OFFLINE_ANONYMOUS) + fprintf(stderr, "the memory is an anonymous page!\n"); + ret = -1; + break; + } + case PG_OFFLINE_PENDING: + { + if (status & PG_OFFLINE_XENPAGE) { + ret = -1; + fprintf(stderr, "Memory mfn %lx offlined succssefully," + "this page is xen page, current state is" + " [PG_OFFLINE_PENDING, PG_OFFLINE_XENPAGE]\n", mfn); + } + else if (status & PG_OFFLINE_OWNED) + { + int result, suspend_evtchn = -1, suspend_lockfd = -1; + xenevtchn_handle *xce; + xce = xenevtchn_open(NULL, 0); + + if (xce == NULL) + { + fprintf(stderr, "When exchange page, fail" + " to open evtchn\n"); + return -1; + } + + domid = status >> PG_OFFLINE_OWNER_SHIFT; + if (suspend_guest(xch, xce, domid, + &suspend_evtchn, &suspend_lockfd)) + { + fprintf(stderr, "Failed to suspend guest %d for" + " mfn %lx\n", domid, mfn); + xenevtchn_close(xce); + return -1; + } + + result = xc_exchange_page(xch, domid, mfn); + + /* Exchange page successfully */ + if (result == 0) + printf("Memory mfn %lx offlined successfully, this " + "page is DOM%d page and being swapped " + "successfully, current state is " + "[PG_OFFLINE_OFFLINED, PG_OFFLINE_OWNED]\n", + mfn, domid); + else { + ret = -1; + fprintf(stderr, "Memory mfn %lx offlined successfully" + " , this page is DOM%d page yet failed to be " + "exchanged. current state is " + "[PG_OFFLINE_PENDING, PG_OFFLINE_OWNED]\n", + mfn, domid); + } + xc_domain_resume(xch, domid, 1); + xc_suspend_evtchn_release(xch, xce, domid, + suspend_evtchn, &suspend_lockfd); + xenevtchn_close(xce); + } + break; + } + }//end of switch + }//end of if + + return ret; +} + +int main_smt_enable(int argc, char *argv[], xc_interface *xch) +{ + int ret; + + if ( argc ) + { + show_help(); + return -1; + } + + for ( ;; ) + { + ret = xc_smt_enable(xch); + if ( (ret >= 0) || (errno != EBUSY) ) + break; + } + + if ( ret < 0 ) + fprintf(stderr, "Unable to enable SMT: errno %d, %s\n", + errno, strerror(errno)); + else + printf("Enabled SMT\n"); + + return ret; +} + +int main_smt_disable(int argc, char *argv[], xc_interface *xch) +{ + int ret; + + if ( argc ) + { + show_help(); + return -1; + } + + for ( ;; ) + { + ret = xc_smt_disable(xch); + if ( (ret >= 0) || (errno != EBUSY) ) + break; + } + + if ( ret < 0 ) + fprintf(stderr, "Unable to disable SMT: errno %d, %s\n", + errno, strerror(errno)); + else + printf("Disabled SMT\n"); + + return ret; +} diff --git a/tools/misc/xen-hptool.c b/tools/misc/xen-hptool.c index 590810b6eb..7b886e2304 100644 --- a/tools/misc/xen-hptool.c +++ b/tools/misc/xen-hptool.c @@ -6,8 +6,8 @@ #include <xenguest.h> #include <xenstore.h> #include <xen-tools/common-macros.h> +#include "xen-hptool.h" -static xc_interface *xch; void show_help(void) { @@ -18,239 +18,25 @@ void show_help(void) " help display this help\n" " cpu-online <cpuid> online CPU <cpuid>\n" " cpu-offline <cpuid> offline CPU <cpuid>\n" +#if defined(__i386__) || defined(__x86_64__) " mem-online <mfn> online MEMORY <mfn>\n" " mem-offline <mfn> offline MEMORY <mfn>\n" " mem-status <mfn> query Memory status<mfn>\n" " smt-enable onlines all SMT threads\n" " smt-disable offlines all SMT threads\n" +#endif ); } /* wrapper function */ -static int help_func(int argc, char *argv[]) +static int help_func(int argc, char *argv[], xc_interface *xch) { show_help(); return 0; } -static int hp_mem_online_func(int argc, char *argv[]) -{ - uint32_t status; - int ret; - unsigned long mfn; - - if (argc != 1) - { - show_help(); - return -1; - } - - sscanf(argv[0], "%lx", &mfn); - printf("Prepare to online MEMORY mfn %lx\n", mfn); - - ret = xc_mark_page_online(xch, mfn, mfn, &status); - - if (ret < 0) - fprintf(stderr, "Onlining page mfn %lx failed, error %x\n", mfn, errno); - else if (status & (PG_ONLINE_FAILED |PG_ONLINE_BROKEN)) { - fprintf(stderr, "Onlining page mfn %lx is broken, " - "Memory online failed\n", mfn); - ret = -1; - } - else if (status & PG_ONLINE_ONLINED) - printf("Memory mfn %lx onlined successfully\n", mfn); - else - printf("Memory is already onlined!\n"); - - return ret; -} - -static int hp_mem_query_func(int argc, char *argv[]) -{ - uint32_t status; - int ret; - unsigned long mfn; - - if (argc != 1) - { - show_help(); - return -1; - } - - sscanf(argv[0], "%lx", &mfn); - printf("Querying MEMORY mfn %lx status\n", mfn); - ret = xc_query_page_offline_status(xch, mfn, mfn, &status); - - if (ret < 0) - fprintf(stderr, "Querying page mfn %lx failed, error %x\n", mfn, errno); - else - { - printf("Memory Status %x: [", status); - if ( status & PG_OFFLINE_STATUS_OFFLINE_PENDING) - printf(" PAGE_OFFLINE_PENDING "); - if ( status & PG_OFFLINE_STATUS_BROKEN ) - printf(" PAGE_BROKEND "); - if ( status & PG_OFFLINE_STATUS_OFFLINED ) - printf(" PAGE_OFFLINED "); - else - printf(" PAGE_ONLINED "); - printf("]\n"); - } - - return ret; -} - -static int suspend_guest(xc_interface *xch, xenevtchn_handle *xce, int domid, - int *evtchn, int *lockfd) -{ - int port, rc, suspend_evtchn = -1; - - *lockfd = -1; - - if (!evtchn) - return -1; - - port = xs_suspend_evtchn_port(domid); - if (port < 0) - { - fprintf(stderr, "DOM%d: No suspend port, try live migration\n", domid); - goto failed; - } - suspend_evtchn = xc_suspend_evtchn_init_exclusive(xch, xce, domid, - port, lockfd); - if (suspend_evtchn < 0) - { - fprintf(stderr, "Suspend evtchn initialization failed\n"); - goto failed; - } - *evtchn = suspend_evtchn; - - rc = xenevtchn_notify(xce, suspend_evtchn); - if (rc < 0) - { - fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc); - goto failed; - } - if (xc_await_suspend(xch, xce, suspend_evtchn) < 0) - { - fprintf(stderr, "Suspend Failed\n"); - goto failed; - } - return 0; - -failed: - if (suspend_evtchn != -1) - xc_suspend_evtchn_release(xch, xce, domid, - suspend_evtchn, lockfd); - - return -1; -} - -static int hp_mem_offline_func(int argc, char *argv[]) -{ - uint32_t status, domid; - int ret; - unsigned long mfn; - - if (argc != 1) - { - show_help(); - return -1; - } - - sscanf(argv[0], "%lx", &mfn); - printf("Prepare to offline MEMORY mfn %lx\n", mfn); - ret = xc_mark_page_offline(xch, mfn, mfn, &status); - if (ret < 0) { - fprintf(stderr, "Offlining page mfn %lx failed, error %x\n", mfn, errno); - if (status & (PG_OFFLINE_XENPAGE | PG_OFFLINE_FAILED)) - fprintf(stderr, "XEN_PAGE is not permitted be offlined\n"); - else if (status & (PG_OFFLINE_FAILED | PG_OFFLINE_NOT_CONV_RAM)) - fprintf(stderr, "RESERVED RAM is not permitted to be offlined\n"); - } - else - { - switch(status & PG_OFFLINE_STATUS_MASK) - { - case PG_OFFLINE_OFFLINED: - { - printf("Memory mfn %lx offlined successfully, current state is" - " [PG_OFFLINE_OFFLINED]\n", mfn); - if (status & PG_OFFLINE_BROKEN) - printf("And this offlined PAGE is already marked broken" - " before!\n"); - break; - } - case PG_OFFLINE_FAILED: - { - fprintf(stderr, "Memory mfn %lx offline failed\n", mfn); - if ( status & PG_OFFLINE_ANONYMOUS) - fprintf(stderr, "the memory is an anonymous page!\n"); - ret = -1; - break; - } - case PG_OFFLINE_PENDING: - { - if (status & PG_OFFLINE_XENPAGE) { - ret = -1; - fprintf(stderr, "Memory mfn %lx offlined succssefully," - "this page is xen page, current state is" - " [PG_OFFLINE_PENDING, PG_OFFLINE_XENPAGE]\n", mfn); - } - else if (status & PG_OFFLINE_OWNED) - { - int result, suspend_evtchn = -1, suspend_lockfd = -1; - xenevtchn_handle *xce; - xce = xenevtchn_open(NULL, 0); - - if (xce == NULL) - { - fprintf(stderr, "When exchange page, fail" - " to open evtchn\n"); - return -1; - } - - domid = status >> PG_OFFLINE_OWNER_SHIFT; - if (suspend_guest(xch, xce, domid, - &suspend_evtchn, &suspend_lockfd)) - { - fprintf(stderr, "Failed to suspend guest %d for" - " mfn %lx\n", domid, mfn); - xenevtchn_close(xce); - return -1; - } - - result = xc_exchange_page(xch, domid, mfn); - - /* Exchange page successfully */ - if (result == 0) - printf("Memory mfn %lx offlined successfully, this " - "page is DOM%d page and being swapped " - "successfully, current state is " - "[PG_OFFLINE_OFFLINED, PG_OFFLINE_OWNED]\n", - mfn, domid); - else { - ret = -1; - fprintf(stderr, "Memory mfn %lx offlined successfully" - " , this page is DOM%d page yet failed to be " - "exchanged. current state is " - "[PG_OFFLINE_PENDING, PG_OFFLINE_OWNED]\n", - mfn, domid); - } - xc_domain_resume(xch, domid, 1); - xc_suspend_evtchn_release(xch, xce, domid, - suspend_evtchn, &suspend_lockfd); - xenevtchn_close(xce); - } - break; - } - }//end of switch - }//end of if - - return ret; -} - -static int exec_cpu_hp_fn(int (*hp_fn)(xc_interface *, int), int cpu) +static int exec_cpu_hp_fn(int (*hp_fn)(xc_interface *, int), int cpu, + xc_interface *xch) { int ret; @@ -265,7 +51,7 @@ static int exec_cpu_hp_fn(int (*hp_fn)(xc_interface *, int), int cpu) return ret; } -static int hp_cpu_online_func(int argc, char *argv[]) +static int hp_cpu_online_func(int argc, char *argv[], xc_interface *xch) { int cpu, ret; @@ -277,7 +63,7 @@ static int hp_cpu_online_func(int argc, char *argv[]) cpu = atoi(argv[0]); printf("Prepare to online CPU %d\n", cpu); - ret = exec_cpu_hp_fn(xc_cpu_online, cpu); + ret = exec_cpu_hp_fn(xc_cpu_online, cpu, xch); if (ret < 0) fprintf(stderr, "CPU %d online failed (error %d: %s)\n", cpu, errno, strerror(errno)); @@ -287,7 +73,7 @@ static int hp_cpu_online_func(int argc, char *argv[]) return ret; } -static int hp_cpu_offline_func(int argc, char *argv[]) +static int hp_cpu_offline_func(int argc, char *argv[], xc_interface *xch) { int cpu, ret; @@ -298,7 +84,7 @@ static int hp_cpu_offline_func(int argc, char *argv[]) } cpu = atoi(argv[0]); printf("Prepare to offline CPU %d\n", cpu); - ret = exec_cpu_hp_fn(xc_cpu_offline, cpu); + ret = exec_cpu_hp_fn(xc_cpu_offline, cpu, xch); if (ret < 0) fprintf(stderr, "CPU %d offline failed (error %d: %s)\n", cpu, errno, strerror(errno)); @@ -308,76 +94,27 @@ static int hp_cpu_offline_func(int argc, char *argv[]) return ret; } -static int main_smt_enable(int argc, char *argv[]) -{ - int ret; - - if ( argc ) - { - show_help(); - return -1; - } - - for ( ;; ) - { - ret = xc_smt_enable(xch); - if ( (ret >= 0) || (errno != EBUSY) ) - break; - } - - if ( ret < 0 ) - fprintf(stderr, "Unable to enable SMT: errno %d, %s\n", - errno, strerror(errno)); - else - printf("Enabled SMT\n"); - - return ret; -} - -static int main_smt_disable(int argc, char *argv[]) -{ - int ret; - - if ( argc ) - { - show_help(); - return -1; - } - - for ( ;; ) - { - ret = xc_smt_disable(xch); - if ( (ret >= 0) || (errno != EBUSY) ) - break; - } - - if ( ret < 0 ) - fprintf(stderr, "Unable to disable SMT: errno %d, %s\n", - errno, strerror(errno)); - else - printf("Disabled SMT\n"); - - return ret; -} - struct { const char *name; - int (*function)(int argc, char *argv[]); + int (*function)(int argc, char *argv[], xc_interface *xch); } main_options[] = { { "help", help_func }, { "cpu-online", hp_cpu_online_func }, { "cpu-offline", hp_cpu_offline_func }, +#if defined(__i386__) || defined(__x86_64__) { "mem-status", hp_mem_query_func}, { "mem-online", hp_mem_online_func}, { "mem-offline", hp_mem_offline_func}, { "smt-enable", main_smt_enable }, { "smt-disable", main_smt_disable }, +#endif }; int main(int argc, char *argv[]) { int i, ret; + xc_interface *xch; if (argc < 2) { @@ -402,7 +139,7 @@ int main(int argc, char *argv[]) return 1; } - ret = main_options[i].function(argc -2, argv + 2); + ret = main_options[i].function(argc -2, argv + 2, xch); xc_interface_close(xch); diff --git a/tools/misc/xen-hptool.h b/tools/misc/xen-hptool.h new file mode 100644 index 0000000000..34f492c34b --- /dev/null +++ b/tools/misc/xen-hptool.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __XEN_HPTOOL_H__ +#define __XEN_HPTOOL_H__ + +#if defined(__i386__) || defined(__x86_64__) +int hp_mem_online_func(int argc, char *argv[], xc_interface *xch); +int hp_mem_query_func(int argc, char *argv[], xc_interface *xch); +int hp_mem_offline_func(int argc, char *argv[], xc_interface *xch); +int main_smt_enable(int argc, char *argv[], xc_interface *xch); +int main_smt_disable(int argc, char *argv[], xc_interface *xch); +#endif + +void show_help(void); + +#endif /* __XEN_HPTOOL_H__ */ -- 2.55.0