- fate#310510 - fix xenpaging
This change reverses the task of xenpaging. Before this change a fixed number of pages was paged out. With this change the guest will not have access to more than the given number of pages at the same time. The xenpaging= config option is replaced by actmem= A new xm mem-swap-target is added. The xenpaging binary is moved to /usr/lib/xen/bin/ xenpaging.HVMCOPY_gfn_paged_out.patch xenpaging.XEN_PAGING_DIR.patch xenpaging.add_evict_pages.patch xenpaging.bitmap_clear.patch xenpaging.cmdline-interface.patch xenpaging.encapsulate_domain_info.patch xenpaging.file_op-return-code.patch xenpaging.guest-memusage.patch xenpaging.install-to-libexec.patch xenpaging.low_target_policy_nomru.patch xenpaging.main-loop-exit-handling.patch xenpaging.misleading-comment.patch xenpaging.page_in-munmap-size.patch xenpaging.print-gfn.patch xenpaging.record-numer-paged-out-pages.patch xenpaging.reset-uncomsumed.patch xenpaging.stale-comments.patch xenpaging.target-tot_pages.patch xenpaging.use-PERROR.patch xenpaging.watch-target-tot_pages.patch xenpaging.watch_event-DPRINTF.patch xenpaging.xc_interface_open-comment.patch - xen.spec: update filelist package /usr/lib*/xen with wildcard to pickup new files remove duplicate /usr/sbin/xen-list from filelist OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=157
This commit is contained in:
parent
7505a6b224
commit
ee2be8156e
41
xen.changes
41
xen.changes
@ -1,3 +1,44 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 3 23:50:31 CET 2011 - ohering@suse.de
|
||||
|
||||
- fate#310510 - fix xenpaging
|
||||
This change reverses the task of xenpaging. Before this change a
|
||||
fixed number of pages was paged out. With this change the guest
|
||||
will not have access to more than the given number of pages at
|
||||
the same time.
|
||||
The xenpaging= config option is replaced by actmem=
|
||||
A new xm mem-swap-target is added.
|
||||
The xenpaging binary is moved to /usr/lib/xen/bin/
|
||||
xenpaging.HVMCOPY_gfn_paged_out.patch
|
||||
xenpaging.XEN_PAGING_DIR.patch
|
||||
xenpaging.add_evict_pages.patch
|
||||
xenpaging.bitmap_clear.patch
|
||||
xenpaging.cmdline-interface.patch
|
||||
xenpaging.encapsulate_domain_info.patch
|
||||
xenpaging.file_op-return-code.patch
|
||||
xenpaging.guest-memusage.patch
|
||||
xenpaging.install-to-libexec.patch
|
||||
xenpaging.low_target_policy_nomru.patch
|
||||
xenpaging.main-loop-exit-handling.patch
|
||||
xenpaging.misleading-comment.patch
|
||||
xenpaging.page_in-munmap-size.patch
|
||||
xenpaging.print-gfn.patch
|
||||
xenpaging.record-numer-paged-out-pages.patch
|
||||
xenpaging.reset-uncomsumed.patch
|
||||
xenpaging.stale-comments.patch
|
||||
xenpaging.target-tot_pages.patch
|
||||
xenpaging.use-PERROR.patch
|
||||
xenpaging.watch-target-tot_pages.patch
|
||||
xenpaging.watch_event-DPRINTF.patch
|
||||
xenpaging.xc_interface_open-comment.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 3 23:32:12 CET 2011 - ohering@suse.de
|
||||
|
||||
- xen.spec: update filelist
|
||||
package /usr/lib*/xen with wildcard to pickup new files
|
||||
remove duplicate /usr/sbin/xen-list from filelist
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 26 10:13:04 MDT 2011 - carnold@novell.com
|
||||
|
||||
|
118
xen.spec
118
xen.spec
@ -381,7 +381,29 @@ Patch1010: xen-unstable.xentrace.t_info_first_offset.patch
|
||||
Patch1011: xen-unstable.xentrace.data_size__read_mostly.patch
|
||||
Patch1012: xen-unstable.xentrace.__insert_record-dst-type.patch
|
||||
# FATE 310510
|
||||
Patch1106: xenpaging.autostart.patch
|
||||
Patch1107: xenpaging.stale-comments.patch
|
||||
Patch1108: xenpaging.misleading-comment.patch
|
||||
Patch1109: xenpaging.use-PERROR.patch
|
||||
Patch1110: xenpaging.file_op-return-code.patch
|
||||
Patch1111: xenpaging.print-gfn.patch
|
||||
Patch1112: xenpaging.xc_interface_open-comment.patch
|
||||
Patch1113: xenpaging.encapsulate_domain_info.patch
|
||||
Patch1114: xenpaging.record-numer-paged-out-pages.patch
|
||||
Patch1115: xenpaging.add_evict_pages.patch
|
||||
Patch1116: xenpaging.main-loop-exit-handling.patch
|
||||
Patch1117: xenpaging.bitmap_clear.patch
|
||||
Patch1118: xenpaging.reset-uncomsumed.patch
|
||||
Patch1119: xenpaging.install-to-libexec.patch
|
||||
Patch1120: xenpaging.XEN_PAGING_DIR.patch
|
||||
Patch1121: xenpaging.target-tot_pages.patch
|
||||
Patch1122: xenpaging.watch-target-tot_pages.patch
|
||||
Patch1123: xenpaging.cmdline-interface.patch
|
||||
Patch1125: xenpaging.watch_event-DPRINTF.patch
|
||||
Patch1126: xenpaging.guest-memusage.patch
|
||||
Patch1127: xenpaging.page_in-munmap-size.patch
|
||||
Patch1128: xenpaging.low_target_policy_nomru.patch
|
||||
Patch1129: xenpaging.autostart.patch
|
||||
Patch1130: xenpaging.HVMCOPY_gfn_paged_out.patch
|
||||
# xenalyze
|
||||
Patch20000: xenalyze.gcc46.patch
|
||||
# Build patch
|
||||
@ -394,6 +416,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
%suse_kernel_module_package -n xen um xen -f kmp_filelist
|
||||
%endif
|
||||
|
||||
|
||||
%description
|
||||
Xen is a virtual machine monitor for x86 that supports execution of
|
||||
multiple guest operating systems with unprecedented levels of
|
||||
@ -455,6 +478,7 @@ Group: System/Kernel
|
||||
#Requires: xen = %{version}
|
||||
AutoReqProv: on
|
||||
|
||||
|
||||
%description libs
|
||||
Xen is a virtual machine monitor for x86 that supports execution of
|
||||
multiple guest operating systems with unprecedented levels of
|
||||
@ -500,6 +524,7 @@ Authors:
|
||||
|
||||
%if %{?with_dom0_support}0
|
||||
|
||||
|
||||
%package tools
|
||||
License: GPLv2+
|
||||
Summary: Xen Virtualization: Control tools for domain 0
|
||||
@ -511,6 +536,7 @@ Provides: xen-tools-ioemu = 3.2
|
||||
Obsoletes: xen-tools-ioemu <= 3.2
|
||||
AutoReqProv: on
|
||||
|
||||
|
||||
%description tools
|
||||
Xen is a virtual machine monitor for x86 that supports execution of
|
||||
multiple guest operating systems with unprecedented levels of
|
||||
@ -558,6 +584,7 @@ Authors:
|
||||
Ian Pratt <ian.pratt@cl.cam.ac.uk>
|
||||
%endif
|
||||
|
||||
|
||||
%package tools-domU
|
||||
License: GPLv2+
|
||||
Summary: Xen Virtualization: Control tools for domain U
|
||||
@ -565,6 +592,7 @@ Group: System/Kernel
|
||||
Conflicts: xen-tools
|
||||
AutoReqProv: on
|
||||
|
||||
|
||||
%description tools-domU
|
||||
Xen is a virtual machine monitor for x86 that supports execution of
|
||||
multiple guest operating systems with unprecedented levels of
|
||||
@ -585,6 +613,7 @@ Summary: Xen Virtualization: Headers and libraries for development
|
||||
Group: System/Kernel
|
||||
Requires: xen-libs = %{version}
|
||||
|
||||
|
||||
%description devel
|
||||
Xen is a virtual machine monitor for x86 that supports execution of
|
||||
multiple guest operating systems with unprecedented levels of
|
||||
@ -630,12 +659,14 @@ Authors:
|
||||
|
||||
%if %{?with_kmp}0
|
||||
|
||||
|
||||
%package KMP
|
||||
License: GPLv2+
|
||||
Group: System/Kernel
|
||||
Summary: Xen para-virtual device drivers for fully virtualized guests
|
||||
Conflicts: xen
|
||||
|
||||
|
||||
%description KMP
|
||||
Xen para-virtual device drivers for fully virtualized guests
|
||||
|
||||
@ -681,11 +712,13 @@ Xen, but is not available for release due to license restrictions.
|
||||
|
||||
%if %{?with_dom0_support}0
|
||||
|
||||
|
||||
%package doc-html
|
||||
License: GPLv2+
|
||||
Summary: Xen Virtualization: HTML documentation
|
||||
Group: Documentation/HTML
|
||||
|
||||
|
||||
%description doc-html
|
||||
Xen is a virtual machine monitor for x86 that supports execution of
|
||||
multiple guest operating systems with unprecedented levels of
|
||||
@ -705,6 +738,7 @@ License: GPLv2+
|
||||
Summary: Xen Virtualization: PDF documentation
|
||||
Group: Documentation/Other
|
||||
|
||||
|
||||
%description doc-pdf
|
||||
Xen is a virtual machine monitor for x86 that supports execution of
|
||||
multiple guest operating systems with unprecedented levels of
|
||||
@ -721,6 +755,7 @@ Authors:
|
||||
Ian Pratt <ian.pratt@cl.cam.ac.uk>
|
||||
%endif
|
||||
|
||||
|
||||
%prep
|
||||
%setup -q -n %xen_build_dir -a 1 -a 20000
|
||||
%patch20000 -p1
|
||||
@ -958,11 +993,34 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools
|
||||
%patch1011 -p1
|
||||
%patch1012 -p1
|
||||
# FATE 310510
|
||||
%patch1106 -p1
|
||||
%patch1107 -p1
|
||||
%patch1108 -p1
|
||||
%patch1109 -p1
|
||||
%patch1110 -p1
|
||||
%patch1111 -p1
|
||||
%patch1112 -p1
|
||||
%patch1113 -p1
|
||||
%patch1114 -p1
|
||||
%patch1115 -p1
|
||||
%patch1116 -p1
|
||||
%patch1117 -p1
|
||||
%patch1118 -p1
|
||||
%patch1119 -p1
|
||||
%patch1120 -p1
|
||||
%patch1121 -p1
|
||||
%patch1122 -p1
|
||||
%patch1123 -p1
|
||||
%patch1125 -p1
|
||||
%patch1126 -p1
|
||||
%patch1127 -p1
|
||||
%patch1128 -p1
|
||||
%patch1129 -p1
|
||||
%patch1130 -p1
|
||||
#
|
||||
%patch99998 -p1
|
||||
%patch99999 -p1
|
||||
|
||||
|
||||
%build
|
||||
XEN_EXTRAVERSION=%version-%release
|
||||
XEN_EXTRAVERSION=${XEN_EXTRAVERSION#%{xvers}}
|
||||
@ -998,6 +1056,7 @@ for flavor in %flavors_to_build; do
|
||||
done
|
||||
%endif
|
||||
|
||||
|
||||
%install
|
||||
export CFLAGS="$RPM_OPT_FLAGS"
|
||||
%if %{?with_dom0_support}0
|
||||
@ -1200,6 +1259,7 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons
|
||||
|
||||
%if %{?with_dom0_support}0
|
||||
|
||||
|
||||
%files -f xen.files.txt
|
||||
%defattr(-,root,root)
|
||||
/boot/xen-%{version}-%{release}.gz
|
||||
@ -1216,6 +1276,7 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons
|
||||
/boot/xen.gz
|
||||
%endif
|
||||
|
||||
|
||||
%files libs
|
||||
%defattr(-,root,root)
|
||||
%{_libdir}/fs/
|
||||
@ -1223,6 +1284,7 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons
|
||||
|
||||
%if %{?with_dom0_support}0
|
||||
|
||||
|
||||
%files tools
|
||||
%defattr(-,root,root)
|
||||
/usr/bin/xenalyze
|
||||
@ -1254,24 +1316,14 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons
|
||||
/usr/sbin/td-util
|
||||
/usr/sbin/vhd-update
|
||||
/usr/sbin/vhd-util
|
||||
/usr/sbin/xen-list
|
||||
/usr/sbin/gdbsx
|
||||
/usr/sbin/xl
|
||||
/usr/sbin/kdd
|
||||
/usr/sbin/tap-ctl
|
||||
%dir %{_libdir}/xen
|
||||
%dir %{_libdir}/xen/bin
|
||||
%{_libdir}/xen
|
||||
%ifarch x86_64
|
||||
%dir /usr/lib/xen
|
||||
%dir /usr/lib/xen/bin
|
||||
/usr/lib/xen
|
||||
%endif
|
||||
%dir /usr/lib/xen/boot
|
||||
%{_libdir}/xen/bin/readnotes
|
||||
%{_libdir}/xen/bin/xc_restore
|
||||
%{_libdir}/xen/bin/xc_save
|
||||
%{_libdir}/xen/bin/xenconsole
|
||||
%{_libdir}/xen/bin/xenctx
|
||||
%{_libdir}/xen/bin/lsevtchn
|
||||
%{_mandir}/man1/*.1.gz
|
||||
%{_mandir}/man5/*.5.gz
|
||||
%{_mandir}/man8/*.8.gz
|
||||
@ -1330,45 +1382,20 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons
|
||||
%{_datadir}/xen/qemu/*
|
||||
%{_datadir}/xen/man/man1/*
|
||||
%{_datadir}/xen/man/man8/*
|
||||
%if %{?with_stubdom}0
|
||||
/usr/lib/xen/bin/stubdom-dm
|
||||
/usr/lib/xen/bin/stubdompath.sh
|
||||
%ifarch x86_64
|
||||
%{_libdir}/xen/bin/stubdom-dm
|
||||
%{_libdir}/xen/bin/stubdompath.sh
|
||||
%endif
|
||||
%endif
|
||||
%{_libdir}/xen/bin/qemu-dm
|
||||
%ifarch x86_64
|
||||
/usr/lib/xen/bin/qemu-dm
|
||||
# NEEDS FIXING
|
||||
##/usr/lib64/xen/bin/xc_kexec
|
||||
%else
|
||||
# NEEDS FIXING
|
||||
#/usr/lib/xen/bin/xc_kexec
|
||||
%endif
|
||||
/usr/lib/xen/boot/hvmloader
|
||||
%{_libdir}/python%{pyver}/site-packages/xen/*
|
||||
/usr/lib/xen/boot/domUloader.py
|
||||
%{_libdir}/python%{pyver}/site-packages/grub/*
|
||||
%{_libdir}/python%{pyver}/site-packages/fsimage.so
|
||||
%if %{?with_stubdom}0
|
||||
/usr/lib/xen/boot/ioemu-stubdom.gz
|
||||
%ifarch x86_64
|
||||
/usr/lib/xen/boot/pv-grub-x86_64.gz
|
||||
%else
|
||||
/usr/lib/xen/boot/pv-grub-x86_32.gz
|
||||
%endif
|
||||
%endif
|
||||
%config %{_fwdefdir}/xend-relocation-server
|
||||
%endif
|
||||
|
||||
|
||||
%files tools-domU
|
||||
%defattr(-,root,root)
|
||||
/usr/bin/xen-detect
|
||||
/bin/domu-xenstore
|
||||
/bin/xenstore-*
|
||||
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/serial-split
|
||||
@ -1378,10 +1405,12 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons
|
||||
|
||||
%if %{?with_dom0_support}0
|
||||
|
||||
|
||||
%files doc-html
|
||||
%defattr(-,root,root)
|
||||
%{_defaultdocdir}/xen/html
|
||||
|
||||
|
||||
%files doc-pdf
|
||||
%defattr(-,root,root)
|
||||
%{_defaultdocdir}/xen/pdf
|
||||
@ -1389,6 +1418,7 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons
|
||||
|
||||
%if %{?with_dom0_support}0
|
||||
|
||||
|
||||
%post tools
|
||||
%if %{?with_xend}0
|
||||
# with_xend
|
||||
@ -1434,9 +1464,11 @@ if [ -f /usr/bin/qemu-nbd ]; then
|
||||
ln -s /usr/bin/qemu-nbd /usr/bin/qemu-nbd-xen
|
||||
fi
|
||||
|
||||
|
||||
%preun tools
|
||||
%{stop_on_removal xendomains xend xencommons}
|
||||
|
||||
|
||||
%postun tools
|
||||
%if %{?with_xend}0
|
||||
# with_xend
|
||||
@ -1451,8 +1483,12 @@ if [ -f /usr/bin/qemu-nbd-xen ]; then
|
||||
fi
|
||||
%endif
|
||||
|
||||
|
||||
%post libs -p /sbin/ldconfig
|
||||
|
||||
|
||||
%postun libs -p /sbin/ldconfig
|
||||
|
||||
|
||||
|
||||
%changelog
|
||||
|
151
xenpaging.HVMCOPY_gfn_paged_out.patch
Normal file
151
xenpaging.HVMCOPY_gfn_paged_out.patch
Normal file
@ -0,0 +1,151 @@
|
||||
|
||||
xenpaging: handle HVMCOPY_gfn_paged_out in copy_from/to_user
|
||||
|
||||
copy_from_user_hvm can fail when __hvm_copy returns
|
||||
HVMCOPY_gfn_paged_out for a referenced gfn, for example during guests
|
||||
pagetable walk. This has to be handled in some way.
|
||||
|
||||
For the time being, return -EAGAIN for the most common case (xen_balloon
|
||||
driver crashing in guest) until the recently added waitqueues will be
|
||||
used.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
xen/arch/x86/hvm/hvm.c | 4 ++++
|
||||
xen/common/memory.c | 39 ++++++++++++++++++++++++++++++++++-----
|
||||
2 files changed, 38 insertions(+), 5 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/xen/arch/x86/hvm/hvm.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/xen/arch/x86/hvm/hvm.c
|
||||
+++ xen-4.1.2-testing/xen/arch/x86/hvm/hvm.c
|
||||
@@ -2247,6 +2247,8 @@ unsigned long copy_to_user_hvm(void *to,
|
||||
|
||||
rc = hvm_copy_to_guest_virt_nofault((unsigned long)to, (void *)from,
|
||||
len, 0);
|
||||
+ if ( unlikely(rc == HVMCOPY_gfn_paged_out) )
|
||||
+ return -EAGAIN;
|
||||
return rc ? len : 0; /* fake a copy_to_user() return code */
|
||||
}
|
||||
|
||||
@@ -2264,6 +2266,8 @@ unsigned long copy_from_user_hvm(void *t
|
||||
#endif
|
||||
|
||||
rc = hvm_copy_from_guest_virt_nofault(to, (unsigned long)from, len, 0);
|
||||
+ if ( unlikely(rc == HVMCOPY_gfn_paged_out) )
|
||||
+ return -EAGAIN;
|
||||
return rc ? len : 0; /* fake a copy_from_user() return code */
|
||||
}
|
||||
|
||||
Index: xen-4.1.2-testing/xen/common/memory.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/xen/common/memory.c
|
||||
+++ xen-4.1.2-testing/xen/common/memory.c
|
||||
@@ -48,6 +48,7 @@ static void increase_reservation(struct
|
||||
{
|
||||
struct page_info *page;
|
||||
unsigned long i;
|
||||
+ unsigned long ctg_ret;
|
||||
xen_pfn_t mfn;
|
||||
struct domain *d = a->domain;
|
||||
|
||||
@@ -81,8 +82,13 @@ static void increase_reservation(struct
|
||||
if ( !guest_handle_is_null(a->extent_list) )
|
||||
{
|
||||
mfn = page_to_mfn(page);
|
||||
- if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) )
|
||||
+ ctg_ret = __copy_to_guest_offset(a->extent_list, i, &mfn, 1);
|
||||
+ if ( unlikely(ctg_ret) )
|
||||
+ {
|
||||
+ if ( (long)ctg_ret == -EAGAIN )
|
||||
+ a->preempted = 1;
|
||||
goto out;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +100,7 @@ static void populate_physmap(struct memo
|
||||
{
|
||||
struct page_info *page;
|
||||
unsigned long i, j;
|
||||
+ unsigned long cftg_ret;
|
||||
xen_pfn_t gpfn, mfn;
|
||||
struct domain *d = a->domain;
|
||||
|
||||
@@ -112,8 +119,13 @@ static void populate_physmap(struct memo
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if ( unlikely(__copy_from_guest_offset(&gpfn, a->extent_list, i, 1)) )
|
||||
+ cftg_ret = __copy_from_guest_offset(&gpfn, a->extent_list, i, 1);
|
||||
+ if ( unlikely(cftg_ret) )
|
||||
+ {
|
||||
+ if ( (long)cftg_ret == -EAGAIN )
|
||||
+ a->preempted = 1;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
if ( a->memflags & MEMF_populate_on_demand )
|
||||
{
|
||||
@@ -143,8 +155,13 @@ static void populate_physmap(struct memo
|
||||
set_gpfn_from_mfn(mfn + j, gpfn + j);
|
||||
|
||||
/* Inform the domain of the new page's machine address. */
|
||||
- if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) )
|
||||
+ cftg_ret = __copy_to_guest_offset(a->extent_list, i, &mfn, 1);
|
||||
+ if ( unlikely(cftg_ret) )
|
||||
+ {
|
||||
+ if ( (long)cftg_ret == -EAGAIN )
|
||||
+ a->preempted = 1;
|
||||
goto out;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,6 +230,7 @@ int guest_remove_page(struct domain *d,
|
||||
static void decrease_reservation(struct memop_args *a)
|
||||
{
|
||||
unsigned long i, j;
|
||||
+ unsigned long cfg_ret;
|
||||
xen_pfn_t gmfn;
|
||||
|
||||
if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done,
|
||||
@@ -227,8 +245,13 @@ static void decrease_reservation(struct
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if ( unlikely(__copy_from_guest_offset(&gmfn, a->extent_list, i, 1)) )
|
||||
+ cfg_ret = __copy_from_guest_offset(&gmfn, a->extent_list, i, 1);
|
||||
+ if ( unlikely(cfg_ret) )
|
||||
+ {
|
||||
+ if ( (long)cfg_ret == -EAGAIN )
|
||||
+ a->preempted = 1;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
if ( tb_init_done )
|
||||
{
|
||||
@@ -509,6 +532,7 @@ long do_memory_op(unsigned long cmd, XEN
|
||||
int rc, op;
|
||||
unsigned int address_bits;
|
||||
unsigned long start_extent;
|
||||
+ unsigned long cfg_ret;
|
||||
struct xen_memory_reservation reservation;
|
||||
struct memop_args args;
|
||||
domid_t domid;
|
||||
@@ -522,8 +546,13 @@ long do_memory_op(unsigned long cmd, XEN
|
||||
case XENMEM_populate_physmap:
|
||||
start_extent = cmd >> MEMOP_EXTENT_SHIFT;
|
||||
|
||||
- if ( copy_from_guest(&reservation, arg, 1) )
|
||||
+ cfg_ret = copy_from_guest(&reservation, arg, 1);
|
||||
+ if ( unlikely(cfg_ret) )
|
||||
+ {
|
||||
+ if ( (long)cfg_ret == -EAGAIN )
|
||||
+ return hypercall_create_continuation(__HYPERVISOR_memory_op, "lh", cmd, arg);
|
||||
return start_extent;
|
||||
+ }
|
||||
|
||||
/* Is size too large for us to encode a continuation? */
|
||||
if ( reservation.nr_extents > (ULONG_MAX >> MEMOP_EXTENT_SHIFT) )
|
51
xenpaging.XEN_PAGING_DIR.patch
Normal file
51
xenpaging.XEN_PAGING_DIR.patch
Normal file
@ -0,0 +1,51 @@
|
||||
xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path()
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
Config.mk | 1 +
|
||||
config/StdGNU.mk | 2 ++
|
||||
tools/xenpaging/Makefile | 2 +-
|
||||
3 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: xen-4.1.2-testing/Config.mk
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/Config.mk
|
||||
+++ xen-4.1.2-testing/Config.mk
|
||||
@@ -124,6 +124,7 @@ define buildmakevars2file-closure
|
||||
echo "XEN_CONFIG_DIR=\"$(XEN_CONFIG_DIR)\"" >> $(1).tmp; \
|
||||
echo "XEN_SCRIPT_DIR=\"$(XEN_SCRIPT_DIR)\"" >> $(1).tmp; \
|
||||
echo "XEN_LOCK_DIR=\"$(XEN_LOCK_DIR)\"" >> $(1).tmp; \
|
||||
+ echo "XEN_PAGING_DIR=\"$(XEN_PAGING_DIR)\"" >> $(1).tmp; \
|
||||
if ! cmp $(1).tmp $(1); then mv -f $(1).tmp $(1); fi
|
||||
endef
|
||||
|
||||
Index: xen-4.1.2-testing/config/StdGNU.mk
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/config/StdGNU.mk
|
||||
+++ xen-4.1.2-testing/config/StdGNU.mk
|
||||
@@ -46,9 +46,11 @@ PRIVATE_BINDIR = $(PRIVATE_PREFIX)/bin
|
||||
ifeq ($(PREFIX),/usr)
|
||||
CONFIG_DIR = /etc
|
||||
XEN_LOCK_DIR = /var/lock
|
||||
+XEN_PAGING_DIR = /var/lib/xen/xenpaging
|
||||
else
|
||||
CONFIG_DIR = $(PREFIX)/etc
|
||||
XEN_LOCK_DIR = $(PREFIX)/var/lock
|
||||
+XEN_PAGING_DIR = $(PREFIX)/var/lib/xen/xenpaging
|
||||
endif
|
||||
|
||||
SYSCONFIG_DIR = $(CONFIG_DIR)/$(CONFIG_LEAF_DIR)
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/Makefile
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/Makefile
|
||||
@@ -28,7 +28,7 @@ xenpaging: $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
|
||||
install: all
|
||||
- $(INSTALL_DIR) $(DESTDIR)/var/lib/xen/xenpaging
|
||||
+ $(INSTALL_DIR) $(DESTDIR)$(XEN_PAGING_DIR)
|
||||
$(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)
|
||||
$(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC)
|
||||
|
165
xenpaging.add_evict_pages.patch
Normal file
165
xenpaging.add_evict_pages.patch
Normal file
@ -0,0 +1,165 @@
|
||||
xenpaging: move page add/resume loops into its own function.
|
||||
|
||||
Move page resume loop into its own function.
|
||||
Move page eviction loop into its own function.
|
||||
Allocate all possible slots in a paging file to allow growing and
|
||||
shrinking of the number of paged-out pages. Adjust other places to
|
||||
iterate over all slots.
|
||||
|
||||
This change is required by subsequent patches.
|
||||
|
||||
v2:
|
||||
- check if victims allocation succeeded
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 94 ++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 61 insertions(+), 33 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -553,6 +553,27 @@ static int xenpaging_populate_page(xenpa
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* Trigger a page-in for a batch of pages */
|
||||
+static void resume_pages(xenpaging_t *paging, int num_pages)
|
||||
+{
|
||||
+ xc_interface *xch = paging->xc_handle;
|
||||
+ int i, num = 0;
|
||||
+
|
||||
+ for ( i = 0; i < paging->max_pages && num < num_pages; i++ )
|
||||
+ {
|
||||
+ if ( test_bit(i, paging->bitmap) )
|
||||
+ {
|
||||
+ paging->pagein_queue[num] = i;
|
||||
+ num++;
|
||||
+ if ( num == XENPAGING_PAGEIN_QUEUE_SIZE )
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ /* num may be less than num_pages, caller has to try again */
|
||||
+ if ( num )
|
||||
+ page_in_trigger();
|
||||
+}
|
||||
+
|
||||
static int evict_victim(xenpaging_t *paging,
|
||||
xenpaging_victim_t *victim, int fd, int i)
|
||||
{
|
||||
@@ -596,6 +617,30 @@ static int evict_victim(xenpaging_t *pag
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* Evict a batch of pages and write them to a free slot in the paging file */
|
||||
+static int evict_pages(xenpaging_t *paging, int fd, xenpaging_victim_t *victims, int num_pages)
|
||||
+{
|
||||
+ xc_interface *xch = paging->xc_handle;
|
||||
+ int rc, slot, num = 0;
|
||||
+
|
||||
+ for ( slot = 0; slot < paging->max_pages && num < num_pages; slot++ )
|
||||
+ {
|
||||
+ /* Slot is allocated */
|
||||
+ if ( victims[slot].gfn != INVALID_MFN )
|
||||
+ continue;
|
||||
+
|
||||
+ rc = evict_victim(paging, &victims[slot], fd, slot);
|
||||
+ if ( rc == -ENOSPC )
|
||||
+ break;
|
||||
+ if ( rc == -EINTR )
|
||||
+ break;
|
||||
+ if ( num && num % 100 == 0 )
|
||||
+ DPRINTF("%d pages evicted\n", num);
|
||||
+ num++;
|
||||
+ }
|
||||
+ return num;
|
||||
+}
|
||||
+
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sigaction act;
|
||||
@@ -638,7 +683,14 @@ int main(int argc, char *argv[])
|
||||
return 2;
|
||||
}
|
||||
|
||||
- victims = calloc(paging->num_pages, sizeof(xenpaging_victim_t));
|
||||
+ /* Allocate upper limit of pages to allow growing and shrinking */
|
||||
+ victims = calloc(paging->max_pages, sizeof(xenpaging_victim_t));
|
||||
+ if ( !victims )
|
||||
+ goto out;
|
||||
+
|
||||
+ /* Mark all slots as unallocated */
|
||||
+ for ( i = 0; i < paging->max_pages; i++ )
|
||||
+ victims[i].gfn = INVALID_MFN;
|
||||
|
||||
/* ensure that if we get a signal, we'll do cleanup, then exit */
|
||||
act.sa_handler = close_handler;
|
||||
@@ -652,18 +704,7 @@ int main(int argc, char *argv[])
|
||||
/* listen for page-in events to stop pager */
|
||||
create_page_in_thread(paging);
|
||||
|
||||
- /* Evict pages */
|
||||
- for ( i = 0; i < paging->num_pages; i++ )
|
||||
- {
|
||||
- rc = evict_victim(paging, &victims[i], fd, i);
|
||||
- if ( rc == -ENOSPC )
|
||||
- break;
|
||||
- if ( rc == -EINTR )
|
||||
- break;
|
||||
- if ( i % 100 == 0 )
|
||||
- DPRINTF("%d pages evicted\n", i);
|
||||
- }
|
||||
-
|
||||
+ i = evict_pages(paging, fd, victims, paging->num_pages);
|
||||
DPRINTF("%d pages evicted. Done.\n", i);
|
||||
|
||||
/* Swap pages in and out */
|
||||
@@ -689,13 +730,13 @@ int main(int argc, char *argv[])
|
||||
if ( test_and_clear_bit(req.gfn, paging->bitmap) )
|
||||
{
|
||||
/* Find where in the paging file to read from */
|
||||
- for ( i = 0; i < paging->num_pages; i++ )
|
||||
+ for ( i = 0; i < paging->max_pages; i++ )
|
||||
{
|
||||
if ( victims[i].gfn == req.gfn )
|
||||
break;
|
||||
}
|
||||
|
||||
- if ( i >= paging->num_pages )
|
||||
+ if ( i >= paging->max_pages )
|
||||
{
|
||||
DPRINTF("Couldn't find page %"PRIx64"\n", req.gfn);
|
||||
goto out;
|
||||
@@ -767,25 +808,12 @@ int main(int argc, char *argv[])
|
||||
/* Write all pages back into the guest */
|
||||
if ( interrupted == SIGTERM || interrupted == SIGINT )
|
||||
{
|
||||
- int num = 0;
|
||||
- for ( i = 0; i < paging->max_pages; i++ )
|
||||
- {
|
||||
- if ( test_bit(i, paging->bitmap) )
|
||||
- {
|
||||
- paging->pagein_queue[num] = i;
|
||||
- num++;
|
||||
- if ( num == XENPAGING_PAGEIN_QUEUE_SIZE )
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- /*
|
||||
- * One more round if there are still pages to process.
|
||||
- * If no more pages to process, exit loop.
|
||||
- */
|
||||
- if ( num )
|
||||
- page_in_trigger();
|
||||
- else if ( i == paging->max_pages )
|
||||
+ /* If no more pages to process, exit loop. */
|
||||
+ if ( !paging->num_paged_out )
|
||||
break;
|
||||
+
|
||||
+ /* One more round if there are still pages to process. */
|
||||
+ resume_pages(paging, paging->num_paged_out);
|
||||
}
|
||||
else
|
||||
{
|
@ -1,4 +1,7 @@
|
||||
xenpaging: start xenpaging via config option
|
||||
# HG changeset patch
|
||||
# Parent 659ee31faec91ac543578db7c9b2849fb7367419
|
||||
|
||||
xenpaging: xend: start xenpaging via config option
|
||||
|
||||
Start xenpaging via config option.
|
||||
|
||||
@ -8,10 +11,14 @@ TODO: parse config values like 42K, 42M, 42G, 42%
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
v5:
|
||||
use actmem=, xenpaging_file=, xenpaging_extra=
|
||||
add xm mem-swap-target
|
||||
|
||||
v4:
|
||||
add config option for pagefile directory
|
||||
add config option to enable debug
|
||||
add config option to set polic mru_size
|
||||
add config option to set policy mru_size
|
||||
fail if chdir fails
|
||||
force self.xenpaging* variables to be strings because a xm new may turn some
|
||||
of them into type int and later os.execve fails with a TypeError
|
||||
@ -26,35 +33,34 @@ v2:
|
||||
allows hardlinking for further inspection
|
||||
|
||||
---
|
||||
tools/examples/xmexample.hvm | 12 ++++
|
||||
tools/python/README.XendConfig | 4 +
|
||||
tools/python/README.sxpcfg | 4 +
|
||||
tools/python/xen/xend/XendConfig.py | 12 ++++
|
||||
tools/python/xen/xend/XendDomainInfo.py | 12 ++++
|
||||
tools/python/xen/xend/image.py | 87 ++++++++++++++++++++++++++++++++
|
||||
tools/python/xen/xm/create.py | 20 +++++++
|
||||
tools/python/xen/xm/xenapi_create.py | 4 +
|
||||
8 files changed, 155 insertions(+)
|
||||
tools/examples/xmexample.hvm | 9 +++
|
||||
tools/python/README.XendConfig | 3 +
|
||||
tools/python/README.sxpcfg | 3 +
|
||||
tools/python/xen/xend/XendConfig.py | 9 +++
|
||||
tools/python/xen/xend/XendDomain.py | 15 +++++
|
||||
tools/python/xen/xend/XendDomainInfo.py | 22 ++++++++
|
||||
tools/python/xen/xend/image.py | 85 ++++++++++++++++++++++++++++++++
|
||||
tools/python/xen/xm/create.py | 15 +++++
|
||||
tools/python/xen/xm/main.py | 14 +++++
|
||||
tools/python/xen/xm/xenapi_create.py | 3 +
|
||||
10 files changed, 178 insertions(+)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/examples/xmexample.hvm
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/examples/xmexample.hvm
|
||||
+++ xen-4.1.2-testing/tools/examples/xmexample.hvm
|
||||
@@ -127,6 +127,18 @@ disk = [ 'file:/var/lib/xen/images/disk.
|
||||
@@ -127,6 +127,15 @@ disk = [ 'file:/var/lib/xen/images/disk.
|
||||
# Device Model to be used
|
||||
device_model = 'qemu-dm'
|
||||
|
||||
+# number of guest pages to page-out, or -1 for entire guest memory range
|
||||
+xenpaging=42
|
||||
+# the amount of memory in MiB for the guest
|
||||
+#actmem=42
|
||||
+
|
||||
+# directory to store guest page file
|
||||
+#xenpaging_workdir="/var/lib/xen/xenpaging"
|
||||
+# Optional: guest page file
|
||||
+#xenpaging_file="/var/lib/xen/xenpaging/<domain_name>.<domaind_id>.paging"
|
||||
+
|
||||
+# enable debug output in pager
|
||||
+#xenpaging_debug=0
|
||||
+
|
||||
+# number of paged-in pages to keep in memory
|
||||
+#xenpaging_policy_mru_size=1024
|
||||
+# Optional: extra cmdline options for xenpaging
|
||||
+#xenpaging_extra=[ 'string', 'string' ]
|
||||
+
|
||||
#-----------------------------------------------------------------------------
|
||||
# boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d)
|
||||
@ -63,14 +69,13 @@ Index: xen-4.1.2-testing/tools/python/README.XendConfig
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/README.XendConfig
|
||||
+++ xen-4.1.2-testing/tools/python/README.XendConfig
|
||||
@@ -120,6 +120,10 @@ otherConfig
|
||||
@@ -120,6 +120,9 @@ otherConfig
|
||||
image.vncdisplay
|
||||
image.vncunused
|
||||
image.hvm.device_model
|
||||
+ image.hvm.xenpaging
|
||||
+ image.hvm.xenpaging_workdir
|
||||
+ image.hvm.xenpaging_debug
|
||||
+ image.hvm.xenpaging_policy_mru_size
|
||||
+ image.hvm.actmem
|
||||
+ image.hvm.xenpaging_file
|
||||
+ image.hvm.xenpaging_extra
|
||||
image.hvm.display
|
||||
image.hvm.xauthority
|
||||
image.hvm.vncconsole
|
||||
@ -78,14 +83,13 @@ Index: xen-4.1.2-testing/tools/python/README.sxpcfg
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/README.sxpcfg
|
||||
+++ xen-4.1.2-testing/tools/python/README.sxpcfg
|
||||
@@ -51,6 +51,10 @@ image
|
||||
@@ -51,6 +51,9 @@ image
|
||||
- vncunused
|
||||
(HVM)
|
||||
- device_model
|
||||
+ - xenpaging
|
||||
+ - xenpaging_workdir
|
||||
+ - xenpaging_debug
|
||||
+ - xenpaging_policy_mru_size
|
||||
+ - actmem
|
||||
+ - xenpaging_file
|
||||
+ - xenpaging_extra
|
||||
- display
|
||||
- xauthority
|
||||
- vncconsole
|
||||
@ -93,37 +97,77 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendConfig.py
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/xen/xend/XendConfig.py
|
||||
+++ xen-4.1.2-testing/tools/python/xen/xend/XendConfig.py
|
||||
@@ -147,6 +147,10 @@ XENAPI_PLATFORM_CFG_TYPES = {
|
||||
@@ -147,6 +147,9 @@ XENAPI_PLATFORM_CFG_TYPES = {
|
||||
'apic': int,
|
||||
'boot': str,
|
||||
'device_model': str,
|
||||
+ 'xenpaging': str,
|
||||
+ 'xenpaging_workdir': str,
|
||||
+ 'xenpaging_debug': str,
|
||||
+ 'xenpaging_policy_mru_size': str,
|
||||
+ 'actmem': str,
|
||||
+ 'xenpaging_file': str,
|
||||
+ 'xenpaging_extra': str,
|
||||
'loader': str,
|
||||
'display' : str,
|
||||
'fda': str,
|
||||
@@ -516,6 +520,14 @@ class XendConfig(dict):
|
||||
@@ -516,6 +519,12 @@ class XendConfig(dict):
|
||||
self['platform']['nomigrate'] = 0
|
||||
|
||||
if self.is_hvm():
|
||||
+ if 'xenpaging' not in self['platform']:
|
||||
+ self['platform']['xenpaging'] = "0"
|
||||
+ if 'xenpaging_workdir' not in self['platform']:
|
||||
+ self['platform']['xenpaging_workdir'] = "/var/lib/xen/xenpaging"
|
||||
+ if 'xenpaging_debug' not in self['platform']:
|
||||
+ self['platform']['xenpaging_debug'] = "0"
|
||||
+ if 'xenpaging_policy_mru_size' not in self['platform']:
|
||||
+ self['platform']['xenpaging_policy_mru_size'] = "0"
|
||||
+ if 'actmem' not in self['platform']:
|
||||
+ self['platform']['actmem'] = "0"
|
||||
+ if 'xenpaging_file' not in self['platform']:
|
||||
+ self['platform']['xenpaging_file'] = ""
|
||||
+ if 'xenpaging_extra' not in self['platform']:
|
||||
+ self['platform']['xenpaging_extra'] = []
|
||||
if 'timer_mode' not in self['platform']:
|
||||
self['platform']['timer_mode'] = 1
|
||||
if 'extid' in self['platform'] and int(self['platform']['extid']) == 1:
|
||||
Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomain.py
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/xen/xend/XendDomain.py
|
||||
+++ xen-4.1.2-testing/tools/python/xen/xend/XendDomain.py
|
||||
@@ -2022,6 +2022,21 @@ class XendDomain:
|
||||
log.exception(ex)
|
||||
raise XendError(str(ex))
|
||||
|
||||
+ def domain_swaptarget_set(self, domid, mem):
|
||||
+ """Set the memory limit for a domain.
|
||||
+
|
||||
+ @param domid: Domain ID or Name
|
||||
+ @type domid: int or string.
|
||||
+ @param mem: memory limit (in MiB)
|
||||
+ @type mem: int
|
||||
+ @raise XendError: fail to set memory
|
||||
+ @rtype: 0
|
||||
+ """
|
||||
+ dominfo = self.domain_lookup_nr(domid)
|
||||
+ if not dominfo:
|
||||
+ raise XendInvalidDomain(str(domid))
|
||||
+ dominfo.setSwapTarget(mem)
|
||||
+
|
||||
def domain_maxmem_set(self, domid, mem):
|
||||
"""Set the memory limit for a domain.
|
||||
|
||||
Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py
|
||||
+++ xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
@@ -2291,6 +2291,8 @@ class XendDomainInfo:
|
||||
@@ -1503,6 +1503,16 @@ class XendDomainInfo:
|
||||
break
|
||||
xen.xend.XendDomain.instance().managed_config_save(self)
|
||||
|
||||
+ def setSwapTarget(self, target):
|
||||
+ """Set the swap target of this domain.
|
||||
+ @param target: In MiB.
|
||||
+ """
|
||||
+ log.debug("Setting swap target of domain %s (%s) to %d MiB.",
|
||||
+ self.info['name_label'], str(self.domid), target)
|
||||
+
|
||||
+ if self.domid > 0:
|
||||
+ self.storeDom("memory/target-tot_pages", target * 1024)
|
||||
+
|
||||
def setMemoryTarget(self, target):
|
||||
"""Set the memory target of this domain.
|
||||
@param target: In MiB.
|
||||
@@ -2291,6 +2301,8 @@ class XendDomainInfo:
|
||||
self.info['name_label'], self.domid, self.info['uuid'],
|
||||
new_name, new_uuid)
|
||||
self._unwatchVm()
|
||||
@ -132,7 +176,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
self._releaseDevices()
|
||||
# Remove existing vm node in xenstore
|
||||
self._removeVm()
|
||||
@@ -2965,6 +2967,9 @@ class XendDomainInfo:
|
||||
@@ -2965,6 +2977,9 @@ class XendDomainInfo:
|
||||
|
||||
self._createDevices()
|
||||
|
||||
@ -142,7 +186,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
self.image.cleanupTmpImages()
|
||||
|
||||
self.info['start_time'] = time.time()
|
||||
@@ -2989,6 +2994,8 @@ class XendDomainInfo:
|
||||
@@ -2989,6 +3004,8 @@ class XendDomainInfo:
|
||||
self.refresh_shutdown_lock.acquire()
|
||||
try:
|
||||
self.unwatchShutdown()
|
||||
@ -151,7 +195,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
self._releaseDevices()
|
||||
bootloader_tidy(self)
|
||||
|
||||
@@ -3073,6 +3080,7 @@ class XendDomainInfo:
|
||||
@@ -3073,6 +3090,7 @@ class XendDomainInfo:
|
||||
self.image = image.create(self, self.info)
|
||||
if self.image:
|
||||
self._createDevices(True)
|
||||
@ -159,7 +203,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
self.console_port = console_port
|
||||
self._storeDomDetails()
|
||||
self._registerWatches()
|
||||
@@ -3214,6 +3222,8 @@ class XendDomainInfo:
|
||||
@@ -3214,6 +3232,8 @@ class XendDomainInfo:
|
||||
# could also fetch a parsed note from xenstore
|
||||
fast = self.info.get_notes().get('SUSPEND_CANCEL') and 1 or 0
|
||||
if not fast:
|
||||
@ -168,7 +212,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
self._releaseDevices()
|
||||
self.testDeviceComplete()
|
||||
self.testvifsComplete()
|
||||
@@ -3229,6 +3239,8 @@ class XendDomainInfo:
|
||||
@@ -3229,6 +3249,8 @@ class XendDomainInfo:
|
||||
self._storeDomDetails()
|
||||
|
||||
self._createDevices()
|
||||
@ -181,38 +225,34 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/image.py
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-4.1.2-testing/tools/python/xen/xend/image.py
|
||||
@@ -122,6 +122,11 @@ class ImageHandler:
|
||||
@@ -122,6 +122,10 @@ class ImageHandler:
|
||||
self.vm.permissionsVm("image/cmdline", { 'dom': self.vm.getDomid(), 'read': True } )
|
||||
|
||||
self.device_model = vmConfig['platform'].get('device_model')
|
||||
+ self.xenpaging = str(vmConfig['platform'].get('xenpaging'))
|
||||
+ self.xenpaging_workdir = str(vmConfig['platform'].get('xenpaging_workdir'))
|
||||
+ self.xenpaging_debug = str(vmConfig['platform'].get('xenpaging_debug'))
|
||||
+ self.xenpaging_policy_mru_size = str(vmConfig['platform'].get('xenpaging_policy_mru_size'))
|
||||
+ self.actmem = str(vmConfig['platform'].get('actmem'))
|
||||
+ self.xenpaging_file = str(vmConfig['platform'].get('xenpaging_file'))
|
||||
+ self.xenpaging_extra = vmConfig['platform'].get('xenpaging_extra')
|
||||
+ self.xenpaging_pid = None
|
||||
|
||||
self.display = vmConfig['platform'].get('display')
|
||||
self.xauthority = vmConfig['platform'].get('xauthority')
|
||||
@@ -392,6 +397,88 @@ class ImageHandler:
|
||||
@@ -392,6 +396,87 @@ class ImageHandler:
|
||||
sentinel_fifos_inuse[sentinel_path_fifo] = 1
|
||||
self.sentinel_path_fifo = sentinel_path_fifo
|
||||
|
||||
+ def createXenPaging(self):
|
||||
+ if not self.vm.info.is_hvm():
|
||||
+ return
|
||||
+ if self.xenpaging == "0":
|
||||
+ if self.actmem == "0":
|
||||
+ return
|
||||
+ if self.xenpaging_pid:
|
||||
+ return
|
||||
+ xenpaging_bin = auxbin.pathTo("xenpaging")
|
||||
+ args = [xenpaging_bin]
|
||||
+ args = args + ([ "%d" % self.vm.getDomid()])
|
||||
+ args = args + ([ "%s" % self.xenpaging])
|
||||
+ env = dict(os.environ)
|
||||
+ if not self.xenpaging_debug == "0":
|
||||
+ env['XENPAGING_DEBUG'] = self.xenpaging_debug
|
||||
+ if not self.xenpaging_policy_mru_size == "0":
|
||||
+ env['XENPAGING_POLICY_MRU_SIZE'] = self.xenpaging_policy_mru_size
|
||||
+ args = args + ([ "-f", "/var/lib/xen/xenpaging/%s.%d.paging" % (str(self.vm.info['name_label']), self.vm.getDomid())])
|
||||
+ if self.xenpaging_extra:
|
||||
+ args = args + (self.xenpaging_extra)
|
||||
+ args = args + ([ "-d", "%d" % self.vm.getDomid()])
|
||||
+ self.xenpaging_logfile = "/var/log/xen/xenpaging-%s.log" % str(self.vm.info['name_label'])
|
||||
+ logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND|os.O_TRUNC
|
||||
+ null = os.open("/dev/null", os.O_RDONLY)
|
||||
@ -230,24 +270,26 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/image.py
|
||||
+ os.dup2(null, 0)
|
||||
+ os.dup2(logfd, 1)
|
||||
+ os.dup2(logfd, 2)
|
||||
+ os.chdir(self.xenpaging_workdir)
|
||||
+ try:
|
||||
+ env = dict(os.environ)
|
||||
+ log.info("starting %s" % args)
|
||||
+ os.execve(xenpaging_bin, args, env)
|
||||
+ except Exception, e:
|
||||
+ log.warn('failed to execute xenpaging: %s' % utils.exception_string(e))
|
||||
+ os._exit(126)
|
||||
+ except:
|
||||
+ log.warn("starting xenpaging in %s failed" % self.xenpaging_workdir)
|
||||
+ log.warn("starting xenpaging failed")
|
||||
+ os._exit(127)
|
||||
+ else:
|
||||
+ osdep.postfork(contract, abandon=True)
|
||||
+ self.xenpaging_pid = xenpaging_pid
|
||||
+ os.close(null)
|
||||
+ os.close(logfd)
|
||||
+ self.vm.storeDom("xenpaging/xenpaging-pid", self.xenpaging_pid)
|
||||
+ self.vm.storeDom("memory/target-tot_pages", int(self.actmem) * 1024)
|
||||
+
|
||||
+ def destroyXenPaging(self):
|
||||
+ if self.xenpaging == "0":
|
||||
+ if self.actmem == "0":
|
||||
+ return
|
||||
+ if self.xenpaging_pid:
|
||||
+ try:
|
||||
@ -286,52 +328,85 @@ Index: xen-4.1.2-testing/tools/python/xen/xm/create.py
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/xen/xm/create.py
|
||||
+++ xen-4.1.2-testing/tools/python/xen/xm/create.py
|
||||
@@ -495,6 +495,22 @@ gopts.var('nfs_root', val="PATH",
|
||||
@@ -495,6 +495,18 @@ gopts.var('nfs_root', val="PATH",
|
||||
fn=set_value, default=None,
|
||||
use="Set the path of the root NFS directory.")
|
||||
|
||||
+gopts.var('xenpaging', val='NUM',
|
||||
+gopts.var('actmem', val='NUM',
|
||||
+ fn=set_value, default='0',
|
||||
+ use="Number of pages to swap.")
|
||||
+
|
||||
+gopts.var('xenpaging_workdir', val='PATH',
|
||||
+ fn=set_value, default='/var/lib/xen/xenpaging',
|
||||
+ use="Number of pages to swap.")
|
||||
+gopts.var('xenpaging_file', val='PATH',
|
||||
+ fn=set_value, default=None,
|
||||
+ use="pagefile to use (optional)")
|
||||
+
|
||||
+gopts.var('xenpaging_debug', val='NUM',
|
||||
+ fn=set_value, default='0',
|
||||
+ use="Number of pages to swap.")
|
||||
+
|
||||
+gopts.var('xenpaging_policy_mru_size', val='NUM',
|
||||
+ fn=set_value, default='0',
|
||||
+ use="Number of pages to swap.")
|
||||
+gopts.var('xenpaging_extra', val='string1,string2',
|
||||
+ fn=append_value, default=[],
|
||||
+ use="additional args for xenpaging (optional)")
|
||||
+
|
||||
gopts.var('device_model', val='FILE',
|
||||
fn=set_value, default=None,
|
||||
use="Path to device model program.")
|
||||
@@ -1095,6 +1111,10 @@ def configure_hvm(config_image, vals):
|
||||
@@ -1095,6 +1107,9 @@ def configure_hvm(config_image, vals):
|
||||
args = [ 'acpi', 'apic',
|
||||
'boot',
|
||||
'cpuid', 'cpuid_check',
|
||||
+ 'xenpaging',
|
||||
+ 'xenpaging_workdir',
|
||||
+ 'xenpaging_debug',
|
||||
+ 'xenpaging_policy_mru_size',
|
||||
+ 'actmem',
|
||||
+ 'xenpaging_file',
|
||||
+ 'xenpaging_extra',
|
||||
'device_model', 'display',
|
||||
'fda', 'fdb',
|
||||
'gfx_passthru', 'guest_os_type',
|
||||
Index: xen-4.1.2-testing/tools/python/xen/xm/main.py
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/xen/xm/main.py
|
||||
+++ xen-4.1.2-testing/tools/python/xen/xm/main.py
|
||||
@@ -115,6 +115,8 @@ SUBCOMMAND_HELP = {
|
||||
'Set the maximum amount reservation for a domain.'),
|
||||
'mem-set' : ('<Domain> <Mem>',
|
||||
'Set the current memory usage for a domain.'),
|
||||
+ 'mem-swap-target' : ('<Domain> <Mem>',
|
||||
+ 'Set the memory usage for a domain.'),
|
||||
'migrate' : ('<Domain> <Host>',
|
||||
'Migrate a domain to another machine.'),
|
||||
'pause' : ('<Domain>', 'Pause execution of a domain.'),
|
||||
@@ -1667,6 +1669,17 @@ def xm_mem_set(args):
|
||||
mem_target = int_unit(args[1], 'm')
|
||||
server.xend.domain.setMemoryTarget(dom, mem_target)
|
||||
|
||||
+def xm_mem_swap_target(args):
|
||||
+ arg_check(args, "mem-swap-target", 2)
|
||||
+
|
||||
+ dom = args[0]
|
||||
+
|
||||
+ if serverType == SERVER_XEN_API:
|
||||
+ err("xenapi not supported")
|
||||
+ else:
|
||||
+ swap_target = int_unit(args[1], 'm')
|
||||
+ server.xend.domain.swaptarget_set(dom, swap_target)
|
||||
+
|
||||
def xm_usb_add(args):
|
||||
arg_check(args, "usb-add", 2)
|
||||
server.xend.domain.usb_add(args[0],args[1])
|
||||
@@ -3926,6 +3939,7 @@ commands = {
|
||||
# memory commands
|
||||
"mem-max": xm_mem_max,
|
||||
"mem-set": xm_mem_set,
|
||||
+ "mem-swap-target": xm_mem_swap_target,
|
||||
# cpu commands
|
||||
"vcpu-pin": xm_vcpu_pin,
|
||||
"vcpu-list": xm_vcpu_list,
|
||||
Index: xen-4.1.2-testing/tools/python/xen/xm/xenapi_create.py
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/python/xen/xm/xenapi_create.py
|
||||
+++ xen-4.1.2-testing/tools/python/xen/xm/xenapi_create.py
|
||||
@@ -1085,6 +1085,10 @@ class sxp2xml:
|
||||
@@ -1085,6 +1085,9 @@ class sxp2xml:
|
||||
'acpi',
|
||||
'apic',
|
||||
'boot',
|
||||
+ 'xenpaging',
|
||||
+ 'xenpaging_workdir',
|
||||
+ 'xenpaging_debug',
|
||||
+ 'xenpaging_policy_mru_size',
|
||||
+ 'actmem',
|
||||
+ 'xenpaging_file',
|
||||
+ 'xenpaging_extra',
|
||||
'device_model',
|
||||
'loader',
|
||||
'fda',
|
||||
|
34
xenpaging.bitmap_clear.patch
Normal file
34
xenpaging.bitmap_clear.patch
Normal file
@ -0,0 +1,34 @@
|
||||
# HG changeset patch
|
||||
# Parent 2ac53905d95e6d02f53c99f6e2fa38f7306b8800
|
||||
libxc: add bitmap_clear function
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/libxc/xc_bitops.h | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/libxc/xc_bitops.h
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/libxc/xc_bitops.h
|
||||
+++ xen-4.1.2-testing/tools/libxc/xc_bitops.h
|
||||
@@ -4,6 +4,7 @@
|
||||
/* bitmap operations for single threaded access */
|
||||
|
||||
#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
|
||||
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
|
||||
#define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6)
|
||||
@@ -25,6 +26,11 @@ static inline unsigned long *bitmap_allo
|
||||
return calloc(1, bitmap_size(nr_bits));
|
||||
}
|
||||
|
||||
+static inline void bitmap_clear(unsigned long *addr, int nr_bits)
|
||||
+{
|
||||
+ memset(addr, 0, bitmap_size(nr_bits));
|
||||
+}
|
||||
+
|
||||
static inline int test_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1;
|
268
xenpaging.cmdline-interface.patch
Normal file
268
xenpaging.cmdline-interface.patch
Normal file
@ -0,0 +1,268 @@
|
||||
# HG changeset patch
|
||||
# Parent 434f0b4da9148b101e184e0108be6c31f67038f4
|
||||
xenpaging: add cmdline interface for pager
|
||||
|
||||
Introduce a cmdline handling for the pager. This simplifies libxl support,
|
||||
debug and mru_size are not passed via the environment anymore.
|
||||
The new interface looks like this:
|
||||
|
||||
xenpaging [options] -f <pagefile> -d <domain_id>
|
||||
options:
|
||||
-d <domid> --domain=<domid> numerical domain_id of guest. This option is required.
|
||||
-f <file> --pagefile=<file> pagefile to use. This option is required.
|
||||
-m <max_memkb> --max_memkb=<max_memkb> maximum amount of memory to handle.
|
||||
-r <num> --mru_size=<num> number of paged-in pages to keep in memory.
|
||||
-d --debug enable debug output.
|
||||
-h --help this output.
|
||||
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 139 ++++++++++++++++++++++++++++++++------------
|
||||
tools/xenpaging/xenpaging.h | 1
|
||||
2 files changed, 103 insertions(+), 37 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <poll.h>
|
||||
#include <xc_private.h>
|
||||
#include <xs.h>
|
||||
+#include <getopt.h>
|
||||
|
||||
#include "xc_bitops.h"
|
||||
#include "file_ops.h"
|
||||
@@ -42,12 +43,12 @@
|
||||
static char *watch_target_tot_pages;
|
||||
static char *dom_path;
|
||||
static char watch_token[16];
|
||||
-static char filename[80];
|
||||
+static char *filename;
|
||||
static int interrupted;
|
||||
|
||||
static void unlink_pagefile(void)
|
||||
{
|
||||
- if ( filename[0] )
|
||||
+ if ( filename && filename[0] )
|
||||
{
|
||||
unlink(filename);
|
||||
filename[0] = '\0';
|
||||
@@ -201,11 +202,85 @@ static void *init_page(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static xenpaging_t *xenpaging_init(domid_t domain_id, int target_tot_pages)
|
||||
+static void usage(void)
|
||||
+{
|
||||
+ printf("usage:\n\n");
|
||||
+
|
||||
+ printf(" xenpaging [options] -f <pagefile> -d <domain_id>\n\n");
|
||||
+
|
||||
+ printf("options:\n");
|
||||
+ printf(" -d <domid> --domain=<domid> numerical domain_id of guest. This option is required.\n");
|
||||
+ printf(" -f <file> --pagefile=<file> pagefile to use. This option is required.\n");
|
||||
+ printf(" -m <max_memkb> --max_memkb=<max_memkb> maximum amount of memory to handle.\n");
|
||||
+ printf(" -r <num> --mru_size=<num> number of paged-in pages to keep in memory.\n");
|
||||
+ printf(" -v --verbose enable debug output.\n");
|
||||
+ printf(" -h --help this output.\n");
|
||||
+}
|
||||
+
|
||||
+static int xenpaging_getopts(xenpaging_t *paging, int argc, char *argv[])
|
||||
+{
|
||||
+ int ch;
|
||||
+ static const char sopts[] = "hvd:f:m:r:";
|
||||
+ static const struct option lopts[] = {
|
||||
+ {"help", 0, NULL, 'h'},
|
||||
+ {"verbose", 0, NULL, 'v'},
|
||||
+ {"domain", 1, NULL, 'd'},
|
||||
+ {"pagefile", 1, NULL, 'f'},
|
||||
+ {"mru_size", 1, NULL, 'm'},
|
||||
+ { }
|
||||
+ };
|
||||
+
|
||||
+ while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1)
|
||||
+ {
|
||||
+ switch(ch) {
|
||||
+ case 'd':
|
||||
+ paging->mem_event.domain_id = atoi(optarg);
|
||||
+ break;
|
||||
+ case 'f':
|
||||
+ filename = strdup(optarg);
|
||||
+ break;
|
||||
+ case 'm':
|
||||
+ /* KiB to pages */
|
||||
+ paging->max_pages = atoi(optarg) >> 2;
|
||||
+ break;
|
||||
+ case 'r':
|
||||
+ paging->policy_mru_size = atoi(optarg);
|
||||
+ break;
|
||||
+ case 'v':
|
||||
+ paging->debug = 1;
|
||||
+ break;
|
||||
+ case 'h':
|
||||
+ case '?':
|
||||
+ usage();
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ argv += optind; argc -= optind;
|
||||
+
|
||||
+ /* Path to pagefile is required */
|
||||
+ if ( !filename )
|
||||
+ {
|
||||
+ printf("Filename for pagefile missing!\n");
|
||||
+ usage();
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ /* Set domain id */
|
||||
+ if ( !paging->mem_event.domain_id )
|
||||
+ {
|
||||
+ printf("Numerical <domain_id> missing!\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static xenpaging_t *xenpaging_init(int argc, char *argv[])
|
||||
{
|
||||
xenpaging_t *paging;
|
||||
xc_domaininfo_t domain_info;
|
||||
- xc_interface *xch;
|
||||
+ xc_interface *xch = NULL;
|
||||
xentoollog_logger *dbg = NULL;
|
||||
char *p;
|
||||
int rc;
|
||||
@@ -215,7 +290,12 @@ static xenpaging_t *xenpaging_init(domid
|
||||
if ( !paging )
|
||||
goto err;
|
||||
|
||||
- if ( getenv("XENPAGING_DEBUG") )
|
||||
+ /* Get cmdline options and domain_id */
|
||||
+ if ( xenpaging_getopts(paging, argc, argv) )
|
||||
+ goto err;
|
||||
+
|
||||
+ /* Enable debug output */
|
||||
+ if ( paging->debug )
|
||||
dbg = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0);
|
||||
|
||||
/* Open connection to xen */
|
||||
@@ -234,7 +314,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
}
|
||||
|
||||
/* write domain ID to watch so we can ignore other domain shutdowns */
|
||||
- snprintf(watch_token, sizeof(watch_token), "%u", domain_id);
|
||||
+ snprintf(watch_token, sizeof(watch_token), "%u", paging->mem_event.domain_id);
|
||||
if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false )
|
||||
{
|
||||
PERROR("Could not bind to shutdown watch\n");
|
||||
@@ -242,7 +322,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
}
|
||||
|
||||
/* Watch xenpagings working target */
|
||||
- dom_path = xs_get_domain_path(paging->xs_handle, domain_id);
|
||||
+ dom_path = xs_get_domain_path(paging->xs_handle, paging->mem_event.domain_id);
|
||||
if ( !dom_path )
|
||||
{
|
||||
PERROR("Could not find domain path\n");
|
||||
@@ -260,16 +340,6 @@ static xenpaging_t *xenpaging_init(domid
|
||||
goto err;
|
||||
}
|
||||
|
||||
- p = getenv("XENPAGING_POLICY_MRU_SIZE");
|
||||
- if ( p && *p )
|
||||
- {
|
||||
- paging->policy_mru_size = atoi(p);
|
||||
- DPRINTF("Setting policy mru_size to %d\n", paging->policy_mru_size);
|
||||
- }
|
||||
-
|
||||
- /* Set domain id */
|
||||
- paging->mem_event.domain_id = domain_id;
|
||||
-
|
||||
/* Initialise shared page */
|
||||
paging->mem_event.shared_page = init_page();
|
||||
if ( paging->mem_event.shared_page == NULL )
|
||||
@@ -335,16 +405,20 @@ static xenpaging_t *xenpaging_init(domid
|
||||
|
||||
paging->mem_event.port = rc;
|
||||
|
||||
- rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1,
|
||||
- &domain_info);
|
||||
- if ( rc != 1 )
|
||||
+ /* Get max_pages from guest if not provided via cmdline */
|
||||
+ if ( !paging->max_pages )
|
||||
{
|
||||
- PERROR("Error getting domain info");
|
||||
- goto err;
|
||||
- }
|
||||
+ rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1,
|
||||
+ &domain_info);
|
||||
+ if ( rc != 1 )
|
||||
+ {
|
||||
+ PERROR("Error getting domain info");
|
||||
+ goto err;
|
||||
+ }
|
||||
|
||||
- /* Record number of max_pages */
|
||||
- paging->max_pages = domain_info.max_pages;
|
||||
+ /* Record number of max_pages */
|
||||
+ paging->max_pages = domain_info.max_pages;
|
||||
+ }
|
||||
|
||||
/* Allocate bitmap for tracking pages that have been paged out */
|
||||
paging->bitmap = bitmap_alloc(paging->max_pages);
|
||||
@@ -355,8 +429,6 @@ static xenpaging_t *xenpaging_init(domid
|
||||
}
|
||||
DPRINTF("max_pages = %d\n", paging->max_pages);
|
||||
|
||||
- paging->target_tot_pages = target_tot_pages;
|
||||
-
|
||||
/* Initialise policy */
|
||||
rc = policy_init(paging);
|
||||
if ( rc != 0 )
|
||||
@@ -718,25 +790,18 @@ int main(int argc, char *argv[])
|
||||
mode_t open_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
int fd;
|
||||
|
||||
- if ( argc != 3 )
|
||||
- {
|
||||
- fprintf(stderr, "Usage: %s <domain_id> <tot_pages>\n", argv[0]);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
/* Initialise domain paging */
|
||||
- paging = xenpaging_init(atoi(argv[1]), atoi(argv[2]));
|
||||
+ paging = xenpaging_init(argc, argv);
|
||||
if ( paging == NULL )
|
||||
{
|
||||
- fprintf(stderr, "Error initialising paging");
|
||||
+ fprintf(stderr, "Error initialising paging\n");
|
||||
return 1;
|
||||
}
|
||||
xch = paging->xc_handle;
|
||||
|
||||
- DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->target_tot_pages);
|
||||
+ DPRINTF("starting %s for domain_id %u with pagefile %s\n", argv[0], paging->mem_event.domain_id, filename);
|
||||
|
||||
/* Open file */
|
||||
- sprintf(filename, "page_cache_%u", paging->mem_event.domain_id);
|
||||
fd = open(filename, open_flags, open_mode);
|
||||
if ( fd < 0 )
|
||||
{
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
|
||||
@@ -52,6 +52,7 @@ typedef struct xenpaging {
|
||||
int num_paged_out;
|
||||
int target_tot_pages;
|
||||
int policy_mru_size;
|
||||
+ int debug;
|
||||
unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
|
||||
} xenpaging_t;
|
||||
|
140
xenpaging.encapsulate_domain_info.patch
Normal file
140
xenpaging.encapsulate_domain_info.patch
Normal file
@ -0,0 +1,140 @@
|
||||
# HG changeset patch
|
||||
# Parent f665912bc70e0b12e194cf1dd1d37bd22b29c54f
|
||||
xenpaging: remove xc_dominfo_t from paging_t
|
||||
|
||||
Remove xc_dominfo_t from paging_t, record only max_pages.
|
||||
This value is used to setup internal data structures.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/policy_default.c | 8 ++++----
|
||||
tools/xenpaging/xenpaging.c | 27 +++++++++++----------------
|
||||
tools/xenpaging/xenpaging.h | 4 ++--
|
||||
3 files changed, 17 insertions(+), 22 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
@@ -41,17 +41,17 @@ int policy_init(xenpaging_t *paging)
|
||||
int i;
|
||||
int rc = -ENOMEM;
|
||||
|
||||
+ max_pages = paging->max_pages;
|
||||
+
|
||||
/* Allocate bitmap for pages not to page out */
|
||||
- bitmap = bitmap_alloc(paging->domain_info->max_pages);
|
||||
+ bitmap = bitmap_alloc(max_pages);
|
||||
if ( !bitmap )
|
||||
goto out;
|
||||
/* Allocate bitmap to track unusable pages */
|
||||
- unconsumed = bitmap_alloc(paging->domain_info->max_pages);
|
||||
+ unconsumed = bitmap_alloc(max_pages);
|
||||
if ( !unconsumed )
|
||||
goto out;
|
||||
|
||||
- max_pages = paging->domain_info->max_pages;
|
||||
-
|
||||
/* Initialise MRU list of paged in pages */
|
||||
if ( paging->policy_mru_size > 0 )
|
||||
mru_size = paging->policy_mru_size;
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -164,6 +164,7 @@ static void *init_page(void)
|
||||
static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages)
|
||||
{
|
||||
xenpaging_t *paging;
|
||||
+ xc_domaininfo_t domain_info;
|
||||
xc_interface *xch;
|
||||
xentoollog_logger *dbg = NULL;
|
||||
char *p;
|
||||
@@ -275,34 +276,29 @@ static xenpaging_t *xenpaging_init(domid
|
||||
|
||||
paging->mem_event.port = rc;
|
||||
|
||||
- /* Get domaininfo */
|
||||
- paging->domain_info = malloc(sizeof(xc_domaininfo_t));
|
||||
- if ( paging->domain_info == NULL )
|
||||
- {
|
||||
- PERROR("Error allocating memory for domain info");
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1,
|
||||
- paging->domain_info);
|
||||
+ &domain_info);
|
||||
if ( rc != 1 )
|
||||
{
|
||||
PERROR("Error getting domain info");
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ /* Record number of max_pages */
|
||||
+ paging->max_pages = domain_info.max_pages;
|
||||
+
|
||||
/* Allocate bitmap for tracking pages that have been paged out */
|
||||
- paging->bitmap = bitmap_alloc(paging->domain_info->max_pages);
|
||||
+ paging->bitmap = bitmap_alloc(paging->max_pages);
|
||||
if ( !paging->bitmap )
|
||||
{
|
||||
PERROR("Error allocating bitmap");
|
||||
goto err;
|
||||
}
|
||||
- DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages);
|
||||
+ DPRINTF("max_pages = %d\n", paging->max_pages);
|
||||
|
||||
- if ( num_pages < 0 || num_pages > paging->domain_info->max_pages )
|
||||
+ if ( num_pages < 0 || num_pages > paging->max_pages )
|
||||
{
|
||||
- num_pages = paging->domain_info->max_pages;
|
||||
+ num_pages = paging->max_pages;
|
||||
DPRINTF("setting num_pages to %d\n", num_pages);
|
||||
}
|
||||
paging->num_pages = num_pages;
|
||||
@@ -337,7 +333,6 @@ static xenpaging_t *xenpaging_init(domid
|
||||
}
|
||||
|
||||
free(paging->bitmap);
|
||||
- free(paging->domain_info);
|
||||
free(paging);
|
||||
}
|
||||
|
||||
@@ -765,7 +760,7 @@ int main(int argc, char *argv[])
|
||||
if ( interrupted == SIGTERM || interrupted == SIGINT )
|
||||
{
|
||||
int num = 0;
|
||||
- for ( i = 0; i < paging->domain_info->max_pages; i++ )
|
||||
+ for ( i = 0; i < paging->max_pages; i++ )
|
||||
{
|
||||
if ( test_bit(i, paging->bitmap) )
|
||||
{
|
||||
@@ -781,7 +776,7 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
if ( num )
|
||||
page_in_trigger();
|
||||
- else if ( i == paging->domain_info->max_pages )
|
||||
+ else if ( i == paging->max_pages )
|
||||
break;
|
||||
}
|
||||
else
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
|
||||
@@ -44,11 +44,11 @@ typedef struct xenpaging {
|
||||
xc_interface *xc_handle;
|
||||
struct xs_handle *xs_handle;
|
||||
|
||||
- xc_domaininfo_t *domain_info;
|
||||
-
|
||||
unsigned long *bitmap;
|
||||
|
||||
mem_event_t mem_event;
|
||||
+ /* number of pages for which data structures were allocated */
|
||||
+ int max_pages;
|
||||
int num_pages;
|
||||
int policy_mru_size;
|
||||
unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
|
85
xenpaging.file_op-return-code.patch
Normal file
85
xenpaging.file_op-return-code.patch
Normal file
@ -0,0 +1,85 @@
|
||||
# HG changeset patch
|
||||
# Parent 7a4a6935bfa145b24d5183cbf43ce8cc140d9183
|
||||
xenpaging: simplify file_op
|
||||
|
||||
Use -1 as return value and let caller read errno.
|
||||
Remove const casts from buffer pointers, the page is writeable.
|
||||
Use wrapper for write() which matches the read() prototype.
|
||||
Remove unused stdarg.h inclusion.
|
||||
Remove unused macro.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/file_ops.c | 29 +++++++++--------------------
|
||||
1 file changed, 9 insertions(+), 20 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/file_ops.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/file_ops.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/file_ops.c
|
||||
@@ -21,55 +21,44 @@
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
-#include <stdarg.h>
|
||||
#include <xc_private.h>
|
||||
|
||||
-
|
||||
-#define page_offset(_pfn) (((off_t)(_pfn)) << PAGE_SHIFT)
|
||||
-
|
||||
-
|
||||
static int file_op(int fd, void *page, int i,
|
||||
- ssize_t (*fn)(int, const void *, size_t))
|
||||
+ ssize_t (*fn)(int, void *, size_t))
|
||||
{
|
||||
off_t seek_ret;
|
||||
- int total;
|
||||
+ int total = 0;
|
||||
int bytes;
|
||||
- int ret;
|
||||
|
||||
seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET);
|
||||
+ if ( seek_ret == (off_t)-1 )
|
||||
+ return -1;
|
||||
|
||||
- total = 0;
|
||||
while ( total < PAGE_SIZE )
|
||||
{
|
||||
bytes = fn(fd, page + total, PAGE_SIZE - total);
|
||||
if ( bytes <= 0 )
|
||||
- {
|
||||
- ret = -errno;
|
||||
- goto err;
|
||||
- }
|
||||
+ return -1;
|
||||
|
||||
total += bytes;
|
||||
}
|
||||
|
||||
return 0;
|
||||
-
|
||||
- err:
|
||||
- return ret;
|
||||
}
|
||||
|
||||
-static ssize_t my_read(int fd, const void *buf, size_t count)
|
||||
+static ssize_t my_write(int fd, void *buf, size_t count)
|
||||
{
|
||||
- return read(fd, (void *)buf, count);
|
||||
+ return write(fd, buf, count);
|
||||
}
|
||||
|
||||
int read_page(int fd, void *page, int i)
|
||||
{
|
||||
- return file_op(fd, page, i, &my_read);
|
||||
+ return file_op(fd, page, i, &read);
|
||||
}
|
||||
|
||||
int write_page(int fd, void *page, int i)
|
||||
{
|
||||
- return file_op(fd, page, i, &write);
|
||||
+ return file_op(fd, page, i, &my_write);
|
||||
}
|
||||
|
||||
|
80
xenpaging.guest-memusage.patch
Normal file
80
xenpaging.guest-memusage.patch
Normal file
@ -0,0 +1,80 @@
|
||||
---
|
||||
tools/xenpaging/Makefile | 2 -
|
||||
tools/xenpaging/xenmem.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 58 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/Makefile
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/Makefile
|
||||
@@ -20,7 +20,7 @@ CFLAGS += -Wp,-MD,.$(@F).d
|
||||
DEPS = .*.d
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
-IBINS = xenpaging
|
||||
+IBINS = xenpaging xenmem
|
||||
|
||||
all: $(IBINS)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenmem.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenmem.c
|
||||
@@ -0,0 +1,57 @@
|
||||
+#include <stdio.h>
|
||||
+#include <xc_private.h>
|
||||
+
|
||||
+static void dump_mem(const char *domid)
|
||||
+{
|
||||
+ xc_interface *xch;
|
||||
+ xc_dominfo_t info;
|
||||
+ unsigned char handle[16];
|
||||
+ char uuid[16 * 2 + 1];
|
||||
+ int i;
|
||||
+
|
||||
+ xch = xc_interface_open(NULL, NULL, 0);
|
||||
+ if (!xch)
|
||||
+ perror("xc_interface_open");
|
||||
+ else {
|
||||
+ i = xc_domain_getinfo(xch, atoi(domid), 1, &info);
|
||||
+ if (i != 1)
|
||||
+ perror("xc_domain_getinfo");
|
||||
+ else {
|
||||
+ printf("domid\t%u\n", info.domid);
|
||||
+ printf("ssidref\t%u\n", info.ssidref);
|
||||
+ printf("dying\t%u\n", info.dying);
|
||||
+ printf("crashed\t%u\n", info.crashed);
|
||||
+ printf("shutdown\t%u\n", info.shutdown);
|
||||
+ printf("paused\t%u\n", info.paused);
|
||||
+ printf("blocked\t%u\n", info.blocked);
|
||||
+ printf("running\t%u\n", info.running);
|
||||
+ printf("hvm\t%u\n", info.hvm);
|
||||
+ printf("debugged\t%u\n", info.debugged);
|
||||
+ printf("shutdown_reason\t%u\n", info.shutdown_reason);
|
||||
+ printf("nr_pages\t%lu\t%lu KiB\t%lu MiB\n", info.nr_pages, info.nr_pages * 4, info.nr_pages * 4 / 1024);
|
||||
+ printf("nr_shared_pages\t%lu\t%lu KiB\t%lu MiB\n", info.nr_shared_pages, info.nr_shared_pages * 4, info.nr_shared_pages * 4 / 1024);
|
||||
+ printf("nr_paged_pages\t%lu\t%lu KiB\t%lu MiB\n", info.nr_paged_pages, info.nr_paged_pages * 4, info.nr_paged_pages * 4 / 1024);
|
||||
+ printf("max_memkb\t%lu KiB\t%lu MiB\n", info.max_memkb, info.max_memkb / 1024);
|
||||
+ printf("shared_info_frame\t%lu\t%lx\n", info.shared_info_frame, info.shared_info_frame);
|
||||
+ printf("cpu_time\t%llu\t%016llx\n", (unsigned long long)info.cpu_time, (unsigned long long)info.cpu_time);
|
||||
+ printf("nr_online_vcpus\t%u\n", info.nr_online_vcpus);
|
||||
+ printf("max_vcpu_id\t%u\n", info.max_vcpu_id);
|
||||
+ printf("cpupool\t%u\n", info.cpupool);
|
||||
+
|
||||
+ memcpy(&handle, &info.handle, sizeof(handle));
|
||||
+ uuid[0] = '\0';
|
||||
+ for (i = 0; i < sizeof(handle); i++)
|
||||
+ snprintf(&uuid[i * 2], sizeof(uuid) - strlen(uuid), "%02x", handle[i]);
|
||||
+ printf("handle\t%s\n", uuid);
|
||||
+ }
|
||||
+ if (xc_interface_close(xch) < 0)
|
||||
+ perror("xc_interface_close");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ if (argv[1])
|
||||
+ dump_mem(argv[1]);
|
||||
+ return 0;
|
||||
+}
|
28
xenpaging.install-to-libexec.patch
Normal file
28
xenpaging.install-to-libexec.patch
Normal file
@ -0,0 +1,28 @@
|
||||
# HG changeset patch
|
||||
# Parent a30ec96cbaa43bc7abd90b7d974a8033265409c1
|
||||
xenpaging: install into LIBEXEC dir
|
||||
|
||||
In preparation of upcoming libxl integration,
|
||||
move xenpaging binary from /usr/sbin/ to /usr/lib/xen/bin/
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/Makefile | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/Makefile
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/Makefile
|
||||
@@ -29,8 +29,8 @@ xenpaging: $(OBJS)
|
||||
|
||||
install: all
|
||||
$(INSTALL_DIR) $(DESTDIR)/var/lib/xen/xenpaging
|
||||
- $(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
|
||||
- $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(SBINDIR)
|
||||
+ $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)
|
||||
+ $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ $(DEPS) xen TAGS $(IBINS) $(LIB)
|
122
xenpaging.low_target_policy_nomru.patch
Normal file
122
xenpaging.low_target_policy_nomru.patch
Normal file
@ -0,0 +1,122 @@
|
||||
# HG changeset patch
|
||||
# Parent 79677f532a2406ca501250b50fa8b33965a8d7d7
|
||||
xenpaging: improve policy mru list handling
|
||||
|
||||
Without this change it is not possible to page-out all guest pages, then
|
||||
trigger a page-in for all pages, and then page-out everything once
|
||||
again. All pages in the mru list can not be paged out because they
|
||||
remain active in the internal bitmap of paged pages.
|
||||
|
||||
Use the mru list only if the number of paged-out pages is larger than
|
||||
the mru list. If the number is smaller, start to clear the mru list. In
|
||||
case the number of paged-out pages drops to zero the mru list and the
|
||||
internal bitmap will be empty as well.
|
||||
|
||||
Also add a new interface for dropped pages. If a gfn was dropped there
|
||||
is no need to adjust the mru list because dropping a page is not usage
|
||||
of a page.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/policy.h | 2 ++
|
||||
tools/xenpaging/policy_default.c | 27 ++++++++++++++++++++++++---
|
||||
tools/xenpaging/xenpaging.c | 11 +++++++++--
|
||||
3 files changed, 35 insertions(+), 5 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/policy.h
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/policy.h
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/policy.h
|
||||
@@ -32,6 +32,8 @@ int policy_init(xenpaging_t *paging);
|
||||
int policy_choose_victim(xenpaging_t *paging, xenpaging_victim_t *victim);
|
||||
void policy_notify_paged_out(unsigned long gfn);
|
||||
void policy_notify_paged_in(unsigned long gfn);
|
||||
+void policy_notify_paged_in_nomru(unsigned long gfn);
|
||||
+void policy_notify_dropped(unsigned long gfn);
|
||||
|
||||
#endif // __XEN_PAGING_POLICY_H__
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
@@ -57,7 +57,7 @@ int policy_init(xenpaging_t *paging)
|
||||
if ( paging->policy_mru_size > 0 )
|
||||
mru_size = paging->policy_mru_size;
|
||||
else
|
||||
- mru_size = DEFAULT_MRU_SIZE;
|
||||
+ mru_size = paging->policy_mru_size = DEFAULT_MRU_SIZE;
|
||||
|
||||
mru = malloc(sizeof(*mru) * mru_size);
|
||||
if ( mru == NULL )
|
||||
@@ -120,17 +120,38 @@ void policy_notify_paged_out(unsigned lo
|
||||
clear_bit(gfn, unconsumed);
|
||||
}
|
||||
|
||||
-void policy_notify_paged_in(unsigned long gfn)
|
||||
+static void policy_handle_paged_in(unsigned long gfn, int do_mru)
|
||||
{
|
||||
unsigned long old_gfn = mru[i_mru & (mru_size - 1)];
|
||||
|
||||
if ( old_gfn != INVALID_MFN )
|
||||
clear_bit(old_gfn, bitmap);
|
||||
|
||||
- mru[i_mru & (mru_size - 1)] = gfn;
|
||||
+ if (do_mru) {
|
||||
+ mru[i_mru & (mru_size - 1)] = gfn;
|
||||
+ } else {
|
||||
+ clear_bit(gfn, bitmap);
|
||||
+ mru[i_mru & (mru_size - 1)] = INVALID_MFN;
|
||||
+ }
|
||||
+
|
||||
i_mru++;
|
||||
}
|
||||
|
||||
+void policy_notify_paged_in(unsigned long gfn)
|
||||
+{
|
||||
+ policy_handle_paged_in(gfn, 1);
|
||||
+}
|
||||
+
|
||||
+void policy_notify_paged_in_nomru(unsigned long gfn)
|
||||
+{
|
||||
+ policy_handle_paged_in(gfn, 0);
|
||||
+}
|
||||
+
|
||||
+void policy_notify_dropped(unsigned long gfn)
|
||||
+{
|
||||
+ clear_bit(gfn, bitmap);
|
||||
+}
|
||||
+
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -616,7 +616,14 @@ static int xenpaging_resume_page(xenpagi
|
||||
/* Notify policy of page being paged in */
|
||||
if ( notify_policy )
|
||||
{
|
||||
- policy_notify_paged_in(rsp->gfn);
|
||||
+ /*
|
||||
+ * Do not add gfn to mru list if the target is lower than mru size.
|
||||
+ * This allows page-out of these gfns if the target grows again.
|
||||
+ */
|
||||
+ if (paging->num_paged_out > paging->policy_mru_size)
|
||||
+ policy_notify_paged_in(rsp->gfn);
|
||||
+ else
|
||||
+ policy_notify_paged_in_nomru(rsp->gfn);
|
||||
|
||||
/* Record number of resumed pages */
|
||||
paging->num_paged_out--;
|
||||
@@ -870,7 +877,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
DPRINTF("drop_page ^ gfn %"PRIx64" pageslot %d\n", req.gfn, i);
|
||||
/* Notify policy of page being dropped */
|
||||
- policy_notify_paged_in(req.gfn);
|
||||
+ policy_notify_dropped(req.gfn);
|
||||
}
|
||||
else
|
||||
{
|
48
xenpaging.main-loop-exit-handling.patch
Normal file
48
xenpaging.main-loop-exit-handling.patch
Normal file
@ -0,0 +1,48 @@
|
||||
# HG changeset patch
|
||||
# Parent f08959fb7528e1724e26365973914ae3e0af78ea
|
||||
xenpaging: improve mainloop exit handling
|
||||
|
||||
Remove the if/else logic to exit from the in case a signal arrives.
|
||||
Update comments.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -805,7 +805,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
- /* Write all pages back into the guest */
|
||||
+ /* If interrupted, write all pages back into the guest */
|
||||
if ( interrupted == SIGTERM || interrupted == SIGINT )
|
||||
{
|
||||
/* If no more pages to process, exit loop. */
|
||||
@@ -814,13 +814,15 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* One more round if there are still pages to process. */
|
||||
resume_pages(paging, paging->num_paged_out);
|
||||
+
|
||||
+ /* Resume main loop */
|
||||
+ continue;
|
||||
}
|
||||
- else
|
||||
- {
|
||||
- /* Exit on any other signal */
|
||||
- if ( interrupted )
|
||||
- break;
|
||||
- }
|
||||
+
|
||||
+ /* Exit main loop on any other signal */
|
||||
+ if ( interrupted )
|
||||
+ break;
|
||||
+
|
||||
}
|
||||
DPRINTF("xenpaging got signal %d\n", interrupted);
|
||||
|
26
xenpaging.misleading-comment.patch
Normal file
26
xenpaging.misleading-comment.patch
Normal file
@ -0,0 +1,26 @@
|
||||
# HG changeset patch
|
||||
# Parent 138406814b338c07af349a477dd7602ecca8be70
|
||||
xenpaging: remove obsolete comment in resume path
|
||||
|
||||
Remove stale comment.
|
||||
If a page was populated several times the vcpu is paused and
|
||||
xenpaging has to unpause it again.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -744,7 +744,6 @@ int main(int argc, char *argv[])
|
||||
!!(req.flags & MEM_EVENT_FLAG_EVICT_FAIL) );
|
||||
|
||||
/* Tell Xen to resume the vcpu */
|
||||
- /* XXX: Maybe just check if the vcpu was paused? */
|
||||
if ( req.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
|
||||
{
|
||||
/* Prepare the response */
|
28
xenpaging.page_in-munmap-size.patch
Normal file
28
xenpaging.page_in-munmap-size.patch
Normal file
@ -0,0 +1,28 @@
|
||||
# HG changeset patch
|
||||
# Parent 951a9879c34bee1dd2fa0329a541ae089f271c11
|
||||
xenpaging: munmap all pages after page-in
|
||||
|
||||
Do munmap() on all mapped pages, not just the first one. Without this
|
||||
change the gfns backing the remaining pages can not be paged out again
|
||||
because the page count does not go down to 1. This change was missing
|
||||
from changeset 23827:d1d6abc1db20.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/pagein.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/pagein.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/pagein.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/pagein.c
|
||||
@@ -44,7 +44,7 @@ static void *page_in(void *arg)
|
||||
/* Ignore errors */
|
||||
page = xc_map_foreign_pages(pia->xch, pia->dom, PROT_READ, gfns, num);
|
||||
if (page)
|
||||
- munmap(page, PAGE_SIZE);
|
||||
+ munmap(page, PAGE_SIZE * num);
|
||||
}
|
||||
page_in_possible = 0;
|
||||
pthread_exit(NULL);
|
95
xenpaging.print-gfn.patch
Normal file
95
xenpaging.print-gfn.patch
Normal file
@ -0,0 +1,95 @@
|
||||
# HG changeset patch
|
||||
# Parent 9c7e82499e983ad11b13dd41d2fa5f12072adecf
|
||||
xenpaging: print gfn in failure case
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 18 +++++++++---------
|
||||
1 file changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -444,7 +444,7 @@ static int xenpaging_evict_page(xenpagin
|
||||
PROT_READ | PROT_WRITE, &gfn, 1);
|
||||
if ( page == NULL )
|
||||
{
|
||||
- PERROR("Error mapping page");
|
||||
+ PERROR("Error mapping page %lx", victim->gfn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -452,7 +452,7 @@ static int xenpaging_evict_page(xenpagin
|
||||
ret = write_page(fd, page, i);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
- PERROR("Error copying page");
|
||||
+ PERROR("Error copying page %lx", victim->gfn);
|
||||
munmap(page, PAGE_SIZE);
|
||||
goto out;
|
||||
}
|
||||
@@ -464,7 +464,7 @@ static int xenpaging_evict_page(xenpagin
|
||||
victim->gfn);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
- PERROR("Error evicting page");
|
||||
+ PERROR("Error evicting page %lx", victim->gfn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ static int xenpaging_populate_page(xenpa
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
- PERROR("Error preparing for page in");
|
||||
+ PERROR("Error preparing %"PRI_xen_pfn" for page-in", gfn);
|
||||
goto out_map;
|
||||
}
|
||||
}
|
||||
@@ -532,7 +532,7 @@ static int xenpaging_populate_page(xenpa
|
||||
PROT_READ | PROT_WRITE, &gfn, 1);
|
||||
if ( page == NULL )
|
||||
{
|
||||
- PERROR("Error mapping page: page is null");
|
||||
+ PERROR("Error mapping page %"PRI_xen_pfn": page is null", gfn);
|
||||
goto out_map;
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ static int xenpaging_populate_page(xenpa
|
||||
ret = read_page(fd, page, i);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
- PERROR("Error reading page");
|
||||
+ PERROR("Error reading page %"PRI_xen_pfn"", gfn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ int main(int argc, char *argv[])
|
||||
rc = xenpaging_populate_page(paging, req.gfn, fd, i);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- PERROR("Error populating page");
|
||||
+ PERROR("Error populating page %"PRIx64"", req.gfn);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -723,7 +723,7 @@ int main(int argc, char *argv[])
|
||||
rc = xenpaging_resume_page(paging, &rsp, 1);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- PERROR("Error resuming page");
|
||||
+ PERROR("Error resuming page %"PRIx64"", req.gfn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -754,7 +754,7 @@ int main(int argc, char *argv[])
|
||||
rc = xenpaging_resume_page(paging, &rsp, 0);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- PERROR("Error resuming");
|
||||
+ PERROR("Error resuming page %"PRIx64"", req.gfn);
|
||||
goto out;
|
||||
}
|
||||
}
|
53
xenpaging.record-numer-paged-out-pages.patch
Normal file
53
xenpaging.record-numer-paged-out-pages.patch
Normal file
@ -0,0 +1,53 @@
|
||||
# HG changeset patch
|
||||
# Parent 8e31f3194c87e1cdb41621caa5a41810ef787293
|
||||
xenpaging: track the number of paged-out pages
|
||||
|
||||
This change is required by subsequent changes.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 8 ++++++++
|
||||
tools/xenpaging/xenpaging.h | 1 +
|
||||
2 files changed, 9 insertions(+)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -467,6 +467,9 @@ static int xenpaging_evict_page(xenpagin
|
||||
/* Notify policy of page being paged out */
|
||||
policy_notify_paged_out(victim->gfn);
|
||||
|
||||
+ /* Record number of evicted pages */
|
||||
+ paging->num_paged_out++;
|
||||
+
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@@ -480,8 +483,13 @@ static int xenpaging_resume_page(xenpagi
|
||||
|
||||
/* Notify policy of page being paged in */
|
||||
if ( notify_policy )
|
||||
+ {
|
||||
policy_notify_paged_in(rsp->gfn);
|
||||
|
||||
+ /* Record number of resumed pages */
|
||||
+ paging->num_paged_out--;
|
||||
+ }
|
||||
+
|
||||
/* Tell Xen page is ready */
|
||||
ret = xc_mem_paging_resume(paging->xc_handle, paging->mem_event.domain_id,
|
||||
rsp->gfn);
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
|
||||
@@ -49,6 +49,7 @@ typedef struct xenpaging {
|
||||
mem_event_t mem_event;
|
||||
/* number of pages for which data structures were allocated */
|
||||
int max_pages;
|
||||
+ int num_paged_out;
|
||||
int num_pages;
|
||||
int policy_mru_size;
|
||||
unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
|
50
xenpaging.reset-uncomsumed.patch
Normal file
50
xenpaging.reset-uncomsumed.patch
Normal file
@ -0,0 +1,50 @@
|
||||
# HG changeset patch
|
||||
# Parent 5d87917314c0b4f13c987575d5329dfa215c5698
|
||||
xenpaging: retry unpageable gfns
|
||||
|
||||
Nomination of gfns can fail, but may succeed later.
|
||||
Thats the case for a guest that starts ballooned.
|
||||
|
||||
v2:
|
||||
- print debug when clearing uncosumed happens
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/policy_default.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
@@ -32,6 +32,7 @@ static unsigned int i_mru;
|
||||
static unsigned int mru_size;
|
||||
static unsigned long *bitmap;
|
||||
static unsigned long *unconsumed;
|
||||
+static unsigned int unconsumed_cleared;
|
||||
static unsigned long current_gfn;
|
||||
static unsigned long max_pages;
|
||||
|
||||
@@ -87,8 +88,21 @@ int policy_choose_victim(xenpaging_t *pa
|
||||
current_gfn++;
|
||||
if ( current_gfn >= max_pages )
|
||||
current_gfn = 0;
|
||||
+ /* Could not nominate any gfn */
|
||||
if ( wrap == current_gfn )
|
||||
{
|
||||
+ /* Count wrap arounds */
|
||||
+ unconsumed_cleared++;
|
||||
+ /* Force retry every few seconds (depends on poll() timeout) */
|
||||
+ if ( unconsumed_cleared > 123)
|
||||
+ {
|
||||
+ /* Force retry of unconsumed gfns */
|
||||
+ bitmap_clear(unconsumed, max_pages);
|
||||
+ unconsumed_cleared = 0;
|
||||
+ DPRINTF("clearing unconsumed, wrap %lx", wrap);
|
||||
+ /* One more round before returning ENOSPC */
|
||||
+ continue;
|
||||
+ }
|
||||
victim->gfn = INVALID_MFN;
|
||||
return -ENOSPC;
|
||||
}
|
42
xenpaging.stale-comments.patch
Normal file
42
xenpaging.stale-comments.patch
Normal file
@ -0,0 +1,42 @@
|
||||
# HG changeset patch
|
||||
# Parent 401247fe2a24c4923a0106c5d8230fb16de0bb96
|
||||
xenpaging: remove filename from comment
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/file_ops.c | 1 -
|
||||
tools/xenpaging/policy_default.c | 1 -
|
||||
tools/xenpaging/xenpaging.c | 1 -
|
||||
3 files changed, 3 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/file_ops.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/file_ops.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/file_ops.c
|
||||
@@ -1,5 +1,4 @@
|
||||
/******************************************************************************
|
||||
- * tools/xenpaging/file_ops.c
|
||||
*
|
||||
* Common file operations.
|
||||
*
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
@@ -1,5 +1,4 @@
|
||||
/******************************************************************************
|
||||
- * tools/xenpaging/policy.c
|
||||
*
|
||||
* Xen domain paging default policy.
|
||||
*
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -1,5 +1,4 @@
|
||||
/******************************************************************************
|
||||
- * tools/xenpaging/xenpaging.c
|
||||
*
|
||||
* Domain paging.
|
||||
* Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp)
|
187
xenpaging.target-tot_pages.patch
Normal file
187
xenpaging.target-tot_pages.patch
Normal file
@ -0,0 +1,187 @@
|
||||
# HG changeset patch
|
||||
# Parent f057eb06706e2bacaadb41cf80fa45001e786e69
|
||||
xenpaging: use guests tot_pages as working target
|
||||
|
||||
This change reverses the task of xenpaging. Before this change a fixed number
|
||||
of pages was paged out. With this change the guest will not have access to
|
||||
more than the given number of pages at the same time.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/policy_default.c | 1
|
||||
tools/xenpaging/xenpaging.c | 78 ++++++++++++++++++++++++++++++---------
|
||||
tools/xenpaging/xenpaging.h | 2 -
|
||||
3 files changed, 61 insertions(+), 20 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/policy_default.c
|
||||
@@ -71,7 +71,6 @@ int policy_init(xenpaging_t *paging)
|
||||
|
||||
/* Start in the middle to avoid paging during BIOS startup */
|
||||
current_gfn = max_pages / 2;
|
||||
- current_gfn -= paging->num_pages / 2;
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -136,6 +136,21 @@ err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static int xenpaging_get_tot_pages(xenpaging_t *paging)
|
||||
+{
|
||||
+ xc_interface *xch = paging->xc_handle;
|
||||
+ xc_domaininfo_t domain_info;
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, &domain_info);
|
||||
+ if ( rc != 1 )
|
||||
+ {
|
||||
+ PERROR("Error getting domain info");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return domain_info.tot_pages;
|
||||
+}
|
||||
+
|
||||
static void *init_page(void)
|
||||
{
|
||||
void *buffer;
|
||||
@@ -161,7 +176,7 @@ static void *init_page(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages)
|
||||
+static xenpaging_t *xenpaging_init(domid_t domain_id, int target_tot_pages)
|
||||
{
|
||||
xenpaging_t *paging;
|
||||
xc_domaininfo_t domain_info;
|
||||
@@ -296,12 +311,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
}
|
||||
DPRINTF("max_pages = %d\n", paging->max_pages);
|
||||
|
||||
- if ( num_pages < 0 || num_pages > paging->max_pages )
|
||||
- {
|
||||
- num_pages = paging->max_pages;
|
||||
- DPRINTF("setting num_pages to %d\n", num_pages);
|
||||
- }
|
||||
- paging->num_pages = num_pages;
|
||||
+ paging->target_tot_pages = target_tot_pages;
|
||||
|
||||
/* Initialise policy */
|
||||
rc = policy_init(paging);
|
||||
@@ -648,7 +658,9 @@ int main(int argc, char *argv[])
|
||||
xenpaging_victim_t *victims;
|
||||
mem_event_request_t req;
|
||||
mem_event_response_t rsp;
|
||||
+ int num, prev_num = 0;
|
||||
int i;
|
||||
+ int tot_pages;
|
||||
int rc = -1;
|
||||
int rc1;
|
||||
xc_interface *xch;
|
||||
@@ -659,7 +671,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if ( argc != 3 )
|
||||
{
|
||||
- fprintf(stderr, "Usage: %s <domain_id> <num_pages>\n", argv[0]);
|
||||
+ fprintf(stderr, "Usage: %s <domain_id> <tot_pages>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -672,7 +684,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
xch = paging->xc_handle;
|
||||
|
||||
- DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->num_pages);
|
||||
+ DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->target_tot_pages);
|
||||
|
||||
/* Open file */
|
||||
sprintf(filename, "page_cache_%u", paging->mem_event.domain_id);
|
||||
@@ -704,9 +716,6 @@ int main(int argc, char *argv[])
|
||||
/* listen for page-in events to stop pager */
|
||||
create_page_in_thread(paging);
|
||||
|
||||
- i = evict_pages(paging, fd, victims, paging->num_pages);
|
||||
- DPRINTF("%d pages evicted. Done.\n", i);
|
||||
-
|
||||
/* Swap pages in and out */
|
||||
while ( 1 )
|
||||
{
|
||||
@@ -771,12 +780,8 @@ int main(int argc, char *argv[])
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* Evict a new page to replace the one we just paged in,
|
||||
- * or clear this pagefile slot on exit */
|
||||
- if ( interrupted )
|
||||
- victims[i].gfn = INVALID_MFN;
|
||||
- else
|
||||
- evict_victim(paging, &victims[i], fd, i);
|
||||
+ /* Clear this pagefile slot */
|
||||
+ victims[i].gfn = INVALID_MFN;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -823,6 +828,43 @@ int main(int argc, char *argv[])
|
||||
if ( interrupted )
|
||||
break;
|
||||
|
||||
+ /* Check if the target has been reached already */
|
||||
+ tot_pages = xenpaging_get_tot_pages(paging);
|
||||
+ if ( tot_pages < 0 )
|
||||
+ goto out;
|
||||
+
|
||||
+ /* Resume all pages if paging is disabled or no target was set */
|
||||
+ if ( paging->target_tot_pages == 0 )
|
||||
+ {
|
||||
+ if ( paging->num_paged_out )
|
||||
+ resume_pages(paging, paging->num_paged_out);
|
||||
+ }
|
||||
+ /* Evict more pages if target not reached */
|
||||
+ else if ( tot_pages > paging->target_tot_pages )
|
||||
+ {
|
||||
+ num = tot_pages - paging->target_tot_pages;
|
||||
+ if ( num != prev_num )
|
||||
+ {
|
||||
+ DPRINTF("Need to evict %d pages to reach %d target_tot_pages\n", num, paging->target_tot_pages);
|
||||
+ prev_num = num;
|
||||
+ }
|
||||
+ /* Limit the number of evicts to be able to process page-in requests */
|
||||
+ if ( num > 42 )
|
||||
+ num = 42;
|
||||
+ evict_pages(paging, fd, victims, num);
|
||||
+ }
|
||||
+ /* Resume some pages if target not reached */
|
||||
+ else if ( tot_pages < paging->target_tot_pages && paging->num_paged_out )
|
||||
+ {
|
||||
+ num = paging->target_tot_pages - tot_pages;
|
||||
+ if ( num != prev_num )
|
||||
+ {
|
||||
+ DPRINTF("Need to resume %d pages to reach %d target_tot_pages\n", num, paging->target_tot_pages);
|
||||
+ prev_num = num;
|
||||
+ }
|
||||
+ resume_pages(paging, num);
|
||||
+ }
|
||||
+
|
||||
}
|
||||
DPRINTF("xenpaging got signal %d\n", interrupted);
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
|
||||
@@ -50,7 +50,7 @@ typedef struct xenpaging {
|
||||
/* number of pages for which data structures were allocated */
|
||||
int max_pages;
|
||||
int num_paged_out;
|
||||
- int num_pages;
|
||||
+ int target_tot_pages;
|
||||
int policy_mru_size;
|
||||
unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
|
||||
} xenpaging_t;
|
281
xenpaging.use-PERROR.patch
Normal file
281
xenpaging.use-PERROR.patch
Normal file
@ -0,0 +1,281 @@
|
||||
# HG changeset patch
|
||||
# Parent 5eb76b80baa127278e0fc1574bef22a79d9513f5
|
||||
xenpaging: use PERROR to print errno
|
||||
|
||||
v3:
|
||||
- adjust arguments for xc_mem_paging_enable() failures
|
||||
|
||||
v2:
|
||||
- move changes to file_op() to different patch
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 58 ++++++++++++++++++++++----------------------
|
||||
1 file changed, 29 insertions(+), 29 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -90,7 +90,7 @@ static int xenpaging_wait_for_event_or_t
|
||||
if (errno == EINTR)
|
||||
return 0;
|
||||
|
||||
- ERROR("Poll exited with an error");
|
||||
+ PERROR("Poll exited with an error");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ static int xenpaging_wait_for_event_or_t
|
||||
port = xc_evtchn_pending(xce);
|
||||
if ( port == -1 )
|
||||
{
|
||||
- ERROR("Failed to read port from event channel");
|
||||
+ PERROR("Failed to read port from event channel");
|
||||
rc = -1;
|
||||
goto err;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ static int xenpaging_wait_for_event_or_t
|
||||
rc = xc_evtchn_unmask(xce, port);
|
||||
if ( rc < 0 )
|
||||
{
|
||||
- ERROR("Failed to unmask event channel port");
|
||||
+ PERROR("Failed to unmask event channel port");
|
||||
}
|
||||
}
|
||||
err:
|
||||
@@ -185,7 +185,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
paging->xs_handle = xs_open(0);
|
||||
if ( paging->xs_handle == NULL )
|
||||
{
|
||||
- ERROR("Error initialising xenstore connection");
|
||||
+ PERROR("Error initialising xenstore connection");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
snprintf(watch_token, sizeof(watch_token), "%u", domain_id);
|
||||
if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false )
|
||||
{
|
||||
- ERROR("Could not bind to shutdown watch\n");
|
||||
+ PERROR("Could not bind to shutdown watch\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
paging->mem_event.shared_page = init_page();
|
||||
if ( paging->mem_event.shared_page == NULL )
|
||||
{
|
||||
- ERROR("Error initialising shared page");
|
||||
+ PERROR("Error initialising shared page");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
paging->mem_event.ring_page = init_page();
|
||||
if ( paging->mem_event.ring_page == NULL )
|
||||
{
|
||||
- ERROR("Error initialising ring page");
|
||||
+ PERROR("Error initialising ring page");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
ERROR("xenpaging not supported in a PoD guest");
|
||||
break;
|
||||
default:
|
||||
- ERROR("Error initialising shared page: %s", strerror(errno));
|
||||
+ PERROR("Error initialising shared page");
|
||||
break;
|
||||
}
|
||||
goto err;
|
||||
@@ -259,7 +259,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
paging->mem_event.xce_handle = xc_evtchn_open(NULL, 0);
|
||||
if ( paging->mem_event.xce_handle == NULL )
|
||||
{
|
||||
- ERROR("Failed to open event channel");
|
||||
+ PERROR("Failed to open event channel");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
paging->mem_event.shared_page->port);
|
||||
if ( rc < 0 )
|
||||
{
|
||||
- ERROR("Failed to bind event channel");
|
||||
+ PERROR("Failed to bind event channel");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
paging->domain_info = malloc(sizeof(xc_domaininfo_t));
|
||||
if ( paging->domain_info == NULL )
|
||||
{
|
||||
- ERROR("Error allocating memory for domain info");
|
||||
+ PERROR("Error allocating memory for domain info");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
paging->domain_info);
|
||||
if ( rc != 1 )
|
||||
{
|
||||
- ERROR("Error getting domain info");
|
||||
+ PERROR("Error getting domain info");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
paging->bitmap = bitmap_alloc(paging->domain_info->max_pages);
|
||||
if ( !paging->bitmap )
|
||||
{
|
||||
- ERROR("Error allocating bitmap");
|
||||
+ PERROR("Error allocating bitmap");
|
||||
goto err;
|
||||
}
|
||||
DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages);
|
||||
@@ -311,7 +311,7 @@ static xenpaging_t *xenpaging_init(domid
|
||||
rc = policy_init(paging);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- ERROR("Error initialising policy");
|
||||
+ PERROR("Error initialising policy");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -358,14 +358,14 @@ static int xenpaging_teardown(xenpaging_
|
||||
rc = xc_mem_paging_disable(xch, paging->mem_event.domain_id);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- ERROR("Error tearing down domain paging in xen");
|
||||
+ PERROR("Error tearing down domain paging in xen");
|
||||
}
|
||||
|
||||
/* Unbind VIRQ */
|
||||
rc = xc_evtchn_unbind(paging->mem_event.xce_handle, paging->mem_event.port);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- ERROR("Error unbinding event port");
|
||||
+ PERROR("Error unbinding event port");
|
||||
}
|
||||
paging->mem_event.port = -1;
|
||||
|
||||
@@ -373,7 +373,7 @@ static int xenpaging_teardown(xenpaging_
|
||||
rc = xc_evtchn_close(paging->mem_event.xce_handle);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- ERROR("Error closing event channel");
|
||||
+ PERROR("Error closing event channel");
|
||||
}
|
||||
paging->mem_event.xce_handle = NULL;
|
||||
|
||||
@@ -384,7 +384,7 @@ static int xenpaging_teardown(xenpaging_
|
||||
rc = xc_interface_close(xch);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- ERROR("Error closing connection to xen");
|
||||
+ PERROR("Error closing connection to xen");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -444,7 +444,7 @@ static int xenpaging_evict_page(xenpagin
|
||||
PROT_READ | PROT_WRITE, &gfn, 1);
|
||||
if ( page == NULL )
|
||||
{
|
||||
- ERROR("Error mapping page");
|
||||
+ PERROR("Error mapping page");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -452,8 +452,8 @@ static int xenpaging_evict_page(xenpagin
|
||||
ret = write_page(fd, page, i);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
+ PERROR("Error copying page");
|
||||
munmap(page, PAGE_SIZE);
|
||||
- ERROR("Error copying page");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -464,7 +464,7 @@ static int xenpaging_evict_page(xenpagin
|
||||
victim->gfn);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
- ERROR("Error evicting page");
|
||||
+ PERROR("Error evicting page");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ static int xenpaging_populate_page(xenpa
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
- ERROR("Error preparing for page in");
|
||||
+ PERROR("Error preparing for page in");
|
||||
goto out_map;
|
||||
}
|
||||
}
|
||||
@@ -532,7 +532,7 @@ static int xenpaging_populate_page(xenpa
|
||||
PROT_READ | PROT_WRITE, &gfn, 1);
|
||||
if ( page == NULL )
|
||||
{
|
||||
- ERROR("Error mapping page: page is null");
|
||||
+ PERROR("Error mapping page: page is null");
|
||||
goto out_map;
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ static int xenpaging_populate_page(xenpa
|
||||
ret = read_page(fd, page, i);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
- ERROR("Error reading page");
|
||||
+ PERROR("Error reading page");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -579,7 +579,7 @@ static int evict_victim(xenpaging_t *pag
|
||||
{
|
||||
if ( j++ % 1000 == 0 )
|
||||
if ( xenpaging_mem_paging_flush_ioemu_cache(paging) )
|
||||
- ERROR("Error flushing ioemu cache");
|
||||
+ PERROR("Error flushing ioemu cache");
|
||||
}
|
||||
}
|
||||
while ( ret );
|
||||
@@ -670,7 +670,7 @@ int main(int argc, char *argv[])
|
||||
rc = xenpaging_wait_for_event_or_timeout(paging);
|
||||
if ( rc < 0 )
|
||||
{
|
||||
- ERROR("Error getting event");
|
||||
+ PERROR("Error getting event");
|
||||
goto out;
|
||||
}
|
||||
else if ( rc != 0 )
|
||||
@@ -710,7 +710,7 @@ int main(int argc, char *argv[])
|
||||
rc = xenpaging_populate_page(paging, req.gfn, fd, i);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- ERROR("Error populating page");
|
||||
+ PERROR("Error populating page");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -723,7 +723,7 @@ int main(int argc, char *argv[])
|
||||
rc = xenpaging_resume_page(paging, &rsp, 1);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- ERROR("Error resuming page");
|
||||
+ PERROR("Error resuming page");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -754,7 +754,7 @@ int main(int argc, char *argv[])
|
||||
rc = xenpaging_resume_page(paging, &rsp, 0);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- ERROR("Error resuming");
|
||||
+ PERROR("Error resuming");
|
||||
goto out;
|
||||
}
|
||||
}
|
120
xenpaging.watch-target-tot_pages.patch
Normal file
120
xenpaging.watch-target-tot_pages.patch
Normal file
@ -0,0 +1,120 @@
|
||||
# HG changeset patch
|
||||
# Parent 0d872bf1203dd36200477f688908797875035b50
|
||||
xenpaging: watch the guests memory/target-tot_pages xenstore value
|
||||
|
||||
Subsequent patches will use xenstored to store the numbers of pages
|
||||
xenpaging is suppose to page-out.
|
||||
Remove num_pages and use target_pages instead.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 51 +++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 50 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -19,8 +19,10 @@
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 600
|
||||
+#define _GNU_SOURCE
|
||||
|
||||
#include <inttypes.h>
|
||||
+#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
@@ -35,6 +37,10 @@
|
||||
#include "policy.h"
|
||||
#include "xenpaging.h"
|
||||
|
||||
+/* Defines number of mfns a guest should use at a time, in KiB */
|
||||
+#define WATCH_TARGETPAGES "memory/target-tot_pages"
|
||||
+static char *watch_target_tot_pages;
|
||||
+static char *dom_path;
|
||||
static char watch_token[16];
|
||||
static char filename[80];
|
||||
static int interrupted;
|
||||
@@ -72,7 +78,7 @@ static int xenpaging_wait_for_event_or_t
|
||||
{
|
||||
xc_interface *xch = paging->xc_handle;
|
||||
xc_evtchn *xce = paging->mem_event.xce_handle;
|
||||
- char **vec;
|
||||
+ char **vec, *val;
|
||||
unsigned int num;
|
||||
struct pollfd fd[2];
|
||||
int port;
|
||||
@@ -111,6 +117,25 @@ static int xenpaging_wait_for_event_or_t
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
+ else if ( strcmp(vec[XS_WATCH_PATH], watch_target_tot_pages) == 0 )
|
||||
+ {
|
||||
+ int ret, target_tot_pages;
|
||||
+ val = xs_read(paging->xs_handle, XBT_NULL, vec[XS_WATCH_PATH], NULL);
|
||||
+ if ( val )
|
||||
+ {
|
||||
+ ret = sscanf(val, "%d", &target_tot_pages);
|
||||
+ if ( ret > 0 )
|
||||
+ {
|
||||
+ /* KiB to pages */
|
||||
+ target_tot_pages >>= 2;
|
||||
+ if ( target_tot_pages < 0 || target_tot_pages > paging->max_pages )
|
||||
+ target_tot_pages = paging->max_pages;
|
||||
+ paging->target_tot_pages = target_tot_pages;
|
||||
+ DPRINTF("new target_tot_pages %d\n", target_tot_pages);
|
||||
+ }
|
||||
+ free(val);
|
||||
+ }
|
||||
+ }
|
||||
free(vec);
|
||||
}
|
||||
}
|
||||
@@ -216,6 +241,25 @@ static xenpaging_t *xenpaging_init(domid
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ /* Watch xenpagings working target */
|
||||
+ dom_path = xs_get_domain_path(paging->xs_handle, domain_id);
|
||||
+ if ( !dom_path )
|
||||
+ {
|
||||
+ PERROR("Could not find domain path\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+ if ( asprintf(&watch_target_tot_pages, "%s/%s", dom_path, WATCH_TARGETPAGES) < 0 )
|
||||
+ {
|
||||
+ PERROR("Could not alloc watch path\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+ DPRINTF("watching '%s'\n", watch_target_tot_pages);
|
||||
+ if ( xs_watch(paging->xs_handle, watch_target_tot_pages, "") == false )
|
||||
+ {
|
||||
+ PERROR("Could not bind to xenpaging watch\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
p = getenv("XENPAGING_POLICY_MRU_SIZE");
|
||||
if ( p && *p )
|
||||
{
|
||||
@@ -342,6 +386,8 @@ static xenpaging_t *xenpaging_init(domid
|
||||
free(paging->mem_event.ring_page);
|
||||
}
|
||||
|
||||
+ free(dom_path);
|
||||
+ free(watch_target_tot_pages);
|
||||
free(paging->bitmap);
|
||||
free(paging);
|
||||
}
|
||||
@@ -357,6 +403,9 @@ static int xenpaging_teardown(xenpaging_
|
||||
if ( paging == NULL )
|
||||
return 0;
|
||||
|
||||
+ xs_unwatch(paging->xs_handle, watch_target_tot_pages, "");
|
||||
+ xs_unwatch(paging->xs_handle, "@releaseDomain", watch_token);
|
||||
+
|
||||
xch = paging->xc_handle;
|
||||
paging->xc_handle = NULL;
|
||||
/* Tear down domain paging in Xen */
|
22
xenpaging.watch_event-DPRINTF.patch
Normal file
22
xenpaging.watch_event-DPRINTF.patch
Normal file
@ -0,0 +1,22 @@
|
||||
# HG changeset patch
|
||||
# Parent 5b764d6fc1e8165d9012cc8866ba08332fb13021
|
||||
xenpaging: add debug to show received watch event.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -108,6 +108,7 @@ static int xenpaging_wait_for_event_or_t
|
||||
vec = xs_read_watch(paging->xs_handle, &num);
|
||||
if ( vec )
|
||||
{
|
||||
+ DPRINTF("path '%s' token '%s'\n", vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]);
|
||||
if ( strcmp(vec[XS_WATCH_TOKEN], watch_token) == 0 )
|
||||
{
|
||||
/* If our guest disappeared, set interrupt flag and fall through */
|
73
xenpaging.xc_interface_open-comment.patch
Normal file
73
xenpaging.xc_interface_open-comment.patch
Normal file
@ -0,0 +1,73 @@
|
||||
# HG changeset patch
|
||||
# Parent c6014fd38d1f150dd433985f8388b4858ba5aaca
|
||||
xenpaging: update xenpaging_init
|
||||
|
||||
Move comment about xc_handle to the right place.
|
||||
Allocate paging early and use calloc.
|
||||
|
||||
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
||||
|
||||
---
|
||||
tools/xenpaging/xenpaging.c | 22 +++++++++++-----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
===================================================================
|
||||
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
|
||||
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
|
||||
@@ -169,18 +169,21 @@ static xenpaging_t *xenpaging_init(domid
|
||||
char *p;
|
||||
int rc;
|
||||
|
||||
+ /* Allocate memory */
|
||||
+ paging = calloc(1, sizeof(xenpaging_t));
|
||||
+ if ( !paging )
|
||||
+ goto err;
|
||||
+
|
||||
if ( getenv("XENPAGING_DEBUG") )
|
||||
dbg = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0);
|
||||
- xch = xc_interface_open(dbg, NULL, 0);
|
||||
+
|
||||
+ /* Open connection to xen */
|
||||
+ paging->xc_handle = xch = xc_interface_open(dbg, NULL, 0);
|
||||
if ( !xch )
|
||||
- goto err_iface;
|
||||
+ goto err;
|
||||
|
||||
DPRINTF("xenpaging init\n");
|
||||
|
||||
- /* Allocate memory */
|
||||
- paging = malloc(sizeof(xenpaging_t));
|
||||
- memset(paging, 0, sizeof(xenpaging_t));
|
||||
-
|
||||
/* Open connection to xenstore */
|
||||
paging->xs_handle = xs_open(0);
|
||||
if ( paging->xs_handle == NULL )
|
||||
@@ -204,9 +207,6 @@ static xenpaging_t *xenpaging_init(domid
|
||||
DPRINTF("Setting policy mru_size to %d\n", paging->policy_mru_size);
|
||||
}
|
||||
|
||||
- /* Open connection to xen */
|
||||
- paging->xc_handle = xch;
|
||||
-
|
||||
/* Set domain id */
|
||||
paging->mem_event.domain_id = domain_id;
|
||||
|
||||
@@ -322,7 +322,8 @@ static xenpaging_t *xenpaging_init(domid
|
||||
{
|
||||
if ( paging->xs_handle )
|
||||
xs_close(paging->xs_handle);
|
||||
- xc_interface_close(xch);
|
||||
+ if ( xch )
|
||||
+ xc_interface_close(xch);
|
||||
if ( paging->mem_event.shared_page )
|
||||
{
|
||||
munlock(paging->mem_event.shared_page, PAGE_SIZE);
|
||||
@@ -340,7 +341,6 @@ static xenpaging_t *xenpaging_init(domid
|
||||
free(paging);
|
||||
}
|
||||
|
||||
- err_iface:
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user