[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 03/10] xen/balloon: consolidate data structures
Put Xen balloon mutex, page list and stats in to struct xen_balloon, so that we can easily back-reference those structures. Page migration callback will need to get hold of those structures in later patch(es). No functional change is introduced. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- drivers/xen/balloon.c | 168 ++++++++++++++++++++++++--------------------- drivers/xen/xen-balloon.c | 24 ++++--- include/xen/balloon.h | 15 +++- 3 files changed, 119 insertions(+), 88 deletions(-) diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 30a0baf..d8055f0 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -84,20 +84,13 @@ enum bp_state { BP_ECANCELED }; - -static DEFINE_MUTEX(balloon_mutex); - -struct balloon_stats balloon_stats; -EXPORT_SYMBOL_GPL(balloon_stats); +struct xen_balloon xen_balloon; +EXPORT_SYMBOL_GPL(xen_balloon); /* We increase/decrease in batches which fit in a page */ static xen_pfn_t frame_list[PAGE_SIZE / sizeof(unsigned long)]; static DEFINE_PER_CPU(struct page *, balloon_scratch_page); - -/* List of ballooned pages, threaded through the mem_map array. */ -static LIST_HEAD(ballooned_pages); - /* Main work function, always executed in process context. */ static void balloon_process(struct work_struct *work); static DECLARE_DELAYED_WORK(balloon_worker, balloon_process); @@ -119,11 +112,11 @@ static void __balloon_append(struct page *page) { /* Lowmem is re-populated first, so highmem pages go at list tail. */ if (PageHighMem(page)) { - list_add_tail(&page->lru, &ballooned_pages); - balloon_stats.balloon_high++; + list_add_tail(&page->lru, &xen_balloon.ballooned_pages); + xen_balloon.balloon_stats.balloon_high++; } else { - list_add(&page->lru, &ballooned_pages); - balloon_stats.balloon_low++; + list_add(&page->lru, &xen_balloon.ballooned_pages); + xen_balloon.balloon_stats.balloon_low++; } } @@ -138,19 +131,21 @@ static struct page *balloon_retrieve(bool prefer_highmem) { struct page *page; - if (list_empty(&ballooned_pages)) + if (list_empty(&xen_balloon.ballooned_pages)) return NULL; if (prefer_highmem) - page = list_entry(ballooned_pages.prev, struct page, lru); + page = list_entry(xen_balloon.ballooned_pages.prev, + struct page, lru); else - page = list_entry(ballooned_pages.next, struct page, lru); + page = list_entry(xen_balloon.ballooned_pages.next, + struct page, lru); list_del(&page->lru); if (PageHighMem(page)) - balloon_stats.balloon_high--; + xen_balloon.balloon_stats.balloon_high--; else - balloon_stats.balloon_low--; + xen_balloon.balloon_stats.balloon_low--; adjust_managed_page_count(page, 1); @@ -160,7 +155,7 @@ static struct page *balloon_retrieve(bool prefer_highmem) static struct page *balloon_next_page(struct page *page) { struct list_head *next = page->lru.next; - if (next == &ballooned_pages) + if (next == &xen_balloon.ballooned_pages) return NULL; return list_entry(next, struct page, lru); } @@ -168,24 +163,27 @@ static struct page *balloon_next_page(struct page *page) static enum bp_state update_schedule(enum bp_state state) { if (state == BP_DONE) { - balloon_stats.schedule_delay = 1; - balloon_stats.retry_count = 1; + xen_balloon.balloon_stats.schedule_delay = 1; + xen_balloon.balloon_stats.retry_count = 1; return BP_DONE; } - ++balloon_stats.retry_count; + ++xen_balloon.balloon_stats.retry_count; - if (balloon_stats.max_retry_count != RETRY_UNLIMITED && - balloon_stats.retry_count > balloon_stats.max_retry_count) { - balloon_stats.schedule_delay = 1; - balloon_stats.retry_count = 1; + if (xen_balloon.balloon_stats.max_retry_count != RETRY_UNLIMITED && + xen_balloon.balloon_stats.retry_count > + xen_balloon.balloon_stats.max_retry_count) { + xen_balloon.balloon_stats.schedule_delay = 1; + xen_balloon.balloon_stats.retry_count = 1; return BP_ECANCELED; } - balloon_stats.schedule_delay <<= 1; + xen_balloon.balloon_stats.schedule_delay <<= 1; - if (balloon_stats.schedule_delay > balloon_stats.max_schedule_delay) - balloon_stats.schedule_delay = balloon_stats.max_schedule_delay; + if (xen_balloon.balloon_stats.schedule_delay > + xen_balloon.balloon_stats.max_schedule_delay) + xen_balloon.balloon_stats.schedule_delay = + xen_balloon.balloon_stats.max_schedule_delay; return BP_EAGAIN; } @@ -193,14 +191,16 @@ static enum bp_state update_schedule(enum bp_state state) #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG static long current_credit(void) { - return balloon_stats.target_pages - balloon_stats.current_pages - - balloon_stats.hotplug_pages; + return xen_balloon.balloon_stats.target_pages - + xen_balloon.balloon_stats.current_pages - + xen_balloon.balloon_stats.hotplug_pages; } static bool balloon_is_inflated(void) { - if (balloon_stats.balloon_low || balloon_stats.balloon_high || - balloon_stats.balloon_hotplug) + if (xen_balloon.balloon_stats.balloon_low || + xen_balloon.balloon_stats.balloon_high || + xen_balloon.balloon_stats.balloon_hotplug) return true; else return false; @@ -236,8 +236,8 @@ static enum bp_state reserve_additional_memory(long credit) balloon_hotplug -= credit; - balloon_stats.hotplug_pages += credit; - balloon_stats.balloon_hotplug = balloon_hotplug; + xen_balloon.balloon_stats.hotplug_pages += credit; + xen_balloon.balloon_stats.balloon_hotplug = balloon_hotplug; return BP_DONE; } @@ -246,16 +246,16 @@ static void xen_online_page(struct page *page) { __online_page_set_limits(page); - mutex_lock(&balloon_mutex); + mutex_lock(&xen_balloon.balloon_mutex); __balloon_append(page); - if (balloon_stats.hotplug_pages) - --balloon_stats.hotplug_pages; + if (xen_balloon.balloon_stats.hotplug_pages) + --xen_balloon.balloon_stats.hotplug_pages; else - --balloon_stats.balloon_hotplug; + --xen_balloon.balloon_stats.balloon_hotplug; - mutex_unlock(&balloon_mutex); + mutex_unlock(&xen_balloon.balloon_mutex); } static int xen_memory_notifier(struct notifier_block *nb, unsigned long val, void *v) @@ -273,19 +273,20 @@ static struct notifier_block xen_memory_nb = { #else static long current_credit(void) { - unsigned long target = balloon_stats.target_pages; + unsigned long target = xen_balloon.balloon_stats.target_pages; target = min(target, - balloon_stats.current_pages + - balloon_stats.balloon_low + - balloon_stats.balloon_high); + xen_balloon.balloon_stats.current_pages + + xen_balloon.balloon_stats.balloon_low + + xen_balloon.balloon_stats.balloon_high); - return target - balloon_stats.current_pages; + return target - xen_balloon.balloon_stats.current_pages; } static bool balloon_is_inflated(void) { - if (balloon_stats.balloon_low || balloon_stats.balloon_high) + if (xen_balloon.balloon_stats.balloon_low || + xen_balloon.balloon_stats.balloon_high) return true; else return false; @@ -293,7 +294,8 @@ static bool balloon_is_inflated(void) static enum bp_state reserve_additional_memory(long credit) { - balloon_stats.target_pages = balloon_stats.current_pages; + xen_balloon.balloon_stats.target_pages = + xen_balloon.balloon_stats.current_pages; return BP_DONE; } #endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */ @@ -310,10 +312,12 @@ static enum bp_state increase_reservation(unsigned long nr_pages) }; #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG - if (!balloon_stats.balloon_low && !balloon_stats.balloon_high) { - nr_pages = min(nr_pages, balloon_stats.balloon_hotplug); - balloon_stats.hotplug_pages += nr_pages; - balloon_stats.balloon_hotplug -= nr_pages; + if (!xen_balloon.balloon_stats.balloon_low && + !xen_balloon.balloon_stats.balloon_high) { + nr_pages = min(nr_pages, + xen_balloon.balloon_stats.balloon_hotplug); + xen_balloon.balloon_stats.hotplug_pages += nr_pages; + xen_balloon.balloon_stats.balloon_hotplug -= nr_pages; return BP_DONE; } #endif @@ -321,7 +325,8 @@ static enum bp_state increase_reservation(unsigned long nr_pages) if (nr_pages > ARRAY_SIZE(frame_list)) nr_pages = ARRAY_SIZE(frame_list); - page = list_first_entry_or_null(&ballooned_pages, struct page, lru); + page = list_first_entry_or_null(&xen_balloon.ballooned_pages, + struct page, lru); for (i = 0; i < nr_pages; i++) { if (!page) { nr_pages = i; @@ -363,7 +368,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages) __free_reserved_page(page); } - balloon_stats.current_pages += rc; + xen_balloon.balloon_stats.current_pages += rc; return BP_DONE; } @@ -381,10 +386,11 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) }; #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG - if (balloon_stats.hotplug_pages) { - nr_pages = min(nr_pages, balloon_stats.hotplug_pages); - balloon_stats.hotplug_pages -= nr_pages; - balloon_stats.balloon_hotplug += nr_pages; + if (xen_balloon.balloon_stats.hotplug_pages) { + nr_pages = min(nr_pages, + xen_balloon.balloon_stats.hotplug_pages); + xen_balloon.balloon_stats.hotplug_pages -= nr_pages; + xen_balloon.balloon_stats.balloon_hotplug += nr_pages; return BP_DONE; } #endif @@ -451,7 +457,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); BUG_ON(ret != nr_pages); - balloon_stats.current_pages -= nr_pages; + xen_balloon.balloon_stats.current_pages -= nr_pages; return state; } @@ -467,7 +473,7 @@ static void balloon_process(struct work_struct *work) enum bp_state state = BP_DONE; long credit; - mutex_lock(&balloon_mutex); + mutex_lock(&xen_balloon.balloon_mutex); do { credit = current_credit(); @@ -492,9 +498,10 @@ static void balloon_process(struct work_struct *work) /* Schedule more work if there is some still to be done. */ if (state == BP_EAGAIN) - schedule_delayed_work(&balloon_worker, balloon_stats.schedule_delay * HZ); + schedule_delayed_work(&balloon_worker, + xen_balloon.balloon_stats.schedule_delay * HZ); - mutex_unlock(&balloon_mutex); + mutex_unlock(&xen_balloon.balloon_mutex); } struct page *get_balloon_scratch_page(void) @@ -513,7 +520,7 @@ void put_balloon_scratch_page(void) void balloon_set_new_target(unsigned long target) { /* No need for lock. Not read-modify-write updates. */ - balloon_stats.target_pages = target; + xen_balloon.balloon_stats.target_pages = target; schedule_delayed_work(&balloon_worker, 0); } EXPORT_SYMBOL_GPL(balloon_set_new_target); @@ -529,7 +536,7 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem) { int pgno = 0; struct page *page; - mutex_lock(&balloon_mutex); + mutex_lock(&xen_balloon.balloon_mutex); while (pgno < nr_pages) { page = balloon_retrieve(highmem); if (page && (highmem || !PageHighMem(page))) { @@ -544,14 +551,14 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem) goto out_undo; } } - mutex_unlock(&balloon_mutex); + mutex_unlock(&xen_balloon.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); + mutex_unlock(&xen_balloon.balloon_mutex); return -ENOMEM; } EXPORT_SYMBOL(alloc_xenballooned_pages); @@ -566,7 +573,7 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) { int i; - mutex_lock(&balloon_mutex); + mutex_lock(&xen_balloon.balloon_mutex); for (i = 0; i < nr_pages; i++) { if (pages[i]) @@ -577,7 +584,7 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) if (current_credit()) schedule_delayed_work(&balloon_worker, 0); - mutex_unlock(&balloon_mutex); + mutex_unlock(&xen_balloon.balloon_mutex); } EXPORT_SYMBOL(free_xenballooned_pages); @@ -660,21 +667,28 @@ static int __init balloon_init(void) pr_info("Initialising balloon driver\n"); - balloon_stats.current_pages = xen_pv_domain() + memset(&xen_balloon, 0, sizeof(xen_balloon)); + + mutex_init(&xen_balloon.balloon_mutex); + + INIT_LIST_HEAD(&xen_balloon.ballooned_pages); + + xen_balloon.balloon_stats.current_pages = xen_pv_domain() ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn) : get_num_physpages(); - balloon_stats.target_pages = balloon_stats.current_pages; - balloon_stats.balloon_low = 0; - balloon_stats.balloon_high = 0; + xen_balloon.balloon_stats.target_pages = + xen_balloon.balloon_stats.current_pages; + xen_balloon.balloon_stats.balloon_low = 0; + xen_balloon.balloon_stats.balloon_high = 0; - balloon_stats.schedule_delay = 1; - balloon_stats.max_schedule_delay = 32; - balloon_stats.retry_count = 1; - balloon_stats.max_retry_count = RETRY_UNLIMITED; + xen_balloon.balloon_stats.schedule_delay = 1; + xen_balloon.balloon_stats.max_schedule_delay = 32; + xen_balloon.balloon_stats.retry_count = 1; + xen_balloon.balloon_stats.max_retry_count = RETRY_UNLIMITED; #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG - balloon_stats.hotplug_pages = 0; - balloon_stats.balloon_hotplug = 0; + xen_balloon.balloon_stats.hotplug_pages = 0; + xen_balloon.balloon_stats.balloon_hotplug = 0; set_online_page_callback(&xen_online_page); register_memory_notifier(&xen_memory_nb); diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index e555845..ef04236 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c @@ -126,19 +126,23 @@ module_exit(balloon_exit); } \ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) -BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); -BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); -BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); - -static DEVICE_ULONG_ATTR(schedule_delay, 0444, balloon_stats.schedule_delay); -static DEVICE_ULONG_ATTR(max_schedule_delay, 0644, balloon_stats.max_schedule_delay); -static DEVICE_ULONG_ATTR(retry_count, 0444, balloon_stats.retry_count); -static DEVICE_ULONG_ATTR(max_retry_count, 0644, balloon_stats.max_retry_count); +BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(xen_balloon.balloon_stats.current_pages)); +BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(xen_balloon.balloon_stats.balloon_low)); +BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(xen_balloon.balloon_stats.balloon_high)); + +static DEVICE_ULONG_ATTR(schedule_delay, 0444, + xen_balloon.balloon_stats.schedule_delay); +static DEVICE_ULONG_ATTR(max_schedule_delay, 0644, + xen_balloon.balloon_stats.max_schedule_delay); +static DEVICE_ULONG_ATTR(retry_count, 0444, + xen_balloon.balloon_stats.retry_count); +static DEVICE_ULONG_ATTR(max_retry_count, 0644, + xen_balloon.balloon_stats.max_retry_count); static ssize_t show_target_kb(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%lu\n", PAGES2KB(balloon_stats.target_pages)); + return sprintf(buf, "%lu\n", PAGES2KB(xen_balloon.balloon_stats.target_pages)); } static ssize_t store_target_kb(struct device *dev, @@ -167,7 +171,7 @@ static ssize_t show_target(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%llu\n", - (unsigned long long)balloon_stats.target_pages + (unsigned long long)xen_balloon.balloon_stats.target_pages << PAGE_SHIFT); } diff --git a/include/xen/balloon.h b/include/xen/balloon.h index a4c1c6a..1d7efae 100644 --- a/include/xen/balloon.h +++ b/include/xen/balloon.h @@ -21,7 +21,20 @@ struct balloon_stats { #endif }; -extern struct balloon_stats balloon_stats; +struct xen_balloon { + /* Mutex to protect xen_balloon across inflation / deflation / + * page migration. + */ + struct mutex balloon_mutex; + + /* List of ballooned pages managed by Xen balloon driver */ + struct list_head ballooned_pages; + + /* Memory statistic */ + struct balloon_stats balloon_stats; +}; + +extern struct xen_balloon xen_balloon; void balloon_set_new_target(unsigned long target); -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |