xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
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

  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).