[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCHv2 08/10] xen/balloon: use hotplugged pages for foreign mappings etc.



On Fri, Jul 24, 2015 at 12:47:46PM +0100, David Vrabel wrote:
> alloc_xenballooned_pages() is used to get ballooned pages to back
> foreign mappings etc.  Instead of having to balloon out real pages,
> use (if supported) hotplugged memory.
> 
> This makes more memory available to the guest and reduces
> fragmentation in the p2m.
> 
> If userspace is lacking a udev rule (or similar) to online hotplugged

Is that udev rule already in distros?

> regions automatically, alloc_xenballooned_pages() will timeout and
> fall back to the old behaviour of ballooning out pages.
> 
> Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx>
> Reviewed-by: Daniel Kiper <daniel.kiper@xxxxxxxxxx>
> ---
>  drivers/xen/balloon.c | 32 ++++++++++++++++++++++++++------
>  include/xen/balloon.h |  1 +
>  2 files changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
> index cc68a4d..fd6970f3 100644
> --- a/drivers/xen/balloon.c
> +++ b/drivers/xen/balloon.c
> @@ -99,6 +99,7 @@ static xen_pfn_t frame_list[PAGE_SIZE / sizeof(unsigned 
> long)];
>  
>  /* List of ballooned pages, threaded through the mem_map array. */
>  static LIST_HEAD(ballooned_pages);
> +static DECLARE_WAIT_QUEUE_HEAD(balloon_wq);
>  
>  /* Main work function, always executed in process context. */
>  static void balloon_process(struct work_struct *work);
> @@ -127,6 +128,7 @@ static void __balloon_append(struct page *page)
>               list_add(&page->lru, &ballooned_pages);
>               balloon_stats.balloon_low++;
>       }
> +     wake_up(&balloon_wq);
>  }
>  
>  static void balloon_append(struct page *page)
> @@ -253,7 +255,8 @@ static enum bp_state reserve_additional_memory(void)
>       int nid, rc;
>       unsigned long balloon_hotplug;
>  
> -     credit = balloon_stats.target_pages - balloon_stats.total_pages;
> +     credit = balloon_stats.target_pages + balloon_stats.target_unpopulated
> +             - balloon_stats.total_pages;
>  
>       /*
>        * Already hotplugged enough pages?  Wait for them to be
> @@ -334,7 +337,7 @@ static struct notifier_block xen_memory_nb = {
>  static enum bp_state reserve_additional_memory(void)
>  {
>       balloon_stats.target_pages = balloon_stats.current_pages;
> -     return BP_DONE;
> +     return BP_ECANCELED;
>  }
>  #endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */
>  
> @@ -538,13 +541,31 @@ int alloc_xenballooned_pages(int nr_pages, struct page 
> **pages)
>  {
>       int pgno = 0;
>       struct page *page;
> +
>       mutex_lock(&balloon_mutex);
> +
> +     balloon_stats.target_unpopulated += nr_pages;
> +
>       while (pgno < nr_pages) {
>               page = balloon_retrieve(true);
>               if (page) {
>                       pages[pgno++] = page;
>               } else {
>                       enum bp_state st;
> +
> +                     st = reserve_additional_memory();
> +                     if (st != BP_ECANCELED) {
> +                             int ret;
> +
> +                             mutex_unlock(&balloon_mutex);
> +                             ret = wait_event_timeout(balloon_wq,
> +                                     !list_empty(&ballooned_pages),
> +                                     msecs_to_jiffies(100));
> +                             mutex_lock(&balloon_mutex);
> +                             if (ret > 0)
> +                                     continue;
> +                     }
> +
>                       st = decrease_reservation(nr_pages - pgno, GFP_USER);
>                       if (st != BP_DONE)
>                               goto out_undo;
> @@ -553,11 +574,8 @@ int alloc_xenballooned_pages(int nr_pages, struct page 
> **pages)
>       mutex_unlock(&balloon_mutex);
>       return 0;
>   out_undo:
> -     while (pgno)
> -             balloon_append(pages[--pgno]);
> -     /* Free the memory back to the kernel soon */
> -     schedule_delayed_work(&balloon_worker, 0);
>       mutex_unlock(&balloon_mutex);
> +     free_xenballooned_pages(pgno, pages);
>       return -ENOMEM;
>  }
>  EXPORT_SYMBOL(alloc_xenballooned_pages);
> @@ -578,6 +596,8 @@ void free_xenballooned_pages(int nr_pages, struct page 
> **pages)
>                       balloon_append(pages[i]);
>       }
>  
> +     balloon_stats.target_unpopulated -= nr_pages;
> +
>       /* The balloon may be too large now. Shrink it if needed. */
>       if (current_credit())
>               schedule_delayed_work(&balloon_worker, 0);
> diff --git a/include/xen/balloon.h b/include/xen/balloon.h
> index 83efdeb..d1767df 100644
> --- a/include/xen/balloon.h
> +++ b/include/xen/balloon.h
> @@ -8,6 +8,7 @@ struct balloon_stats {
>       /* We aim for 'current allocation' == 'target allocation'. */
>       unsigned long current_pages;
>       unsigned long target_pages;
> +     unsigned long target_unpopulated;
>       /* Number of pages in high- and low-memory balloons. */
>       unsigned long balloon_low;
>       unsigned long balloon_high;
> -- 
> 2.1.4
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.