Mailing List Archive

[linux-2.6.18-xen] linux/x86: revert the effect of xen_limit_pages_to_max_mfn()
# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1227879058 0
# Node ID 39a8680e7a70a28ce639c507fb6a9bc0aa7d8f14
# Parent d545a95fca739d0b1963b73a9eb64ea64a244e76
linux/x86: revert the effect of xen_limit_pages_to_max_mfn()

Signed-off-by: Jan Beulich <jbeulich@novell.com>
---
arch/i386/mm/hypervisor.c | 43 +++++++++++++++++++++++++++++++++++++-----
arch/i386/mm/pgtable-xen.c | 8 ++++++-
arch/x86_64/mm/pageattr-xen.c | 8 ++++++-
drivers/xen/core/gnttab.c | 5 ++--
drivers/xen/netback/netback.c | 6 ++---
include/linux/page-flags.h | 6 ++---
mm/page_alloc.c | 4 +--
7 files changed, 63 insertions(+), 17 deletions(-)

diff -r d545a95fca73 -r 39a8680e7a70 arch/i386/mm/hypervisor.c
--- a/arch/i386/mm/hypervisor.c Fri Nov 28 13:30:27 2008 +0000
+++ b/arch/i386/mm/hypervisor.c Fri Nov 28 13:30:58 2008 +0000
@@ -374,6 +374,15 @@ void xen_destroy_contiguous_region(unsig
}
EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);

+static void undo_limit_pages(struct page *pages, unsigned int order)
+{
+ BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
+ BUG_ON(order > MAX_CONTIG_ORDER);
+ xen_limit_pages_to_max_mfn(pages, order, 0);
+ ClearPageForeign(pages);
+ __free_pages(pages, order);
+}
+
int xen_limit_pages_to_max_mfn(
struct page *pages, unsigned int order, unsigned int address_bits)
{
@@ -402,16 +411,28 @@ int xen_limit_pages_to_max_mfn(
if (unlikely(order > MAX_CONTIG_ORDER))
return -ENOMEM;

- bitmap_zero(limit_map, 1U << order);
+ if (address_bits) {
+ if (address_bits < PAGE_SHIFT)
+ return -EINVAL;
+ bitmap_zero(limit_map, 1U << order);
+ } else if (order) {
+ BUILD_BUG_ON(sizeof(pages->index) != sizeof(*limit_map));
+ for (i = 0; i < BITS_TO_LONGS(1U << order); ++i)
+ limit_map[i] = pages[i + 1].index;
+ } else
+ __set_bit(0, limit_map);
+
set_xen_guest_handle(exchange.in.extent_start, in_frames);
set_xen_guest_handle(exchange.out.extent_start, out_frames);

/* 0. Scrub the pages. */
for (i = 0, n = 0; i < 1U<<order ; i++) {
page = &pages[i];
- if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - PAGE_SHIFT)))
- continue;
- __set_bit(i, limit_map);
+ if (address_bits) {
+ if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - PAGE_SHIFT)))
+ continue;
+ __set_bit(i, limit_map);
+ }

if (!PageHighMem(page))
scrub_pages(page_address(page), 1);
@@ -497,7 +518,19 @@ int xen_limit_pages_to_max_mfn(

balloon_unlock(flags);

- return success ? 0 : -ENOMEM;
+ if (!success)
+ return -ENOMEM;
+
+ if (address_bits) {
+ if (order) {
+ BUILD_BUG_ON(sizeof(*limit_map) != sizeof(pages->index));
+ for (i = 0; i < BITS_TO_LONGS(1U << order); ++i)
+ pages[i + 1].index = limit_map[i];
+ }
+ SetPageForeign(pages, undo_limit_pages);
+ }
+
+ return 0;
}
EXPORT_SYMBOL_GPL(xen_limit_pages_to_max_mfn);

diff -r d545a95fca73 -r 39a8680e7a70 arch/i386/mm/pgtable-xen.c
--- a/arch/i386/mm/pgtable-xen.c Fri Nov 28 13:30:27 2008 +0000
+++ b/arch/i386/mm/pgtable-xen.c Fri Nov 28 13:30:58 2008 +0000
@@ -152,6 +152,12 @@ pte_t *pte_alloc_one_kernel(struct mm_st
return pte;
}

+static void _pte_free(struct page *page, unsigned int order)
+{
+ BUG_ON(order);
+ pte_free(page);
+}
+
struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
struct page *pte;
@@ -162,7 +168,7 @@ struct page *pte_alloc_one(struct mm_str
pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
#endif
if (pte) {
- SetPageForeign(pte, pte_free);
+ SetPageForeign(pte, _pte_free);
init_page_count(pte);
}
return pte;
diff -r d545a95fca73 -r 39a8680e7a70 arch/x86_64/mm/pageattr-xen.c
--- a/arch/x86_64/mm/pageattr-xen.c Fri Nov 28 13:30:27 2008 +0000
+++ b/arch/x86_64/mm/pageattr-xen.c Fri Nov 28 13:30:58 2008 +0000
@@ -248,13 +248,19 @@ void _arch_exit_mmap(struct mm_struct *m
mm_unpin(mm);
}

+static void _pte_free(struct page *page, unsigned int order)
+{
+ BUG_ON(order);
+ pte_free(page);
+}
+
struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
struct page *pte;

pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
if (pte) {
- SetPageForeign(pte, pte_free);
+ SetPageForeign(pte, _pte_free);
init_page_count(pte);
}
return pte;
diff -r d545a95fca73 -r 39a8680e7a70 drivers/xen/core/gnttab.c
--- a/drivers/xen/core/gnttab.c Fri Nov 28 13:30:27 2008 +0000
+++ b/drivers/xen/core/gnttab.c Fri Nov 28 13:30:58 2008 +0000
@@ -505,8 +505,9 @@ static int gnttab_map(unsigned int start
return 0;
}

-static void gnttab_page_free(struct page *page)
-{
+static void gnttab_page_free(struct page *page, unsigned int order)
+{
+ BUG_ON(order);
ClearPageForeign(page);
gnttab_reset_grant_page(page);
put_page(page);
diff -r d545a95fca73 -r 39a8680e7a70 drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c Fri Nov 28 13:30:27 2008 +0000
+++ b/drivers/xen/netback/netback.c Fri Nov 28 13:30:58 2008 +0000
@@ -55,7 +55,6 @@ struct netbk_tx_pending_inuse {
};

static void netif_idx_release(u16 pending_idx);
-static void netif_page_release(struct page *page);
static void make_tx_response(netif_t *netif,
netif_tx_request_t *txp,
s8 st);
@@ -1436,8 +1435,9 @@ static void netif_idx_release(u16 pendin
tasklet_schedule(&net_tx_tasklet);
}

-static void netif_page_release(struct page *page)
-{
+static void netif_page_release(struct page *page, unsigned int order)
+{
+ BUG_ON(order);
netif_idx_release(netif_page_index(page));
}

diff -r d545a95fca73 -r 39a8680e7a70 include/linux/page-flags.h
--- a/include/linux/page-flags.h Fri Nov 28 13:30:27 2008 +0000
+++ b/include/linux/page-flags.h Fri Nov 28 13:30:58 2008 +0000
@@ -252,15 +252,15 @@
#define PageForeign(page) test_bit(PG_foreign, &(page)->flags)
#define SetPageForeign(_page, dtor) do { \
set_bit(PG_foreign, &(_page)->flags); \
- BUG_ON((dtor) == (void (*)(struct page *))0); \
+ BUG_ON((dtor) == (void (*)(struct page *, unsigned int))0); \
(_page)->index = (long)(dtor); \
} while (0)
#define ClearPageForeign(page) do { \
clear_bit(PG_foreign, &(page)->flags); \
(page)->index = 0; \
} while (0)
-#define PageForeignDestructor(_page) \
- ((void (*)(struct page *))(_page)->index)(_page)
+#define PageForeignDestructor(_page, order) \
+ ((void (*)(struct page *, unsigned int))(_page)->index)(_page, order)

struct page; /* forward declaration */

diff -r d545a95fca73 -r 39a8680e7a70 mm/page_alloc.c
--- a/mm/page_alloc.c Fri Nov 28 13:30:27 2008 +0000
+++ b/mm/page_alloc.c Fri Nov 28 13:30:58 2008 +0000
@@ -453,7 +453,7 @@ static void __free_pages_ok(struct page

#ifdef CONFIG_XEN
if (PageForeign(page)) {
- PageForeignDestructor(page);
+ PageForeignDestructor(page, order);
return;
}
#endif
@@ -737,7 +737,7 @@ static void fastcall free_hot_cold_page(

#ifdef CONFIG_XEN
if (PageForeign(page)) {
- PageForeignDestructor(page);
+ PageForeignDestructor(page, 0);
return;
}
#endif

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog