[PATCH] own header file for struct page
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Wed, 27 Sep 2006 08:50:01 +0000 (01:50 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 27 Sep 2006 15:26:12 +0000 (08:26 -0700)
This moves the definition of struct page from mm.h to its own header file
page-struct.h.  This is a prereq to fix SetPageUptodate which is broken on
s390:

#define SetPageUptodate(_page)
       do {
               struct page *__page = (_page);
               if (!test_and_set_bit(PG_uptodate, &__page->flags))
                       page_test_and_clear_dirty(_page);
       } while (0)

_page gets used twice in this macro which can cause subtle bugs.  Using
__page for the page_test_and_clear_dirty call doesn't work since it causes
yet another problem with the page_test_and_clear_dirty macro as well.

In order to avoid all these problems caused by macros it seems to be a good
idea to get rid of them and convert them to static inline functions.
Because of header file include order it's necessary to have a seperate
header file for the struct page definition.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
include/linux/mm.h
include/linux/mm_types.h [new file with mode: 0644]
include/linux/mmzone.h

index 9d046db31e7663899b112f1276b3cf7f5fdaa861..7477fb59c4f27eb9c495d89e8c31b2e70b7b0b7c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mutex.h>
 #include <linux/debug_locks.h>
 #include <linux/backing-dev.h>
+#include <linux/mm_types.h>
 
 struct mempolicy;
 struct anon_vma;
@@ -215,62 +216,6 @@ struct vm_operations_struct {
 struct mmu_gather;
 struct inode;
 
-/*
- * Each physical page in the system has a struct page associated with
- * it to keep track of whatever it is we are using the page for at the
- * moment. Note that we have no way to track which tasks are using
- * a page, though if it is a pagecache page, rmap structures can tell us
- * who is mapping it.
- */
-struct page {
-       unsigned long flags;            /* Atomic flags, some possibly
-                                        * updated asynchronously */
-       atomic_t _count;                /* Usage count, see below. */
-       atomic_t _mapcount;             /* Count of ptes mapped in mms,
-                                        * to show when page is mapped
-                                        * & limit reverse map searches.
-                                        */
-       union {
-           struct {
-               unsigned long private;          /* Mapping-private opaque data:
-                                                * usually used for buffer_heads
-                                                * if PagePrivate set; used for
-                                                * swp_entry_t if PageSwapCache;
-                                                * indicates order in the buddy
-                                                * system if PG_buddy is set.
-                                                */
-               struct address_space *mapping;  /* If low bit clear, points to
-                                                * inode address_space, or NULL.
-                                                * If page mapped as anonymous
-                                                * memory, low bit is set, and
-                                                * it points to anon_vma object:
-                                                * see PAGE_MAPPING_ANON below.
-                                                */
-           };
-#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
-           spinlock_t ptl;
-#endif
-       };
-       pgoff_t index;                  /* Our offset within mapping. */
-       struct list_head lru;           /* Pageout list, eg. active_list
-                                        * protected by zone->lru_lock !
-                                        */
-       /*
-        * On machines where all RAM is mapped into kernel address space,
-        * we can simply calculate the virtual address. On machines with
-        * highmem some memory is mapped into kernel virtual memory
-        * dynamically, so we need a place to store that address.
-        * Note that this field could be 16 bits on x86 ... ;)
-        *
-        * Architectures with slow multiplication can define
-        * WANT_PAGE_VIRTUAL in asm/page.h
-        */
-#if defined(WANT_PAGE_VIRTUAL)
-       void *virtual;                  /* Kernel virtual address (NULL if
-                                          not kmapped, ie. highmem) */
-#endif /* WANT_PAGE_VIRTUAL */
-};
-
 #define page_private(page)             ((page)->private)
 #define set_page_private(page, v)      ((page)->private = (v))
 
@@ -546,11 +491,6 @@ static inline void set_page_links(struct page *page, enum zone_type zone,
  */
 #include <linux/vmstat.h>
 
-#ifndef CONFIG_DISCONTIGMEM
-/* The array of struct pages - for discontigmem use pgdat->lmem_map */
-extern struct page *mem_map;
-#endif
-
 static __always_inline void *lowmem_page_address(struct page *page)
 {
        return __va(page_to_pfn(page) << PAGE_SHIFT);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
new file mode 100644 (file)
index 0000000..c3852fd
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef _LINUX_MM_TYPES_H
+#define _LINUX_MM_TYPES_H
+
+#include <linux/types.h>
+#include <linux/threads.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+struct address_space;
+
+/*
+ * Each physical page in the system has a struct page associated with
+ * it to keep track of whatever it is we are using the page for at the
+ * moment. Note that we have no way to track which tasks are using
+ * a page, though if it is a pagecache page, rmap structures can tell us
+ * who is mapping it.
+ */
+struct page {
+       unsigned long flags;            /* Atomic flags, some possibly
+                                        * updated asynchronously */
+       atomic_t _count;                /* Usage count, see below. */
+       atomic_t _mapcount;             /* Count of ptes mapped in mms,
+                                        * to show when page is mapped
+                                        * & limit reverse map searches.
+                                        */
+       union {
+           struct {
+               unsigned long private;          /* Mapping-private opaque data:
+                                                * usually used for buffer_heads
+                                                * if PagePrivate set; used for
+                                                * swp_entry_t if PageSwapCache;
+                                                * indicates order in the buddy
+                                                * system if PG_buddy is set.
+                                                */
+               struct address_space *mapping;  /* If low bit clear, points to
+                                                * inode address_space, or NULL.
+                                                * If page mapped as anonymous
+                                                * memory, low bit is set, and
+                                                * it points to anon_vma object:
+                                                * see PAGE_MAPPING_ANON below.
+                                                */
+           };
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+           spinlock_t ptl;
+#endif
+       };
+       pgoff_t index;                  /* Our offset within mapping. */
+       struct list_head lru;           /* Pageout list, eg. active_list
+                                        * protected by zone->lru_lock !
+                                        */
+       /*
+        * On machines where all RAM is mapped into kernel address space,
+        * we can simply calculate the virtual address. On machines with
+        * highmem some memory is mapped into kernel virtual memory
+        * dynamically, so we need a place to store that address.
+        * Note that this field could be 16 bits on x86 ... ;)
+        *
+        * Architectures with slow multiplication can define
+        * WANT_PAGE_VIRTUAL in asm/page.h
+        */
+#if defined(WANT_PAGE_VIRTUAL)
+       void *virtual;                  /* Kernel virtual address (NULL if
+                                          not kmapped, ie. highmem) */
+#endif /* WANT_PAGE_VIRTUAL */
+};
+
+#endif /* _LINUX_MM_TYPES_H */
index 1b0680cd84d2f04abd3352a58ca695cc3e3aeec4..562cf7a8f3ee3cce0c1a5c6d3aba2cb2c86072d8 100644 (file)
@@ -314,6 +314,11 @@ struct node_active_region {
 };
 #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
 
+#ifndef CONFIG_DISCONTIGMEM
+/* The array of struct pages - for discontigmem use pgdat->lmem_map */
+extern struct page *mem_map;
+#endif
+
 /*
  * The pg_data_t structure is used in machines with CONFIG_DISCONTIGMEM
  * (mostly NUMA machines?) to denote a higher-level memory zone than the