[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] linux/x86: revert the effect of xen_limit_pages_to_max_mfn()



As usual, written and tested on 2.6.27.7 and made apply to the 2.6.18
tree without further testing.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

Index: head-2008-11-25/arch/i386/mm/hypervisor.c
===================================================================
--- head-2008-11-25.orig/arch/i386/mm/hypervisor.c      2008-11-17 
14:07:20.000000000 +0100
+++ head-2008-11-25/arch/i386/mm/hypervisor.c   2008-11-26 15:01:10.000000000 
+0100
@@ -437,6 +437,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)
 {
@@ -465,16 +474,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);
@@ -560,7 +581,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);
 
Index: head-2008-11-25/arch/i386/mm/pgtable-xen.c
===================================================================
--- head-2008-11-25.orig/arch/i386/mm/pgtable-xen.c     2008-11-17 
14:07:20.000000000 +0100
+++ head-2008-11-25/arch/i386/mm/pgtable-xen.c  2008-11-26 10:48:36.000000000 
+0100
@@ -146,6 +146,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;
@@ -156,7 +162,7 @@ struct page *pte_alloc_one(struct mm_struct
        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;
Index: head-2008-11-25/arch/x86_64/mm/pageattr-xen.c
===================================================================
--- head-2008-11-25.orig/arch/x86_64/mm/pageattr-xen.c  2008-11-17 
14:07:20.000000000 +0100
+++ head-2008-11-25/arch/x86_64/mm/pageattr-xen.c       2008-11-26 
10:48:36.000000000 +0100
@@ -216,6 +216,12 @@ void _arch_exit_mmap(struct mm_struct *
                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;
@@ -222,7 +228,7 @@ struct page *pte_alloc_one(struct mm_struct
 
        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;
Index: head-2008-11-25/drivers/xen/core/gnttab.c
===================================================================
--- head-2008-11-25.orig/drivers/xen/core/gnttab.c      2008-11-26 
11:39:29.000000000 +0100
+++ head-2008-11-25/drivers/xen/core/gnttab.c   2008-11-26 10:41:13.000000000 
+0100
@@ -506,8 +506,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);
Index: head-2008-11-25/drivers/xen/netback/netback.c
===================================================================
--- head-2008-11-25.orig/drivers/xen/netback/netback.c  2008-11-06 
09:53:04.000000000 +0100
+++ head-2008-11-25/drivers/xen/netback/netback.c       2008-11-26 
13:39:51.000000000 +0100
@@ -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);
@@ -1453,8 +1452,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));
 }
 
Index: head-2008-11-25/include/linux/page-flags.h
===================================================================
--- head-2008-11-25.orig/include/linux/page-flags.h     2008-11-26 
11:37:58.000000000 +0100
+++ head-2008-11-25/include/linux/page-flags.h  2008-11-26 10:40:38.000000000 
+0100
@@ -285,15 +285,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 */
 
Index: head-2008-11-25/mm/page_alloc.c
===================================================================
--- head-2008-11-25.orig/mm/page_alloc.c        2008-11-26 11:37:58.000000000 
+0100
+++ head-2008-11-25/mm/page_alloc.c     2008-11-26 10:38:38.000000000 +0100
@@ -505,7 +505,7 @@ static void __free_pages_ok(struct page 
 
 #ifdef CONFIG_XEN
        if (PageForeign(page)) {
-               PageForeignDestructor(page);
+               PageForeignDestructor(page, order);
                return;
        }
 #endif
@@ -803,7 +803,7 @@ static void free_hot_cold_page(struct pa
 
 #ifdef CONFIG_XEN
        if (PageForeign(page)) {
-               PageForeignDestructor(page);
+               PageForeignDestructor(page, 0);
                return;
        }
 #endif



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.