This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / include / linux / mmzone.h
index f1e1a72..f13406a 100644 (file)
@@ -35,7 +35,7 @@ struct pglist_data;
  */
 #if defined(CONFIG_SMP)
 struct zone_padding {
-       int x;
+       char x[0];
 } ____cacheline_maxaligned_in_smp;
 #define ZONE_PADDING(name)     struct zone_padding name;
 #else
@@ -69,7 +69,34 @@ struct per_cpu_pageset {
 #define MAX_NR_ZONES           3       /* Sync this with ZONES_SHIFT */
 #define ZONES_SHIFT            2       /* ceil(log2(MAX_NR_ZONES)) */
 
+
+/*
+ * When a memory allocation must conform to specific limitations (such
+ * as being suitable for DMA) the caller will pass in hints to the
+ * allocator in the gfp_mask, in the zone modifier bits.  These bits
+ * are used to select a priority ordered list of memory zones which
+ * match the requested limits.  GFP_ZONEMASK defines which bits within
+ * the gfp_mask should be considered as zone modifiers.  Each valid
+ * combination of the zone modifier bits has a corresponding list
+ * of zones (in node_zonelists).  Thus for two zone modifiers there
+ * will be a maximum of 4 (2 ** 2) zonelists, for 3 modifiers there will
+ * be 8 (2 ** 3) zonelists.  GFP_ZONETYPES defines the number of possible
+ * combinations of zone modifiers in "zone modifier space".
+ */
 #define GFP_ZONEMASK   0x03
+/*
+ * As an optimisation any zone modifier bits which are only valid when
+ * no other zone modifier bits are set (loners) should be placed in
+ * the highest order bits of this field.  This allows us to reduce the
+ * extent of the zonelists thus saving space.  For example in the case
+ * of three zone modifier bits, we could require up to eight zonelists.
+ * If the left most zone modifier is a "loner" then the highest valid
+ * zonelist would be four allowing us to allocate only five zonelists.
+ * Use the first form when the left most bit is not a "loner", otherwise
+ * use the second.
+ */
+/* #define GFP_ZONETYPES       (GFP_ZONEMASK + 1) */           /* Non-loner */
+#define GFP_ZONETYPES  ((GFP_ZONEMASK + 1) / 2 + 1)            /* Loner */
 
 /*
  * On machines where it is needed (eg PCs) we divide physical memory
@@ -81,10 +108,7 @@ struct per_cpu_pageset {
  */
 
 struct zone {
-       /*
-        * Commonly accessed fields:
-        */
-       spinlock_t              lock;
+       /* Fields commonly accessed by the page allocator */
        unsigned long           free_pages;
        unsigned long           pages_min, pages_low, pages_high;
        /*
@@ -101,19 +125,27 @@ struct zone {
         */
        unsigned long           protection[MAX_NR_ZONES];
 
+       struct per_cpu_pageset  pageset[NR_CPUS];
+
+       /*
+        * free areas of different sizes
+        */
+       spinlock_t              lock;
+       struct free_area        free_area[MAX_ORDER];
+
+
        ZONE_PADDING(_pad1_)
 
+       /* Fields commonly accessed by the page reclaim scanner */
        spinlock_t              lru_lock;       
        struct list_head        active_list;
        struct list_head        inactive_list;
-       atomic_t                nr_scan_active;
-       atomic_t                nr_scan_inactive;
+       unsigned long           nr_scan_active;
+       unsigned long           nr_scan_inactive;
        unsigned long           nr_active;
        unsigned long           nr_inactive;
-       int                     all_unreclaimable; /* All pages pinned */
        unsigned long           pages_scanned;     /* since last reclaim */
-
-       ZONE_PADDING(_pad2_)
+       int                     all_unreclaimable; /* All pages pinned */
 
        /*
         * prev_priority holds the scanning priority for this zone.  It is
@@ -134,10 +166,9 @@ struct zone {
        int temp_priority;
        int prev_priority;
 
-       /*
-        * free areas of different sizes
-        */
-       struct free_area        free_area[MAX_ORDER];
+
+       ZONE_PADDING(_pad2_)
+       /* Rarely used or read-mostly fields */
 
        /*
         * wait_table           -- the array holding the hash table
@@ -167,10 +198,6 @@ struct zone {
        unsigned long           wait_table_size;
        unsigned long           wait_table_bits;
 
-       ZONE_PADDING(_pad3_)
-
-       struct per_cpu_pageset  pageset[NR_CPUS];
-
        /*
         * Discontig memory support fields.
         */
@@ -179,12 +206,13 @@ struct zone {
        /* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
        unsigned long           zone_start_pfn;
 
+       unsigned long           spanned_pages;  /* total size, including holes */
+       unsigned long           present_pages;  /* amount of memory (excluding holes) */
+
        /*
         * rarely used fields:
         */
        char                    *name;
-       unsigned long           spanned_pages;  /* total size, including holes */
-       unsigned long           present_pages;  /* amount of memory (excluding holes) */
 } ____cacheline_maxaligned_in_smp;
 
 
@@ -225,7 +253,7 @@ struct zonelist {
 struct bootmem_data;
 typedef struct pglist_data {
        struct zone node_zones[MAX_NR_ZONES];
-       struct zonelist node_zonelists[MAX_NR_ZONES];
+       struct zonelist node_zonelists[GFP_ZONETYPES];
        int nr_zones;
        struct page *node_mem_map;
        struct bootmem_data *bdata;
@@ -245,6 +273,8 @@ typedef struct pglist_data {
 extern int numnodes;
 extern struct pglist_data *pgdat_list;
 
+void __get_zone_counts(unsigned long *active, unsigned long *inactive,
+                       unsigned long *free, struct pglist_data *pgdat);
 void get_zone_counts(unsigned long *active, unsigned long *inactive,
                        unsigned long *free);
 void build_all_zonelists(void);
@@ -306,6 +336,15 @@ static inline struct zone *next_zone(struct zone *zone)
 #define for_each_zone(zone) \
        for (zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
 
+static inline int is_highmem_idx(int idx)
+{
+       return (idx == ZONE_HIGHMEM);
+}
+
+static inline int is_normal_idx(int idx)
+{
+       return (idx == ZONE_NORMAL);
+}
 /**
  * is_highmem - helper function to quickly check if a struct zone is a 
  *              highmem zone or not.  This is an attempt to keep references
@@ -314,21 +353,21 @@ static inline struct zone *next_zone(struct zone *zone)
  */
 static inline int is_highmem(struct zone *zone)
 {
-       return (zone - zone->zone_pgdat->node_zones == ZONE_HIGHMEM);
+       return (is_highmem_idx(zone - zone->zone_pgdat->node_zones));
 }
 
 static inline int is_normal(struct zone *zone)
 {
-       return (zone - zone->zone_pgdat->node_zones == ZONE_NORMAL);
+       return (is_normal_idx(zone - zone->zone_pgdat->node_zones));
 }
 
 /* These two functions are used to setup the per zone pages min values */
 struct ctl_table;
 struct file;
 int min_free_kbytes_sysctl_handler(struct ctl_table *, int, struct file *, 
-                                       void __user *, size_t *);
+                                       void __user *, size_t *, loff_t *);
 int lower_zone_protection_sysctl_handler(struct ctl_table *, int, struct file *,
-                                       void __user *, size_t *);
+                                       void __user *, size_t *, loff_t *);
 
 #include <linux/topology.h>
 /* Returns the number of the current Node. */
@@ -372,35 +411,6 @@ extern struct pglist_data contig_page_data;
 #error ZONES_SHIFT > MAX_ZONES_SHIFT
 #endif
 
-extern DECLARE_BITMAP(node_online_map, MAX_NUMNODES);
-
-#if defined(CONFIG_DISCONTIGMEM) || defined(CONFIG_NUMA)
-
-#define node_online(node)      test_bit(node, node_online_map)
-#define node_set_online(node)  set_bit(node, node_online_map)
-#define node_set_offline(node) clear_bit(node, node_online_map)
-static inline unsigned int num_online_nodes(void)
-{
-       int i, num = 0;
-
-       for(i = 0; i < MAX_NUMNODES; i++){
-               if (node_online(i))
-                       num++;
-       }
-       return num;
-}
-
-#else /* !CONFIG_DISCONTIGMEM && !CONFIG_NUMA */
-
-#define node_online(node) \
-       ({ BUG_ON((node) != 0); test_bit(node, node_online_map); })
-#define node_set_online(node) \
-       ({ BUG_ON((node) != 0); set_bit(node, node_online_map); })
-#define node_set_offline(node) \
-       ({ BUG_ON((node) != 0); clear_bit(node, node_online_map); })
-#define num_online_nodes()     1
-
-#endif /* CONFIG_DISCONTIGMEM || CONFIG_NUMA */
 #endif /* !__ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MMZONE_H */