|
@@ -396,7 +396,9 @@ void split_page(struct page *page, unsigned int order);
|
|
* We are going to use the flags for the page to node mapping if its in
|
|
* We are going to use the flags for the page to node mapping if its in
|
|
* there. This includes the case where there is no node, so it is implicit.
|
|
* there. This includes the case where there is no node, so it is implicit.
|
|
*/
|
|
*/
|
|
-#define FLAGS_HAS_NODE (NODES_WIDTH > 0 || NODES_SHIFT == 0)
|
|
|
|
|
|
+#if !(NODES_WIDTH > 0 || NODES_SHIFT == 0)
|
|
|
|
+#define NODE_NOT_IN_PAGE_FLAGS
|
|
|
|
+#endif
|
|
|
|
|
|
#ifndef PFN_SECTION_SHIFT
|
|
#ifndef PFN_SECTION_SHIFT
|
|
#define PFN_SECTION_SHIFT 0
|
|
#define PFN_SECTION_SHIFT 0
|
|
@@ -411,13 +413,18 @@ void split_page(struct page *page, unsigned int order);
|
|
#define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0))
|
|
#define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0))
|
|
#define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0))
|
|
#define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0))
|
|
|
|
|
|
-/* NODE:ZONE or SECTION:ZONE is used to lookup the zone from a page. */
|
|
|
|
-#if FLAGS_HAS_NODE
|
|
|
|
-#define ZONETABLE_SHIFT (NODES_SHIFT + ZONES_SHIFT)
|
|
|
|
|
|
+/* NODE:ZONE or SECTION:ZONE is used to ID a zone for the buddy allcator */
|
|
|
|
+#ifdef NODE_NOT_IN_PAGEFLAGS
|
|
|
|
+#define ZONEID_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT)
|
|
#else
|
|
#else
|
|
-#define ZONETABLE_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT)
|
|
|
|
|
|
+#define ZONEID_SHIFT (NODES_SHIFT + ZONES_SHIFT)
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#if ZONES_WIDTH > 0
|
|
|
|
+#define ZONEID_PGSHIFT ZONES_PGSHIFT
|
|
|
|
+#else
|
|
|
|
+#define ZONEID_PGSHIFT NODES_PGOFF
|
|
#endif
|
|
#endif
|
|
-#define ZONETABLE_PGSHIFT ZONES_PGSHIFT
|
|
|
|
|
|
|
|
#if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
|
|
#if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
|
|
#error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
|
|
#error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
|
|
@@ -426,23 +433,25 @@ void split_page(struct page *page, unsigned int order);
|
|
#define ZONES_MASK ((1UL << ZONES_WIDTH) - 1)
|
|
#define ZONES_MASK ((1UL << ZONES_WIDTH) - 1)
|
|
#define NODES_MASK ((1UL << NODES_WIDTH) - 1)
|
|
#define NODES_MASK ((1UL << NODES_WIDTH) - 1)
|
|
#define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1)
|
|
#define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1)
|
|
-#define ZONETABLE_MASK ((1UL << ZONETABLE_SHIFT) - 1)
|
|
|
|
|
|
+#define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1)
|
|
|
|
|
|
static inline enum zone_type page_zonenum(struct page *page)
|
|
static inline enum zone_type page_zonenum(struct page *page)
|
|
{
|
|
{
|
|
return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK;
|
|
return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK;
|
|
}
|
|
}
|
|
|
|
|
|
-struct zone;
|
|
|
|
-extern struct zone *zone_table[];
|
|
|
|
-
|
|
|
|
|
|
+/*
|
|
|
|
+ * The identification function is only used by the buddy allocator for
|
|
|
|
+ * determining if two pages could be buddies. We are not really
|
|
|
|
+ * identifying a zone since we could be using a the section number
|
|
|
|
+ * id if we have not node id available in page flags.
|
|
|
|
+ * We guarantee only that it will return the same value for two
|
|
|
|
+ * combinable pages in a zone.
|
|
|
|
+ */
|
|
static inline int page_zone_id(struct page *page)
|
|
static inline int page_zone_id(struct page *page)
|
|
{
|
|
{
|
|
- return (page->flags >> ZONETABLE_PGSHIFT) & ZONETABLE_MASK;
|
|
|
|
-}
|
|
|
|
-static inline struct zone *page_zone(struct page *page)
|
|
|
|
-{
|
|
|
|
- return zone_table[page_zone_id(page)];
|
|
|
|
|
|
+ BUILD_BUG_ON(ZONEID_PGSHIFT == 0 && ZONEID_MASK);
|
|
|
|
+ return (page->flags >> ZONEID_PGSHIFT) & ZONEID_MASK;
|
|
}
|
|
}
|
|
|
|
|
|
static inline unsigned long zone_to_nid(struct zone *zone)
|
|
static inline unsigned long zone_to_nid(struct zone *zone)
|
|
@@ -454,13 +463,20 @@ static inline unsigned long zone_to_nid(struct zone *zone)
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef NODE_NOT_IN_PAGE_FLAGS
|
|
|
|
+extern unsigned long page_to_nid(struct page *page);
|
|
|
|
+#else
|
|
static inline unsigned long page_to_nid(struct page *page)
|
|
static inline unsigned long page_to_nid(struct page *page)
|
|
{
|
|
{
|
|
- if (FLAGS_HAS_NODE)
|
|
|
|
- return (page->flags >> NODES_PGSHIFT) & NODES_MASK;
|
|
|
|
- else
|
|
|
|
- return zone_to_nid(page_zone(page));
|
|
|
|
|
|
+ return (page->flags >> NODES_PGSHIFT) & NODES_MASK;
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+static inline struct zone *page_zone(struct page *page)
|
|
|
|
+{
|
|
|
|
+ return &NODE_DATA(page_to_nid(page))->node_zones[page_zonenum(page)];
|
|
|
|
+}
|
|
|
|
+
|
|
static inline unsigned long page_to_section(struct page *page)
|
|
static inline unsigned long page_to_section(struct page *page)
|
|
{
|
|
{
|
|
return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
|
|
return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
|
|
@@ -477,6 +493,7 @@ static inline void set_page_node(struct page *page, unsigned long node)
|
|
page->flags &= ~(NODES_MASK << NODES_PGSHIFT);
|
|
page->flags &= ~(NODES_MASK << NODES_PGSHIFT);
|
|
page->flags |= (node & NODES_MASK) << NODES_PGSHIFT;
|
|
page->flags |= (node & NODES_MASK) << NODES_PGSHIFT;
|
|
}
|
|
}
|
|
|
|
+
|
|
static inline void set_page_section(struct page *page, unsigned long section)
|
|
static inline void set_page_section(struct page *page, unsigned long section)
|
|
{
|
|
{
|
|
page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT);
|
|
page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT);
|
|
@@ -947,8 +964,6 @@ extern void mem_init(void);
|
|
extern void show_mem(void);
|
|
extern void show_mem(void);
|
|
extern void si_meminfo(struct sysinfo * val);
|
|
extern void si_meminfo(struct sysinfo * val);
|
|
extern void si_meminfo_node(struct sysinfo *val, int nid);
|
|
extern void si_meminfo_node(struct sysinfo *val, int nid);
|
|
-extern void zonetable_add(struct zone *zone, int nid, enum zone_type zid,
|
|
|
|
- unsigned long pfn, unsigned long size);
|
|
|
|
|
|
|
|
#ifdef CONFIG_NUMA
|
|
#ifdef CONFIG_NUMA
|
|
extern void setup_per_cpu_pageset(void);
|
|
extern void setup_per_cpu_pageset(void);
|