]> xenbits.xensource.com Git - people/liuw/linux.git/commitdiff
XXX: balloon bitmap and sysrq key to dump bitmap wip.balloon-compaction-rfc
authorWei Liu <wei.liu2@citrix.com>
Wed, 15 Oct 2014 11:37:23 +0000 (12:37 +0100)
committerWei Liu <wei.liu2@citrix.com>
Wed, 15 Oct 2014 15:31:39 +0000 (16:31 +0100)
Maintain a bitmap of balloon pages to give intuitive overview of their
locations.

Write 'x' to /proc/sysrq-trigger to print out this bitmap.

This patch is only for debugging purpose.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
drivers/xen/balloon.c

index 112190e257a15106ae9272cc035eb6bf891c4ce0..9af620686c9aae9d9c3c057a308775863a58af77 100644 (file)
 #include <linux/memory.h>
 #include <linux/memory_hotplug.h>
 #include <linux/percpu-defs.h>
+#include <linux/bitmap.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/sysrq.h>
 
 #include <asm/page.h>
 #include <asm/pgalloc.h>
@@ -102,6 +106,53 @@ static void scrub_page(struct page *page)
 #endif
 }
 
+static unsigned long *balloon_bitmap;
+static unsigned long balloon_bitmap_len;
+
+static inline void xen_balloon_bitmap_init(void)
+{
+       balloon_bitmap_len = BITS_TO_LONGS(max_pfn);
+       balloon_bitmap = kzalloc(balloon_bitmap_len * sizeof(unsigned long),
+                                GFP_KERNEL);
+       /* XXX: this bitmap is only for debugging anyway... */
+       BUG_ON(!balloon_bitmap);
+}
+
+static inline void xen_balloon_bitmap_set(struct page *page)
+{
+       unsigned long pfn = page_to_pfn(page);
+       set_bit(pfn, balloon_bitmap);
+}
+
+static inline void xen_balloon_bitmap_clear(struct page *page)
+{
+       unsigned long pfn = page_to_pfn(page);
+       clear_bit(pfn, balloon_bitmap);
+}
+
+void xen_balloon_bitmap_dump(void)
+{
+       unsigned long i;
+
+       for (i = 0; i < balloon_bitmap_len; i++) {
+               if ((i % 8) == 0)
+                       printk("%8lu: ", i);
+               printk("%016lx ", balloon_bitmap[i]);
+               if (((i + 1) % 8) == 0)
+                       printk("\n");
+       }
+}
+
+static void sysrq_handle_dump_xen_balloon_bitmap(int key)
+{
+       xen_balloon_bitmap_dump();
+}
+static struct sysrq_key_op sysrq_xen_op = {
+       .handler        = sysrq_handle_dump_xen_balloon_bitmap,
+       .help_msg       = "dump-balloon-bitmap(x)",
+       .action_msg     = "Dump balloon bitmap",
+};
+
 static inline void update_balloon_stats(struct page *page, int count)
 {
        if (PageHighMem(page))
@@ -132,6 +183,7 @@ static void balloon_append(struct page *page, bool managed)
 {
        __balloon_append(page, managed);
        adjust_managed_page_count(page, -1);
+       xen_balloon_bitmap_set(page);
 }
 
 /* balloon_retrieve: rescue a page from Xen balloon driver, if it is
@@ -449,6 +501,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
                /* We only account for those pages that have been populated. */
                update_balloon_stats(page, -1);
                adjust_managed_page_count(page, 1);
+               xen_balloon_bitmap_clear(page);
        }
 
        xen_balloon.balloon_stats.current_pages += rc;
@@ -622,6 +675,7 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
                        pages[pgno++] = page;
                        update_balloon_stats(page, -1);
                        adjust_managed_page_count(page, 1);
+                       xen_balloon_bitmap_clear(page);
                } else {
                        enum bp_state st;
                        gfp_t gfp = highmem ? GFP_HIGHUSER : GFP_USER;
@@ -818,6 +872,9 @@ static int xen_balloon_migratepage(struct address_space *mapping,
 
        rc = MIGRATEPAGE_BALLOON_SUCCESS;
 
+       xen_balloon_bitmap_clear(page);
+       xen_balloon_bitmap_set(newpage);
+
        flush_tlb_all();
 out:
        mutex_unlock(&xb->balloon_mutex);
@@ -911,6 +968,9 @@ static int __init balloon_init(void)
                        balloon_add_region(PFN_UP(xen_extra_mem[i].start),
                                           PFN_DOWN(xen_extra_mem[i].size));
 
+       xen_balloon_bitmap_init();
+       register_sysrq_key('x', &sysrq_xen_op);
+
        return 0;
 
 out_free_xb_dev_info: