diff options
author | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-11-17 13:13:55 +0000 |
---|---|---|
committer | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-11-17 13:13:55 +0000 |
commit | 79085091e61e3fc04591343e6a0a2e7191438e2e (patch) | |
tree | fd03b1b2b31b9f079c899a4959ea6c6565158a02 | |
parent | 3d95c173026bf69250e7e2bf7e0a8117d55e23d3 (diff) | |
download | xen-79085091e61e3fc04591343e6a0a2e7191438e2e.tar.gz xen-79085091e61e3fc04591343e6a0a2e7191438e2e.tar.bz2 xen-79085091e61e3fc04591343e6a0a2e7191438e2e.zip |
bitkeeper revision 1.1159.170.37 (419b4e93x5uYHCJBfuNflDeySU4JpQ)
Clean up "foreign pages" patch to refelect what we pushed upstream to
the core Linux maintainers.
-rw-r--r-- | .rootkeys | 3 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/arch/xen/Kconfig | 4 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig | 3 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig | 3 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c | 2 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/page.h | 9 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/include/asm-xen/foreign_page.h | 33 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/include/linux/gfp.h | 141 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/include/linux/page-flags.h | 338 | ||||
-rw-r--r-- | linux-2.6.9-xen-sparse/mm/page_alloc.c | 9 |
10 files changed, 193 insertions, 352 deletions
@@ -237,6 +237,7 @@ 40f5623bxUbeGjkRrjDguCy_Gm8RLw linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/xor.h 40f5623bYNP7tHE2zX6YQxp9Zq2utQ linux-2.6.9-xen-sparse/include/asm-xen/ctrl_if.h 40f5623b3Eqs8pAc5WpPX8_jTzV2qw linux-2.6.9-xen-sparse/include/asm-xen/evtchn.h +419b4e9367PjTEvdjwavWN12BeBBXg linux-2.6.9-xen-sparse/include/asm-xen/foreign_page.h 412dfaeazclyNDM0cpnp60Yo4xulpQ linux-2.6.9-xen-sparse/include/asm-xen/gnttab.h 40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.9-xen-sparse/include/asm-xen/hypervisor.h 3f108af1ylCIm82H052FVTfXACBHrw linux-2.6.9-xen-sparse/include/asm-xen/linux-public/privcmd.h @@ -245,7 +246,7 @@ 4122466356eIBnC9ot44WSVVIFyhQA linux-2.6.9-xen-sparse/include/asm-xen/queues.h 3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.9-xen-sparse/include/asm-xen/xen_proc.h 4124d8c4aocX7A-jIbuGraWN84pxGQ linux-2.6.9-xen-sparse/include/linux/bio.h -4124f66fp5QwbDHEfoUIa7pqO5Xhag linux-2.6.9-xen-sparse/include/linux/page-flags.h +419b4e93z2S0gR17XTy8wg09JEwAhg linux-2.6.9-xen-sparse/include/linux/gfp.h 4124f66f4NaKNa0xPiGGykn9QaZk3w linux-2.6.9-xen-sparse/include/linux/skbuff.h 40f56a0ddHCSs3501MY4hRf22tctOw linux-2.6.9-xen-sparse/mkbuildtree 412f46c0LJuKAgSPGoC0Z1DEkLfuLA linux-2.6.9-xen-sparse/mm/memory.c diff --git a/linux-2.6.9-xen-sparse/arch/xen/Kconfig b/linux-2.6.9-xen-sparse/arch/xen/Kconfig index a9675229ae..13b3d1fed6 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/Kconfig +++ b/linux-2.6.9-xen-sparse/arch/xen/Kconfig @@ -111,10 +111,6 @@ config XEN_SCRUB_PAGES endmenu -config FOREIGN_PAGES - bool - default y - config HAVE_ARCH_DEV_ALLOC_SKB bool default y diff --git a/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig index 1532ab3dfb..80bd0dbc2a 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig +++ b/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig @@ -19,7 +19,6 @@ CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set CONFIG_XEN_WRITABLE_PAGETABLES=y CONFIG_XEN_SCRUB_PAGES=y -CONFIG_FOREIGN_PAGES=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_X86=y # CONFIG_X86_64 is not set @@ -158,7 +157,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_FRAME_POINTER is not set -CONFIG_4KSTACKS=y +# CONFIG_4KSTACKS is not set CONFIG_X86_BIOS_REBOOT=y CONFIG_X86_STD_RESOURCES=y CONFIG_PC=y diff --git a/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig b/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig index 24c57a3f50..d7b98c3b9d 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig +++ b/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig @@ -19,7 +19,6 @@ CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set CONFIG_XEN_WRITABLE_PAGETABLES=y CONFIG_XEN_SCRUB_PAGES=y -CONFIG_FOREIGN_PAGES=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_X86=y # CONFIG_X86_64 is not set @@ -119,7 +118,7 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_FRAME_POINTER is not set -CONFIG_4KSTACKS=y +# CONFIG_4KSTACKS is not set CONFIG_X86_BIOS_REBOOT=y CONFIG_X86_STD_RESOURCES=y CONFIG_PC=y diff --git a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c index 791c6ce3f8..2fadb97535 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c @@ -23,6 +23,8 @@ #include <asm/tlbflush.h> #include <asm/io.h> +#include <asm-xen/foreign_page.h> + void show_mem(void) { int total = 0, reserved = 0; diff --git a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/page.h b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/page.h index f8ddd5a8c5..dcea67475a 100644 --- a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/page.h +++ b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/page.h @@ -16,6 +16,15 @@ #include <linux/string.h> #include <linux/types.h> #include <asm-xen/xen-public/xen.h> +#include <asm-xen/foreign_page.h> + +#define arch_free_page(_page,_order) \ +({ int foreign = PageForeign(_page); \ + if (foreign) \ + (PageForeignDestructor(_page))(_page); \ + foreign; \ +}) +#define HAVE_ARCH_FREE_PAGE #ifdef CONFIG_XEN_SCRUB_PAGES #define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT) diff --git a/linux-2.6.9-xen-sparse/include/asm-xen/foreign_page.h b/linux-2.6.9-xen-sparse/include/asm-xen/foreign_page.h new file mode 100644 index 0000000000..688df84eb9 --- /dev/null +++ b/linux-2.6.9-xen-sparse/include/asm-xen/foreign_page.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * foreign_page.h + * + * Provide a "foreign" page type, that is owned by a foreign allocator and + * not the normal buddy allocator in page_alloc.c + * + * Copyright (c) 2004, K A Fraser + */ + +#ifndef __ASM_XEN_FOREIGN_PAGE_H__ +#define __ASM_XEN_FOREIGN_PAGE_H__ + +/* + * NOTE: PG_foreign must not conflict with any PG_ definition in page-flags.h!! + */ +#define PG_foreign 25 + +#define PageForeign(page) test_bit(PG_foreign, &(page)->flags) + +#define SetPageForeign(page, dtor) do { \ + set_bit(PG_foreign, &(page)->flags); \ + (page)->mapping = (void *)dtor; \ +} while (0) + +#define ClearPageForeign(page) do { \ + clear_bit(PG_foreign, &(page)->flags); \ + (page)->mapping = NULL; \ +} while (0) + +#define PageForeignDestructor(page) \ + ( (void (*) (struct page *)) (page)->mapping ) + +#endif /* __ASM_XEN_FOREIGN_PAGE_H__ */ diff --git a/linux-2.6.9-xen-sparse/include/linux/gfp.h b/linux-2.6.9-xen-sparse/include/linux/gfp.h new file mode 100644 index 0000000000..0c7098657a --- /dev/null +++ b/linux-2.6.9-xen-sparse/include/linux/gfp.h @@ -0,0 +1,141 @@ +#ifndef __LINUX_GFP_H +#define __LINUX_GFP_H + +#include <linux/mmzone.h> +#include <linux/stddef.h> +#include <linux/linkage.h> +#include <linux/config.h> + +struct vm_area_struct; + +/* + * GFP bitmasks.. + */ +/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */ +#define __GFP_DMA 0x01 +#define __GFP_HIGHMEM 0x02 + +/* + * Action modifiers - doesn't change the zoning + * + * __GFP_REPEAT: Try hard to allocate the memory, but the allocation attempt + * _might_ fail. This depends upon the particular VM implementation. + * + * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller + * cannot handle allocation failures. + * + * __GFP_NORETRY: The VM implementation must not retry indefinitely. + */ +#define __GFP_WAIT 0x10 /* Can wait and reschedule? */ +#define __GFP_HIGH 0x20 /* Should access emergency pools? */ +#define __GFP_IO 0x40 /* Can start physical IO? */ +#define __GFP_FS 0x80 /* Can call down to low-level FS? */ +#define __GFP_COLD 0x100 /* Cache-cold page required */ +#define __GFP_NOWARN 0x200 /* Suppress page allocation failure warning */ +#define __GFP_REPEAT 0x400 /* Retry the allocation. Might fail */ +#define __GFP_NOFAIL 0x800 /* Retry for ever. Cannot fail */ +#define __GFP_NORETRY 0x1000 /* Do not retry. Might fail */ +#define __GFP_NO_GROW 0x2000 /* Slab internal usage */ +#define __GFP_COMP 0x4000 /* Add compound page metadata */ + +#define __GFP_BITS_SHIFT 16 /* Room for 16 __GFP_FOO bits */ +#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1) + +/* if you forget to add the bitmask here kernel will crash, period */ +#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \ + __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \ + __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP) + +#define GFP_ATOMIC (__GFP_HIGH) +#define GFP_NOIO (__GFP_WAIT) +#define GFP_NOFS (__GFP_WAIT | __GFP_IO) +#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM) + +/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some + platforms, used as appropriate on others */ + +#define GFP_DMA __GFP_DMA + + +/* + * There is only one page-allocator function, and two main namespaces to + * it. The alloc_page*() variants return 'struct page *' and as such + * can allocate highmem pages, the *get*page*() variants return + * virtual kernel addresses to the allocated page(s). + */ + +/* + * We get the zone list from the current node and the gfp_mask. + * This zone list contains a maximum of MAXNODES*MAX_NR_ZONES zones. + * + * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets + * optimized to &contig_page_data at compile-time. + */ + +/* + * If arch_free_page returns non-zero then the generic free_page code can + * immediately bail: the arch-specific function has done all the work. + */ +#ifndef HAVE_ARCH_FREE_PAGE +static inline int arch_free_page(struct page *page, int order) +{ + /* Generic free_page must do the work. */ + return 0; +} +#endif + +extern struct page * +FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *)); + +static inline struct page *alloc_pages_node(int nid, unsigned int gfp_mask, + unsigned int order) +{ + if (unlikely(order >= MAX_ORDER)) + return NULL; + + return __alloc_pages(gfp_mask, order, + NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK)); +} + +#ifdef CONFIG_NUMA +extern struct page *alloc_pages_current(unsigned gfp_mask, unsigned order); + +static inline struct page * +alloc_pages(unsigned int gfp_mask, unsigned int order) +{ + if (unlikely(order >= MAX_ORDER)) + return NULL; + + return alloc_pages_current(gfp_mask, order); +} +extern struct page *alloc_page_vma(unsigned gfp_mask, + struct vm_area_struct *vma, unsigned long addr); +#else +#define alloc_pages(gfp_mask, order) \ + alloc_pages_node(numa_node_id(), gfp_mask, order) +#define alloc_page_vma(gfp_mask, vma, addr) alloc_pages(gfp_mask, 0) +#endif +#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) + +extern unsigned long FASTCALL(__get_free_pages(unsigned int gfp_mask, unsigned int order)); +extern unsigned long FASTCALL(get_zeroed_page(unsigned int gfp_mask)); + +#define __get_free_page(gfp_mask) \ + __get_free_pages((gfp_mask),0) + +#define __get_dma_pages(gfp_mask, order) \ + __get_free_pages((gfp_mask) | GFP_DMA,(order)) + +extern void FASTCALL(__free_pages(struct page *page, unsigned int order)); +extern void FASTCALL(free_pages(unsigned long addr, unsigned int order)); +extern void FASTCALL(free_hot_page(struct page *page)); +extern void FASTCALL(free_cold_page(struct page *page)); + +#define __free_page(page) __free_pages((page), 0) +#define free_page(addr) free_pages((addr),0) + +void page_alloc_init(void); + +#endif /* __LINUX_GFP_H */ diff --git a/linux-2.6.9-xen-sparse/include/linux/page-flags.h b/linux-2.6.9-xen-sparse/include/linux/page-flags.h deleted file mode 100644 index 9e4cd6d6d4..0000000000 --- a/linux-2.6.9-xen-sparse/include/linux/page-flags.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Macros for manipulating and testing page->flags - */ - -#ifndef PAGE_FLAGS_H -#define PAGE_FLAGS_H - -#include <linux/percpu.h> -#include <linux/cache.h> -#include <asm/pgtable.h> - -/* - * Various page->flags bits: - * - * PG_reserved is set for special pages, which can never be swapped out. Some - * of them might not even exist (eg empty_bad_page)... - * - * The PG_private bitflag is set if page->private contains a valid value. - * - * During disk I/O, PG_locked is used. This bit is set before I/O and - * reset when I/O completes. page_waitqueue(page) is a wait queue of all tasks - * waiting for the I/O on this page to complete. - * - * PG_uptodate tells whether the page's contents is valid. When a read - * completes, the page becomes uptodate, unless a disk I/O error happened. - * - * For choosing which pages to swap out, inode pages carry a PG_referenced bit, - * which is set any time the system accesses that page through the (mapping, - * index) hash table. This referenced bit, together with the referenced bit - * in the page tables, is used to manipulate page->age and move the page across - * the active, inactive_dirty and inactive_clean lists. - * - * Note that the referenced bit, the page->lru list_head and the active, - * inactive_dirty and inactive_clean lists are protected by the - * zone->lru_lock, and *NOT* by the usual PG_locked bit! - * - * PG_error is set to indicate that an I/O error occurred on this page. - * - * PG_arch_1 is an architecture specific page state bit. The generic code - * guarantees that this bit is cleared for a page when it first is entered into - * the page cache. - * - * PG_highmem pages are not permanently mapped into the kernel virtual address - * space, they need to be kmapped separately for doing IO on the pages. The - * struct page (these bits with information) are always mapped into kernel - * address space... - */ - -/* - * Don't use the *_dontuse flags. Use the macros. Otherwise you'll break - * locked- and dirty-page accounting. The top eight bits of page->flags are - * used for page->zone, so putting flag bits there doesn't work. - */ -#define PG_locked 0 /* Page is locked. Don't touch. */ -#define PG_error 1 -#define PG_referenced 2 -#define PG_uptodate 3 - -#define PG_dirty 4 -#define PG_lru 5 -#define PG_active 6 -#define PG_slab 7 /* slab debug (Suparna wants this) */ - -#define PG_highmem 8 -#define PG_checked 9 /* kill me in 2.5.<early>. */ -#define PG_arch_1 10 -#define PG_reserved 11 - -#define PG_private 12 /* Has something at ->private */ -#define PG_writeback 13 /* Page is under writeback */ -#define PG_nosave 14 /* Used for system suspend/resume */ -#define PG_compound 15 /* Part of a compound page */ - -#define PG_swapcache 16 /* Swap page: swp_entry_t in private */ -#define PG_mappedtodisk 17 /* Has blocks allocated on-disk */ -#define PG_reclaim 18 /* To be reclaimed asap */ - -#define PG_foreign 21 /* Page belongs to foreign allocator */ - - -/* - * Global page accounting. One instance per CPU. Only unsigned longs are - * allowed. - */ -struct page_state { - unsigned long nr_dirty; /* Dirty writeable pages */ - unsigned long nr_writeback; /* Pages under writeback */ - unsigned long nr_unstable; /* NFS unstable pages */ - unsigned long nr_page_table_pages;/* Pages used for pagetables */ - unsigned long nr_mapped; /* mapped into pagetables */ - unsigned long nr_slab; /* In slab */ -#define GET_PAGE_STATE_LAST nr_slab - - /* - * The below are zeroed by get_page_state(). Use get_full_page_state() - * to add up all these. - */ - unsigned long pgpgin; /* Disk reads */ - unsigned long pgpgout; /* Disk writes */ - unsigned long pswpin; /* swap reads */ - unsigned long pswpout; /* swap writes */ - unsigned long pgalloc_high; /* page allocations */ - - unsigned long pgalloc_normal; - unsigned long pgalloc_dma; - unsigned long pgfree; /* page freeings */ - unsigned long pgactivate; /* pages moved inactive->active */ - unsigned long pgdeactivate; /* pages moved active->inactive */ - - unsigned long pgfault; /* faults (major+minor) */ - unsigned long pgmajfault; /* faults (major only) */ - unsigned long pgrefill_high; /* inspected in refill_inactive_zone */ - unsigned long pgrefill_normal; - unsigned long pgrefill_dma; - - unsigned long pgsteal_high; /* total highmem pages reclaimed */ - unsigned long pgsteal_normal; - unsigned long pgsteal_dma; - unsigned long pgscan_kswapd_high;/* total highmem pages scanned */ - unsigned long pgscan_kswapd_normal; - - unsigned long pgscan_kswapd_dma; - unsigned long pgscan_direct_high;/* total highmem pages scanned */ - unsigned long pgscan_direct_normal; - unsigned long pgscan_direct_dma; - unsigned long pginodesteal; /* pages reclaimed via inode freeing */ - - unsigned long slabs_scanned; /* slab objects scanned */ - unsigned long kswapd_steal; /* pages reclaimed by kswapd */ - unsigned long kswapd_inodesteal;/* reclaimed via kswapd inode freeing */ - unsigned long pageoutrun; /* kswapd's calls to page reclaim */ - unsigned long allocstall; /* direct reclaim calls */ - - unsigned long pgrotated; /* pages rotated to tail of the LRU */ -}; - -DECLARE_PER_CPU(struct page_state, page_states); - -extern void get_page_state(struct page_state *ret); -extern void get_full_page_state(struct page_state *ret); -extern unsigned long __read_page_state(unsigned offset); - -#define read_page_state(member) \ - __read_page_state(offsetof(struct page_state, member)) - -#define mod_page_state(member, delta) \ - do { \ - unsigned long flags; \ - local_irq_save(flags); \ - __get_cpu_var(page_states).member += (delta); \ - local_irq_restore(flags); \ - } while (0) - - -#define inc_page_state(member) mod_page_state(member, 1UL) -#define dec_page_state(member) mod_page_state(member, 0UL - 1) -#define add_page_state(member,delta) mod_page_state(member, (delta)) -#define sub_page_state(member,delta) mod_page_state(member, 0UL - (delta)) - -#define mod_page_state_zone(zone, member, delta) \ - do { \ - unsigned long flags; \ - local_irq_save(flags); \ - if (is_highmem(zone)) \ - __get_cpu_var(page_states).member##_high += (delta);\ - else if (is_normal(zone)) \ - __get_cpu_var(page_states).member##_normal += (delta);\ - else \ - __get_cpu_var(page_states).member##_dma += (delta);\ - local_irq_restore(flags); \ - } while (0) - -/* - * Manipulation of page state flags - */ -#define PageLocked(page) \ - test_bit(PG_locked, &(page)->flags) -#define SetPageLocked(page) \ - set_bit(PG_locked, &(page)->flags) -#define TestSetPageLocked(page) \ - test_and_set_bit(PG_locked, &(page)->flags) -#define ClearPageLocked(page) \ - clear_bit(PG_locked, &(page)->flags) -#define TestClearPageLocked(page) \ - test_and_clear_bit(PG_locked, &(page)->flags) - -#define PageError(page) test_bit(PG_error, &(page)->flags) -#define SetPageError(page) set_bit(PG_error, &(page)->flags) -#define ClearPageError(page) clear_bit(PG_error, &(page)->flags) - -#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags) -#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags) -#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags) -#define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags) - -#define PageUptodate(page) test_bit(PG_uptodate, &(page)->flags) -#ifndef SetPageUptodate -#define SetPageUptodate(page) set_bit(PG_uptodate, &(page)->flags) -#endif -#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags) - -#define PageDirty(page) test_bit(PG_dirty, &(page)->flags) -#define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags) -#define TestSetPageDirty(page) test_and_set_bit(PG_dirty, &(page)->flags) -#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags) -#define TestClearPageDirty(page) test_and_clear_bit(PG_dirty, &(page)->flags) - -#define SetPageLRU(page) set_bit(PG_lru, &(page)->flags) -#define PageLRU(page) test_bit(PG_lru, &(page)->flags) -#define TestSetPageLRU(page) test_and_set_bit(PG_lru, &(page)->flags) -#define TestClearPageLRU(page) test_and_clear_bit(PG_lru, &(page)->flags) - -#define PageActive(page) test_bit(PG_active, &(page)->flags) -#define SetPageActive(page) set_bit(PG_active, &(page)->flags) -#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags) -#define TestClearPageActive(page) test_and_clear_bit(PG_active, &(page)->flags) -#define TestSetPageActive(page) test_and_set_bit(PG_active, &(page)->flags) - -#define PageSlab(page) test_bit(PG_slab, &(page)->flags) -#define SetPageSlab(page) set_bit(PG_slab, &(page)->flags) -#define ClearPageSlab(page) clear_bit(PG_slab, &(page)->flags) -#define TestClearPageSlab(page) test_and_clear_bit(PG_slab, &(page)->flags) -#define TestSetPageSlab(page) test_and_set_bit(PG_slab, &(page)->flags) - -#ifdef CONFIG_HIGHMEM -#define PageHighMem(page) test_bit(PG_highmem, &(page)->flags) -#else -#define PageHighMem(page) 0 /* needed to optimize away at compile time */ -#endif - -#define PageChecked(page) test_bit(PG_checked, &(page)->flags) -#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags) -#define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags) - -#define PageReserved(page) test_bit(PG_reserved, &(page)->flags) -#define SetPageReserved(page) set_bit(PG_reserved, &(page)->flags) -#define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags) -#define __ClearPageReserved(page) __clear_bit(PG_reserved, &(page)->flags) - -#define SetPagePrivate(page) set_bit(PG_private, &(page)->flags) -#define ClearPagePrivate(page) clear_bit(PG_private, &(page)->flags) -#define PagePrivate(page) test_bit(PG_private, &(page)->flags) - -#define PageWriteback(page) test_bit(PG_writeback, &(page)->flags) -#define SetPageWriteback(page) \ - do { \ - if (!test_and_set_bit(PG_writeback, \ - &(page)->flags)) \ - inc_page_state(nr_writeback); \ - } while (0) -#define TestSetPageWriteback(page) \ - ({ \ - int ret; \ - ret = test_and_set_bit(PG_writeback, \ - &(page)->flags); \ - if (!ret) \ - inc_page_state(nr_writeback); \ - ret; \ - }) -#define ClearPageWriteback(page) \ - do { \ - if (test_and_clear_bit(PG_writeback, \ - &(page)->flags)) \ - dec_page_state(nr_writeback); \ - } while (0) -#define TestClearPageWriteback(page) \ - ({ \ - int ret; \ - ret = test_and_clear_bit(PG_writeback, \ - &(page)->flags); \ - if (ret) \ - dec_page_state(nr_writeback); \ - ret; \ - }) - -#define PageNosave(page) test_bit(PG_nosave, &(page)->flags) -#define SetPageNosave(page) set_bit(PG_nosave, &(page)->flags) -#define TestSetPageNosave(page) test_and_set_bit(PG_nosave, &(page)->flags) -#define ClearPageNosave(page) clear_bit(PG_nosave, &(page)->flags) -#define TestClearPageNosave(page) test_and_clear_bit(PG_nosave, &(page)->flags) - -#define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags) -#define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags) -#define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags) - -#define PageReclaim(page) test_bit(PG_reclaim, &(page)->flags) -#define SetPageReclaim(page) set_bit(PG_reclaim, &(page)->flags) -#define ClearPageReclaim(page) clear_bit(PG_reclaim, &(page)->flags) -#define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags) - -#define PageCompound(page) test_bit(PG_compound, &(page)->flags) -#define SetPageCompound(page) set_bit(PG_compound, &(page)->flags) -#define ClearPageCompound(page) clear_bit(PG_compound, &(page)->flags) - -/* A foreign page uses a custom destructor rather than the buddy allocator. */ -#ifdef CONFIG_FOREIGN_PAGES -#define PageForeign(page) test_bit(PG_foreign, &(page)->flags) -#define SetPageForeign(page, dtor) do { \ - set_bit(PG_foreign, &(page)->flags); \ - (page)->mapping = (void *)dtor; \ -} while (0) -#define ClearPageForeign(page) do { \ - clear_bit(PG_foreign, &(page)->flags); \ - (page)->mapping = NULL; \ -} while (0) -#define PageForeignDestructor(page) \ - ( (void (*) (struct page *)) (page)->mapping ) -#else -#define PageForeign(page) 0 -#define PageForeignDestructor(page) void -#endif - -#ifdef CONFIG_SWAP -#define PageSwapCache(page) test_bit(PG_swapcache, &(page)->flags) -#define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags) -#define ClearPageSwapCache(page) clear_bit(PG_swapcache, &(page)->flags) -#else -#define PageSwapCache(page) 0 -#endif - -struct page; /* forward declaration */ - -int test_clear_page_dirty(struct page *page); -int __clear_page_dirty(struct page *page); -int test_clear_page_writeback(struct page *page); -int test_set_page_writeback(struct page *page); - -static inline void clear_page_dirty(struct page *page) -{ - test_clear_page_dirty(page); -} - -static inline void set_page_writeback(struct page *page) -{ - test_set_page_writeback(page); -} - -#endif /* PAGE_FLAGS_H */ diff --git a/linux-2.6.9-xen-sparse/mm/page_alloc.c b/linux-2.6.9-xen-sparse/mm/page_alloc.c index 9d560ae4c7..ce900f5015 100644 --- a/linux-2.6.9-xen-sparse/mm/page_alloc.c +++ b/linux-2.6.9-xen-sparse/mm/page_alloc.c @@ -275,7 +275,8 @@ void __free_pages_ok(struct page *page, unsigned int order) LIST_HEAD(list); int i; - arch_free_page(page, order); + if (arch_free_page(page, order)) + return; mod_page_state(pgfree, 1 << order); for (i = 0 ; i < (1 << order) ; ++i) @@ -505,10 +506,8 @@ static void fastcall free_hot_cold_page(struct page *page, int cold) struct per_cpu_pages *pcp; unsigned long flags; - if (PageForeign(page)) - return (PageForeignDestructor(page))(page); - - arch_free_page(page, 0); + if (arch_free_page(page, 0)) + return; kernel_map_pages(page, 1, 0); inc_page_state(pgfree); |