]> xenbits.xensource.com Git - people/liuw/linux.git/commitdiff
balloon_compaction: don't BUG() when it is not necessary
authorWei Liu <wei.liu2@citrix.com>
Tue, 4 Mar 2014 15:30:27 +0000 (15:30 +0000)
committerWei Liu <wei.liu2@citrix.com>
Wed, 15 Oct 2014 14:50:48 +0000 (15:50 +0100)
Xen balloon driver has several sources for ballooned pages.  One of the
sources will be generic balloon driver, in the sense that Xen balloon
driver gets pages from that.

When Xen balloon driver asks for a page from these sources, generic
balloon driver might not have enough pages to return to caller. In that
case we don't want to call BUG(). Simply return NULL will be sufficient.

So this patch introduces a flag indicating if caller want to be very
strict about empty list in generic balloon driver. If the flag is set to
true, generic balloon driver calls BUG() when a request cannot be
satisfied, which is the same behavior as before; otherwise it will just
return NULL and let caller handle that situation.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
drivers/virtio/virtio_balloon.c
include/linux/balloon_compaction.h
mm/balloon_compaction.c

index 25ebe8eecdb7397be646623775bd42c538ba0100..97337316cbe6d448b2e954e0e5e89229160cdbd2 100644 (file)
@@ -179,7 +179,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
        mutex_lock(&vb->balloon_lock);
        for (vb->num_pfns = 0; vb->num_pfns < num;
             vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
-               page = balloon_page_dequeue(vb_dev_info);
+               page = balloon_page_dequeue(vb_dev_info, true);
                if (!page)
                        break;
                set_page_pfns(vb->pfns + vb->num_pfns, page);
index 089743ade734fc564e18bfa7be35608da68d6fde..1e1f888cbc347f3ce28cd07fac9689b6ba840d91 100644 (file)
@@ -62,7 +62,8 @@ struct balloon_dev_info {
 };
 
 extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info);
-extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info);
+extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info,
+                                        bool strict);
 extern struct balloon_dev_info *balloon_devinfo_alloc(
                                                void *balloon_dev_descriptor);
 
index 6e45a5074bf023b85896b1feb01198a5f1c652ff..d604e8395554d3fd51ac1e3bd50c935b265854c9 100644 (file)
@@ -72,14 +72,17 @@ EXPORT_SYMBOL_GPL(balloon_page_enqueue);
  * balloon_page_dequeue - removes a page from balloon's page list and returns
  *                       the its address to allow the driver release the page.
  * @b_dev_info: balloon device decriptor where we will grab a page from.
+ * @strict: strictly bookkeep number of pages.
  *
  * Driver must call it to properly de-allocate a previous enlisted balloon page
  * before definetively releasing it back to the guest system.
  * This function returns the page address for the recently dequeued page or
  * NULL in the case we find balloon's page list temporarily empty due to
- * compaction isolated pages.
+ * compaction isolated pages. If @strict is set to true and caller asks for
+ * more pages than we have, BUG().
  */
-struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
+struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info,
+                                 bool strict)
 {
        struct page *page, *tmp;
        unsigned long flags;
@@ -122,7 +125,7 @@ struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
                 */
                spin_lock_irqsave(&b_dev_info->pages_lock, flags);
                if (unlikely(list_empty(&b_dev_info->pages) &&
-                            !b_dev_info->isolated_pages))
+                            !b_dev_info->isolated_pages) && strict)
                        BUG();
                spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
                page = NULL;