From: Wei Liu <wei.liu2@citrix.com>
To: xen-devel@lists.xen.org
Cc: Wei Liu <wei.liu2@citrix.com>,
ian.campbell@citrix.com, stefano.stabellini@eu.citrix.com,
david.vrabel@citrix.com, boris.ostrovsky@oracle.com
Subject: [PATCH RFC 03/10] xen/balloon: consolidate data structures
Date: Wed, 15 Oct 2014 16:54:12 +0100 [thread overview]
Message-ID: <1413388459-4663-4-git-send-email-wei.liu2@citrix.com> (raw)
In-Reply-To: <1413388459-4663-1-git-send-email-wei.liu2@citrix.com>
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@citrix.com>
---
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
next prev parent reply other threads:[~2014-10-15 15:54 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-15 15:54 [PATCH RFC 00/10] Xen balloon page compaction support Wei Liu
2014-10-15 15:54 ` [PATCH RFC 01/10] balloon_compaction: don't BUG() when it is not necessary Wei Liu
2014-10-15 15:54 ` [PATCH RFC 02/10] xen/balloon: fix code comment for free_xenballooned_pages Wei Liu
2014-10-15 15:54 ` Wei Liu [this message]
2014-10-15 15:54 ` [PATCH RFC 04/10] xen/balloon: factor out function to update balloon stats Wei Liu
2014-10-15 15:54 ` [PATCH RFC 05/10] xen/balloon: rework increase_reservation Wei Liu
2014-10-15 15:54 ` [PATCH RFC 06/10] xen/balloon: make use of generic balloon driver Wei Liu
2014-10-15 15:54 ` [PATCH RFC 07/10] xen/balloon: factor out some helper functions Wei Liu
2014-10-15 15:54 ` [PATCH RFC 08/10] xen/balloon: implement migratepage Wei Liu
2014-10-15 16:16 ` David Vrabel
2014-10-16 9:28 ` Ian Campbell
2014-10-15 15:54 ` [PATCH RFC 09/10] balloon: BALLOON_COMPACTION now depends on XEN_BALLOON Wei Liu
2014-10-15 15:54 ` [PATCH RFC 10/10] XXX: balloon bitmap and sysrq key to dump bitmap Wei Liu
2014-10-15 16:25 ` [PATCH RFC 00/10] Xen balloon page compaction support David Vrabel
2014-10-15 16:30 ` Wei Liu
2014-10-16 9:31 ` David Vrabel
2014-10-15 16:54 ` Andrew Cooper
2014-10-15 17:00 ` Wei Liu
2014-10-15 17:14 ` Andrew Cooper
2014-10-16 9:12 ` Wei Liu
2014-10-16 9:26 ` Ian Campbell
2014-10-17 12:35 ` Andrew Cooper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1413388459-4663-4-git-send-email-wei.liu2@citrix.com \
--to=wei.liu2@citrix.com \
--cc=boris.ostrovsky@oracle.com \
--cc=david.vrabel@citrix.com \
--cc=ian.campbell@citrix.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).