Date: Sat, 21 Jun 2014 08:31:21 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: Roger Pau Monn? <roger.pau@citrix.com> Cc: virtualization@FreeBSD.org, "freebsd-xen@freebsd.org" <freebsd-xen@freebsd.org>, bryanv@FreeBSD.org Subject: Re: FreeBSD and memory balloon drivers Message-ID: <20140621053121.GK3991@kib.kiev.ua> In-Reply-To: <53A467B4.8070501@citrix.com> References: <53A40079.9000804@citrix.com> <20140620132816.GH3991@kib.kiev.ua> <53A4501F.4020201@citrix.com> <20140620152610.GI3991@kib.kiev.ua> <53A467B4.8070501@citrix.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--N7OK10pvBj1bDp4V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Fri, Jun 20, 2014 at 06:56:20PM +0200, Roger Pau Monn? wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>=20
> On 20/06/14 17:26, Konstantin Belousov wrote:
> > On Fri, Jun 20, 2014 at 05:15:43PM +0200, Roger Pau Monn? wrote:
> >> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
> >>=20
> >> On 20/06/14 15:28, Konstantin Belousov wrote:
> >>> On Fri, Jun 20, 2014 at 11:35:53AM +0200, Roger Pau Monn?
> >>> wrote:
> >>>> Hello,
> >>>>=20
> >>>> I've been looking into the Xen balloon driver, because I've=20
> >>>> experienced problems when ballooning memory down which AFAICT
> >>>> are also present in the VirtIO balloon driver. The problem
> >>>> I've experienced is that when ballooning memory down, we
> >>>> basically allocate a bunch of memory as WIRED, to make sure
> >>>> nobody tries to swap it do disk, since it will crash the
> >>>> kernel because the memory is not populated. Due to this
> >>>> massive amount of memory allocated as WIRED, user-space
> >>>> programs that try to use mlock will fail because we hit the
> >>>> limit in vm.max_wired.
> >>>>=20
> >>>> I'm not sure what's the best way to deal with this
> >>>> limitation, should vm.max_wired be changed from the balloon
> >>>> drivers when ballooning down/up? Is there anyway to remove
> >>>> the pages ballooned down from the memory accounting of wired
> >>>> pages?
> >>>=20
> >>> You could change the type of pages the ballon driver is=20
> >>> allocating. Instead of wired pages, you may request unmanaged,
> >>> by passing NULL object to vm_page_alloc(). This would also
> >>> save on the trie nodes for managing the radix trie for the
> >>> object. There are still plinks or listq to keep track of the
> >>> allocated pages.
> >>=20
> >> Thanks for the info, I have the following patch which fixes the
> >> usage of WIRED for both the Xen and the VirtIO balloon drivers,
> >> could someone please test the VirtIO side?
> > I briefly looked at the xen balloon. You do not need
> > balloon_append(). Use struct vm_page plinks field to link the
> > pages.
>=20
> Sure, thanks for the review, here is an updated version.
It looks fine to me.
>=20
> Roger.
>=20
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.12 (Darwin)
>=20
> iQEcBAEBAgAGBQJTpGe0AAoJEKXZdqUyumTA5acH/jQ+Iwjw+QTwUtsh9ZLs7Gm0
> h7XaCwa/gASEjzcxK2smIBuKA10LUSoulcYkC3cUWXqaPwFega14JcbySBRI06Z1
> 1bU50DL8TPLuQIzrVWZgtA+QsZkwEu/jhijr0AMxTcnm6Wq1LV5QRDoqhD0kRiHu
> kEW1ez832y/0j+oeQAq0aR67zVw7hoIouH9eLaWXS4Vgxz5YQ2Pal1BMAY/OCgua
> xyF7BHia9KsGTKZ9pPUQfQAW5eJrwAxR0AitQjmOwRKtWyRqymZxhYHjLYOgOKQJ
> w93aLRVeG2oo0NNC6a9JD/c64sGHLABg37mnSTRL/v9gTj9I1DcFoid2q0iDGbM=3D
> =3D8nDn
> -----END PGP SIGNATURE-----
> >From e5c898b1b2b734fdc4aa2acf645efd481f09b71d Mon Sep 17 00:00:00 2001
> From: Roger Pau Monne <roger.pau@citrix.com>
> Date: Fri, 20 Jun 2014 16:34:31 +0200
> Subject: [PATCH] xen/virtio: fix balloon drivers to not mark pages as WIR=
ED
>=20
> Prevent the Xen and VirtIO balloon drivers from marking pages as
> wired. This prevents them from increasing the system wired page count,
> which can lead to mlock failing because of hitting the limit in
> vm.max_wired.
>=20
> In the Xen case make sure pages are zeroed before giving them back to
> the hypervisor, or else we might be leaking data. Also remove the
> balloon_{append/retrieve} and link pages directly into the
> ballooned_pages queue using the plinks.q field in the page struct.
>=20
> Sponsored by: Citrix Systems R&D
> Reviewed by: xxx
> Approved by: xxx
>=20
> dev/virtio/balloon/virtio_balloon.c:
> - Don't allocate pages with VM_ALLOC_WIRED.
>=20
> dev/xen/balloon/balloon.c:
> - Don't allocate pages with VM_ALLOC_WIRED.
> - Make sure pages are zeroed before giving them back to the
> hypervisor.
> - Remove the balloon_entry struct and the balloon_{append/retrieve}
> functions and use the page plinks.q entry to link the pages
> directly into the ballooned_pages queue.
> ---
> sys/dev/virtio/balloon/virtio_balloon.c | 4 +-
> sys/dev/xen/balloon/balloon.c | 87 ++++++++-----------------=
------
> 2 files changed, 23 insertions(+), 68 deletions(-)
>=20
> diff --git a/sys/dev/virtio/balloon/virtio_balloon.c b/sys/dev/virtio/bal=
loon/virtio_balloon.c
> index d540099..6d00ef3 100644
> --- a/sys/dev/virtio/balloon/virtio_balloon.c
> +++ b/sys/dev/virtio/balloon/virtio_balloon.c
> @@ -438,8 +438,7 @@ vtballoon_alloc_page(struct vtballoon_softc *sc)
> {
> vm_page_t m;
> =20
> - m =3D vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_WIRED |
> - VM_ALLOC_NOOBJ);
> + m =3D vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ);
> if (m !=3D NULL)
> sc->vtballoon_current_npages++;
> =20
> @@ -450,7 +449,6 @@ static void
> vtballoon_free_page(struct vtballoon_softc *sc, vm_page_t m)
> {
> =20
> - vm_page_unwire(m, PQ_INACTIVE);
> vm_page_free(m);
> sc->vtballoon_current_npages--;
> }
> diff --git a/sys/dev/xen/balloon/balloon.c b/sys/dev/xen/balloon/balloon.c
> index fa56c86..0d2bba2 100644
> --- a/sys/dev/xen/balloon/balloon.c
> +++ b/sys/dev/xen/balloon/balloon.c
> @@ -94,13 +94,8 @@ SYSCTL_ULONG(_dev_xen_balloon, OID_AUTO, low_mem, CTLF=
LAG_RD,
> SYSCTL_ULONG(_dev_xen_balloon, OID_AUTO, high_mem, CTLFLAG_RD,
> &bs.balloon_high, 0, "High-mem balloon");
> =20
> -struct balloon_entry {
> - vm_page_t page;
> - STAILQ_ENTRY(balloon_entry) list;
> -};
> -
> /* List of ballooned pages, threaded through the mem_map array. */
> -static STAILQ_HEAD(,balloon_entry) ballooned_pages;
> +static TAILQ_HEAD(,vm_page) ballooned_pages;
> =20
> /* Main work function, always executed in process context. */
> static void balloon_process(void *unused);
> @@ -110,47 +105,6 @@ static void balloon_process(void *unused);
> #define WPRINTK(fmt, args...) \
> printk(KERN_WARNING "xen_mem: " fmt, ##args)
> =20
> -/* balloon_append: add the given page to the balloon. */
> -static int
> -balloon_append(vm_page_t page)
> -{
> - struct balloon_entry *entry;
> -
> - mtx_assert(&balloon_mutex, MA_OWNED);
> -
> - entry =3D malloc(sizeof(struct balloon_entry), M_BALLOON, M_NOWAIT);
> - if (!entry)
> - return (ENOMEM);
> - entry->page =3D page;
> - STAILQ_INSERT_HEAD(&ballooned_pages, entry, list);
> - bs.balloon_low++;
> -
> - return (0);
> -}
> -
> -/* balloon_retrieve: rescue a page from the balloon, if it is not empty.=
*/
> -static vm_page_t
> -balloon_retrieve(void)
> -{
> - vm_page_t page;
> - struct balloon_entry *entry;
> -
> - mtx_assert(&balloon_mutex, MA_OWNED);
> -
> - if (STAILQ_EMPTY(&ballooned_pages))
> - return (NULL);
> -
> - entry =3D STAILQ_FIRST(&ballooned_pages);
> - STAILQ_REMOVE_HEAD(&ballooned_pages, list);
> -
> - page =3D entry->page;
> - free(entry, M_BALLOON);
> -=09
> - bs.balloon_low--;
> -
> - return (page);
> -}
> -
> static unsigned long=20
> current_target(void)
> {
> @@ -203,7 +157,6 @@ static int
> increase_reservation(unsigned long nr_pages)
> {
> unsigned long pfn, i;
> - struct balloon_entry *entry;
> vm_page_t page;
> long rc;
> struct xen_memory_reservation reservation =3D {
> @@ -217,10 +170,9 @@ increase_reservation(unsigned long nr_pages)
> if (nr_pages > nitems(frame_list))
> nr_pages =3D nitems(frame_list);
> =20
> - for (entry =3D STAILQ_FIRST(&ballooned_pages), i =3D 0;
> - i < nr_pages; i++, entry =3D STAILQ_NEXT(entry, list)) {
> - KASSERT(entry, ("ballooned_pages list corrupt"));
> - page =3D entry->page;
> + for (page =3D TAILQ_FIRST(&ballooned_pages), i =3D 0;
> + i < nr_pages; i++, page =3D TAILQ_NEXT(page, plinks.q)) {
> + KASSERT(page !=3D NULL, ("ballooned_pages list corrupt"));
> frame_list[i] =3D (VM_PAGE_TO_PHYS(page) >> PAGE_SHIFT);
> }
> =20
> @@ -245,8 +197,10 @@ increase_reservation(unsigned long nr_pages)
> }
> =20
> for (i =3D 0; i < nr_pages; i++) {
> - page =3D balloon_retrieve();
> - KASSERT(page, ("balloon_retrieve failed"));
> + page =3D TAILQ_FIRST(&ballooned_pages);
> + KASSERT(page !=3D NULL, ("Unable to get ballooned page"));
> + TAILQ_REMOVE(&ballooned_pages, page, plinks.q);
> + bs.balloon_low--;
> =20
> pfn =3D (VM_PAGE_TO_PHYS(page) >> PAGE_SHIFT);
> KASSERT((xen_feature(XENFEAT_auto_translated_physmap) ||
> @@ -255,7 +209,6 @@ increase_reservation(unsigned long nr_pages)
> =20
> set_phys_to_machine(pfn, frame_list[i]);
> =20
> - vm_page_unwire(page, PQ_INACTIVE);
> vm_page_free(page);
> }
> =20
> @@ -286,24 +239,27 @@ decrease_reservation(unsigned long nr_pages)
> for (i =3D 0; i < nr_pages; i++) {
> if ((page =3D vm_page_alloc(NULL, 0,=20
> VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ |=20
> - VM_ALLOC_WIRED | VM_ALLOC_ZERO)) =3D=3D NULL) {
> + VM_ALLOC_ZERO)) =3D=3D NULL) {
> nr_pages =3D i;
> need_sleep =3D 1;
> break;
> }
> =20
> + if ((page->flags & PG_ZERO) =3D=3D 0) {
> + /*
> + * Zero the page, or else we might be leaking
> + * important data to other domains on the same
> + * host.
> + */
> + pmap_zero_page(page);
> + }
> +
> pfn =3D (VM_PAGE_TO_PHYS(page) >> PAGE_SHIFT);
> frame_list[i] =3D PFNTOMFN(pfn);
> =20
> set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
> - if (balloon_append(page) !=3D 0) {
> - vm_page_unwire(page, PQ_INACTIVE);
> - vm_page_free(page);
> -
> - nr_pages =3D i;
> - need_sleep =3D 1;
> - break;
> - }
> + TAILQ_INSERT_HEAD(&ballooned_pages, page, plinks.q);
> + bs.balloon_low++;
> }
> =20
> set_xen_guest_handle(reservation.extent_start, frame_list);
> @@ -438,7 +394,8 @@ balloon_init(void *arg)
> /* Initialise the balloon with excess memory space. */
> for (pfn =3D xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
> page =3D PHYS_TO_VM_PAGE(pfn << PAGE_SHIFT);
> - balloon_append(page);
> + TAILQ_INSERT_HEAD(&ballooned_pages, page, plinks.q);
> + bs.balloon_low++;
> }
> #undef max_pfn
> #endif
> --=20
> 1.7.7.5 (Apple Git-26)
>=20
--N7OK10pvBj1bDp4V
Content-Type: application/pgp-signature
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAEBAgAGBQJTpRioAAoJEJDCuSvBvK1BSxEP/1Oxdr7ActnPpw7M6pRHqXMe
63ZkiIdwovfBdABA/Qs/+EAgCuPxbZmaD3e3b/1ypi/qXihB4kbnWTTneXUei5NF
7Xot0YppkCmnKLiGiku3rV/biIFjmTJg5aCsrKdTpQfHCG1WInDwWZTW4UlMwkf2
j05qqBY6CeI8ckvmGDDZPpVAtnUnMI0AQOV2hve77kN3zWisxHG3qsBpCFIsDLAk
9eNBKasKHVWZlDTj1SHT9Fk3UgEqNOoSdOPgeMA+RMNAerLlg6uQXkdFZL8+nCA9
KzChvmglVepdC46qwai2UgkCr7ikEy6btijb4d+3pr0+XbzlfOCJ5nduwaYN72Uz
7qgxpX3AgagBIdLfv1zBtWX7K1fbQVkCLIe0pwPqKw8fAUP1lu2TmjsU+Ziq6wLa
ncN0Lafh3sihUt6rsrW2GGFTtXiWqJqtb2QHdLYgxA7F27OupxLXl+ZXFgqTHSdc
BXOFsE6NxtGkf8U9dnNHgHVDDyXKTMzy8/VblRxw2VIBSPV4ilCOXuE8E0+3/ASg
mFZv2o8Yr7SO5OHouZAdKYvtW29Ch4YYl1HvJJt+ZHgZmvGQiv9HUqzPJvgOGrKK
tNth+Vcbp14xEhgHrnuJeymtAa39hhBXJVvgOQJRJsWpyhhycLCAaIgr8h0qC8A/
Ax1qZuC61xLOmFWRHPMf
=fFv2
-----END PGP SIGNATURE-----
--N7OK10pvBj1bDp4V--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140621053121.GK3991>
