|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2 of 2] Lowmemd: Simple demo code to show use of VIRQ_ENOMEM
>>> On 28.02.12 at 22:56, Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx> wrote:
Thanks for contributing this.
> --- a/tools/misc/Makefile
> +++ b/tools/misc/Makefile
> @@ -9,7 +9,7 @@ CFLAGS += $(CFLAGS_xeninclude)
> HDRS = $(wildcard *.h)
>
> TARGETS-y := xenperf xenpm xen-tmem-list-parse gtraceview gtracestat
> xenlockprof xenwatchdogd
> -TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash
> +TARGETS-$(CONFIG_X86) += xen-detect xen-hvmctx xen-hvmcrash lowmemd
If this should get committed (which I'm in favor of at least as a first
step, to get more advanced over time if needed), we would certainly
want to prefix the binary with xen- (since that's what it's for, it's not
dealing with domain side low memory conditions).
Jan
> TARGETS-$(CONFIG_MIGRATE) += xen-hptool
> TARGETS := $(TARGETS-y)
>
> @@ -21,7 +21,7 @@ INSTALL_BIN-y := xencons
> INSTALL_BIN-$(CONFIG_X86) += xen-detect
> INSTALL_BIN := $(INSTALL_BIN-y)
>
> -INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm
> xen-tmem-list-parse gtraceview gtracestat xenlockprof xenwatchdogd
> xen-ringwatch
> +INSTALL_SBIN-y := xm xen-bugtool xen-python-path xend xenperf xsview xenpm
> xen-tmem-list-parse gtraceview gtracestat xenlockprof xenwatchdogd
> xen-ringwatch lowmemd
> INSTALL_SBIN-$(CONFIG_X86) += xen-hvmctx xen-hvmcrash
> INSTALL_SBIN-$(CONFIG_MIGRATE) += xen-hptool
> INSTALL_SBIN := $(INSTALL_SBIN-y)
> @@ -70,6 +70,9 @@ xen-hptool: xen-hptool.o
> xenwatchdogd: xenwatchdogd.o
> $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
>
> +lowmemd: lowmemd.o
> + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore)
> $(APPEND_LDFLAGS)
> +
> gtraceview: gtraceview.o
> $(CC) $(LDFLAGS) -o $@ $< $(CURSES_LIBS) $(APPEND_LDFLAGS)
>
> diff -r c44e9fe0ecca -r 4300b0d76575 tools/misc/lowmemd.c
> --- /dev/null
> +++ b/tools/misc/lowmemd.c
> @@ -0,0 +1,148 @@
> +/*
> + * lowmemd: demo VIRQ_ENOMEM
> + * Andres Lagar-Cavilla (GridCentric Inc.)
> + */
> +
> +#include <stdio.h>
> +#include <xenctrl.h>
> +#include <xs.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +static evtchn_port_t virq_port = -1;
> +static xc_evtchn *xce_handle = NULL;
> +static xc_interface *xch = NULL;
> +static struct xs_handle *xs_handle = NULL;
> +
> +void cleanup(void)
> +{
> + if (virq_port > -1)
> + xc_evtchn_unbind(xce_handle, virq_port);
> + if (xce_handle)
> + xc_evtchn_close(xce_handle);
> + if (xch)
> + xc_interface_close(xch);
> + if (xs_handle)
> + xs_daemon_close(xs_handle);
> +}
> +
> +/* Never shrink dom0 below 1 GiB */
> +#define DOM0_FLOOR (1 << 30)
> +#define DOM0_FLOOR_PG ((DOM0_FLOOR) >> 12)
> +
> +/* Act if free memory is less than 92 MiB */
> +#define THRESHOLD (92 << 20)
> +#define THRESHOLD_PG ((THRESHOLD) >> 12)
> +
> +#define BUFSZ 512
> +void handle_low_mem(void)
> +{
> + xc_dominfo_t dom0_info;
> + xc_physinfo_t info;
> + unsigned long long free_pages, dom0_pages, diff, dom0_target;
> + char data[BUFSZ], error[BUFSZ];
> +
> + if (xc_physinfo(xch, &info) < 0)
> + {
> + perror("Getting physinfo failed");
> + return;
> + }
> +
> + free_pages = (unsigned long long) info.free_pages;
> + printf("Available free pages: 0x%llx:%llux\n",
> + free_pages, free_pages);
> +
> + /* Don't do anything if we have more than the threshold free */
> + if ( free_pages >= THRESHOLD_PG )
> + return;
> + diff = THRESHOLD_PG - free_pages;
> +
> + if (xc_domain_getinfo(xch, 0, 1, &dom0_info) < 1)
> + {
> + perror("Failed to get dom0 info");
> + return;
> + }
> +
> + dom0_pages = (unsigned long long) dom0_info.nr_pages;
> + printf("Dom0 pages: 0x%llx:%llu\n", dom0_pages, dom0_pages);
> + dom0_target = dom0_pages - diff;
> + if (dom0_target <= DOM0_FLOOR_PG)
> + return;
> +
> + printf("Shooting for dom0 target 0x%llx:%llu\n",
> + dom0_target, dom0_target);
> +
> + snprintf(data, BUFSZ, "%llu", dom0_target);
> + if (!xs_write(xs_handle, XBT_NULL,
> + "/local/domain/0/memory/target", data, strlen(data)))
> + {
> + snprintf(error, BUFSZ,"Failed to write target %s to xenstore",
> data);
> + perror(error);
> + }
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + int rc;
> +
> + atexit(cleanup);
> +
> + xch = xc_interface_open(NULL, NULL, 0);
> + if (xch == NULL)
> + {
> + perror("Failed to open xc interface");
> + return 1;
> + }
> +
> + xce_handle = xc_evtchn_open(NULL, 0);
> + if (xce_handle == NULL)
> + {
> + perror("Failed to open evtchn device");
> + return 2;
> + }
> +
> + xs_handle = xs_daemon_open();
> + if (xs_handle == NULL)
> + {
> + perror("Failed to open xenstore connection");
> + return 3;
> + }
> +
> + if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_ENOMEM)) == -1)
> + {
> + perror("Failed to bind to domain exception virq port");
> + return 4;
> + }
> +
> + virq_port = rc;
> +
> + while(1)
> + {
> + evtchn_port_t port;
> +
> + if ((port = xc_evtchn_pending(xce_handle)) == -1)
> + {
> + perror("Failed to listen for pending event channel");
> + return 5;
> + }
> +
> + if (port != virq_port)
> + {
> + char data[BUFSZ];
> + snprintf(data, BUFSZ, "Wrong port, got %d expected %d", port,
> virq_port);
> + perror(data);
> + return 6;
> + }
> +
> + if (xc_evtchn_unmask(xce_handle, port) == -1)
> + {
> + perror("Failed to unmask port");
> + return 7;
> + }
> +
> + printf("Got a virq kick, time to get work\n");
> + handle_low_mem();
> + }
> +
> + return 0;
> +}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |