#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>
#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))
{
__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
/* 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;
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;
rc = MIGRATEPAGE_BALLOON_SUCCESS;
+ xen_balloon_bitmap_clear(page);
+ xen_balloon_bitmap_set(newpage);
+
flush_tlb_all();
out:
mutex_unlock(&xb->balloon_mutex);
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: