Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1191753 > unrolled thread
| Started by | David Vrabel <david.vrabel@citrix.com> |
|---|---|
| First post | 2015-07-24 13:50 +0200 |
| Last post | 2015-07-27 11:40 +0200 |
| Articles | 6 — 1 participant |
Back to article view | Back to linux.kernel
[PATCHv2 00/10] mm, xen/balloon: memory hotplug improvements David Vrabel <david.vrabel@citrix.com> - 2015-07-24 13:50 +0200
[PATCHv2 07/10] xen/balloon: make alloc_xenballoon_pages() always allocate low pages David Vrabel <david.vrabel@citrix.com> - 2015-07-24 13:50 +0200
[PATCHv2 09/10] x86/xen: export xen_alloc_p2m_entry() David Vrabel <david.vrabel@citrix.com> - 2015-07-24 14:00 +0200
[PATCHv2 04/10] xen/balloon: find non-conflicting regions to place hotplugged memory David Vrabel <david.vrabel@citrix.com> - 2015-07-24 14:00 +0200
[PATCHv2 10/10] xen/balloon: pre-allocate p2m entries for ballooned pages David Vrabel <david.vrabel@citrix.com> - 2015-07-24 14:20 +0200
Re: [Xen-devel] [PATCHv2 10/10] xen/balloon: pre-allocate p2m entries for ballooned pages David Vrabel <david.vrabel@citrix.com> - 2015-07-27 11:40 +0200
| From | David Vrabel <david.vrabel@citrix.com> |
|---|---|
| Date | 2015-07-24 13:50 +0200 |
| Subject | [PATCHv2 00/10] mm, xen/balloon: memory hotplug improvements |
| Message-ID | <pPJEd-4HJ-5@gated-at.bofh.it> |
The series improves the use of hotplug memory in the Xen balloon driver. - Reliably find a non-conflicting location for the hotplugged memory (this fixes memory hotplug in a number of cases, particularly in dom0). - Use hotplugged memory for alloc_xenballooned_pages() (keeping more memory available for the domain and reducing fragmentation of the p2m). Changes in v2: - New BP_WAIT state to signal the balloon process to wait for userspace to online the new memory. - Preallocate P2M entries in alloc_xenballooned_pages() so they do not need allocated later (in a context where GFP_KERNEL allocations are not possible). David -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | David Vrabel <david.vrabel@citrix.com> |
|---|---|
| Date | 2015-07-24 13:50 +0200 |
| Subject | [PATCHv2 07/10] xen/balloon: make alloc_xenballoon_pages() always allocate low pages |
| Message-ID | <pPJEf-4HJ-39@gated-at.bofh.it> |
| In reply to | #1191753 |
All users of alloc_xenballoon_pages() wanted low memory pages, so
remove the option for high memory.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
arch/x86/xen/grant-table.c | 2 +-
drivers/xen/balloon.c | 21 ++++++++-------------
drivers/xen/grant-table.c | 2 +-
drivers/xen/privcmd.c | 2 +-
drivers/xen/xenbus/xenbus_client.c | 3 +--
include/xen/balloon.h | 3 +--
6 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 1580e7a..e079500 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -133,7 +133,7 @@ static int __init xlated_setup_gnttab_pages(void)
kfree(pages);
return -ENOMEM;
}
- rc = alloc_xenballooned_pages(nr_grant_frames, pages, 0 /* lowmem */);
+ rc = alloc_xenballooned_pages(nr_grant_frames, pages);
if (rc) {
pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
nr_grant_frames, rc);
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index ced34cd..cc68a4d 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -136,17 +136,16 @@ static void balloon_append(struct page *page)
}
/* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
-static struct page *balloon_retrieve(bool prefer_highmem)
+static struct page *balloon_retrieve(bool require_lowmem)
{
struct page *page;
if (list_empty(&ballooned_pages))
return NULL;
- if (prefer_highmem)
- page = list_entry(ballooned_pages.prev, struct page, lru);
- else
- page = list_entry(ballooned_pages.next, struct page, lru);
+ page = list_entry(ballooned_pages.next, struct page, lru);
+ if (require_lowmem && PageHighMem(page))
+ return NULL;
list_del(&page->lru);
if (PageHighMem(page))
@@ -533,24 +532,20 @@ EXPORT_SYMBOL_GPL(balloon_set_new_target);
* alloc_xenballooned_pages - get pages that have been ballooned out
* @nr_pages: Number of pages to get
* @pages: pages returned
- * @highmem: allow highmem pages
* @return 0 on success, error otherwise
*/
-int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
+int alloc_xenballooned_pages(int nr_pages, struct page **pages)
{
int pgno = 0;
struct page *page;
mutex_lock(&balloon_mutex);
while (pgno < nr_pages) {
- page = balloon_retrieve(highmem);
- if (page && (highmem || !PageHighMem(page))) {
+ page = balloon_retrieve(true);
+ if (page) {
pages[pgno++] = page;
} else {
enum bp_state st;
- if (page)
- balloon_append(page);
- st = decrease_reservation(nr_pages - pgno,
- highmem ? GFP_HIGHUSER : GFP_USER);
+ st = decrease_reservation(nr_pages - pgno, GFP_USER);
if (st != BP_DONE)
goto out_undo;
}
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 62f591f..a4b702c 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -687,7 +687,7 @@ int gnttab_alloc_pages(int nr_pages, struct page **pages)
int i;
int ret;
- ret = alloc_xenballooned_pages(nr_pages, pages, false);
+ ret = alloc_xenballooned_pages(nr_pages, pages);
if (ret < 0)
return ret;
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 5a29616..59cfec9 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -401,7 +401,7 @@ static int alloc_empty_pages(struct vm_area_struct *vma, int numpgs)
if (pages == NULL)
return -ENOMEM;
- rc = alloc_xenballooned_pages(numpgs, pages, 0);
+ rc = alloc_xenballooned_pages(numpgs, pages);
if (rc != 0) {
pr_warn("%s Could not alloc %d pfns rc:%d\n", __func__,
numpgs, rc);
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 9ad3272..2a2da04 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -614,8 +614,7 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
if (!node)
return -ENOMEM;
- err = alloc_xenballooned_pages(nr_grefs, node->hvm.pages,
- false /* lowmem */);
+ err = alloc_xenballooned_pages(nr_grefs, node->hvm.pages);
if (err)
goto out_err;
diff --git a/include/xen/balloon.h b/include/xen/balloon.h
index c8aee7a..83efdeb 100644
--- a/include/xen/balloon.h
+++ b/include/xen/balloon.h
@@ -22,8 +22,7 @@ extern struct balloon_stats balloon_stats;
void balloon_set_new_target(unsigned long target);
-int alloc_xenballooned_pages(int nr_pages, struct page **pages,
- bool highmem);
+int alloc_xenballooned_pages(int nr_pages, struct page **pages);
void free_xenballooned_pages(int nr_pages, struct page **pages);
struct device;
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Vrabel <david.vrabel@citrix.com> |
|---|---|
| Date | 2015-07-24 14:00 +0200 |
| Subject | [PATCHv2 09/10] x86/xen: export xen_alloc_p2m_entry() |
| Message-ID | <pPJNV-4T4-5@gated-at.bofh.it> |
| In reply to | #1191753 |
Rename alloc_p2m() to xen_alloc_p2m_entry() and export it.
This is useful for ensuring that a p2m entry is allocated (i.e., not a
shared missing or identity entry) so that subsequent set_phys_to_machine()
calls will require no further allocations.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
arch/x86/include/asm/xen/page.h | 2 ++
arch/x86/xen/p2m.c | 16 ++++++++++------
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index c44a5d5..960b380 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -45,6 +45,8 @@ extern unsigned long *xen_p2m_addr;
extern unsigned long xen_p2m_size;
extern unsigned long xen_max_p2m_pfn;
+extern int xen_alloc_p2m_entry(unsigned long pfn);
+
extern unsigned long get_phys_to_machine(unsigned long pfn);
extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 8b7f18e..ef93ccf 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -503,7 +503,7 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
* the new pages are installed with cmpxchg; if we lose the race then
* simply free the page we allocated and use the one that's there.
*/
-static bool alloc_p2m(unsigned long pfn)
+int xen_alloc_p2m_entry(unsigned long pfn)
{
unsigned topidx, mididx;
unsigned long *top_mfn_p, *mid_mfn;
@@ -524,7 +524,7 @@ static bool alloc_p2m(unsigned long pfn)
/* PMD level is missing, allocate a new one */
ptep = alloc_p2m_pmd(addr, pte_pg);
if (!ptep)
- return false;
+ return -ENOMEM;
}
if (p2m_top_mfn) {
@@ -541,7 +541,7 @@ static bool alloc_p2m(unsigned long pfn)
mid_mfn = alloc_p2m_page();
if (!mid_mfn)
- return false;
+ return -ENOMEM;
p2m_mid_mfn_init(mid_mfn, p2m_missing);
@@ -567,7 +567,7 @@ static bool alloc_p2m(unsigned long pfn)
p2m = alloc_p2m_page();
if (!p2m)
- return false;
+ return -ENOMEM;
if (p2m_pfn == PFN_DOWN(__pa(p2m_missing)))
p2m_init(p2m);
@@ -590,8 +590,9 @@ static bool alloc_p2m(unsigned long pfn)
free_p2m_page(p2m);
}
- return true;
+ return 0;
}
+EXPORT_SYMBOL(xen_alloc_p2m);
unsigned long __init set_phys_range_identity(unsigned long pfn_s,
unsigned long pfn_e)
@@ -648,7 +649,10 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
{
if (unlikely(!__set_phys_to_machine(pfn, mfn))) {
- if (!alloc_p2m(pfn))
+ int ret;
+
+ ret = xen_alloc_p2m_entry(pfn);
+ if (ret < 0)
return false;
return __set_phys_to_machine(pfn, mfn);
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Vrabel <david.vrabel@citrix.com> |
|---|---|
| Date | 2015-07-24 14:00 +0200 |
| Subject | [PATCHv2 04/10] xen/balloon: find non-conflicting regions to place hotplugged memory |
| Message-ID | <pPJNV-4T4-25@gated-at.bofh.it> |
| In reply to | #1191753 |
Instead of placing hotplugged memory at the end of RAM (which may
conflict with PCI devices or reserved regions) use allocate_resource()
to get a new, suitably aligned resource that does not conflict.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
drivers/xen/balloon.c | 64 +++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 54 insertions(+), 10 deletions(-)
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index fd93369..29aeb8f 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -54,6 +54,7 @@
#include <linux/memory.h>
#include <linux/memory_hotplug.h>
#include <linux/percpu-defs.h>
+#include <linux/slab.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
@@ -208,6 +209,43 @@ static bool balloon_is_inflated(void)
return false;
}
+static struct resource *additional_memory_resource(phys_addr_t size)
+{
+ struct resource *res;
+ int ret;
+
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return NULL;
+
+ res->name = "System RAM";
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ ret = allocate_resource(&iomem_resource, res,
+ size, 0, -1,
+ PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL);
+ if (ret < 0) {
+ pr_err("Cannot allocate new System RAM resource\n");
+ kfree(res);
+ return NULL;
+ }
+
+ return res;
+}
+
+static void release_memory_resource(struct resource *resource)
+{
+ if (!resource)
+ return;
+
+ /*
+ * No need to reset region to identity mapped since we now
+ * know that no I/O can be in this region
+ */
+ release_resource(resource);
+ kfree(resource);
+}
+
/*
* reserve_additional_memory() adds memory region of size >= credit above
* max_pfn. New region is section aligned and size is modified to be multiple
@@ -221,13 +259,17 @@ static bool balloon_is_inflated(void)
static enum bp_state reserve_additional_memory(long credit)
{
+ struct resource *resource;
int nid, rc;
- u64 hotplug_start_paddr;
- unsigned long balloon_hotplug = credit;
+ unsigned long balloon_hotplug;
+
+ balloon_hotplug = round_up(credit, PAGES_PER_SECTION);
+
+ resource = additional_memory_resource(balloon_hotplug * PAGE_SIZE);
+ if (!resource)
+ goto err;
- hotplug_start_paddr = PFN_PHYS(SECTION_ALIGN_UP(max_pfn));
- balloon_hotplug = round_up(balloon_hotplug, PAGES_PER_SECTION);
- nid = memory_add_physaddr_to_nid(hotplug_start_paddr);
+ nid = memory_add_physaddr_to_nid(resource->start);
#ifdef CONFIG_XEN_HAVE_PVMMU
/*
@@ -242,21 +284,20 @@ static enum bp_state reserve_additional_memory(long credit)
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
unsigned long pfn, i;
- pfn = PFN_DOWN(hotplug_start_paddr);
+ pfn = PFN_DOWN(resource->start);
for (i = 0; i < balloon_hotplug; i++) {
if (!set_phys_to_machine(pfn + i, INVALID_P2M_ENTRY)) {
pr_warn("set_phys_to_machine() failed, no memory added\n");
- return BP_ECANCELED;
+ goto err;
}
}
}
#endif
- rc = add_memory(nid, hotplug_start_paddr, balloon_hotplug << PAGE_SHIFT);
-
+ rc = add_memory_resource(nid, resource);
if (rc) {
pr_warn("Cannot add additional memory (%i)\n", rc);
- return BP_ECANCELED;
+ goto err;
}
balloon_hotplug -= credit;
@@ -265,6 +306,9 @@ static enum bp_state reserve_additional_memory(long credit)
balloon_stats.balloon_hotplug = balloon_hotplug;
return BP_DONE;
+ err:
+ release_memory_resource(resource);
+ return BP_ECANCELED;
}
static void xen_online_page(struct page *page)
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Vrabel <david.vrabel@citrix.com> |
|---|---|
| Date | 2015-07-24 14:20 +0200 |
| Subject | [PATCHv2 10/10] xen/balloon: pre-allocate p2m entries for ballooned pages |
| Message-ID | <pPK7h-5uX-25@gated-at.bofh.it> |
| In reply to | #1191753 |
Pages returned by alloc_xenballooned_pages() will be used for grant
mapping which will call set_phys_to_machine() (in PV guests).
Ballooned pages are set as INVALID_P2M_ENTRY in the p2m and thus may
be using the (shared) missing tables and a subsequent
set_phys_to_machine() will need to allocate new tables.
Since the grant mapping may be done from a context that cannot sleep,
the p2m entries must already be allocated.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
drivers/xen/balloon.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index fd6970f3..8932d10 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -541,6 +541,7 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages)
{
int pgno = 0;
struct page *page;
+ int ret = -ENOMEM;
mutex_lock(&balloon_mutex);
@@ -550,6 +551,11 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages)
page = balloon_retrieve(true);
if (page) {
pages[pgno++] = page;
+#ifdef CONFIG_XEN_HAVE_PVMMU
+ ret = xen_alloc_p2m_entry(page_to_pfn(page));
+ if (ret < 0)
+ goto out_undo;
+#endif
} else {
enum bp_state st;
@@ -576,7 +582,7 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages)
out_undo:
mutex_unlock(&balloon_mutex);
free_xenballooned_pages(pgno, pages);
- return -ENOMEM;
+ return ret;
}
EXPORT_SYMBOL(alloc_xenballooned_pages);
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Vrabel <david.vrabel@citrix.com> |
|---|---|
| Date | 2015-07-27 11:40 +0200 |
| Subject | Re: [Xen-devel] [PATCHv2 10/10] xen/balloon: pre-allocate p2m entries for ballooned pages |
| Message-ID | <pQN34-62M-13@gated-at.bofh.it> |
| In reply to | #1191776 |
On 25/07/15 00:21, Julien Grall wrote:
> On 24/07/2015 12:47, David Vrabel wrote:
>> @@ -550,6 +551,11 @@ int alloc_xenballooned_pages(int nr_pages, struct
>> page **pages)
>> page = balloon_retrieve(true);
>> if (page) {
>> pages[pgno++] = page;
>> +#ifdef CONFIG_XEN_HAVE_PVMMU
>> + ret = xen_alloc_p2m_entry(page_to_pfn(page));
>
> Don't you want to call this function only when the guest is not using
> auto-translated physmap?
xen_alloc_p2m_entry() is a nop in auto-xlate guests, so no need for an
additional check here.
David
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web